Port readline lib into gnu system tree.

Really we don't need copy of this library into each program
(gdb f.e.)

P.S. it is much cleaner port than /usr/ports version and based
on /usr/ports version. /usr/ports version will be removed.
This commit is contained in:
Andrey A. Chernov 1994-05-09 15:59:10 +00:00
parent 494578e684
commit 8a67c71748
25 changed files with 13338 additions and 0 deletions

257
gnu/lib/libreadline/COPYING Normal file
View File

@ -0,0 +1,257 @@
GNU GENERAL PUBLIC LICENSE
Version 1, February 1989
Copyright (C) 1989 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
The Free Software Foundation has exempted Bash from the requirement of
Paragraph 2c of the General Public License. This is to say, there is
no requirement for Bash to print a notice when it is started
interactively in the usual way. We made this exception because users
and standards expect shells not to print such messages. This
exception applies to any program that serves as a shell and that is
based primarily on Bash as opposed to other GNU software.
Preamble
The license agreements of most software companies try to keep users
at the mercy of those companies. By contrast, our General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. The
General Public License applies to the Free Software Foundation's
software and to any other program whose authors commit to using it.
You can use it for your programs, too.
When we speak of free software, we are referring to freedom, not
price. Specifically, the General Public License is designed to make
sure that you have the freedom to give away or sell copies of free
software, that you receive source code or can get it if you want it,
that you can change the software or use pieces of it in new free
programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of a such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must tell them their rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any program or other work which
contains a notice placed by the copyright holder saying it may be
distributed under the terms of this General Public License. The
"Program", below, refers to any such program or work, and a "work based
on the Program" means either the Program or any work containing the
Program or a portion of it, either verbatim or with modifications. Each
licensee is addressed as "you".
1. You may copy and distribute verbatim copies of the Program's source
code as you receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice and
disclaimer of warranty; keep intact all the notices that refer to this
General Public License and to the absence of any warranty; and give any
other recipients of the Program a copy of this General Public License
along with the Program. You may charge a fee for the physical act of
transferring a copy.
2. You may modify your copy or copies of the Program or any portion of
it, and copy and distribute such modifications under the terms of Paragraph
1 above, provided that you also do the following:
a) cause the modified files to carry prominent notices stating that
you changed the files and the date of any change; and
b) cause the whole of any work that you distribute or publish, that
in whole or in part contains the Program or any part thereof, either
with or without modifications, to be licensed at no charge to all
third parties under the terms of this General Public License (except
that you may choose to grant warranty protection to some or all
third parties, at your option).
c) If the modified program normally reads commands interactively when
run, you must cause it, when started running for such interactive use
in the simplest and most usual way, to print or display an
announcement including an appropriate copyright notice and a notice
that there is no warranty (or else, saying that you provide a
warranty) and that users may redistribute the program under these
conditions, and telling the user how to view a copy of this General
Public License.
d) You may charge a fee for the physical act of transferring a
copy, and you may at your option offer warranty protection in
exchange for a fee.
Mere aggregation of another independent work with the Program (or its
derivative) on a volume of a storage or distribution medium does not bring
the other work under the scope of these terms.
3. You may copy and distribute the Program (or a portion or derivative of
it, under Paragraph 2) in object code or executable form under the terms of
Paragraphs 1 and 2 above provided that you also do one of the following:
a) accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of
Paragraphs 1 and 2 above; or,
b) accompany it with a written offer, valid for at least three
years, to give any third party free (except for a nominal charge
for the cost of distribution) a complete machine-readable copy of the
corresponding source code, to be distributed under the terms of
Paragraphs 1 and 2 above; or,
c) accompany it with the information you received as to where the
corresponding source code may be obtained. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form alone.)
Source code for a work means the preferred form of the work for making
modifications to it. For an executable file, complete source code means
all the source code for all modules it contains; but, as a special
exception, it need not include source code for modules which are standard
libraries that accompany the operating system on which the executable
file runs, or for standard header files or definitions files that
accompany that operating system.
4. You may not copy, modify, sublicense, distribute or transfer the
Program except as expressly provided under this General Public License.
Any attempt otherwise to copy, modify, sublicense, distribute or transfer
the Program is void, and will automatically terminate your rights to use
the Program under this License. However, parties who have received
copies, or rights to use copies, from you under this General Public
License will not have their licenses terminated so long as such parties
remain in full compliance.
5. By copying, distributing or modifying the Program (or any work based
on the Program) you indicate your acceptance of this license to do so,
and all its terms and conditions.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the original
licensor to copy, distribute or modify the Program subject to these
terms and conditions. You may not impose any further restrictions on the
recipients' exercise of the rights granted herein.
7. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of the license which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
the license, you may choose any version ever published by the Free Software
Foundation.
8. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to humanity, the best way to achieve this is to make it
free software which everyone can redistribute and change under these
terms.
To do so, attach the following notices to the program. It is safest to
attach them to the start of each source file to most effectively convey
the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19xx name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the
appropriate parts of the General Public License. Of course, the
commands you use may be called something other than `show w' and `show
c'; they could even be mouse-clicks or menu items--whatever suits your
program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
program `Gnomovision' (a program to direct compilers to make passes
at assemblers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
That's all there is to it!

View File

@ -0,0 +1,120 @@
Thu Apr 25 12:03:49 1991 Brian Fox (bfox at gnuwest.fsf.org)
* vi_mode.c (rl_vi_fword, fWord, etc. All functions use
the macro `isident()'. Fixed movement bug which prevents
continious movement through the text.
Fri Jul 27 16:47:01 1990 Brian Fox (bfox at gnuwest.fsf.org)
* readline.c (parser_if) Allow "$if term=foo" construct.
Wed May 23 16:10:33 1990 Brian Fox (bfox at gnuwest.fsf.org)
* readline.c (rl_dispatch) Correctly remember the last command
executed. Fixed typo in username_completion_function ().
Mon Apr 9 19:55:48 1990 Brian Fox (bfox at gnuwest.fsf.org)
* readline.c: username_completion_function (); For text passed in
with a leading `~', remember that this could be a filename (after
it is completed).
Thu Apr 5 13:44:24 1990 Brian Fox (bfox at gnuwest.fsf.org)
* readline.c: rl_search_history (): Correctly handle case of an
unfound search string, but a graceful exit (as with ESC).
* readline.c: rl_restart_output (); The Apollo passes the address
of the file descriptor to TIOCSTART, not the descriptor itself.
Tue Mar 20 05:38:55 1990 Brian Fox (bfox at gnuwest.fsf.org)
* readline.c: rl_complete (); second call in a row causes possible
completions to be listed.
* readline.c: rl_redisplay (), added prompt_this_line variable
which is the first character character following \n in prompt.
Sun Mar 11 04:32:03 1990 Brian Fox (bfox at gnuwest.fsf.org)
* Signals are now supposedly handled inside of SYSV compilation.
Wed Jan 17 19:24:09 1990 Brian Fox (bfox at sbphy.ucsb.edu)
* history.c: history_expand (); fixed overwriting memory error,
added needed argument to call to get_history_event ().
Thu Jan 11 10:54:04 1990 Brian Fox (bfox at sbphy.ucsb.edu)
* readline.c: added mark_modified_lines to control the
display of an asterisk on modified history lines. Also
added a user variable called mark-modified-lines to the
`set' command.
Thu Jan 4 10:38:05 1990 Brian Fox (bfox at sbphy.ucsb.edu)
* readline.c: start_insert (). Only use IC if we don't have an im
capability.
Fri Sep 8 09:00:45 1989 Brian Fox (bfox at aurel)
* readline.c: rl_prep_terminal (). Only turn on 8th bit
as meta-bit iff the terminal is not using parity.
Sun Sep 3 08:57:40 1989 Brian Fox (bfox at aurel)
* readline.c: start_insert (). Uses multiple
insertion call in cases where that makes sense.
rl_insert (). Read type-ahead buffer for additional
keys that are bound to rl_insert, and insert them
all at once. Make insertion of single keys given
with an argument much more efficient.
Tue Aug 8 18:13:57 1989 Brian Fox (bfox at aurel)
* readline.c: Changed handling of EOF. readline () returns
(char *)EOF or consed string. The EOF character is read from the
tty, or if the tty doesn't have one, defaults to C-d.
* readline.c: Added support for event driven programs.
rl_event_hook is the address of a function you want called
while Readline is waiting for input.
* readline.c: Cleanup time. Functions without type declarations
do not use return with a value.
* history.c: history_expand () has new variable which is the
characters to ignore immediately following history_expansion_char.
Sun Jul 16 08:14:00 1989 Brian Fox (bfox at aurel)
* rl_prep_terminal ()
BSD version turns off C-s, C-q, C-y, C-v.
* readline.c -- rl_prep_terminal ()
SYSV version hacks readline_echoing_p.
BSD version turns on passing of the 8th bit for the duration
of reading the line.
Tue Jul 11 06:25:01 1989 Brian Fox (bfox at aurel)
* readline.c: new variable rl_tilde_expander.
If non-null, this contains the address of a function to call if
the standard meaning for expanding a tilde fails. The function is
called with the text sans tilde (as in "foo"), and returns a
malloc()'ed string which is the expansion, or a NULL pointer if
there is no expansion.
* readline.h - new file chardefs.h
Separates things that only readline.c needs from the standard
header file publishing interesting things about readline.
* readline.c:
readline_default_bindings () now looks at terminal chararacters
and binds those as well.
Wed Jun 28 20:20:51 1989 Brian Fox (bfox at aurel)
* Made readline and history into independent libraries.

View File

@ -0,0 +1,22 @@
# $Id: Makefile,v 1.1 1993/12/28 07:54:51 ache Exp $
SHLIB_MAJOR=1
SHLIB_MINOR=0
CFLAGS+= -I${.CURDIR} -I${.CURDIR}/readline -DVOID_SIGHANDLER -Dstricmp=strcasecmp -Dstrnicmp=strncasecmp
LIB= readline
SRCS+= readline.c history.c funmap.c keymaps.c
NOMAN= noman
beforeinstall:
@-if [ ! -d ${DESTDIR}/usr/include/readline ]; then \
mkdir ${DESTDIR}/usr/include/readline; \
chown ${BINOWN}.${BINGRP} ${DESTDIR}/usr/include/readline; \
chmod 755 ${DESTDIR}/usr/include/readline; \
fi
cd ${.CURDIR}/readline; \
install -c -o ${BINOWN} -g ${BINGRP} -m 444 \
readline.h keymaps.h chardefs.h ${DESTDIR}/usr/include/readline
.include <bsd.lib.mk>

View File

@ -0,0 +1,14 @@
The GNU Readline library is a programming tool that provides a
consistent user interface for recalling lines of previously typed
input and performing editing tasks on input lines.
paul@freefall.cdrom.com
There was a bug with tcsh: when readline attempt to get tty
modes from background, it got no-echo editing tcsh mode.
Workaround for this implemented via TIOCGWINSZ/TIOCSWINSZ
with same winsize structure: it does nothing expect polling
process from background. Look tcsh_hack.readme for details.
ache@astral.msk.su

View File

@ -0,0 +1,30 @@
# This makefile for Readline library documentation is in -*- text -*- mode.
# Emacs likes it that way.
DVIOBJ = readline.dvi history.dvi
INFOBJ = readline.info history.info
all: $(DVIOBJ) $(INFOBJ)
readline.dvi: rlman.texinfo rluser.texinfo rltech.texinfo
tex rlman.texinfo
tex rlman.texinfo
mv rlman.dvi readline.dvi
history.dvi: hist.texinfo hsuser.texinfo hstech.texinfo
tex hist.texinfo
tex hist.texinfo
mv hist.dvi history.dvi
readline.info: rlman.texinfo rluser.texinfo rltech.texinfo
makeinfo rlman.texinfo
history.info: hist.texinfo hsuser.texinfo hstech.texinfo
makeinfo hist.texinfo
clean:
rm -f *.log *.cp *.ky *.tp *.vr *.fn *.aux *.pg *.toc core
squeaky-clean:
rm -f *.log *.cp *.ky *.tp *.vr *.fn *.aux *.pg *.toc core *.dvi *.~* *.info

View File

@ -0,0 +1,106 @@
\input texinfo @c -*-texinfo-*-
@comment %**start of header (This is for running Texinfo on a region.)
@setfilename history.info
@settitle GNU Readline Library
@comment %**end of header (This is for running Texinfo on a region.)
@synindex fn vr
@setchapternewpage odd
@ifinfo
This document describes the GNU History library, a programming tool that
provides a consistent user interface for recalling lines of previously
typed input.
Copyright (C) 1988, 1991 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
pare preserved on all copies.
@ignore
Permission is granted to process this file through TeX and print the
results, provided the printed document carries copying permission
notice identical to this one except for the removal of this paragraph
(this paragraph not being relevant to the printed manual).
@end ignore
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided that the entire
resulting derived work is distributed under the terms of a permission
notice identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions,
except that this permission notice may be stated in a translation approved
by the Foundation.
@end ifinfo
@titlepage
@sp 10
@center @titlefont{GNU History Library}
@center Brian Fox
@center Free Software Foundation
@center Version 1.1
@center April 1991
@c Include the Distribution inside the titlepage environment so
@c that headings are turned off.
@page
This document describes the GNU History library, a programming tool that
provides a consistent user interface for recalling lines of previously
typed input.
Published by the Free Software Foundation @*
675 Massachusetts Avenue, @*
Cambridge, MA 02139 USA
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided that the entire
resulting derived work is distributed under the terms of a permission
notice identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions,
except that this permission notice may be stated in a translation approved
by the Foundation.
@vskip 0pt plus 1filll
Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc.
@end titlepage
@ifinfo
@node Top
@top GNU History Library
This document describes the GNU History library, a programming tool that
provides a consistent user interface for recalling lines of previously
typed input.
@menu
* Using History Interactively:: GNU History User's Manual.
* Programming with GNU History:: GNU History Programmer's Manual.
* Concept Index:: Index of concepts described in this manual.
* Function and Variable Index:: Index of externally visible functions
and variables.
@end menu
@end ifinfo
@include hsuser.texinfo
@include hstech.texinfo
@node Concept Index
@appendix Concept Index
@printindex cp
@node Function and Variable Index
@appendix Function and Variable Index
@printindex vr
@contents
@bye

View File

@ -0,0 +1,311 @@
@ignore
This file documents the user interface to the GNU History library.
Copyright (C) 1988, 1991 Free Software Foundation, Inc.
Authored by Brian Fox.
Permission is granted to make and distribute verbatim copies of this manual
provided the copyright notice and this permission notice are preserved on
all copies.
Permission is granted to process this file through Tex and print the
results, provided the printed document carries copying permission notice
identical to this one except for the removal of this paragraph (this
paragraph not being relevant to the printed manual).
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided also that the
GNU Copyright statement is available to the distributee, and provided that
the entire resulting derived work is distributed under the terms of a
permission notice identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions.
@end ignore
@node Programming with GNU History
@chapter Programming with GNU History
This chapter describes how to interface the GNU History Library with
programs that you write. It should be considered a technical guide.
For information on the interactive use of GNU History, @pxref{Using
History Interactively}.
@menu
* Introduction to History:: What is the GNU History library for?
* History Storage:: How information is stored.
* History Functions:: Functions that you can use.
* History Variables:: Variables that control behaviour.
* History Programming Example:: Example of using the GNU History Library.
@end menu
@node Introduction to History
@section Introduction to History
Many programs read input from the user a line at a time. The GNU history
library is able to keep track of those lines, associate arbitrary data with
each line, and utilize information from previous lines in making up new
ones.
The programmer using the History library has available to him functions
for remembering lines on a history stack, associating arbitrary data
with a line, removing lines from the stack, searching through the stack
for a line containing an arbitrary text string, and referencing any line
on the stack directly. In addition, a history @dfn{expansion} function
is available which provides for a consistent user interface across many
different programs.
The end-user using programs written with the History library has the
benifit of a consistent user interface, with a set of well-known
commands for manipulating the text of previous lines and using that text
in new commands. The basic history manipulation commands are similar to
the history substitution used by @code{Csh}.
If the programmer desires, he can use the Readline library, which
includes some history manipulation by default, and has the added
advantage of Emacs style command line editing.
@node History Storage
@section History Storage
@example
typedef struct _hist_entry @{
char *line;
char *data;
@} HIST_ENTRY;
@end example
@node History Functions
@section History Functions
This section describes the calling sequence for the various functions
present in GNU History.
@defun {void using_history} ()
Begin a session in which the history functions might be used. This
just initializes the interactive variables.
@end defun
@defun {void add_history} (char *string)
Place @var{string} at the end of the history list. The associated data
field (if any) is set to @code{NULL}.
@end defun
@defun {int where_history} ()
Returns the number which says what history element we are now looking
at.
@end defun
@defun {int history_set_pos} (int pos)
Set the position in the history list to @var{pos}.
@end defun
@defun {int history_search_pos} (char *string, int direction, int pos)
Search for @var{string} in the history list, starting at @var{pos}, an
absolute index into the list. @var{direction}, if negative, says to search
backwards from @var{pos}, else forwards. Returns the absolute index of
the history element where @var{string} was found, or -1 otherwise.
@end defun
@defun {HIST_ENTRY *remove_history} ();
Remove history element @var{which} from the history. The removed
element is returned to you so you can free the line, data,
and containing structure.
@end defun
@defun {void stifle_history} (int max)
Stifle the history list, remembering only @var{max} number of entries.
@end defun
@defun {int unstifle_history} ();
Stop stifling the history. This returns the previous amount the
history was stifled by. The value is positive if the history was
stifled, negative if it wasn't.
@end defun
@defun {int read_history} (char *filename)
Add the contents of @var{filename} to the history list, a line at a
time. If @var{filename} is @code{NULL}, then read from
@file{~/.history}. Returns 0 if successful, or errno if not.
@end defun
@defun {int read_history_range} (char *filename, int from, int to)
Read a range of lines from @var{filename}, adding them to the history list.
Start reading at the @var{from}'th line and end at the @var{to}'th. If
@var{from} is zero, start at the beginning. If @var{to} is less than
@var{from}, then read until the end of the file. If @var{filename} is
@code{NULL}, then read from @file{~/.history}. Returns 0 if successful,
or @code{errno} if not.
@end defun
@defun {int write_history} (char *filename)
Append the current history to @var{filename}. If @var{filename} is
@code{NULL}, then append the history list to @file{~/.history}. Values
returned are as in @code{read_history ()}.
@end defun
@defun {int append_history} (int nelements, char *filename)
Append @var{nelement} entries to @var{filename}. The entries appended
are from the end of the list minus @var{nelements} up to the end of the
list.
@end defun
@defun {HIST_ENTRY *replace_history_entry} ()
Make the history entry at @var{which} have @var{line} and @var{data}.
This returns the old entry so you can dispose of the data. In the case
of an invalid @var{which}, a @code{NULL} pointer is returned.
@end defun
@defun {HIST_ENTRY *current_history} ()
Return the history entry at the current position, as determined by
@code{history_offset}. If there is no entry there, return a @code{NULL}
pointer.
@end defun
@defun {HIST_ENTRY *previous_history} ()
Back up @var{history_offset} to the previous history entry, and return a
pointer to that entry. If there is no previous entry, return a
@code{NULL} pointer.
@end defun
@defun {HIST_ENTRY *next_history} ()
Move @code{history_offset} forward to the next history entry, and return
the a pointer to that entry. If there is no next entry, return a
@code{NULL} pointer.
@end defun
@defun {HIST_ENTRY **history_list} ()
Return a @code{NULL} terminated array of @code{HIST_ENTRY} which is the
current input history. Element 0 of this list is the beginning of time.
If there is no history, return @code{NULL}.
@end defun
@defun {int history_search} (char *string, int direction)
Search the history for @var{string}, starting at @code{history_offset}.
If @var{direction} < 0, then the search is through previous entries,
else through subsequent. If @var{string} is found, then
@code{current_history ()} is the history entry, and the value of this
function is the offset in the line of that history entry that the
@var{string} was found in. Otherwise, nothing is changed, and a -1 is
returned.
@end defun
@defun {int history_expand} (char *string, char **output)
Expand @var{string}, placing the result into @var{output}, a pointer
to a string. Returns:
@table @code
@item 0
If no expansions took place (or, if the only change in
the text was the de-slashifying of the history expansion
character),
@item 1
if expansions did take place, or
@item -1
if there was an error in expansion.
@end table
If an error ocurred in expansion, then @var{output} contains a descriptive
error message.
@end defun
@defun {char *history_arg_extract} (int first, int last, char *string)
Extract a string segment consisting of the @var{first} through @var{last}
arguments present in @var{string}. Arguments are broken up as in
the GNU Bash shell.
@end defun
@defun {int history_total_bytes} ();
Return the number of bytes that the primary history entries are using.
This just adds up the lengths of @code{the_history->lines}.
@end defun
@node History Variables
@section History Variables
This section describes the variables in GNU History that are externally
visible.
@defvar {int history_base}
For convenience only. You set this when interpreting history commands.
It is the logical offset of the first history element.
@end defvar
@node History Programming Example
@section History Programming Example
The following snippet of code demonstrates simple use of the GNU History
Library.
@smallexample
main ()
@{
char line[1024], *t;
int done = 0;
line[0] = 0;
while (!done)
@{
fprintf (stdout, "history%% ");
t = gets (line);
if (!t)
strcpy (line, "quit");
if (line[0])
@{
char *expansion;
int result;
using_history ();
result = history_expand (line, &expansion);
strcpy (line, expansion);
free (expansion);
if (result)
fprintf (stderr, "%s\n", line);
if (result < 0)
continue;
add_history (line);
@}
if (strcmp (line, "quit") == 0) done = 1;
if (strcmp (line, "save") == 0) write_history (0);
if (strcmp (line, "read") == 0) read_history (0);
if (strcmp (line, "list") == 0)
@{
register HIST_ENTRY **the_list = history_list ();
register int i;
if (the_list)
for (i = 0; the_list[i]; i++)
fprintf (stdout, "%d: %s\n",
i + history_base, the_list[i]->line);
@}
if (strncmp (line, "delete", strlen ("delete")) == 0)
@{
int which;
if ((sscanf (line + strlen ("delete"), "%d", &which)) == 1)
@{
HIST_ENTRY *entry = remove_history (which);
if (!entry)
fprintf (stderr, "No such entry %d\n", which);
else
@{
free (entry->line);
free (entry);
@}
@}
else
@{
fprintf (stderr, "non-numeric arg given to `delete'\n");
@}
@}
@}
@}
@end smallexample

View File

@ -0,0 +1,153 @@
@ignore
This file documents the user interface to the GNU History library.
Copyright (C) 1988, 1991 Free Software Foundation, Inc.
Authored by Brian Fox.
Permission is granted to make and distribute verbatim copies of this manual
provided the copyright notice and this permission notice are preserved on
all copies.
Permission is granted to process this file through Tex and print the
results, provided the printed document carries copying permission notice
identical to this one except for the removal of this paragraph (this
paragraph not being relevant to the printed manual).
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided also that the
GNU Copyright statement is available to the distributee, and provided that
the entire resulting derived work is distributed under the terms of a
permission notice identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions.
@end ignore
@node Using History Interactively
@chapter Using History Interactively
This chapter describes how to use the GNU History Library interactively,
from a user's standpoint. It should be considered a user's guide. For
information on using the GNU History Library in your own programs,
@pxref{Programming with GNU History}.
@menu
* History Interaction:: What it feels like using History as a user.
@end menu
@node History Interaction
@section History Interaction
@cindex expansion
The History library provides a history expansion feature that is similar
to the history expansion in Csh. The following text describes the sytax
that you use to manipulate the history information.
History expansion takes place in two parts. The first is to determine
which line from the previous history should be used during substitution.
The second is to select portions of that line for inclusion into the
current one. The line selected from the previous history is called the
@dfn{event}, and the portions of that line that are acted upon are
called @dfn{words}. The line is broken into words in the same fashion
that the Bash shell does, so that several English (or Unix) words
surrounded by quotes are considered as one word.
@menu
* Event Designators:: How to specify which history line to use.
* Word Designators:: Specifying which words are of interest.
* Modifiers:: Modifying the results of susbstitution.
@end menu
@node Event Designators
@subsection Event Designators
@cindex event designators
An event designator is a reference to a command line entry in the
history list.
@table @asis
@item @code{!}
Start a history subsititution, except when followed by a space, tab, or
the end of the line... @key{=} or @key{(}.
@item @code{!!}
Refer to the previous command. This is a synonym for @code{!-1}.
@item @code{!n}
Refer to command line @var{n}.
@item @code{!-n}
Refer to the command line @var{n} lines back.
@item @code{!string}
Refer to the most recent command starting with @var{string}.
@item @code{!?string}[@code{?}]
Refer to the most recent command containing @var{string}.
@end table
@node Word Designators
@subsection Word Designators
A @key{:} separates the event specification from the word designator. It
can be omitted if the word designator begins with a @key{^}, @key{$},
@key{*} or @key{%}. Words are numbered from the beginning of the line,
with the first word being denoted by a 0 (zero).
@table @code
@item 0 (zero)
The zero'th word. For many applications, this is the command word.
@item n
The @var{n}'th word.
@item ^
The first argument. that is, word 1.
@item $
The last argument.
@item %
The word matched by the most recent @code{?string?} search.
@item x-y
A range of words; @code{-@var{y}} Abbreviates @code{0-@var{y}}.
@item *
All of the words, excepting the zero'th. This is a synonym for @code{1-$}.
It is not an error to use @key{*} if there is just one word in the event.
The empty string is returned in that case.
@end table
@node Modifiers
@subsection Modifiers
After the optional word designator, you can add a sequence of one or more
of the following modifiers, each preceded by a @key{:}.
@table @code
@item #
The entire command line typed so far. This means the current command,
not the previous command, so it really isn't a word designator, and doesn't
belong in this section.
@item h
Remove a trailing pathname component, leaving only the head.
@item r
Remove a trailing suffix of the form @samp{.}@var{suffix}, leaving the basename.
@item e
Remove all but the suffix.
@item t
Remove all leading pathname components, leaving the tail.
@item p
Print the new command but do not execute it.
@end table

View File

@ -0,0 +1,103 @@
\input texinfo @c -*-texinfo-*-
@comment %**start of header (This is for running Texinfo on a region.)
@setfilename readline.info
@settitle GNU Readline Library
@comment %**end of header (This is for running Texinfo on a region.)
@synindex fn vr
@setchapternewpage odd
@ifinfo
This document describes the GNU Readline Library, a utility for aiding
in the consitency of user interface across discrete programs that need
to provide a command line interface.
Copyright (C) 1988, 1991 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
pare preserved on all copies.
@ignore
Permission is granted to process this file through TeX and print the
results, provided the printed document carries copying permission
notice identical to this one except for the removal of this paragraph
(this paragraph not being relevant to the printed manual).
@end ignore
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided that the entire
resulting derived work is distributed under the terms of a permission
notice identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions,
except that this permission notice may be stated in a translation approved
by the Foundation.
@end ifinfo
@titlepage
@sp 10
@center @titlefont{GNU Readline Library}
@center Brian Fox
@center Free Software Foundation
@center Version 1.1
@center April 1991
@page
This document describes the GNU Readline Library, a utility for aiding
in the consistency of user interface across discrete programs that need
to provide a command line interface.
Published by the Free Software Foundation @*
675 Massachusetts Avenue, @*
Cambridge, MA 02139 USA
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided that the entire
resulting derived work is distributed under the terms of a permission
notice identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions,
except that this permission notice may be stated in a translation approved
by the Foundation.
@vskip 0pt plus 1filll
Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc.
@end titlepage
@ifinfo
@node Top
@top GNU Readline Library
This document describes the GNU Readline Library, a utility for aiding
in the consistency of user interface across discrete programs that need
to provide a command line interface.
@menu
* Command Line Editing:: GNU Readline User's Manual.
* Programming with GNU Readline:: GNU Readline Programmer's Manual.
* Concept Index:: Index of concepts described in this manual.
* Function and Variable Index:: Index of externally visible functions
and variables.
@end menu
@end ifinfo
@include rluser.texinfo
@include rltech.texinfo
@node Concept Index
@appendix Concept Index
@printindex cp
@node Function and Variable Index
@appendix Function and Variable Index
@printindex vr
@contents
@bye

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,489 @@
@comment %**start of header (This is for running Texinfo on a region.)
@setfilename rluser.info
@synindex fn vr
@comment %**end of header (This is for running Texinfo on a region.)
@setchapternewpage odd
@ignore
This file documents the end user interface to the GNU command line
editing feautres. It is to be an appendix to manuals for programs which
use these features. There is a document entitled "readline.texinfo"
which contains both end-user and programmer documentation for the GNU
Readline Library.
Copyright (C) 1988 Free Software Foundation, Inc.
Authored by Brian Fox.
Permission is granted to process this file through Tex and print the
results, provided the printed document carries copying permission notice
identical to this one except for the removal of this paragraph (this
paragraph not being relevant to the printed manual).
Permission is granted to make and distribute verbatim copies of this manual
provided the copyright notice and this permission notice are preserved on
all copies.
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided also that the
GNU Copyright statement is available to the distributee, and provided that
the entire resulting derived work is distributed under the terms of a
permission notice identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions.
@end ignore
@node Command Line Editing
@chapter Command Line Editing
This text describes GNU's command line editing interface.
@menu
* Introduction and Notation:: Notation used in this text.
* Readline Interaction:: The minimum set of commands for editing a line.
* Readline Init File:: Customizing Readline from a user's view.
@end menu
@node Introduction and Notation
@section Introduction to Line Editing
In this tex a the following notation is used to describe keystrokes.
The text @key{C-k} is read as `Control-K' and describes the character
produced when the Control key is depressed and the @key{k} key is struck.
The text @key{M-k} is read as `Meta-K' and describes the character
produced when the meta key (if you have one) is depressed, and the @key{k}
key is struck. If you do not have a meta key, the identical keystroke
can be generated by typing @key{ESC} @i{first}, and then typing @key{k}.
Either process is known as @dfn{metafying} the @key{k} key.
The text @key{M-C-k} is read as `Meta-Control-k' and describes the
character produced by @dfn{metafying} @key{C-k}.
In addition, several keys have their own names. Specifically,
@key{DEL}, @key{ESC}, @key{LFD}, @key{SPC}, @key{RET}, and @key{TAB} all
stand for themselves when seen in this text, or in an init file
(@pxref{Readline Init File}, for more info).
@node Readline Interaction
@section Readline Interaction
@cindex interaction, readline
Often during an interactive session you type in a long line of text,
only to notice that the first word on the line is misspelled. The
Readline library gives you a set of commands for manipulating the text
as you type it in, allowing you to just fix your typo, and not forcing
you to retype the majority of the line. Using these editing commands,
you move the cursor to the place that needs correction, and delete or
insert the text of the corrections. Then, when you are satisfied with
the line, you simply press @key{RETURN}. You do not have to be at the
end of the line to press @key{RETURN}; the entire line is accepted
regardless of the location of the cursor within the line.
@menu
* Readline Bare Essentials:: The least you need to know about Readline.
* Readline Movement Commands:: Moving about the input line.
* Readline Killing Commands:: How to delete text, and how to get it back!
* Readline Arguments:: Giving numeric arguments to commands.
@end menu
@node Readline Bare Essentials
@subsection Readline Bare Essentials
In order to enter characters into the line, simply type them. The typed
character appears where the cursor was, and then the cursor moves one
space to the right. If you mistype a character, you can use @key{DEL} to
back up, and delete the mistyped character.
Sometimes you may miss typing a character that you wanted to type, and
not notice your error until you have typed several other characters. In
that case, you can type @key{C-b} to move the cursor to the left, and then
correct your mistake. Aftwerwards, you can move the cursor to the right
with @key{C-f}.
When you add text in the middle of a line, you will notice that characters
to the right of the cursor get `pushed over' to make room for the text
that you have inserted. Likewise, when you delete text behind the cursor,
characters to the right of the cursor get `pulled back' to fill in the
blank space created by the removal of the text. A list of the basic bare
essentials for editing the text of an input line follows.
@table @asis
@item @key{C-b}
Move back one character.
@item @key{C-f}
Move forward one character.
@item @key{DEL}
Delete the character to the left of the cursor.
@item @key{C-d}
Delete the character underneath the cursor.
@item @w{Printing characters}
Insert itself into the line at the cursor.
@item @key{C-_}
Undo the last thing that you did. You can undo all the way back to an
empty line.
@end table
@node Readline Movement Commands
@subsection Readline Movement Commands
The above table describes the most basic possible keystrokes that you need
in order to do editing of the input line. For your convenience, many
other commands have been added in addition to @key{C-b}, @key{C-f},
@key{C-d}, and @key{DEL}. Here are some commands for moving more rapidly
about the line.
@table @key
@item C-a
Move to the start of the line.
@item C-e
Move to the end of the line.
@item M-f
Move forward a word.
@item M-b
Move backward a word.
@item C-l
Clear the screen, reprinting the current line at the top.
@end table
Notice how @key{C-f} moves forward a character, while @key{M-f} moves
forward a word. It is a loose convention that control keystrokes
operate on characters while meta keystrokes operate on words.
@node Readline Killing Commands
@subsection Readline Killing Commands
The act of @dfn{cutting} text means to delete the text from the line, and
to save away the deleted text for later use, just as if you had cut the
text out of the line with a pair of scissors. There is a
@dfn{Killing} text means to delete the text from the line, but to save
it away for later use, usually by @dfn{yanking} it back into the line.
If the description for a command says that it `kills' text, then you can
be sure that you can get the text back in a different (or the same)
place later.
Here is the list of commands for killing text.
@table @key
@item C-k
Kill the text from the current cursor position to the end of the line.
@item M-d
Kill from the cursor to the end of the current word, or if between
words, to the end of the next word.
@item M-DEL
Kill fromthe cursor the start ofthe previous word, or if between words, to the start of the previous word.
@item C-w
Kill from the cursor to the previous whitespace. This is different than
@key{M-DEL} because the word boundaries differ.
@end table
And, here is how to @dfn{yank} the text back into the line. Yanking
is
@table @key
@item C-y
Yank the most recently killed text back into the buffer at the cursor.
@item M-y
Rotate the kill-ring, and yank the new top. You can only do this if
the prior command is @key{C-y} or @key{M-y}.
@end table
When you use a kill command, the text is saved in a @dfn{kill-ring}.
Any number of consecutive kills save all of the killed text together, so
that when you yank it back, you get it in one clean sweep. The kill
ring is not line specific; the text that you killed on a previously
typed line is available to be yanked back later, when you are typing
another line.
@node Readline Arguments
@subsection Readline Arguments
You can pass numeric arguments to Readline commands. Sometimes the
argument acts as a repeat count, other times it is the @i{sign} of the
argument that is significant. If you pass a negative argument to a
command which normally acts in a forward direction, that command will
act in a backward direction. For example, to kill text back to the
start of the line, you might type @key{M--} @key{C-k}.
The general way to pass numeric arguments to a command is to type meta
digits before the command. If the first `digit' you type is a minus
sign (@key{-}), then the sign of the argument will be negative. Once
you have typed one meta digit to get the argument started, you can type
the remainder of the digits, and then the command. For example, to give
the @key{C-d} command an argument of 10, you could type @key{M-1 0 C-d}.
@node Readline Init File
@section Readline Init File
Although the Readline library comes with a set of Emacs-like
keybindings, it is possible that you would like to use a different set
of keybindings. You can customize programs that use Readline by putting
commands in an @dfn{init} file in your home directory. The name of this
file is @file{~/.inputrc}.
When a program which uses the Readline library starts up, the
@file{~/.inputrc} file is read, and the keybindings are set.
@menu
* Readline Init Syntax:: Syntax for the commands in @file{~/.inputrc}.
* Readline Vi Mode:: Switching to @code{vi} mode in Readline.
@end menu
@node Readline Init Syntax
@subsection Readline Init Syntax
You can start up with a vi-like editing mode by placing
@example
@code{set editing-mode vi}
@end example
in your @file{~/.inputrc} file.
You can have Readline use a single line for display, scrolling the input
between the two edges of the screen by placing
@example
@code{set horizontal-scroll-mode On}
@end example
in your @file{~/.inputrc} file.
The syntax for controlling keybindings in the @file{~/.inputrc} file is
simple. First you have to know the @i{name} of the command that you
want to change. The following pages contain tables of the command name, the
default keybinding, and a short description of what the command does.
Once you know the name of the command, simply place the name of the key
you wish to bind the command to, a colon, and then the name of the
command on a line in the @file{~/.inputrc} file. Here is an example:
@example
# This is a comment line.
Meta-Rubout: backward-kill-word
Control-u: universal-argument
@end example
@menu
* Commands For Moving:: Moving about the line.
* Commands For History:: Getting at previous lines.
* Commands For Text:: Commands for changing text.
* Commands For Killing:: Commands for killing and yanking.
* Numeric Arguments:: Specifying numeric arguments, repeat counts.
* Commands For Completion:: Getting Readline to do the typing for you.
* Miscellaneous Commands:: Other miscillaneous commands.
@end menu
@node Commands For Moving
@subsubsection Commands For Moving
@table @code
@item beginning-of-line (C-a)
Move to the start of the current line.
@item end-of-line (C-e)
Move to the end of the line.
@item forward-char (C-f)
Move forward a character.
@item backward-char (C-b)
Move back a character.
@item forward-word (M-f)
Move forward to the end of the next word.
@item backward-word (M-b)
Move back to the start of this, or the previous, word.
@item clear-screen (C-l)
Clear the screen leaving the current line at the top of the screen.
@end table
@node Commands For History
@subsubsection Commands For Manipulating The History
@table @code
@item accept-line (Newline, Return)
Accept the line regardless of where the cursor is. If this line is
non-empty, add it too the history list. If this line was a history
line, then restore the history line to its original state.
@item previous-history (C-p)
Move `up' through the history list.
@item next-history (C-n)
Move `down' through the history list.
@item beginning-of-history (M-<)
Move to the first line in the history.
@item end-of-history (M->)
Move to the end of the input history, i.e., the line you are entering!
@item reverse-search-history (C-r)
Search backward starting at the current line and moving `up' through
the history as necessary. This is an incremental search.
@item forward-search-history (C-s)
Search forward starting at the current line and moving `down' through
the the history as neccessary.
@end table
@node Commands For Text
@subsubsection Commands For Changing Text
@table @code
@item delete-char (C-d)
Delete the character under the cursor. If the cursor is at the
beginning of the line, and there are no characters in the line, and
the last character typed was not C-d, then return EOF.
@item backward-delete-char (Rubout)
Delete the character behind the cursor. A numeric arg says to kill
the characters instead of deleting them.
@item quoted-insert (C-q, C-v)
Add the next character that you type to the line verbatim. This is
how to insert things like C-q for example.
@item tab-insert (M-TAB)
Insert a tab character.
@item self-insert (a, b, A, 1, !, ...)
Insert yourself.
@item transpose-chars (C-t)
Drag the character before point forward over the character at point.
Point moves forward as well. If point is at the end of the line, then
transpose the two characters before point. Negative args don't work.
@item transpose-words (M-t)
Drag the word behind the cursor past the word in front of the cursor
moving the cursor over that word as well.
@item upcase-word (M-u)
Uppercase the current (or following) word. With a negative argument,
do the previous word, but do not move point.
@item downcase-word (M-l)
Lowercase the current (or following) word. With a negative argument,
do the previous word, but do not move point.
@item capitalize-word (M-c)
Uppercase the current (or following) word. With a negative argument,
do the previous word, but do not move point.
@end table
@node Commands For Killing
@subsubsection Killing And Yanking
@table @code
@item kill-line (C-k)
Kill the text from the current cursor position to the end of the line.
@item backward-kill-line ()
Kill backward to the beginning of the line. This is normally unbound.
@item kill-word (M-d)
Kill from the cursor to the end of the current word, or if between
words, to the end of the next word.
@item backward-kill-word (M-DEL)
Kill the word behind the cursor.
@item unix-line-discard (C-u)
Do what C-u used to do in Unix line input. We save the killed text on
the kill-ring, though.
@item unix-word-rubout (C-w)
Do what C-w used to do in Unix line input. The killed text is saved
on the kill-ring. This is different than backward-kill-word because
the word boundaries differ.
@item yank (C-y)
Yank the top of the kill ring into the buffer at point.
@item yank-pop (M-y)
Rotate the kill-ring, and yank the new top. You can only do this if
the prior command is yank or yank-pop.
@end table
@node Numeric Arguments
@subsubsection Specifying Numeric Arguments
@table @code
@item digit-argument (M-0, M-1, ... M--)
Add this digit to the argument already accumulating, or start a new
argument. M-- starts a negative argument.
@item universal-argument ()
Do what C-u does in emacs. By default, this is not bound.
@end table
@node Commands For Completion
@subsubsection Letting Readline Type For You
@table @code
@item complete (TAB)
Attempt to do completion on the text before point. This is
implementation defined. Generally, if you are typing a filename
argument, you can do filename completion; if you are typing a command,
you can do command completion, if you are typing in a symbol to GDB, you
can do symbol name completion, if you are typing in a variable to Bash,
you can do variable name completion...
@item possible-completions (M-?)
List the possible completions of the text before point.
@end table
@node Miscellaneous Commands
@subsubsection Some Miscellaneous Commands
@table @code
@item abort (C-g)
Ding! Stops things.
@item do-uppercase-version (M-a, M-b, ...)
Run the command that is bound to your uppercase brother.
@item prefix-meta (ESC)
Make the next character that you type be metafied. This is for
people without a meta key. @key{ESC-f} is equivalent to @key{M-f}.
@item undo (C-_)
Incremental undo, separately remembered for each line.
@item revert-line (M-r)
Undo all changes made to this line. This is like typing the `undo'
command enough times to get back to the beginning.
@end table
@node Readline Vi Mode
@subsection Readline Vi Mode
While the Readline library does not have a full set of Vi editing
functions, it does contain enough to allow simple editing of the line.
In order to switch interactively between Emacs and Vi editing modes, use
the command M-C-j (toggle-editing-mode).
When you enter a line in Vi mode, you are already placed in `insertion'
mode, as if you had typed an `i'. Pressing @key{ESC} switches you into
`edit' mode, where you can edit the text of the line with the standard
Vi movement keys, move to previous history lines with `k', and following
lines with `j', and so forth.

View File

@ -0,0 +1,472 @@
/* emacs_keymap.c -- the keymap for emacs_mode in readline (). */
/* Copyright (C) 1988,1989 Free Software Foundation, Inc.
This file is part of GNU Readline, a library for reading lines
of text with interactive input and history editing.
Readline is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 1, or (at your option) any
later version.
Readline is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with Readline; see the file COPYING. If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef BUFSIZ
#include <stdio.h>
#endif /* BUFSIZ */
#include "readline.h"
/* An array of function pointers, one for each possible key.
If the type byte is ISKMAP, then the pointer is the address of
a keymap. */
KEYMAP_ENTRY_ARRAY emacs_standard_keymap = {
/* Control keys. */
{ ISFUNC, (Function *)0x0 }, /* Control-@ */
{ ISFUNC, rl_beg_of_line }, /* Control-a */
{ ISFUNC, rl_backward }, /* Control-b */
{ ISFUNC, (Function *)0x0 }, /* Control-c */
{ ISFUNC, rl_delete }, /* Control-d */
{ ISFUNC, rl_end_of_line }, /* Control-e */
{ ISFUNC, rl_forward }, /* Control-f */
{ ISFUNC, rl_abort }, /* Control-g */
{ ISFUNC, rl_rubout }, /* Control-h */
{ ISFUNC, rl_complete }, /* Control-i */
{ ISFUNC, rl_newline }, /* Control-j */
{ ISFUNC, rl_kill_line }, /* Control-k */
{ ISFUNC, rl_clear_screen }, /* Control-l */
{ ISFUNC, rl_newline }, /* Control-m */
{ ISFUNC, rl_get_next_history }, /* Control-n */
{ ISFUNC, (Function *)0x0 }, /* Control-o */
{ ISFUNC, rl_get_previous_history }, /* Control-p */
{ ISFUNC, rl_quoted_insert }, /* Control-q */
{ ISFUNC, rl_reverse_search_history }, /* Control-r */
{ ISFUNC, rl_forward_search_history }, /* Control-s */
{ ISFUNC, rl_transpose_chars }, /* Control-t */
{ ISFUNC, rl_unix_line_discard }, /* Control-u */
{ ISFUNC, rl_quoted_insert }, /* Control-v */
{ ISFUNC, rl_unix_word_rubout }, /* Control-w */
{ ISKMAP, (Function *)emacs_ctlx_keymap }, /* Control-x */
{ ISFUNC, rl_yank }, /* Control-y */
{ ISFUNC, (Function *)0x0 }, /* Control-z */
{ ISKMAP, (Function *)emacs_meta_keymap }, /* Control-[ */
{ ISFUNC, (Function *)0x0 }, /* Control-\ */
{ ISFUNC, (Function *)0x0 }, /* Control-] */
{ ISFUNC, (Function *)0x0 }, /* Control-^ */
{ ISFUNC, rl_undo_command }, /* Control-_ */
/* The start of printing characters. */
{ ISFUNC, rl_insert }, /* SPACE */
{ ISFUNC, rl_insert }, /* ! */
{ ISFUNC, rl_insert }, /* " */
{ ISFUNC, rl_insert }, /* # */
{ ISFUNC, rl_insert }, /* $ */
{ ISFUNC, rl_insert }, /* % */
{ ISFUNC, rl_insert }, /* & */
{ ISFUNC, rl_insert }, /* ' */
{ ISFUNC, rl_insert }, /* ( */
{ ISFUNC, rl_insert }, /* ) */
{ ISFUNC, rl_insert }, /* * */
{ ISFUNC, rl_insert }, /* + */
{ ISFUNC, rl_insert }, /* , */
{ ISFUNC, rl_insert }, /* - */
{ ISFUNC, rl_insert }, /* . */
{ ISFUNC, rl_insert }, /* / */
/* Regular digits. */
{ ISFUNC, rl_insert }, /* 0 */
{ ISFUNC, rl_insert }, /* 1 */
{ ISFUNC, rl_insert }, /* 2 */
{ ISFUNC, rl_insert }, /* 3 */
{ ISFUNC, rl_insert }, /* 4 */
{ ISFUNC, rl_insert }, /* 5 */
{ ISFUNC, rl_insert }, /* 6 */
{ ISFUNC, rl_insert }, /* 7 */
{ ISFUNC, rl_insert }, /* 8 */
{ ISFUNC, rl_insert }, /* 9 */
/* A little more punctuation. */
{ ISFUNC, rl_insert }, /* : */
{ ISFUNC, rl_insert }, /* ; */
{ ISFUNC, rl_insert }, /* < */
{ ISFUNC, rl_insert }, /* = */
{ ISFUNC, rl_insert }, /* > */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* @ */
/* Uppercase alphabet. */
{ ISFUNC, rl_insert }, /* A */
{ ISFUNC, rl_insert }, /* B */
{ ISFUNC, rl_insert }, /* C */
{ ISFUNC, rl_insert }, /* D */
{ ISFUNC, rl_insert }, /* E */
{ ISFUNC, rl_insert }, /* F */
{ ISFUNC, rl_insert }, /* G */
{ ISFUNC, rl_insert }, /* H */
{ ISFUNC, rl_insert }, /* I */
{ ISFUNC, rl_insert }, /* J */
{ ISFUNC, rl_insert }, /* K */
{ ISFUNC, rl_insert }, /* L */
{ ISFUNC, rl_insert }, /* M */
{ ISFUNC, rl_insert }, /* N */
{ ISFUNC, rl_insert }, /* O */
{ ISFUNC, rl_insert }, /* P */
{ ISFUNC, rl_insert }, /* Q */
{ ISFUNC, rl_insert }, /* R */
{ ISFUNC, rl_insert }, /* S */
{ ISFUNC, rl_insert }, /* T */
{ ISFUNC, rl_insert }, /* U */
{ ISFUNC, rl_insert }, /* V */
{ ISFUNC, rl_insert }, /* W */
{ ISFUNC, rl_insert }, /* X */
{ ISFUNC, rl_insert }, /* Y */
{ ISFUNC, rl_insert }, /* Z */
/* Some more punctuation. */
{ ISFUNC, rl_insert }, /* [ */
{ ISFUNC, rl_insert }, /* \ */
{ ISFUNC, rl_insert }, /* ] */
{ ISFUNC, rl_insert }, /* ^ */
{ ISFUNC, rl_insert }, /* _ */
{ ISFUNC, rl_insert }, /* ` */
/* Lowercase alphabet. */
{ ISFUNC, rl_insert }, /* a */
{ ISFUNC, rl_insert }, /* b */
{ ISFUNC, rl_insert }, /* c */
{ ISFUNC, rl_insert }, /* d */
{ ISFUNC, rl_insert }, /* e */
{ ISFUNC, rl_insert }, /* f */
{ ISFUNC, rl_insert }, /* g */
{ ISFUNC, rl_insert }, /* h */
{ ISFUNC, rl_insert }, /* i */
{ ISFUNC, rl_insert }, /* j */
{ ISFUNC, rl_insert }, /* k */
{ ISFUNC, rl_insert }, /* l */
{ ISFUNC, rl_insert }, /* m */
{ ISFUNC, rl_insert }, /* n */
{ ISFUNC, rl_insert }, /* o */
{ ISFUNC, rl_insert }, /* p */
{ ISFUNC, rl_insert }, /* q */
{ ISFUNC, rl_insert }, /* r */
{ ISFUNC, rl_insert }, /* s */
{ ISFUNC, rl_insert }, /* t */
{ ISFUNC, rl_insert }, /* u */
{ ISFUNC, rl_insert }, /* v */
{ ISFUNC, rl_insert }, /* w */
{ ISFUNC, rl_insert }, /* x */
{ ISFUNC, rl_insert }, /* y */
{ ISFUNC, rl_insert }, /* z */
/* Final punctuation. */
{ ISFUNC, rl_insert }, /* { */
{ ISFUNC, rl_insert }, /* | */
{ ISFUNC, rl_insert }, /* } */
{ ISFUNC, rl_insert }, /* ~ */
{ ISFUNC, rl_rubout } /* RUBOUT */
};
KEYMAP_ENTRY_ARRAY emacs_meta_keymap = {
/* Meta keys. Just like above, but the high bit is set. */
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-@ */
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-a */
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-b */
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-c */
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-d */
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-e */
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-f */
{ ISFUNC, rl_abort }, /* Meta-Control-g */
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-h */
{ ISFUNC, rl_tab_insert }, /* Meta-Control-i */
{ ISFUNC, rl_vi_editing_mode }, /* Meta-Control-j */
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-k */
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-l */
{ ISFUNC, rl_vi_editing_mode }, /* Meta-Control-m */
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-n */
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-o */
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-p */
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-q */
{ ISFUNC, rl_revert_line }, /* Meta-Control-r */
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-s */
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-t */
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-u */
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-v */
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-w */
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-x */
{ ISFUNC, rl_yank_nth_arg }, /* Meta-Control-y */
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-z */
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-[ */
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-\ */
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-] */
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-^ */
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-_ */
/* The start of printing characters. */
{ ISFUNC, (Function *)0x0 }, /* Meta-SPACE */
{ ISFUNC, (Function *)0x0 }, /* Meta-! */
{ ISFUNC, (Function *)0x0 }, /* Meta-" */
{ ISFUNC, (Function *)0x0 }, /* Meta-# */
{ ISFUNC, (Function *)0x0 }, /* Meta-$ */
{ ISFUNC, (Function *)0x0 }, /* Meta-% */
{ ISFUNC, (Function *)0x0 }, /* Meta-& */
{ ISFUNC, (Function *)0x0 }, /* Meta-' */
{ ISFUNC, (Function *)0x0 }, /* Meta-( */
{ ISFUNC, (Function *)0x0 }, /* Meta-) */
{ ISFUNC, (Function *)0x0 }, /* Meta-* */
{ ISFUNC, (Function *)0x0 }, /* Meta-+ */
{ ISFUNC, (Function *)0x0 }, /* Meta-, */
{ ISFUNC, rl_digit_argument }, /* Meta-- */
{ ISFUNC, (Function *)0x0 }, /* Meta-. */
{ ISFUNC, (Function *)0x0 }, /* Meta-/ */
/* Regular digits. */
{ ISFUNC, rl_digit_argument }, /* Meta-0 */
{ ISFUNC, rl_digit_argument }, /* Meta-1 */
{ ISFUNC, rl_digit_argument }, /* Meta-2 */
{ ISFUNC, rl_digit_argument }, /* Meta-3 */
{ ISFUNC, rl_digit_argument }, /* Meta-4 */
{ ISFUNC, rl_digit_argument }, /* Meta-5 */
{ ISFUNC, rl_digit_argument }, /* Meta-6 */
{ ISFUNC, rl_digit_argument }, /* Meta-7 */
{ ISFUNC, rl_digit_argument }, /* Meta-8 */
{ ISFUNC, rl_digit_argument }, /* Meta-9 */
/* A little more punctuation. */
{ ISFUNC, (Function *)0x0 }, /* Meta-: */
{ ISFUNC, (Function *)0x0 }, /* Meta-; */
{ ISFUNC, rl_beginning_of_history }, /* Meta-< */
{ ISFUNC, (Function *)0x0 }, /* Meta-= */
{ ISFUNC, rl_end_of_history }, /* Meta-> */
{ ISFUNC, rl_possible_completions }, /* Meta-? */
{ ISFUNC, (Function *)0x0 }, /* Meta-@ */
/* Uppercase alphabet. */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-A */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-B */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-C */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-D */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-E */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-F */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-G */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-H */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-I */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-J */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-K */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-L */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-M */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-N */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-O */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-P */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-Q */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-R */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-S */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-T */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-U */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-V */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-W */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-X */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-Y */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-Z */
/* Some more punctuation. */
{ ISFUNC, rl_arrow_keys }, /* Meta-[ */
{ ISFUNC, (Function *)0x0 }, /* Meta-\ */
{ ISFUNC, (Function *)0x0 }, /* Meta-] */
{ ISFUNC, (Function *)0x0 }, /* Meta-^ */
{ ISFUNC, (Function *)0x0 }, /* Meta-_ */
{ ISFUNC, (Function *)0x0 }, /* Meta-` */
/* Lowercase alphabet. */
{ ISFUNC, (Function *)0x0 }, /* Meta-a */
{ ISFUNC, rl_backward_word }, /* Meta-b */
{ ISFUNC, rl_capitalize_word }, /* Meta-c */
{ ISFUNC, rl_kill_word }, /* Meta-d */
{ ISFUNC, (Function *)0x0 }, /* Meta-e */
{ ISFUNC, rl_forward_word }, /* Meta-f */
{ ISFUNC, (Function *)0x0 }, /* Meta-g */
{ ISFUNC, (Function *)0x0 }, /* Meta-h */
{ ISFUNC, (Function *)0x0 }, /* Meta-i */
{ ISFUNC, (Function *)0x0 }, /* Meta-j */
{ ISFUNC, (Function *)0x0 }, /* Meta-k */
{ ISFUNC, rl_downcase_word }, /* Meta-l */
{ ISFUNC, (Function *)0x0 }, /* Meta-m */
{ ISFUNC, (Function *)0x0 }, /* Meta-n */
{ ISFUNC, rl_arrow_keys }, /* Meta-o */
{ ISFUNC, (Function *)0x0 }, /* Meta-p */
{ ISFUNC, (Function *)0x0 }, /* Meta-q */
{ ISFUNC, rl_revert_line }, /* Meta-r */
{ ISFUNC, (Function *)0x0 }, /* Meta-s */
{ ISFUNC, rl_transpose_words }, /* Meta-t */
{ ISFUNC, rl_upcase_word }, /* Meta-u */
{ ISFUNC, (Function *)0x0 }, /* Meta-v */
{ ISFUNC, (Function *)0x0 }, /* Meta-w */
{ ISFUNC, (Function *)0x0 }, /* Meta-x */
{ ISFUNC, rl_yank_pop }, /* Meta-y */
{ ISFUNC, (Function *)0x0 }, /* Meta-z */
/* Final punctuation. */
{ ISFUNC, (Function *)0x0 }, /* Meta-{ */
{ ISFUNC, (Function *)0x0 }, /* Meta-| */
{ ISFUNC, (Function *)0x0 }, /* Meta-} */
{ ISFUNC, (Function *)0x0 }, /* Meta-~ */
{ ISFUNC, rl_backward_kill_word } /* Meta-rubout */
};
KEYMAP_ENTRY_ARRAY emacs_ctlx_keymap = {
/* Control keys. */
{ ISFUNC, (Function *)0x0 }, /* Control-@ */
{ ISFUNC, (Function *)0x0 }, /* Control-a */
{ ISFUNC, (Function *)0x0 }, /* Control-b */
{ ISFUNC, (Function *)0x0 }, /* Control-c */
{ ISFUNC, (Function *)0x0 }, /* Control-d */
{ ISFUNC, (Function *)0x0 }, /* Control-e */
{ ISFUNC, (Function *)0x0 }, /* Control-f */
{ ISFUNC, rl_abort }, /* Control-g */
{ ISFUNC, (Function *)0x0 }, /* Control-h */
{ ISFUNC, (Function *)0x0 }, /* Control-i */
{ ISFUNC, (Function *)0x0 }, /* Control-j */
{ ISFUNC, (Function *)0x0 }, /* Control-k */
{ ISFUNC, (Function *)0x0 }, /* Control-l */
{ ISFUNC, (Function *)0x0 }, /* Control-m */
{ ISFUNC, (Function *)0x0 }, /* Control-n */
{ ISFUNC, (Function *)0x0 }, /* Control-o */
{ ISFUNC, (Function *)0x0 }, /* Control-p */
{ ISFUNC, (Function *)0x0 }, /* Control-q */
{ ISFUNC, rl_re_read_init_file }, /* Control-r */
{ ISFUNC, (Function *)0x0 }, /* Control-s */
{ ISFUNC, (Function *)0x0 }, /* Control-t */
{ ISFUNC, rl_undo_command }, /* Control-u */
{ ISFUNC, (Function *)0x0 }, /* Control-v */
{ ISFUNC, (Function *)0x0 }, /* Control-w */
{ ISFUNC, (Function *)0x0 }, /* Control-x */
{ ISFUNC, (Function *)0x0 }, /* Control-y */
{ ISFUNC, (Function *)0x0 }, /* Control-z */
{ ISFUNC, (Function *)0x0 }, /* Control-[ */
{ ISFUNC, (Function *)0x0 }, /* Control-\ */
{ ISFUNC, (Function *)0x0 }, /* Control-] */
{ ISFUNC, (Function *)0x0 }, /* Control-^ */
{ ISFUNC, (Function *)0x0 }, /* Control-_ */
/* The start of printing characters. */
{ ISFUNC, (Function *)0x0 }, /* SPACE */
{ ISFUNC, (Function *)0x0 }, /* ! */
{ ISFUNC, (Function *)0x0 }, /* " */
{ ISFUNC, (Function *)0x0 }, /* # */
{ ISFUNC, (Function *)0x0 }, /* $ */
{ ISFUNC, (Function *)0x0 }, /* % */
{ ISFUNC, (Function *)0x0 }, /* & */
{ ISFUNC, (Function *)0x0 }, /* ' */
{ ISFUNC, rl_start_kbd_macro }, /* ( */
{ ISFUNC, rl_end_kbd_macro }, /* ) */
{ ISFUNC, (Function *)0x0 }, /* * */
{ ISFUNC, (Function *)0x0 }, /* + */
{ ISFUNC, (Function *)0x0 }, /* , */
{ ISFUNC, (Function *)0x0 }, /* - */
{ ISFUNC, (Function *)0x0 }, /* . */
{ ISFUNC, (Function *)0x0 }, /* / */
/* Regular digits. */
{ ISFUNC, (Function *)0x0 }, /* 0 */
{ ISFUNC, (Function *)0x0 }, /* 1 */
{ ISFUNC, (Function *)0x0 }, /* 2 */
{ ISFUNC, (Function *)0x0 }, /* 3 */
{ ISFUNC, (Function *)0x0 }, /* 4 */
{ ISFUNC, (Function *)0x0 }, /* 5 */
{ ISFUNC, (Function *)0x0 }, /* 6 */
{ ISFUNC, (Function *)0x0 }, /* 7 */
{ ISFUNC, (Function *)0x0 }, /* 8 */
{ ISFUNC, (Function *)0x0 }, /* 9 */
/* A little more punctuation. */
{ ISFUNC, (Function *)0x0 }, /* : */
{ ISFUNC, (Function *)0x0 }, /* ; */
{ ISFUNC, (Function *)0x0 }, /* < */
{ ISFUNC, (Function *)0x0 }, /* = */
{ ISFUNC, (Function *)0x0 }, /* > */
{ ISFUNC, (Function *)0x0 }, /* ? */
{ ISFUNC, (Function *)0x0 }, /* @ */
/* Uppercase alphabet. */
{ ISFUNC, rl_do_lowercase_version }, /* A */
{ ISFUNC, rl_do_lowercase_version }, /* B */
{ ISFUNC, rl_do_lowercase_version }, /* C */
{ ISFUNC, rl_do_lowercase_version }, /* D */
{ ISFUNC, rl_do_lowercase_version }, /* E */
{ ISFUNC, rl_do_lowercase_version }, /* F */
{ ISFUNC, rl_do_lowercase_version }, /* G */
{ ISFUNC, rl_do_lowercase_version }, /* H */
{ ISFUNC, rl_do_lowercase_version }, /* I */
{ ISFUNC, rl_do_lowercase_version }, /* J */
{ ISFUNC, rl_do_lowercase_version }, /* K */
{ ISFUNC, rl_do_lowercase_version }, /* L */
{ ISFUNC, rl_do_lowercase_version }, /* M */
{ ISFUNC, rl_do_lowercase_version }, /* N */
{ ISFUNC, rl_do_lowercase_version }, /* O */
{ ISFUNC, rl_do_lowercase_version }, /* P */
{ ISFUNC, rl_do_lowercase_version }, /* Q */
{ ISFUNC, rl_do_lowercase_version }, /* R */
{ ISFUNC, rl_do_lowercase_version }, /* S */
{ ISFUNC, rl_do_lowercase_version }, /* T */
{ ISFUNC, rl_do_lowercase_version }, /* U */
{ ISFUNC, rl_do_lowercase_version }, /* V */
{ ISFUNC, rl_do_lowercase_version }, /* W */
{ ISFUNC, rl_do_lowercase_version }, /* X */
{ ISFUNC, rl_do_lowercase_version }, /* Y */
{ ISFUNC, rl_do_lowercase_version }, /* Z */
/* Some more punctuation. */
{ ISFUNC, (Function *)0x0 }, /* [ */
{ ISFUNC, (Function *)0x0 }, /* \ */
{ ISFUNC, (Function *)0x0 }, /* ] */
{ ISFUNC, (Function *)0x0 }, /* ^ */
{ ISFUNC, (Function *)0x0 }, /* _ */
{ ISFUNC, (Function *)0x0 }, /* ` */
/* Lowercase alphabet. */
{ ISFUNC, (Function *)0x0 }, /* a */
{ ISFUNC, (Function *)0x0 }, /* b */
{ ISFUNC, (Function *)0x0 }, /* c */
{ ISFUNC, (Function *)0x0 }, /* d */
{ ISFUNC, rl_call_last_kbd_macro }, /* e */
{ ISFUNC, (Function *)0x0 }, /* f */
{ ISFUNC, (Function *)0x0 }, /* g */
{ ISFUNC, (Function *)0x0 }, /* h */
{ ISFUNC, (Function *)0x0 }, /* i */
{ ISFUNC, (Function *)0x0 }, /* j */
{ ISFUNC, (Function *)0x0 }, /* k */
{ ISFUNC, (Function *)0x0 }, /* l */
{ ISFUNC, (Function *)0x0 }, /* m */
{ ISFUNC, (Function *)0x0 }, /* n */
{ ISFUNC, (Function *)0x0 }, /* o */
{ ISFUNC, (Function *)0x0 }, /* p */
{ ISFUNC, (Function *)0x0 }, /* q */
{ ISFUNC, (Function *)0x0 }, /* r */
{ ISFUNC, (Function *)0x0 }, /* s */
{ ISFUNC, (Function *)0x0 }, /* t */
{ ISFUNC, (Function *)0x0 }, /* u */
{ ISFUNC, (Function *)0x0 }, /* v */
{ ISFUNC, (Function *)0x0 }, /* w */
{ ISFUNC, (Function *)0x0 }, /* x */
{ ISFUNC, (Function *)0x0 }, /* y */
{ ISFUNC, (Function *)0x0 }, /* z */
/* Final punctuation. */
{ ISFUNC, (Function *)0x0 }, /* { */
{ ISFUNC, (Function *)0x0 }, /* | */
{ ISFUNC, (Function *)0x0 }, /* } */
{ ISFUNC, (Function *)0x0 }, /* ~ */
{ ISFUNC, rl_backward_kill_line } /* RUBOUT */
};

View File

@ -0,0 +1,12 @@
# This is the Makefile for the examples subdirectory of readline. -*- text -*-
#
EXECUTABLES = fileman
CFLAGS = -g -I../..
LDFLAGS = -g -L..
fileman: fileman.o
$(CC) $(LDFLAGS) -o fileman fileman.o -lreadline -ltermcap
fileman.o: fileman.c

View File

@ -0,0 +1,392 @@
/* fileman.c -- A tiny application which demonstrates how to use the
GNU Readline library. This application interactively allows users
to manipulate files and their modes. */
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <sys/types.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/errno.h>
/* The names of functions that actually do the manipulation. */
int com_list (), com_view (), com_rename (), com_stat (), com_pwd ();
int com_delete (), com_help (), com_cd (), com_quit ();
/* A structure which contains information on the commands this program
can understand. */
typedef struct {
char *name; /* User printable name of the function. */
Function *func; /* Function to call to do the job. */
char *doc; /* Documentation for this function. */
} COMMAND;
COMMAND commands[] = {
{ "cd", com_cd, "Change to directory DIR" },
{ "delete", com_delete, "Delete FILE" },
{ "help", com_help, "Display this text" },
{ "?", com_help, "Synonym for `help'" },
{ "list", com_list, "List files in DIR" },
{ "ls", com_list, "Synonym for `list'" },
{ "pwd", com_pwd, "Print the current working directory" },
{ "quit", com_quit, "Quit using Fileman" },
{ "rename", com_rename, "Rename FILE to NEWNAME" },
{ "stat", com_stat, "Print out statistics on FILE" },
{ "view", com_view, "View the contents of FILE" },
{ (char *)NULL, (Function *)NULL, (char *)NULL }
};
/* The name of this program, as taken from argv[0]. */
char *progname;
/* When non-zero, this global means the user is done using this program. */
int done = 0;
main (argc, argv)
int argc;
char **argv;
{
progname = argv[0];
initialize_readline (); /* Bind our completer. */
/* Loop reading and executing lines until the user quits. */
while (!done)
{
char *line;
line = readline ("FileMan: ");
if (!line)
{
done = 1; /* Encountered EOF at top level. */
}
else
{
/* Remove leading and trailing whitespace from the line.
Then, if there is anything left, add it to the history list
and execute it. */
stripwhite (line);
if (*line)
{
add_history (line);
execute_line (line);
}
}
if (line)
free (line);
}
exit (0);
}
/* Execute a command line. */
execute_line (line)
char *line;
{
register int i;
COMMAND *find_command (), *command;
char *word;
/* Isolate the command word. */
i = 0;
while (line[i] && !whitespace (line[i]))
i++;
word = line;
if (line[i])
line[i++] = '\0';
command = find_command (word);
if (!command)
{
fprintf (stderr, "%s: No such command for FileMan.\n", word);
return;
}
/* Get argument to command, if any. */
while (whitespace (line[i]))
i++;
word = line + i;
/* Call the function. */
(*(command->func)) (word);
}
/* Look up NAME as the name of a command, and return a pointer to that
command. Return a NULL pointer if NAME isn't a command name. */
COMMAND *
find_command (name)
char *name;
{
register int i;
for (i = 0; commands[i].name; i++)
if (strcmp (name, commands[i].name) == 0)
return (&commands[i]);
return ((COMMAND *)NULL);
}
/* Strip whitespace from the start and end of STRING. */
stripwhite (string)
char *string;
{
register int i = 0;
while (whitespace (string[i]))
i++;
if (i)
strcpy (string, string + i);
i = strlen (string) - 1;
while (i > 0 && whitespace (string[i]))
i--;
string[++i] = '\0';
}
/* **************************************************************** */
/* */
/* Interface to Readline Completion */
/* */
/* **************************************************************** */
/* Tell the GNU Readline library how to complete. We want to try to complete
on command names if this is the first word in the line, or on filenames
if not. */
initialize_readline ()
{
char **fileman_completion ();
/* Allow conditional parsing of the ~/.inputrc file. */
rl_readline_name = "FileMan";
/* Tell the completer that we want a crack first. */
rl_attempted_completion_function = (Function *)fileman_completion;
}
/* Attempt to complete on the contents of TEXT. START and END show the
region of TEXT that contains the word to complete. We can use the
entire line in case we want to do some simple parsing. Return the
array of matches, or NULL if there aren't any. */
char **
fileman_completion (text, start, end)
char *text;
int start, end;
{
char **matches;
char *command_generator ();
matches = (char **)NULL;
/* If this word is at the start of the line, then it is a command
to complete. Otherwise it is the name of a file in the current
directory. */
if (start == 0)
matches = completion_matches (text, command_generator);
return (matches);
}
/* Generator function for command completion. STATE lets us know whether
to start from scratch; without any state (i.e. STATE == 0), then we
start at the top of the list. */
char *
command_generator (text, state)
char *text;
int state;
{
static int list_index, len;
char *name;
/* If this is a new word to complete, initialize now. This includes
saving the length of TEXT for efficiency, and initializing the index
variable to 0. */
if (!state)
{
list_index = 0;
len = strlen (text);
}
/* Return the next name which partially matches from the command list. */
while (name = commands[list_index].name)
{
list_index++;
if (strncmp (name, text, len) == 0)
return (name);
}
/* If no names matched, then return NULL. */
return ((char *)NULL);
}
/* **************************************************************** */
/* */
/* FileMan Commands */
/* */
/* **************************************************************** */
/* String to pass to system (). This is for the LIST, VIEW and RENAME
commands. */
static char syscom[1024];
/* List the file(s) named in arg. */
com_list (arg)
char *arg;
{
sprintf (syscom, "ls -FClg %s", arg);
system (syscom);
}
com_view (arg)
char *arg;
{
if (!valid_argument ("view", arg))
return;
sprintf (syscom, "cat %s | more", arg);
system (syscom);
}
com_rename (arg)
char *arg;
{
too_dangerous ("rename");
}
com_stat (arg)
char *arg;
{
struct stat finfo;
if (!valid_argument ("stat", arg))
return;
if (stat (arg, &finfo) == -1)
{
perror (arg);
return;
}
printf ("Statistics for `%s':\n", arg);
printf ("%s has %d link%s, and is %d bytes in length.\n", arg,
finfo.st_nlink, (finfo.st_nlink == 1) ? "" : "s", finfo.st_size);
printf (" Created on: %s", ctime (&finfo.st_ctime));
printf (" Last access at: %s", ctime (&finfo.st_atime));
printf ("Last modified at: %s", ctime (&finfo.st_mtime));
}
com_delete (arg)
char *arg;
{
too_dangerous ("delete");
}
/* Print out help for ARG, or for all of the commands if ARG is
not present. */
com_help (arg)
char *arg;
{
register int i;
int printed = 0;
for (i = 0; commands[i].name; i++)
{
if (!*arg || (strcmp (arg, commands[i].name) == 0))
{
printf ("%s\t\t%s.\n", commands[i].name, commands[i].doc);
printed++;
}
}
if (!printed)
{
printf ("No commands match `%s'. Possibilties are:\n", arg);
for (i = 0; commands[i].name; i++)
{
/* Print in six columns. */
if (printed == 6)
{
printed = 0;
printf ("\n");
}
printf ("%s\t", commands[i].name);
printed++;
}
if (printed)
printf ("\n");
}
}
/* Change to the directory ARG. */
com_cd (arg)
char *arg;
{
if (chdir (arg) == -1)
perror (arg);
com_pwd ("");
}
/* Print out the current working directory. */
com_pwd (ignore)
char *ignore;
{
char dir[1024];
(void) getwd (dir);
printf ("Current directory is %s\n", dir);
}
/* The user wishes to quit using this program. Just set DONE non-zero. */
com_quit (arg)
char *arg;
{
done = 1;
}
/* Function which tells you that you can't do this. */
too_dangerous (caller)
char *caller;
{
fprintf (stderr,
"%s: Too dangerous for me to distribute. Write it yourself.\n",
caller);
}
/* Return non-zero if ARG is a valid argument for CALLER, else print
an error message and return zero. */
int
valid_argument (caller, arg)
char *caller, *arg;
{
if (!arg || !*arg)
{
fprintf (stderr, "%s: Argument required.\n", caller);
return (0);
}
return (1);
}
/*
* Local variables:
* compile-command: "cc -g -I../.. -L.. -o fileman fileman.c -lreadline -ltermcap"
* end:
*/

View File

@ -0,0 +1,96 @@
/* manexamp.c -- The examples which appear in the documentation are here. */
#include <stdio.h>
#include <readline/readline.h>
/* **************************************************************** */
/* */
* How to Emulate gets () */
/* */
/* **************************************************************** */
/* A static variable for holding the line. */
static char *line_read = (char *)NULL;
/* Read a string, and return a pointer to it. Returns NULL on EOF. */
char *
do_gets ()
{
/* If the buffer has already been allocated, return the memory
to the free pool. */
if (line_read != (char *)NULL)
{
free (line_read);
line_read = (char *)NULL;
}
/* Get a line from the user. */
line_read = readline ("");
/* If the line has any text in it, save it on the history. */
if (line_read && *line_read)
add_history (line_read);
return (line_read);
}
/* **************************************************************** */
/* */
/* Writing a Function to be Called by Readline. */
/* */
/* **************************************************************** */
/* Invert the case of the COUNT following characters. */
invert_case_line (count, key)
int count, key;
{
register int start, end;
start = rl_point;
if (count < 0)
{
direction = -1;
count = -count;
}
else
direction = 1;
/* Find the end of the range to modify. */
end = start + (count * direction);
/* Force it to be within range. */
if (end > rl_end)
end = rl_end;
else if (end < 0)
end = -1;
if (start > end)
{
int temp = start;
start = end;
end = temp;
}
if (start == end)
return;
/* Tell readline that we are modifying the line, so save the undo
information. */
rl_modifying (start, end);
for (; start != end; start += direction)
{
if (uppercase_p (rl_line_buffer[start]))
rl_line_buffer[start] = to_lower (rl_line_buffer[start]);
else if (lowercase_p (rl_line_buffer[start]))
rl_line_buffer[start] = to_upper (rl_line_buffer[start]);
}
/* Move point to on top of the last character changed. */
rl_point = end - direction;
}

View File

@ -0,0 +1,214 @@
/* funmap.c -- attach names to functions. */
/* Copyright (C) 1988,1989 Free Software Foundation, Inc.
This file is part of GNU Readline, a library for reading lines
of text with interactive input and history editing.
Readline is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 1, or (at your option) any
later version.
Readline is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with Readline; see the file COPYING. If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#define STATIC_MALLOC
#ifndef STATIC_MALLOC
extern char *xmalloc (), *xrealloc ();
#else
static char *xmalloc (), *xrealloc ();
#endif
#ifndef BUFSIZ
#include <stdio.h>
#endif /* BUFSIZ */
#include "readline.h"
FUNMAP **funmap = (FUNMAP **)NULL;
static int funmap_size = 0;
static int funmap_entry = 0;
static FUNMAP default_funmap[] = {
{ "arrow-key-prefix", rl_arrow_keys },
{ "redraw-current-line", rl_refresh_line},
{ "beginning-of-line", rl_beg_of_line },
{ "backward-char", rl_backward },
{ "delete-char", rl_delete },
{ "end-of-line", rl_end_of_line },
{ "forward-char", rl_forward },
{ "accept-line", rl_newline },
{ "kill-line", rl_kill_line },
{ "clear-screen", rl_clear_screen },
{ "next-history", rl_get_next_history },
{ "previous-history", rl_get_previous_history },
{ "quoted-insert", rl_quoted_insert },
{ "reverse-search-history", rl_reverse_search_history },
{ "forward-search-history", rl_forward_search_history },
{ "transpose-chars", rl_transpose_chars },
{ "unix-line-discard", rl_unix_line_discard },
{ "unix-word-rubout", rl_unix_word_rubout },
{ "yank", rl_yank },
{ "yank-pop", rl_yank_pop },
{ "yank-nth-arg", rl_yank_nth_arg },
{ "backward-delete-char", rl_rubout },
{ "backward-word", rl_backward_word },
{ "kill-word", rl_kill_word },
{ "forward-word", rl_forward_word },
{ "tab-insert", rl_tab_insert },
{ "backward-kill-word", rl_backward_kill_word },
{ "backward-kill-line", rl_backward_kill_line },
{ "transpose-words", rl_transpose_words },
{ "digit-argument", rl_digit_argument },
{ "complete", rl_complete },
{ "possible-completions", rl_possible_completions },
{ "do-lowercase-version", rl_do_lowercase_version },
{ "digit-argument", rl_digit_argument },
{ "universal-argument", rl_universal_argument },
{ "abort", rl_abort },
{ "undo", rl_undo_command },
{ "upcase-word", rl_upcase_word },
{ "downcase-word", rl_downcase_word },
{ "capitalize-word", rl_capitalize_word },
{ "revert-line", rl_revert_line },
{ "beginning-of-history", rl_beginning_of_history },
{ "end-of-history", rl_end_of_history },
{ "self-insert", rl_insert },
{ "start-kbd-macro", rl_start_kbd_macro },
{ "end-kbd-macro", rl_end_kbd_macro },
{ "re-read-init-file", rl_re_read_init_file },
#ifdef VI_MODE
{ "vi-movement-mode", rl_vi_movement_mode },
{ "vi-insertion-mode", rl_vi_insertion_mode },
{ "vi-arg-digit", rl_vi_arg_digit },
{ "vi-prev-word", rl_vi_prev_word },
{ "vi-next-word", rl_vi_next_word },
{ "vi-char-search", rl_vi_char_search },
{ "vi-editing-mode", rl_vi_editing_mode },
{ "vi-eof-maybe", rl_vi_eof_maybe },
{ "vi-append-mode", rl_vi_append_mode },
{ "vi-put", rl_vi_put },
{ "vi-append-eol", rl_vi_append_eol },
{ "vi-insert-beg", rl_vi_insert_beg },
{ "vi-delete", rl_vi_delete },
{ "vi-comment", rl_vi_comment },
{ "vi-first-print", rl_vi_first_print },
{ "vi-fword", rl_vi_fword },
{ "vi-fWord", rl_vi_fWord },
{ "vi-bword", rl_vi_bword },
{ "vi-bWord", rl_vi_bWord },
{ "vi-eword", rl_vi_eword },
{ "vi-eWord", rl_vi_eWord },
{ "vi-end-word", rl_vi_end_word },
{ "vi-change-case", rl_vi_change_case },
{ "vi-match", rl_vi_match },
{ "vi-bracktype", rl_vi_bracktype },
{ "vi-change-char", rl_vi_change_char },
{ "vi-yank-arg", rl_vi_yank_arg },
{ "vi-search", rl_vi_search },
{ "vi-search-again", rl_vi_search_again },
{ "vi-dosearch", rl_vi_dosearch },
{ "vi-subst", rl_vi_subst },
{ "vi-overstrike", rl_vi_overstrike },
{ "vi-overstrike-delete", rl_vi_overstrike_delete },
{ "vi-replace, ", rl_vi_replace },
{ "vi-column", rl_vi_column },
{ "vi-delete-to", rl_vi_delete_to },
{ "vi-change-to", rl_vi_change_to },
{ "vi-yank-to", rl_vi_yank_to },
{ "vi-complete", rl_vi_complete },
#endif /* VI_MODE */
{(char *)NULL, (Function *)NULL }
};
rl_add_funmap_entry (name, function)
char *name;
Function *function;
{
if (funmap_entry + 2 >= funmap_size)
if (!funmap)
funmap = (FUNMAP **)xmalloc ((funmap_size = 80) * sizeof (FUNMAP *));
else
funmap =
(FUNMAP **)xrealloc (funmap, (funmap_size += 80) * sizeof (FUNMAP *));
funmap[funmap_entry] = (FUNMAP *)xmalloc (sizeof (FUNMAP));
funmap[funmap_entry]->name = name;
funmap[funmap_entry]->function = function;
funmap[++funmap_entry] = (FUNMAP *)NULL;
}
static int funmap_initialized = 0;
/* Make the funmap contain all of the default entries. */
rl_initialize_funmap ()
{
register int i;
if (funmap_initialized)
return;
for (i = 0; default_funmap[i].name; i++)
rl_add_funmap_entry (default_funmap[i].name, default_funmap[i].function);
funmap_initialized = 1;
}
/* Things that mean `Control'. */
char *possible_control_prefixes[] = {
"Control-", "C-", "CTRL-", (char *)NULL
};
char *possible_meta_prefixes[] = {
"Meta", "M-", (char *)NULL
};
#ifdef STATIC_MALLOC
/* **************************************************************** */
/* */
/* xmalloc and xrealloc () */
/* */
/* **************************************************************** */
static void memory_error_and_abort ();
static char *
xmalloc (bytes)
int bytes;
{
char *temp = (char *)malloc (bytes);
if (!temp)
memory_error_and_abort ();
return (temp);
}
static char *
xrealloc (pointer, bytes)
char *pointer;
int bytes;
{
char *temp = (char *)realloc (pointer, bytes);
if (!temp)
memory_error_and_abort ();
return (temp);
}
static void
memory_error_and_abort ()
{
fprintf (stderr, "history: Out of virtual memory!\n");
abort ();
}
#endif /* STATIC_MALLOC */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,173 @@
/* keymaps.c -- Functions and keymaps for the GNU Readline library. */
/* Copyright (C) 1988,1989 Free Software Foundation, Inc.
This file is part of GNU Readline, a library for reading lines
of text with interactive input and history editing.
Readline is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 1, or (at your option) any
later version.
Readline is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with Readline; see the file COPYING. If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "keymaps.h"
#include "emacs_keymap.c"
#ifdef VI_MODE
#include "vi_keymap.c"
#endif
/* Remove these declarations when we have a complete libgnu.a. */
#define STATIC_MALLOC
#ifndef STATIC_MALLOC
extern char *xmalloc (), *xrealloc ();
#else
static char *xmalloc (), *xrealloc ();
#endif
/* **************************************************************** */
/* */
/* Functions for manipulating Keymaps. */
/* */
/* **************************************************************** */
/* Return a new, empty keymap.
Free it with free() when you are done. */
Keymap
rl_make_bare_keymap ()
{
register int i;
Keymap keymap = (Keymap)xmalloc (128 * sizeof (KEYMAP_ENTRY));
for (i = 0; i < 128; i++)
{
keymap[i].type = ISFUNC;
keymap[i].function = (Function *)NULL;
}
for (i = 'A'; i < ('Z' + 1); i++)
{
keymap[i].type = ISFUNC;
keymap[i].function = rl_do_lowercase_version;
}
return (keymap);
}
/* Return a new keymap which is a copy of MAP. */
Keymap
rl_copy_keymap (map)
Keymap map;
{
register int i;
Keymap temp = rl_make_bare_keymap ();
for (i = 0; i < 128; i++)
{
temp[i].type = map[i].type;
temp[i].function = map[i].function;
}
return (temp);
}
/* Return a new keymap with the printing characters bound to rl_insert,
the uppercase Meta characters bound to run their lowercase equivalents,
and the Meta digits bound to produce numeric arguments. */
Keymap
rl_make_keymap ()
{
extern rl_insert (), rl_rubout (), rl_do_lowercase_version ();
extern rl_digit_argument ();
register int i;
Keymap newmap;
newmap = rl_make_bare_keymap ();
/* All printing characters are self-inserting. */
for (i = ' '; i < 126; i++)
newmap[i].function = rl_insert;
newmap[TAB].function = rl_insert;
newmap[RUBOUT].function = rl_rubout;
newmap[CTRL('H')].function = rl_rubout;
return (newmap);
}
/* Free the storage associated with MAP. */
rl_discard_keymap (map)
Keymap (map);
{
int i;
if (!map)
return;
for (i = 0; i < 128; i++)
{
switch (map[i].type)
{
case ISFUNC:
break;
case ISKMAP:
rl_discard_keymap ((Keymap)map[i].function);
break;
case ISMACR:
free ((char *)map[i].function);
break;
}
}
}
#ifdef STATIC_MALLOC
/* **************************************************************** */
/* */
/* xmalloc and xrealloc () */
/* */
/* **************************************************************** */
static void memory_error_and_abort ();
static char *
xmalloc (bytes)
int bytes;
{
char *temp = (char *)malloc (bytes);
if (!temp)
memory_error_and_abort ();
return (temp);
}
static char *
xrealloc (pointer, bytes)
char *pointer;
int bytes;
{
char *temp = (char *)realloc (pointer, bytes);
if (!temp)
memory_error_and_abort ();
return (temp);
}
static void
memory_error_and_abort ()
{
fprintf (stderr, "readline: Out of virtual memory!\n");
abort ();
}
#endif /* STATIC_MALLOC */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,50 @@
/* chardefs.h -- Character definitions for readline. */
#ifndef _CHARDEFS_
#ifndef savestring
#define savestring(x) (char *)strcpy (xmalloc (1 + strlen (x)), (x))
#endif
#ifndef whitespace
#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
#endif
#ifdef CTRL
#undef CTRL
#endif
/* Some character stuff. */
#define control_character_threshold 0x020 /* smaller than this is control */
#define meta_character_threshold 0x07f /* larger than this is Meta. */
#define control_character_bit 0x40 /* 0x000000, must be off. */
#define meta_character_bit 0x080 /* x0000000, must be on. */
#define CTRL(c) ((c) & (~control_character_bit))
#define META(c) ((c) | meta_character_bit)
#define UNMETA(c) ((c) & (~meta_character_bit))
#define UNCTRL(c) to_upper(((c)|control_character_bit))
#define lowercase_p(c) (((c) > ('a' - 1) && (c) < ('z' + 1)))
#define uppercase_p(c) (((c) > ('A' - 1) && (c) < ('Z' + 1)))
#define pure_alphabetic(c) (lowercase_p(c) || uppercase_p(c))
#ifndef to_upper
#define to_upper(c) (lowercase_p(c) ? ((c) - 32) : (c))
#define to_lower(c) (uppercase_p(c) ? ((c) + 32) : (c))
#endif
#define CTRL_P(c) ((c) < control_character_threshold)
#define META_P(c) ((c) > meta_character_threshold)
#define NEWLINE '\n'
#define RETURN CTRL('M')
#define RUBOUT 0x07f
#define TAB '\t'
#define ABORT_CHAR CTRL('G')
#define PAGE CTRL('L')
#define SPACE 0x020
#define ESC CTRL('[')
#endif /* _CHARDEFS_ */

View File

@ -0,0 +1,51 @@
/* keymaps.h -- Manipulation of readline keymaps. */
#ifndef _KEYMAPS_H_
#define _KEYMAPS_H_
#include <readline/chardefs.h>
#ifndef __FUNCTION_DEF
typedef int Function ();
#define __FUNCTION_DEF
#endif
/* A keymap contains one entry for each key in the ASCII set.
Each entry consists of a type and a pointer.
POINTER is the address of a function to run, or the
address of a keymap to indirect through.
TYPE says which kind of thing POINTER is. */
typedef struct _keymap_entry {
char type;
Function *function;
} KEYMAP_ENTRY;
/* I wanted to make the above structure contain a union of:
union { Function *function; struct _keymap_entry *keymap; } value;
but this made it impossible for me to create a static array.
Maybe I need C lessons. */
typedef KEYMAP_ENTRY KEYMAP_ENTRY_ARRAY[128];
typedef KEYMAP_ENTRY *Keymap;
/* The values that TYPE can have in a keymap entry. */
#define ISFUNC 0
#define ISKMAP 1
#define ISMACR 2
extern KEYMAP_ENTRY_ARRAY emacs_standard_keymap, emacs_meta_keymap, emacs_ctlx_keymap;
extern KEYMAP_ENTRY_ARRAY vi_insertion_keymap, vi_movement_keymap;
/* Return a new, empty keymap.
Free it with free() when you are done. */
Keymap rl_make_bare_keymap ();
/* Return a new keymap which is a copy of MAP. */
Keymap rl_copy_keymap ();
/* Return a new keymap with the printing characters bound to rl_insert,
the lowercase Meta characters bound to run their equivalents, and
the Meta digits bound to produce numeric arguments. */
Keymap rl_make_keymap ();
#endif /* _KEYMAPS_H_ */

View File

@ -0,0 +1,179 @@
/* Readline.h -- the names of functions callable from within readline. */
#ifndef _READLINE_H_
#define _READLINE_H_
#include <readline/keymaps.h>
#ifndef __FUNCTION_DEF
typedef int Function ();
#define __FUNCTION_DEF
#endif
/* The functions for manipulating the text of the line within readline.
Most of these functions are bound to keys by default. */
extern int
rl_beg_of_line (), rl_backward (), rl_delete (), rl_end_of_line (),
rl_forward (), ding (), rl_backward (), rl_newline (), rl_kill_line (),
rl_clear_screen (), rl_get_next_history (), rl_get_previous_history (),
rl_quoted_insert (), rl_reverse_search_history (), rl_transpose_chars
(), rl_unix_line_discard (), rl_quoted_insert (), rl_unix_word_rubout
(), rl_yank (), rl_rubout (), rl_backward_word (), rl_kill_word (),
rl_forward_word (), rl_tab_insert (), rl_yank_pop (), rl_yank_nth_arg (),
rl_backward_kill_word (), rl_backward_kill_line (), rl_transpose_words
(), rl_complete (), rl_possible_completions (), rl_do_lowercase_version
(), rl_digit_argument (), rl_universal_argument (), rl_abort (),
rl_undo_command (), rl_revert_line (), rl_beginning_of_history (),
rl_end_of_history (), rl_forward_search_history (), rl_insert (),
rl_upcase_word (), rl_downcase_word (), rl_capitalize_word (),
rl_restart_output (), rl_re_read_init_file ();
/* These are *both* defined even when VI_MODE is not. */
extern int rl_vi_editing_mode (), rl_emacs_editing_mode ();
#ifdef VI_MODE
/* Things for vi mode. */
extern int rl_vi_movement_mode (), rl_vi_insertion_mode (), rl_vi_arg_digit (),
rl_vi_prev_word (), rl_vi_next_word (), rl_vi_char_search (),
rl_vi_eof_maybe (), rl_vi_append_mode (), rl_vi_put (),
rl_vi_append_eol (), rl_vi_insert_beg (), rl_vi_delete (), rl_vi_comment (),
rl_vi_first_print (), rl_vi_fword (), rl_vi_fWord (), rl_vi_bword (),
rl_vi_bWord (), rl_vi_eword (), rl_vi_eWord (), rl_vi_end_word (),
rl_vi_change_case (), rl_vi_match (), rl_vi_bracktype (), rl_vi_change_char (),
rl_vi_yank_arg (), rl_vi_search (), rl_vi_search_again (),
rl_vi_dosearch (), rl_vi_subst (), rl_vi_overstrike (),
rl_vi_overstrike_delete (), rl_vi_replace(), rl_vi_column (),
rl_vi_delete_to (), rl_vi_change_to (), rl_vi_yank_to (), rl_vi_complete ();
#endif /* VI_MODE */
/* Keyboard macro commands. */
extern int
rl_start_kbd_macro (), rl_end_kbd_macro (), rl_call_last_kbd_macro ();
extern int rl_arrow_keys(), rl_refresh_line ();
/* Maintaining the state of undo. We remember individual deletes and inserts
on a chain of things to do. */
/* The actions that undo knows how to undo. Notice that UNDO_DELETE means
to insert some text, and UNDO_INSERT means to delete some text. I.e.,
the code tells undo what to undo, not how to undo it. */
enum undo_code { UNDO_DELETE, UNDO_INSERT, UNDO_BEGIN, UNDO_END };
/* What an element of THE_UNDO_LIST looks like. */
typedef struct undo_list {
struct undo_list *next;
int start, end; /* Where the change took place. */
char *text; /* The text to insert, if undoing a delete. */
enum undo_code what; /* Delete, Insert, Begin, End. */
} UNDO_LIST;
/* The current undo list for RL_LINE_BUFFER. */
extern UNDO_LIST *rl_undo_list;
/* The data structure for mapping textual names to code addresses. */
typedef struct {
char *name;
Function *function;
} FUNMAP;
extern FUNMAP **funmap;
/* **************************************************************** */
/* */
/* Well Published Variables */
/* */
/* **************************************************************** */
/* The name of the calling program. You should initialize this to
whatever was in argv[0]. It is used when parsing conditionals. */
extern char *rl_readline_name;
/* The line buffer that is in use. */
extern char *rl_line_buffer;
/* The location of point, and end. */
extern int rl_point, rl_end;
/* The name of the terminal to use. */
extern char *rl_terminal_name;
/* The input and output streams. */
extern FILE *rl_instream, *rl_outstream;
/* The basic list of characters that signal a break between words for the
completer routine. The initial contents of this variable is what
breaks words in the shell, i.e. "n\"\\'`@$>". */
extern char *rl_basic_word_break_characters;
/* The list of characters that signal a break between words for
rl_complete_internal. The default list is the contents of
rl_basic_word_break_characters. */
extern char *rl_completer_word_break_characters;
/* List of characters that are word break characters, but should be left
in TEXT when it is passed to the completion function. The shell uses
this to help determine what kind of completing to do. */
extern char *rl_special_prefixes;
/* Pointer to the generator function for completion_matches ().
NULL means to use filename_entry_function (), the default filename
completer. */
extern Function *rl_completion_entry_function;
/* If rl_ignore_some_completions_function is non-NULL it is the address
of a function to call after all of the possible matches have been
generated, but before the actual completion is done to the input line.
The function is called with one argument; a NULL terminated array
of (char *). If your function removes any of the elements, they
must be free()'ed. */
extern Function *rl_ignore_some_completions_function;
/* Pointer to alternative function to create matches.
Function is called with TEXT, START, and END.
START and END are indices in RL_LINE_BUFFER saying what the boundaries
of TEXT are.
If this function exists and returns NULL then call the value of
rl_completion_entry_function to try to match, otherwise use the
array of strings returned. */
extern Function *rl_attempted_completion_function;
/* If non-null, this contains the address of a function to call if the
standard meaning for expanding a tilde fails. The function is called
with the text (sans tilde, as in "foo"), and returns a malloc()'ed string
which is the expansion, or a NULL pointer if there is no expansion. */
extern Function *rl_tilde_expander;
/* If non-zero, then this is the address of a function to call just
before readline_internal () prints the first prompt. */
extern Function *rl_startup_hook;
/* If non-zero, then this is the address of a function to call when
completing on a directory name. The function is called with
the address of a string (the current directory name) as an arg. */
extern Function *rl_symbolic_link_hook;
/* Non-zero means that modified history lines are preceded
with an asterisk. */
extern int rl_show_star;
/* **************************************************************** */
/* */
/* Well Published Functions */
/* */
/* **************************************************************** */
/* Read a line of input. Prompt with PROMPT. A NULL PROMPT means none. */
extern char *readline ();
/* Return an array of strings which are the result of repeatadly calling
FUNC with TEXT. */
extern char **completion_matches ();
/* rl_add_defun (char *name, Function *function, int key)
Add NAME to the list of named functions. Make FUNCTION
be the function that gets called.
If KEY is not -1, then bind it. */
extern int rl_add_defun ();
#endif /* _READLINE_H_ */

View File

@ -0,0 +1,50 @@
*** readline.c.orig Thu May 5 04:02:17 1994
--- readline.c Mon May 9 00:33:44 1994
***************
*** 32,37 ****
--- 32,38 ----
#include <stdio.h>
#include <sys/types.h>
+ #include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/file.h>
#include <signal.h>
***************
*** 280,285 ****
--- 281,295 ----
/* Non-zero means to save keys that we dispatch on in a kbd macro. */
static int defining_kbd_macro = 0;
+ /* XXX this prevents to got editing mode from tcsh */
+ static void wait_foreground(void)
+ {
+ struct winsize w;
+ int tty = fileno (rl_instream);
+
+ if (ioctl (tty, TIOCGWINSZ, &w) == 0)
+ (void) ioctl (tty, TIOCSWINSZ, &w);
+ }
/* **************************************************************** */
/* */
***************
*** 1153,1158 ****
--- 1163,1169 ----
#endif /* POSIX */
int tty = fileno (rl_instream);
+ wait_foreground (); /* XXX this prevents to got editing mode from tcsh */
#if defined (_POSIX_VERSION)
if (tcgetattr (tty, &ttybuff) != -1)
#else
***************
*** 2307,2312 ****
--- 2318,2324 ----
# endif /* HAVE_BSD_SIGNALS */
#endif /* POSIX */
+ wait_foreground (); /* XXX this prevents to got editing mode from tcsh */
#if defined (_POSIX_VERSION)
tcgetattr (tty, &tio);
#else

View File

@ -0,0 +1,474 @@
/* vi_keymap.c -- the keymap for vi_mode in readline (). */
/* Copyright (C) 1988,1989 Free Software Foundation, Inc.
This file is part of GNU Readline, a library for reading lines
of text with interactive input and history editing.
Readline is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 1, or (at your option) any
later version.
Readline is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with Readline; see the file COPYING. If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef BUFSIZ
#include <stdio.h>
#endif /* BUFSIZ */
#include "readline.h"
extern KEYMAP_ENTRY_ARRAY vi_escape_keymap;
/* The keymap arrays for handling vi mode. */
KEYMAP_ENTRY_ARRAY vi_movement_keymap = {
/* The regular control keys come first. */
{ ISFUNC, (Function *)0x0 }, /* Control-@ */
{ ISFUNC, (Function *)0x0 }, /* Control-a */
{ ISFUNC, (Function *)0x0 }, /* Control-b */
{ ISFUNC, (Function *)0x0 }, /* Control-c */
{ ISFUNC, rl_vi_eof_maybe }, /* Control-d */
{ ISFUNC, rl_emacs_editing_mode }, /* Control-e */
{ ISFUNC, (Function *)0x0 }, /* Control-f */
{ ISFUNC, rl_abort }, /* Control-g */
{ ISFUNC, rl_rubout }, /* Control-h */
{ ISFUNC, (Function *)0x0 }, /* Control-i */
{ ISFUNC, rl_newline }, /* Control-j */
{ ISFUNC, rl_kill_line }, /* Control-k */
{ ISFUNC, rl_clear_screen }, /* Control-l */
{ ISFUNC, rl_newline }, /* Control-m */
{ ISFUNC, rl_get_next_history }, /* Control-n */
{ ISFUNC, (Function *)0x0 }, /* Control-o */
{ ISFUNC, rl_get_previous_history }, /* Control-p */
{ ISFUNC, rl_quoted_insert }, /* Control-q */
{ ISFUNC, rl_reverse_search_history }, /* Control-r */
{ ISFUNC, rl_forward_search_history }, /* Control-s */
{ ISFUNC, rl_transpose_chars }, /* Control-t */
{ ISFUNC, rl_unix_line_discard }, /* Control-u */
{ ISFUNC, rl_quoted_insert }, /* Control-v */
{ ISFUNC, rl_unix_word_rubout }, /* Control-w */
{ ISFUNC, (Function *)0x0 }, /* Control-x */
{ ISFUNC, rl_yank }, /* Control-y */
{ ISFUNC, (Function *)0x0 }, /* Control-z */
{ ISKMAP, (Function *)vi_escape_keymap }, /* Control-[ */
{ ISFUNC, (Function *)0x0 }, /* Control-\ */
{ ISFUNC, (Function *)0x0 }, /* Control-] */
{ ISFUNC, (Function *)0x0 }, /* Control-^ */
{ ISFUNC, rl_undo_command }, /* Control-_ */
/* The start of printing characters. */
{ ISFUNC, rl_forward }, /* SPACE */
{ ISFUNC, (Function *)0x0 }, /* ! */
{ ISFUNC, (Function *)0x0 }, /* " */
{ ISFUNC, rl_vi_comment }, /* # */
{ ISFUNC, rl_end_of_line }, /* $ */
{ ISFUNC, rl_vi_match }, /* % */
{ ISFUNC, (Function *)0x0 }, /* & */
{ ISFUNC, (Function *)0x0 }, /* ' */
{ ISFUNC, (Function *)0x0 }, /* ( */
{ ISFUNC, (Function *)0x0 }, /* ) */
{ ISFUNC, rl_vi_complete }, /* * */
{ ISFUNC, rl_get_next_history}, /* + */
{ ISFUNC, rl_vi_char_search }, /* , */
{ ISFUNC, rl_get_previous_history }, /* - */
{ ISFUNC, (Function *)0x0 }, /* . */
{ ISFUNC, rl_vi_search }, /* / */
/* Regular digits. */
{ ISFUNC, rl_vi_arg_digit }, /* 0 */
{ ISFUNC, rl_vi_arg_digit }, /* 1 */
{ ISFUNC, rl_vi_arg_digit }, /* 2 */
{ ISFUNC, rl_vi_arg_digit }, /* 3 */
{ ISFUNC, rl_vi_arg_digit }, /* 4 */
{ ISFUNC, rl_vi_arg_digit }, /* 5 */
{ ISFUNC, rl_vi_arg_digit }, /* 6 */
{ ISFUNC, rl_vi_arg_digit }, /* 7 */
{ ISFUNC, rl_vi_arg_digit }, /* 8 */
{ ISFUNC, rl_vi_arg_digit }, /* 9 */
/* A little more punctuation. */
{ ISFUNC, (Function *)0x0 }, /* : */
{ ISFUNC, rl_vi_char_search }, /* ; */
{ ISFUNC, (Function *)0x0 }, /* < */
{ ISFUNC, (Function *)0x0 }, /* = */
{ ISFUNC, (Function *)0x0 }, /* > */
{ ISFUNC, rl_vi_search }, /* ? */
{ ISFUNC, (Function *)0x0 }, /* @ */
/* Uppercase alphabet. */
{ ISFUNC, rl_vi_append_eol }, /* A */
{ ISFUNC, rl_vi_prev_word}, /* B */
{ ISFUNC, rl_vi_change_to }, /* C */
{ ISFUNC, rl_vi_delete_to }, /* D */
{ ISFUNC, rl_vi_end_word }, /* E */
{ ISFUNC, rl_vi_char_search }, /* F */
{ ISFUNC, (Function *)0x0 }, /* G */
{ ISFUNC, (Function *)0x0 }, /* H */
{ ISFUNC, rl_vi_insert_beg }, /* I */
{ ISFUNC, (Function *)0x0 }, /* J */
{ ISFUNC, (Function *)0x0 }, /* K */
{ ISFUNC, (Function *)0x0 }, /* L */
{ ISFUNC, (Function *)0x0 }, /* M */
{ ISFUNC, rl_vi_search_again }, /* N */
{ ISFUNC, (Function *)0x0 }, /* O */
{ ISFUNC, rl_vi_put }, /* P */
{ ISFUNC, (Function *)0x0 }, /* Q */
{ ISFUNC, rl_vi_replace }, /* R */
{ ISFUNC, rl_vi_subst }, /* S */
{ ISFUNC, rl_vi_char_search }, /* T */
{ ISFUNC, rl_revert_line }, /* U */
{ ISFUNC, (Function *)0x0 }, /* V */
{ ISFUNC, rl_vi_next_word }, /* W */
{ ISFUNC, rl_rubout }, /* X */
{ ISFUNC, rl_vi_yank_to }, /* Y */
{ ISFUNC, (Function *)0x0 }, /* Z */
/* Some more punctuation. */
{ ISFUNC, (Function *)0x0 }, /* [ */
{ ISFUNC, (Function *)0x0 }, /* \ */
{ ISFUNC, (Function *)0x0 }, /* ] */
{ ISFUNC, rl_vi_first_print }, /* ^ */
{ ISFUNC, rl_vi_yank_arg }, /* _ */
{ ISFUNC, (Function *)0x0 }, /* ` */
/* Lowercase alphabet. */
{ ISFUNC, rl_vi_append_mode }, /* a */
{ ISFUNC, rl_vi_prev_word }, /* b */
{ ISFUNC, rl_vi_change_to }, /* c */
{ ISFUNC, rl_vi_delete_to }, /* d */
{ ISFUNC, rl_vi_end_word }, /* e */
{ ISFUNC, rl_vi_char_search }, /* f */
{ ISFUNC, (Function *)0x0 }, /* g */
{ ISFUNC, rl_backward }, /* h */
{ ISFUNC, rl_vi_insertion_mode }, /* i */
{ ISFUNC, rl_get_next_history }, /* j */
{ ISFUNC, rl_get_previous_history }, /* k */
{ ISFUNC, rl_forward }, /* l */
{ ISFUNC, (Function *)0x0 }, /* m */
{ ISFUNC, rl_vi_search_again }, /* n */
{ ISFUNC, (Function *)0x0 }, /* o */
{ ISFUNC, rl_vi_put }, /* p */
{ ISFUNC, (Function *)0x0 }, /* q */
{ ISFUNC, rl_vi_change_char }, /* r */
{ ISFUNC, rl_vi_subst }, /* s */
{ ISFUNC, rl_vi_char_search }, /* t */
{ ISFUNC, rl_undo_command }, /* u */
{ ISFUNC, (Function *)0x0 }, /* v */
{ ISFUNC, rl_vi_next_word }, /* w */
{ ISFUNC, rl_vi_delete }, /* x */
{ ISFUNC, rl_vi_yank_to }, /* y */
{ ISFUNC, (Function *)0x0 }, /* z */
/* Final punctuation. */
{ ISFUNC, (Function *)0x0 }, /* { */
{ ISFUNC, rl_vi_column }, /* | */
{ ISFUNC, (Function *)0x0 }, /* } */
{ ISFUNC, rl_vi_change_case }, /* ~ */
{ ISFUNC, rl_backward } /* RUBOUT */
};
KEYMAP_ENTRY_ARRAY vi_insertion_keymap = {
/* The regular control keys come first. */
{ ISFUNC, (Function *)0x0 }, /* Control-@ */
{ ISFUNC, rl_insert }, /* Control-a */
{ ISFUNC, rl_insert }, /* Control-b */
{ ISFUNC, rl_insert }, /* Control-c */
{ ISFUNC, rl_vi_eof_maybe }, /* Control-d */
{ ISFUNC, rl_insert }, /* Control-e */
{ ISFUNC, rl_insert }, /* Control-f */
{ ISFUNC, rl_insert }, /* Control-g */
{ ISFUNC, rl_rubout }, /* Control-h */
{ ISFUNC, rl_complete }, /* Control-i */
{ ISFUNC, rl_newline }, /* Control-j */
{ ISFUNC, rl_insert }, /* Control-k */
{ ISFUNC, rl_insert }, /* Control-l */
{ ISFUNC, rl_newline }, /* Control-m */
{ ISFUNC, rl_insert }, /* Control-n */
{ ISFUNC, rl_insert }, /* Control-o */
{ ISFUNC, rl_insert }, /* Control-p */
{ ISFUNC, rl_insert }, /* Control-q */
{ ISFUNC, rl_reverse_search_history }, /* Control-r */
{ ISFUNC, rl_forward_search_history }, /* Control-s */
{ ISFUNC, rl_transpose_chars }, /* Control-t */
{ ISFUNC, rl_unix_line_discard }, /* Control-u */
{ ISFUNC, rl_quoted_insert }, /* Control-v */
{ ISFUNC, rl_unix_word_rubout }, /* Control-w */
{ ISFUNC, rl_insert }, /* Control-x */
{ ISFUNC, rl_yank }, /* Control-y */
{ ISFUNC, rl_insert }, /* Control-z */
{ ISFUNC, rl_vi_movement_mode }, /* Control-[ */
{ ISFUNC, rl_insert }, /* Control-\ */
{ ISFUNC, rl_insert }, /* Control-] */
{ ISFUNC, rl_insert }, /* Control-^ */
{ ISFUNC, rl_undo_command }, /* Control-_ */
/* The start of printing characters. */
{ ISFUNC, rl_insert }, /* SPACE */
{ ISFUNC, rl_insert }, /* ! */
{ ISFUNC, rl_insert }, /* " */
{ ISFUNC, rl_insert }, /* # */
{ ISFUNC, rl_insert }, /* $ */
{ ISFUNC, rl_insert }, /* % */
{ ISFUNC, rl_insert }, /* & */
{ ISFUNC, rl_insert }, /* ' */
{ ISFUNC, rl_insert }, /* ( */
{ ISFUNC, rl_insert }, /* ) */
{ ISFUNC, rl_insert }, /* * */
{ ISFUNC, rl_insert }, /* + */
{ ISFUNC, rl_insert }, /* , */
{ ISFUNC, rl_insert }, /* - */
{ ISFUNC, rl_insert }, /* . */
{ ISFUNC, rl_insert }, /* / */
/* Regular digits. */
{ ISFUNC, rl_insert }, /* 0 */
{ ISFUNC, rl_insert }, /* 1 */
{ ISFUNC, rl_insert }, /* 2 */
{ ISFUNC, rl_insert }, /* 3 */
{ ISFUNC, rl_insert }, /* 4 */
{ ISFUNC, rl_insert }, /* 5 */
{ ISFUNC, rl_insert }, /* 6 */
{ ISFUNC, rl_insert }, /* 7 */
{ ISFUNC, rl_insert }, /* 8 */
{ ISFUNC, rl_insert }, /* 9 */
/* A little more punctuation. */
{ ISFUNC, rl_insert }, /* : */
{ ISFUNC, rl_insert }, /* ; */
{ ISFUNC, rl_insert }, /* < */
{ ISFUNC, rl_insert }, /* = */
{ ISFUNC, rl_insert }, /* > */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* @ */
/* Uppercase alphabet. */
{ ISFUNC, rl_insert }, /* A */
{ ISFUNC, rl_insert }, /* B */
{ ISFUNC, rl_insert }, /* C */
{ ISFUNC, rl_insert }, /* D */
{ ISFUNC, rl_insert }, /* E */
{ ISFUNC, rl_insert }, /* F */
{ ISFUNC, rl_insert }, /* G */
{ ISFUNC, rl_insert }, /* H */
{ ISFUNC, rl_insert }, /* I */
{ ISFUNC, rl_insert }, /* J */
{ ISFUNC, rl_insert }, /* K */
{ ISFUNC, rl_insert }, /* L */
{ ISFUNC, rl_insert }, /* M */
{ ISFUNC, rl_insert }, /* N */
{ ISFUNC, rl_insert }, /* O */
{ ISFUNC, rl_insert }, /* P */
{ ISFUNC, rl_insert }, /* Q */
{ ISFUNC, rl_insert }, /* R */
{ ISFUNC, rl_insert }, /* S */
{ ISFUNC, rl_insert }, /* T */
{ ISFUNC, rl_insert }, /* U */
{ ISFUNC, rl_insert }, /* V */
{ ISFUNC, rl_insert }, /* W */
{ ISFUNC, rl_insert }, /* X */
{ ISFUNC, rl_insert }, /* Y */
{ ISFUNC, rl_insert }, /* Z */
/* Some more punctuation. */
{ ISFUNC, rl_insert }, /* [ */
{ ISFUNC, rl_insert }, /* \ */
{ ISFUNC, rl_insert }, /* ] */
{ ISFUNC, rl_insert }, /* ^ */
{ ISFUNC, rl_insert }, /* _ */
{ ISFUNC, rl_insert }, /* ` */
/* Lowercase alphabet. */
{ ISFUNC, rl_insert }, /* a */
{ ISFUNC, rl_insert }, /* b */
{ ISFUNC, rl_insert }, /* c */
{ ISFUNC, rl_insert }, /* d */
{ ISFUNC, rl_insert }, /* e */
{ ISFUNC, rl_insert }, /* f */
{ ISFUNC, rl_insert }, /* g */
{ ISFUNC, rl_insert }, /* h */
{ ISFUNC, rl_insert }, /* i */
{ ISFUNC, rl_insert }, /* j */
{ ISFUNC, rl_insert }, /* k */
{ ISFUNC, rl_insert }, /* l */
{ ISFUNC, rl_insert }, /* m */
{ ISFUNC, rl_insert }, /* n */
{ ISFUNC, rl_insert }, /* o */
{ ISFUNC, rl_insert }, /* p */
{ ISFUNC, rl_insert }, /* q */
{ ISFUNC, rl_insert }, /* r */
{ ISFUNC, rl_insert }, /* s */
{ ISFUNC, rl_insert }, /* t */
{ ISFUNC, rl_insert }, /* u */
{ ISFUNC, rl_insert }, /* v */
{ ISFUNC, rl_insert }, /* w */
{ ISFUNC, rl_insert }, /* x */
{ ISFUNC, rl_insert }, /* y */
{ ISFUNC, rl_insert }, /* z */
/* Final punctuation. */
{ ISFUNC, rl_insert }, /* { */
{ ISFUNC, rl_insert }, /* | */
{ ISFUNC, rl_insert }, /* } */
{ ISFUNC, rl_insert }, /* ~ */
{ ISFUNC, rl_rubout } /* RUBOUT */
};
KEYMAP_ENTRY_ARRAY vi_escape_keymap = {
/* The regular control keys come first. */
{ ISFUNC, (Function *)0x0 }, /* Control-@ */
{ ISFUNC, (Function *)0x0 }, /* Control-a */
{ ISFUNC, (Function *)0x0 }, /* Control-b */
{ ISFUNC, (Function *)0x0 }, /* Control-c */
{ ISFUNC, (Function *)0x0 }, /* Control-d */
{ ISFUNC, (Function *)0x0 }, /* Control-e */
{ ISFUNC, (Function *)0x0 }, /* Control-f */
{ ISFUNC, (Function *)0x0 }, /* Control-g */
{ ISFUNC, (Function *)0x0 }, /* Control-h */
{ ISFUNC, rl_tab_insert}, /* Control-i */
{ ISFUNC, rl_emacs_editing_mode}, /* Control-j */
{ ISFUNC, rl_kill_line }, /* Control-k */
{ ISFUNC, (Function *)0x0 }, /* Control-l */
{ ISFUNC, rl_emacs_editing_mode}, /* Control-m */
{ ISFUNC, (Function *)0x0 }, /* Control-n */
{ ISFUNC, (Function *)0x0 }, /* Control-o */
{ ISFUNC, (Function *)0x0 }, /* Control-p */
{ ISFUNC, (Function *)0x0 }, /* Control-q */
{ ISFUNC, (Function *)0x0 }, /* Control-r */
{ ISFUNC, (Function *)0x0 }, /* Control-s */
{ ISFUNC, (Function *)0x0 }, /* Control-t */
{ ISFUNC, (Function *)0x0 }, /* Control-u */
{ ISFUNC, (Function *)0x0 }, /* Control-v */
{ ISFUNC, (Function *)0x0 }, /* Control-w */
{ ISFUNC, (Function *)0x0 }, /* Control-x */
{ ISFUNC, (Function *)0x0 }, /* Control-y */
{ ISFUNC, (Function *)0x0 }, /* Control-z */
{ ISFUNC, rl_vi_movement_mode }, /* Control-[ */
{ ISFUNC, (Function *)0x0 }, /* Control-\ */
{ ISFUNC, (Function *)0x0 }, /* Control-] */
{ ISFUNC, (Function *)0x0 }, /* Control-^ */
{ ISFUNC, rl_undo_command }, /* Control-_ */
/* The start of printing characters. */
{ ISFUNC, (Function *)0x0 }, /* SPACE */
{ ISFUNC, (Function *)0x0 }, /* ! */
{ ISFUNC, (Function *)0x0 }, /* " */
{ ISFUNC, (Function *)0x0 }, /* # */
{ ISFUNC, (Function *)0x0 }, /* $ */
{ ISFUNC, (Function *)0x0 }, /* % */
{ ISFUNC, (Function *)0x0 }, /* & */
{ ISFUNC, (Function *)0x0 }, /* ' */
{ ISFUNC, (Function *)0x0 }, /* ( */
{ ISFUNC, (Function *)0x0 }, /* ) */
{ ISFUNC, (Function *)0x0 }, /* * */
{ ISFUNC, (Function *)0x0 }, /* + */
{ ISFUNC, (Function *)0x0 }, /* , */
{ ISFUNC, (Function *)0x0 }, /* - */
{ ISFUNC, (Function *)0x0 }, /* . */
{ ISFUNC, (Function *)0x0 }, /* / */
/* Regular digits. */
{ ISFUNC, rl_vi_arg_digit }, /* 0 */
{ ISFUNC, rl_vi_arg_digit }, /* 1 */
{ ISFUNC, rl_vi_arg_digit }, /* 2 */
{ ISFUNC, rl_vi_arg_digit }, /* 3 */
{ ISFUNC, rl_vi_arg_digit }, /* 4 */
{ ISFUNC, rl_vi_arg_digit }, /* 5 */
{ ISFUNC, rl_vi_arg_digit }, /* 6 */
{ ISFUNC, rl_vi_arg_digit }, /* 7 */
{ ISFUNC, rl_vi_arg_digit }, /* 8 */
{ ISFUNC, rl_vi_arg_digit }, /* 9 */
/* A little more punctuation. */
{ ISFUNC, (Function *)0x0 }, /* : */
{ ISFUNC, (Function *)0x0 }, /* ; */
{ ISFUNC, (Function *)0x0 }, /* < */
{ ISFUNC, (Function *)0x0 }, /* = */
{ ISFUNC, (Function *)0x0 }, /* > */
{ ISFUNC, (Function *)0x0 }, /* ? */
{ ISFUNC, (Function *)0x0 }, /* @ */
/* Uppercase alphabet. */
{ ISFUNC, rl_do_lowercase_version }, /* A */
{ ISFUNC, rl_do_lowercase_version }, /* B */
{ ISFUNC, rl_do_lowercase_version }, /* C */
{ ISFUNC, rl_do_lowercase_version }, /* D */
{ ISFUNC, rl_do_lowercase_version }, /* E */
{ ISFUNC, rl_do_lowercase_version }, /* F */
{ ISFUNC, rl_do_lowercase_version }, /* G */
{ ISFUNC, rl_do_lowercase_version }, /* H */
{ ISFUNC, rl_do_lowercase_version }, /* I */
{ ISFUNC, rl_do_lowercase_version }, /* J */
{ ISFUNC, rl_do_lowercase_version }, /* K */
{ ISFUNC, rl_do_lowercase_version }, /* L */
{ ISFUNC, rl_do_lowercase_version }, /* M */
{ ISFUNC, rl_do_lowercase_version }, /* N */
{ ISFUNC, rl_do_lowercase_version }, /* O */
{ ISFUNC, rl_do_lowercase_version }, /* P */
{ ISFUNC, rl_do_lowercase_version }, /* Q */
{ ISFUNC, rl_do_lowercase_version }, /* R */
{ ISFUNC, rl_do_lowercase_version }, /* S */
{ ISFUNC, rl_do_lowercase_version }, /* T */
{ ISFUNC, rl_do_lowercase_version }, /* U */
{ ISFUNC, rl_do_lowercase_version }, /* V */
{ ISFUNC, rl_do_lowercase_version }, /* W */
{ ISFUNC, rl_do_lowercase_version }, /* X */
{ ISFUNC, rl_do_lowercase_version }, /* Y */
{ ISFUNC, rl_do_lowercase_version }, /* Z */
/* Some more punctuation. */
{ ISFUNC, (Function *)0x0 }, /* [ */
{ ISFUNC, (Function *)0x0 }, /* \ */
{ ISFUNC, (Function *)0x0 }, /* ] */
{ ISFUNC, (Function *)0x0 }, /* ^ */
{ ISFUNC, (Function *)0x0 }, /* _ */
{ ISFUNC, (Function *)0x0 }, /* ` */
/* Lowercase alphabet. */
{ ISFUNC, (Function *)0x0 }, /* a */
{ ISFUNC, (Function *)0x0 }, /* b */
{ ISFUNC, (Function *)0x0 }, /* c */
{ ISFUNC, (Function *)0x0 }, /* d */
{ ISFUNC, (Function *)0x0 }, /* e */
{ ISFUNC, (Function *)0x0 }, /* f */
{ ISFUNC, (Function *)0x0 }, /* g */
{ ISFUNC, (Function *)0x0 }, /* h */
{ ISFUNC, (Function *)0x0 }, /* i */
{ ISFUNC, (Function *)0x0 }, /* j */
{ ISFUNC, (Function *)0x0 }, /* k */
{ ISFUNC, (Function *)0x0 }, /* l */
{ ISFUNC, (Function *)0x0 }, /* m */
{ ISFUNC, (Function *)0x0 }, /* n */
{ ISFUNC, (Function *)0x0 }, /* o */
{ ISFUNC, (Function *)0x0 }, /* p */
{ ISFUNC, (Function *)0x0 }, /* q */
{ ISFUNC, (Function *)0x0 }, /* r */
{ ISFUNC, (Function *)0x0 }, /* s */
{ ISFUNC, (Function *)0x0 }, /* t */
{ ISFUNC, (Function *)0x0 }, /* u */
{ ISFUNC, (Function *)0x0 }, /* v */
{ ISFUNC, (Function *)0x0 }, /* w */
{ ISFUNC, (Function *)0x0 }, /* x */
{ ISFUNC, (Function *)0x0 }, /* y */
{ ISFUNC, (Function *)0x0 }, /* z */
/* Final punctuation. */
{ ISFUNC, (Function *)0x0 }, /* { */
{ ISFUNC, (Function *)0x0 }, /* | */
{ ISFUNC, (Function *)0x0 }, /* } */
{ ISFUNC, (Function *)0x0 }, /* ~ */
{ ISFUNC, rl_backward_kill_word } /* RUBOUT */
};

View File

@ -0,0 +1,987 @@
/* vi_mode.c -- A vi emulation mode for Bash.
Derived from code written by Jeff Sparkes (jeff1@????).
*/
/* **************************************************************** */
/* */
/* VI Emulation Mode */
/* */
/* **************************************************************** */
/* Last string searched for from `/' or `?'. */
static char *vi_last_search = (char *)NULL;
static int vi_histpos;
/* Non-zero means enter insertion mode. */
int vi_doing_insert = 0;
/* *** UNCLEAN *** */
/* Command keys which do movement for xxx_to commands. */
static char *vi_motion = " hl^$0ftFt;,%wbeWBE|";
/* Keymap used for vi replace characters. Created dynamically since
rarely used. */
static Keymap vi_replace_map = (Keymap)NULL;
/* The number of characters inserted in the last replace operation. */
static vi_replace_count = 0;
/* Yank the nth arg from the previous line into this line at point. */
rl_vi_yank_arg (count)
int count;
{
rl_yank_nth_arg (count, 0);
}
/* Search again for the last thing searched for. */
rl_vi_search_again (ignore, key)
int ignore, key;
{
switch (key)
{
case 'n':
rl_vi_dosearch (vi_last_search, -1);
break;
case 'N':
rl_vi_dosearch (vi_last_search, 1);
break;
}
}
/* Do a vi style search. */
rl_vi_search (count, key)
int count, key;
{
int dir, c, save_pos;
char *p;
switch (key)
{
case '?':
dir = 1;
break;
case '/':
dir = -1;
break;
default:
ding ();
return;
}
vi_histpos = where_history ();
maybe_save_line ();
save_pos = rl_point;
/* Reuse the line input buffer to read the search string. */
the_line[0] = 0;
rl_end = rl_point = 0;
p = (char *)alloca (2 + (rl_prompt ? strlen (rl_prompt) : 0));
sprintf (p, "%s%c", rl_prompt ? rl_prompt : "", key);
rl_message (p, 0, 0);
while (c = rl_read_key ())
{
switch (c)
{
case CTRL('H'):
case RUBOUT:
if (rl_point == 0)
{
maybe_unsave_line ();
rl_clear_message ();
rl_point = save_pos;
return;
}
case CTRL('W'):
case CTRL('U'):
rl_dispatch (c, keymap);
break;
case ESC:
case RETURN:
case NEWLINE:
goto dosearch;
break;
case CTRL('C'):
maybe_unsave_line ();
rl_clear_message ();
rl_point = 0;
ding ();
return;
default:
rl_insert (1, c);
break;
}
rl_redisplay ();
}
dosearch:
if (vi_last_search)
free (vi_last_search);
vi_last_search = savestring (the_line);
rl_vi_dosearch (the_line, dir);
}
rl_vi_dosearch (string, dir)
char *string;
int dir;
{
int old, save = vi_histpos;
HIST_ENTRY *h;
if (string == 0 || *string == 0 || vi_histpos < 0)
{
ding ();
return;
}
if ((save = history_search_pos (string, dir, vi_histpos + dir)) == -1)
{
maybe_unsave_line ();
rl_clear_message ();
rl_point = 0;
ding ();
return;
}
vi_histpos = save;
old = where_history ();
history_set_pos (vi_histpos);
h = current_history ();
history_set_pos (old);
strcpy (the_line, h->line);
rl_undo_list = (UNDO_LIST *)h->data;
rl_end = strlen (the_line);
rl_point = 0;
rl_clear_message ();
}
/* Completion, from vi's point of view. */
rl_vi_complete (ignore, key)
int ignore, key;
{
if ((rl_point < rl_end) && (!whitespace (the_line[rl_point])))
{
if (!whitespace (the_line[rl_point + 1]))
rl_vi_end_word (1, 'E');
rl_point++;
}
if (key == '*')
rl_complete_internal ('*');
else
rl_complete (0, key);
rl_vi_insertion_mode ();
}
/* Previous word in vi mode. */
rl_vi_prev_word (count, key)
int count, key;
{
if (count < 0)
{
rl_vi_next_word (-count, key);
return;
}
if (uppercase_p (key))
rl_vi_bWord (count);
else
rl_vi_bword (count);
}
/* Next word in vi mode. */
rl_vi_next_word (count, key)
int count;
{
if (count < 0)
{
rl_vi_prev_word (-count, key);
return;
}
if (uppercase_p (key))
rl_vi_fWord (count);
else
rl_vi_fword (count);
}
/* Move to the end of the ?next? word. */
rl_vi_end_word (count, key)
int count, key;
{
if (count < 0)
{
ding ();
return;
}
if (uppercase_p (key))
rl_vi_eWord (count);
else
rl_vi_eword (count);
}
/* Move forward a word the way that 'W' does. */
/* Move forward a word the way that 'W' does. */
rl_vi_fWord (count)
int count;
{
while (count-- && rl_point < (rl_end - 1))
{
/* Skip until whitespace. */
while (!whitespace (the_line[rl_point]) && rl_point < rl_end)
rl_point++;
/* Now skip whitespace. */
while (whitespace (the_line[rl_point]) && rl_point < rl_end)
rl_point++;
}
}
rl_vi_bWord (count)
int count;
{
while (count-- && rl_point > 0)
{
/* If we are at the start of a word, move back to whitespace so
we will go back to the start of the previous word. */
if (!whitespace (the_line[rl_point]) &&
whitespace (the_line[rl_point - 1]))
rl_point--;
while (rl_point > 0 && whitespace (the_line[rl_point]))
rl_point--;
if (rl_point > 0)
{
while (--rl_point >= 0 && !whitespace (the_line[rl_point]));
rl_point++;
}
}
}
rl_vi_eWord (count)
int count;
{
while (count-- && rl_point < (rl_end - 1))
{
/* Move to white space. */
while (++rl_point < rl_end && whitespace (the_line[rl_point]))
;
if (rl_point && rl_point < rl_end)
{
/* Skip whitespace. */
while (rl_point < rl_end && whitespace (the_line[rl_point]))
rl_point++;
/* Skip until whitespace. */
while (rl_point < rl_end && !whitespace (the_line[rl_point]))
rl_point++;
/* Move back to the last character of the word. */
rl_point--;
}
}
}
rl_vi_fword (count)
int count;
{
while (count-- && rl_point < (rl_end - 1))
{
/* Move to white space (really non-identifer). */
if (isident (the_line[rl_point]))
{
while (isident (the_line[rl_point]) && rl_point < rl_end)
rl_point++;
}
else /* if (!whitespace (the_line[rl_point])) */
{
while (!isident (the_line[rl_point]) &&
!whitespace (the_line[rl_point]) && rl_point < rl_end)
rl_point++;
}
/* Move past whitespace. */
while (whitespace (the_line[rl_point]) && rl_point < rl_end)
rl_point++;
}
}
rl_vi_bword (count)
int count;
{
while (count-- && rl_point > 0)
{
int last_is_ident;
/* If we are at the start of a word, move back to a non-identifier
so we will go back to the start of the previous word. */
if (isident (the_line[rl_point]) && !isident (the_line[rl_point - 1]))
rl_point--;
/* If this character and the previous character are `opposite', move
back so we don't get messed up by the rl_point++ down there in
the while loop. Without this code, words like `l;' screw up the
function. */
last_is_ident = isident (the_line[rl_point - 1]);
if ((isident (the_line[rl_point]) && !last_is_ident) ||
(!isident (the_line[rl_point]) && last_is_ident))
rl_point--;
while (rl_point > 0 && whitespace (the_line[rl_point]))
rl_point--;
if (rl_point > 0)
{
if (isident (the_line[rl_point]))
while (--rl_point >= 0 && isident (the_line[rl_point]));
else
while (--rl_point >= 0 && !isident (the_line[rl_point]) &&
!whitespace (the_line[rl_point]));
rl_point++;
}
}
}
rl_vi_eword (count)
int count;
{
while (count-- && rl_point < rl_end - 1)
{
while (++rl_point < rl_end && whitespace (the_line[rl_point]))
;
if (rl_point < rl_end)
{
if (isident (the_line[rl_point]))
while (++rl_point < rl_end && isident (the_line[rl_point]));
else
while (++rl_point < rl_end && !isident (the_line[rl_point])
&& !whitespace (the_line[rl_point]));
rl_point--;
}
}
}
rl_vi_insert_beg ()
{
rl_beg_of_line ();
rl_vi_insertion_mode ();
return 0;
}
rl_vi_append_mode ()
{
if (rl_point < rl_end)
rl_point += 1;
rl_vi_insertion_mode ();
return 0;
}
rl_vi_append_eol ()
{
rl_end_of_line ();
rl_vi_append_mode ();
return 0;
}
/* What to do in the case of C-d. */
rl_vi_eof_maybe (count, c)
int count, c;
{
rl_newline (1, '\n');
}
/* Insertion mode stuff. */
/* Switching from one mode to the other really just involves
switching keymaps. */
rl_vi_insertion_mode ()
{
keymap = vi_insertion_keymap;
}
rl_vi_movement_mode ()
{
if (rl_point > 0)
rl_backward (1);
keymap = vi_movement_keymap;
vi_done_inserting ();
}
vi_done_inserting ()
{
if (vi_doing_insert)
{
rl_end_undo_group ();
vi_doing_insert = 0;
}
}
rl_vi_arg_digit (count, c)
int count, c;
{
if (c == '0' && rl_numeric_arg == 1 && !rl_explicit_arg)
rl_beg_of_line ();
else
rl_digit_argument (count, c);
}
/* Doesn't take an arg count in vi */
rl_vi_change_case (ignore1, ignore2)
int ignore1, ignore2;
{
char c = 0;
/* Don't try this on an empty line. */
if (rl_point >= rl_end - 1)
return;
if (uppercase_p (the_line[rl_point]))
c = to_lower (the_line[rl_point]);
else if (lowercase_p (the_line[rl_point]))
c = to_upper (the_line[rl_point]);
/* Vi is kind of strange here. */
if (c)
{
rl_begin_undo_group ();
rl_delete (1, c);
rl_insert (1, c);
rl_end_undo_group ();
rl_vi_check ();
}
else
rl_forward (1);
}
rl_vi_put (count, key)
int count, key;
{
if (!uppercase_p (key) && (rl_point + 1 <= rl_end))
rl_forward (1);
rl_yank ();
rl_backward (1);
}
rl_vi_check ()
{
if (rl_point && rl_point == rl_end)
rl_point--;
}
rl_vi_column (count)
{
if (count > rl_end)
rl_end_of_line ();
else
rl_point = count - 1;
}
int
rl_vi_domove (key, nextkey)
int key, *nextkey;
{
int c, save;
rl_mark = rl_point;
c = rl_read_key ();
*nextkey = c;
if (!member (c, vi_motion))
{
if (digit (c))
{
save = rl_numeric_arg;
rl_digit_loop1 ();
rl_numeric_arg *= save;
}
else if ((key == 'd' && c == 'd') ||
(key == 'c' && c == 'c'))
{
rl_mark = rl_end;
rl_beg_of_line ();
return (0);
}
else
return (-1);
}
rl_dispatch (c, keymap);
/* No change in position means the command failed. */
if (rl_mark == rl_point)
return (-1);
if ((c == 'w' || c == 'W') && rl_point < rl_end)
rl_point--;
if (rl_mark < rl_point)
exchange (rl_point, rl_mark);
return (0);
}
/* A simplified loop for vi. Don't dispatch key at end.
Don't recognize minus sign? */
rl_digit_loop1 ()
{
int key, c;
while (1)
{
rl_message ("(arg: %d) ", arg_sign * rl_numeric_arg, 0);
key = c = rl_read_key ();
if (keymap[c].type == ISFUNC &&
keymap[c].function == rl_universal_argument)
{
rl_numeric_arg *= 4;
continue;
}
c = UNMETA (c);
if (numeric (c))
{
if (rl_explicit_arg)
rl_numeric_arg = (rl_numeric_arg * 10) + (c - '0');
else
rl_numeric_arg = (c - '0');
rl_explicit_arg = 1;
}
else
{
rl_clear_message ();
rl_stuff_char (key);
break;
}
}
}
rl_vi_delete_to (count, key)
int count, key;
{
int c;
if (uppercase_p (key))
rl_stuff_char ('$');
if (rl_vi_domove (key, &c))
{
ding ();
return;
}
if ((c != '|') && (c != 'h') && rl_mark < rl_end)
rl_mark++;
rl_kill_text (rl_point, rl_mark);
}
rl_vi_change_to (count, key)
int count, key;
{
int c;
if (uppercase_p (key))
rl_stuff_char ('$');
if (rl_vi_domove (key, &c))
{
ding ();
return;
}
if ((c != '|') && (c != 'h') && rl_mark < rl_end)
rl_mark++;
rl_begin_undo_group ();
vi_doing_insert = 1;
rl_kill_text (rl_point, rl_mark);
rl_vi_insertion_mode ();
}
rl_vi_yank_to (count, key)
int count, key;
{
int c, save = rl_point;
if (uppercase_p (key))
rl_stuff_char ('$');
if (rl_vi_domove (key, &c))
{
ding ();
return;
}
rl_begin_undo_group ();
rl_kill_text (rl_point, rl_mark);
rl_end_undo_group ();
rl_do_undo ();
rl_point = save;
}
rl_vi_delete (count)
{
int end;
if (rl_end == 0)
{
ding ();
return;
}
end = rl_point + count;
if (end >= rl_end)
end = rl_end;
rl_kill_text (rl_point, end);
if (rl_point > 0 && rl_point == rl_end)
rl_backward (1);
}
/* Turn the current line into a comment in shell history.
A K*rn shell style function. */
rl_vi_comment ()
{
rl_beg_of_line ();
rl_insert_text (": "); /* `#' doesn't work in interactive mode */
rl_redisplay ();
rl_newline (1, '\010');
}
rl_vi_first_print ()
{
rl_back_to_indent ();
}
rl_back_to_indent (ignore1, ignore2)
int ignore1, ignore2;
{
rl_beg_of_line ();
while (rl_point < rl_end && whitespace (the_line[rl_point]))
rl_point++;
}
/* NOTE: it is necessary that opposite directions are inverses */
#define FTO 1 /* forward to */
#define BTO -1 /* backward to */
#define FFIND 2 /* forward find */
#define BFIND -2 /* backward find */
rl_vi_char_search (count, key)
int count, key;
{
static char target;
static int orig_dir, dir;
int pos;
if (key == ';' || key == ',')
dir = (key == ';' ? orig_dir : -orig_dir);
else
{
target = rl_getc (in_stream);
switch (key)
{
case 't':
orig_dir = dir = FTO;
break;
case 'T':
orig_dir = dir = BTO;
break;
case 'f':
orig_dir = dir = FFIND;
break;
case 'F':
orig_dir = dir = BFIND;
break;
}
}
pos = rl_point;
if (dir < 0)
{
pos--;
do
{
if (the_line[pos] == target)
{
if (dir == BTO)
rl_point = pos + 1;
else
rl_point = pos;
return;
}
}
while (pos--);
if (pos < 0)
{
ding ();
return;
}
}
else
{ /* dir > 0 */
pos++;
do
{
if (the_line[pos] == target)
{
if (dir == FTO)
rl_point = pos - 1;
else
rl_point = pos;
return;
}
}
while (++pos < rl_end);
if (pos >= (rl_end - 1))
ding ();
}
}
/* Match brackets */
rl_vi_match ()
{
int count = 1, brack, pos;
pos = rl_point;
if ((brack = rl_vi_bracktype (the_line[rl_point])) == 0)
{
while ((brack = rl_vi_bracktype (the_line[rl_point])) == 0 &&
rl_point < rl_end - 1)
rl_forward (1);
if (brack <= 0)
{
rl_point = pos;
ding ();
return;
}
}
pos = rl_point;
if (brack < 0)
{
while (count)
{
if (--pos >= 0)
{
int b = rl_vi_bracktype (the_line[pos]);
if (b == -brack)
count--;
else if (b == brack)
count++;
}
else
{
ding ();
return;
}
}
}
else
{ /* brack > 0 */
while (count)
{
if (++pos < rl_end)
{
int b = rl_vi_bracktype (the_line[pos]);
if (b == -brack)
count--;
else if (b == brack)
count++;
}
else
{
ding ();
return;
}
}
}
rl_point = pos;
}
int
rl_vi_bracktype (c)
int c;
{
switch (c)
{
case '(': return 1;
case ')': return -1;
case '[': return 2;
case ']': return -2;
case '{': return 3;
case '}': return -3;
default: return 0;
}
}
rl_vi_change_char ()
{
int c;
c = rl_getc (in_stream);
switch (c)
{
case '\033':
case CTRL('C'):
return;
default:
rl_begin_undo_group ();
rl_delete (1, c);
rl_insert (1, c);
rl_end_undo_group ();
break;
}
}
rl_vi_subst (count, key)
int count, key;
{
rl_begin_undo_group ();
vi_doing_insert = 1;
if (uppercase_p (key))
{
rl_beg_of_line ();
rl_kill_line (1);
}
else
rl_delete (count, key);
rl_vi_insertion_mode ();
}
rl_vi_overstrike (count, key)
int count, key;
{
int i;
if (vi_doing_insert == 0)
{
vi_doing_insert = 1;
rl_begin_undo_group ();
}
for (i = 0; i < count; i++)
{
vi_replace_count++;
rl_begin_undo_group ();
if (rl_point < rl_end)
{
rl_delete (1, key);
rl_insert (1, key);
}
else
rl_insert (1, key);
rl_end_undo_group ();
}
}
rl_vi_overstrike_delete (count)
int count;
{
int i, s;
for (i = 0; i < count; i++)
{
if (vi_replace_count == 0)
{
ding ();
break;
}
s = rl_point;
if (rl_do_undo ())
vi_replace_count--;
if (rl_point == s)
rl_backward (1);
}
if (vi_replace_count == 0 && vi_doing_insert)
{
rl_end_undo_group ();
rl_do_undo ();
vi_doing_insert = 0;
}
}
rl_vi_replace ()
{
int i;
vi_replace_count = 0;
vi_replace_map = rl_make_bare_keymap ();
for (i = ' '; i < 127; i++)
vi_replace_map[i].function = rl_vi_overstrike;
vi_replace_map[RUBOUT].function = rl_vi_overstrike_delete;
vi_replace_map[ESC].function = rl_vi_movement_mode;
vi_replace_map[RETURN].function = rl_newline;
vi_replace_map[NEWLINE].function = rl_newline;
keymap = vi_replace_map;
}
/*
* Try to complete the word we are standing on or the word that ends with
* the previous character. A space matches everything.
* Word delimiters are space and ;.
*/
rl_vi_possible_completions()
{
int save_pos = rl_point;
if (!index (" ;", the_line[rl_point]))
{
while (!index(" ;", the_line[++rl_point]))
;
}
else if (the_line[rl_point-1] == ';')
{
ding ();
return (0);
}
rl_possible_completions ();
rl_point = save_pos;
return (0);
}