Imported from ../bash-2.0.tar.gz.
This commit is contained in:
@@ -1,46 +1,40 @@
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 1, February 1989
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
Copyright (C) 1989, 1991 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
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU 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.
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
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.
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), 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
|
||||
For example, if you distribute copies of 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.
|
||||
source code. And you must show them these terms so they know 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,
|
||||
@@ -53,122 +47,209 @@ 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.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
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".
|
||||
0. This License 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 derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) 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.
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
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:
|
||||
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 License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
a) cause the modified files to carry prominent notices stating that
|
||||
you changed the files and the date of any change; and
|
||||
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.
|
||||
|
||||
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).
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
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.
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
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.
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
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.
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary 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
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
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:
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
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,
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
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,
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
c) accompany it with the information you received as to where the
|
||||
corresponding source code may be obtained. (This alternative is
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 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 Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form alone.)
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
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.
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
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.
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this 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.
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing 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 for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
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.
|
||||
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.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
7. The Free Software Foundation may publish revised and/or new versions
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. 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
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this 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
|
||||
this 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
|
||||
10. 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
|
||||
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
|
||||
@@ -176,7 +257,7 @@ of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
11. 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
|
||||
@@ -186,7 +267,7 @@ 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
|
||||
12. 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
|
||||
@@ -201,22 +282,21 @@ POSSIBILITY OF SUCH DAMAGES.
|
||||
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.
|
||||
possible use to the public, 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.
|
||||
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>
|
||||
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.
|
||||
the Free Software Foundation; either version 2 of the License, 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
|
||||
@@ -232,26 +312,28 @@ 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 version 69, Copyright (C) 19yy 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.
|
||||
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:
|
||||
necessary. Here is 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.
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
|
||||
@@ -1,134 +0,0 @@
|
||||
## -*- text -*- ####################################################
|
||||
# #
|
||||
# Makefile for the GNU Readline and History Libraries. #
|
||||
# #
|
||||
####################################################################
|
||||
|
||||
srcdir = .
|
||||
VPATH = .:$(srcdir)
|
||||
|
||||
INSTALL = install -c
|
||||
INSTALL_PROGRAM = ${INSTALL}
|
||||
INSTALL_DATA = ${INSTALL} -m 644
|
||||
|
||||
RANLIB = ranlib
|
||||
AR = ar
|
||||
RM = rm
|
||||
CP = cp
|
||||
MV = mv
|
||||
|
||||
# See the file STANDALONE for the -D defines that readline understands
|
||||
DEFS =
|
||||
# For libraries which include headers from other libraries.
|
||||
LOCAL_INCLUDES = -I. -I..
|
||||
|
||||
CPPFLAGS = $(DEFS) $(LOCAL_INCLUDES)
|
||||
|
||||
# Here is a rule for making .o files from .c files that doesn't force
|
||||
# the type of the machine (like -sun3) into the flags.
|
||||
.c.o:
|
||||
$(CC) -c $(CPPFLAGS) $(CFLAGS) $<
|
||||
|
||||
# The name of the main library target.
|
||||
LIBRARY_NAME = libreadline.a
|
||||
|
||||
# The C code source files for this library.
|
||||
CSOURCES = $(srcdir)readline.c $(srcdir)funmap.c $(srcdir)keymaps.c \
|
||||
$(srcdir)vi_mode.c $(srcdir)parens.c $(srcdir)rltty.c \
|
||||
$(srcdir)complete.c $(srcdir)bind.c $(srcdir)isearch.c \
|
||||
$(srcdir)display.c $(srcdir)signals.c $(srcdir)emacs_keymap.c \
|
||||
$(srcdir)vi_keymap.c $(srcdir)history.c $(srcdir)tilde.c \
|
||||
$(srcdir)xmalloc.c
|
||||
|
||||
# The header files for this library.
|
||||
HSOURCES = readline.h rldefs.h chardefs.h keymaps.h history.h \
|
||||
posixstat.h tilde.h rlconf.h
|
||||
|
||||
OBJECTS = readline.o vi_mode.o funmap.o keymaps.o parens.o search.o \
|
||||
rltty.o complete.o bind.o isearch.o display.o signals.o \
|
||||
history.o tilde.o xmalloc.o
|
||||
|
||||
# The texinfo files which document this library.
|
||||
DOCSOURCE = doc/rlman.texinfo doc/rltech.texinfo doc/rluser.texinfo
|
||||
DOCOBJECT = doc/readline.dvi
|
||||
DOCSUPPORT = doc/Makefile
|
||||
DOCUMENTATION = $(DOCSOURCE) $(DOCOBJECT) $(DOCSUPPORT)
|
||||
|
||||
SUPPORT = Makefile ChangeLog $(DOCSUPPORT) examples/[-a-z.]*
|
||||
|
||||
SOURCES = $(CSOURCES) $(HSOURCES) $(DOCSOURCE)
|
||||
|
||||
THINGS_TO_TAR = $(SOURCES) $(SUPPORT)
|
||||
|
||||
##########################################################################
|
||||
|
||||
all: libreadline.a libhistory.a
|
||||
|
||||
libreadline.a: $(OBJECTS)
|
||||
$(RM) -f $@
|
||||
$(AR) cq $@ $(OBJECTS)
|
||||
-[ -n "$(RANLIB)" ] && $(RANLIB) $@
|
||||
|
||||
libhistory.a: history.o
|
||||
$(RM) -f $@
|
||||
$(AR) cq $@ history.o
|
||||
-[ -n "$(RANLIB)" ] && $(RANLIB) $@
|
||||
|
||||
documentation: force
|
||||
[ ! -d doc ] && mkdir doc
|
||||
(if [ -d doc ]; then cd doc; $(MAKE) $(MFLAGS); fi)
|
||||
|
||||
force:
|
||||
|
||||
# The rule for 'includes' is written funny so that the if statement
|
||||
# always returns TRUE unless there really was an error installing the
|
||||
# include files.
|
||||
install: installdirs libreadline.a
|
||||
${INSTALL_DATA} readline.h keymaps.h chardefs.h history.h \
|
||||
$(incdir)/readline
|
||||
-${MV} $(libdir)/libreadline.a $(libdir)/libreadline.old
|
||||
${INSTALL_DATA} libreadline.a $(bindir)/libreadline.a
|
||||
-[ -n "$(RANLIB)" ] && $(RANLIB) -t $(bindir)/libreadline.a
|
||||
|
||||
installdirs:
|
||||
[ ! -d $(incdir)/readline ] && { \
|
||||
mkdir $(incdir)/readline && chmod chmod 755 $(incdir)/readline; }
|
||||
|
||||
uninstall:
|
||||
cd $(incdir)/readline && ${RM} -f ${INSTALLED_HEADERS}
|
||||
cd $(libdir) && ${RM} -f libreadline.a libreadline.old
|
||||
|
||||
tags: force
|
||||
etags $(CSOURCES) $(HSOURCES)
|
||||
|
||||
TAGS: force
|
||||
ctags -x $(CSOURCES) $(HSOURCES) > $@
|
||||
|
||||
readline: readline.h rldefs.h chardefs.h
|
||||
readline: $(OBJECTS)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(READLINE_DEFINES) \
|
||||
$(LOCAL_INCLUDES) -DTEST -o readline readline.c vi_mode.o funmap.o \
|
||||
keymaps.o -ltermcap
|
||||
|
||||
clean:
|
||||
$(RM) -f $(OBJECTS) libreadline.a libhistory.a
|
||||
(if [ -d doc ]; then cd doc; $(MAKE) $(MFLAGS) $@; fi)
|
||||
|
||||
maintainer-clean realclean distclean mostlyclean: clean
|
||||
(if [ -d doc ]; then cd doc; $(MAKE) $(MFLAGS) $@; fi)
|
||||
|
||||
# Dependencies
|
||||
readline.o: readline.c readline.h rldefs.h rlconf.h chardefs.h
|
||||
readline.o: keymaps.h history.h
|
||||
vi_mode.o: rldefs.h rlconf.h readline.h history.h
|
||||
funmap.o: funmap.c readline.h rlconf.h
|
||||
keymaps.o: keymaps.c emacs_keymap.c vi_keymap.c keymaps.h chardefs.h rlconf.h
|
||||
history.o: history.h memalloc.h
|
||||
isearch.o: memalloc.h readline.h history.h
|
||||
search.o: memalloc.h readline.h history.h
|
||||
display.o: readline.h history.h rldefs.h rlconf.h
|
||||
complete.o: readline.h rldefs.h rlconf.h
|
||||
rltty.o: rldefs.h rlconf.h readline.h
|
||||
bind.o: rldefs.h rlconf.h readline.h history.h
|
||||
signals.o: rldefs.h rlconf.h readline.h history.h
|
||||
parens.o: readline.h
|
||||
192
lib/readline/Makefile.in
Normal file
192
lib/readline/Makefile.in
Normal file
@@ -0,0 +1,192 @@
|
||||
## -*- text -*- ####################################################
|
||||
# #
|
||||
# Makefile for the GNU Readline and History Libraries. #
|
||||
# #
|
||||
####################################################################
|
||||
|
||||
srcdir = @srcdir@
|
||||
VPATH = .:@srcdir@
|
||||
topdir = @top_srcdir@
|
||||
BUILD_DIR = @BUILD_DIR@
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
CC = @CC@
|
||||
RANLIB = @RANLIB@
|
||||
AR = @AR@
|
||||
RM = rm -f
|
||||
CP = cp
|
||||
MV = mv
|
||||
|
||||
# See the file STANDALONE for the -D defines that readline understands
|
||||
|
||||
CFLAGS = @CFLAGS@
|
||||
LOCAL_CFLAGS = @LOCAL_CFLAGS@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
DEFS = @DEFS@
|
||||
|
||||
INCLUDES = -I. -I$(BUILD_DIR) -I$(topdir) -I$(topdir)/lib
|
||||
|
||||
CCFLAGS = $(DEFS) $(APP_CFLAGS) $(CPPFLAGS) ${INCLUDES} $(LOCAL_CFLAGS) $(CFLAGS)
|
||||
|
||||
# Here is a rule for making .o files from .c files that doesn't force
|
||||
# the type of the machine (like -sun3) into the flags.
|
||||
.c.o:
|
||||
$(CC) -c $(CCFLAGS) $<
|
||||
|
||||
# The name of the main library target.
|
||||
LIBRARY_NAME = libreadline.a
|
||||
|
||||
# The C code source files for this library.
|
||||
CSOURCES = $(srcdir)/readline.c $(srcdir)/funmap.c $(srcdir)/keymaps.c \
|
||||
$(srcdir)/vi_mode.c $(srcdir)/parens.c $(srcdir)/rltty.c \
|
||||
$(srcdir)/complete.c $(srcdir)/bind.c $(srcdir)/isearch.c \
|
||||
$(srcdir)/display.c $(srcdir)/signals.c $(srcdir)/emacs_keymap.c \
|
||||
$(srcdir)/vi_keymap.c $(srcdir)/util.c $(srcdir)/kill.c \
|
||||
$(srcdir)/undo.c $(srcdir)/macro.c $(srcdir)/input.c \
|
||||
$(srcdir)/callback.c $(srcdir)/terminal.c $(srcdir)/xmalloc.c \
|
||||
$(srcdir)/history.c $(srcdir)/histsearch.c $(srcdir)/histexpand.c \
|
||||
$(srcdir)/histfile.c $(srcdir)/nls.c \
|
||||
$(srcdir)/tilde.c \
|
||||
|
||||
# The header files for this library.
|
||||
HSOURCES = readline.h rldefs.h chardefs.h keymaps.h history.h histlib.h \
|
||||
posixstat.h tilde.h rlconf.h tcap.h
|
||||
|
||||
HISTOBJ = history.o histexpand.o histfile.o histsearch.o
|
||||
TILDEOBJ= tilde.o
|
||||
OBJECTS = readline.o vi_mode.o funmap.o keymaps.o parens.o search.o \
|
||||
rltty.o complete.o bind.o isearch.o display.o signals.o \
|
||||
util.o kill.o undo.o macro.o input.o callback.o terminal.o \
|
||||
nls.o xmalloc.o \
|
||||
$(HISTOBJ) $(TILDEOBJ)
|
||||
|
||||
# The texinfo files which document this library.
|
||||
DOCSOURCE = doc/rlman.texinfo doc/rltech.texinfo doc/rluser.texinfo
|
||||
DOCOBJECT = doc/readline.dvi
|
||||
DOCSUPPORT = doc/Makefile
|
||||
DOCUMENTATION = $(DOCSOURCE) $(DOCOBJECT) $(DOCSUPPORT)
|
||||
|
||||
SUPPORT = Makefile ChangeLog $(DOCSUPPORT) examples/[-a-z.]*
|
||||
|
||||
SOURCES = $(CSOURCES) $(HSOURCES) $(DOCSOURCE)
|
||||
|
||||
THINGS_TO_TAR = $(SOURCES) $(SUPPORT)
|
||||
|
||||
INSTALLED_HEADERS = readline.h chardefs.h keymaps.h history.h tilde.h
|
||||
|
||||
##########################################################################
|
||||
|
||||
all: libreadline.a libhistory.a
|
||||
|
||||
libreadline.a: $(OBJECTS)
|
||||
$(RM) -f $@
|
||||
$(AR) cr $@ $(OBJECTS)
|
||||
-test -n "$(RANLIB)" && $(RANLIB) $@
|
||||
|
||||
libhistory.a: $(HISTOBJ) xmalloc.o
|
||||
$(RM) -f $@
|
||||
$(AR) cr $@ $(HISTOBJ) xmalloc.o
|
||||
-test -n "$(RANLIB)" && $(RANLIB) $@
|
||||
|
||||
documentation: force
|
||||
test -d doc || mkdir doc
|
||||
-( cd doc && $(MAKE) $(MFLAGS) )
|
||||
|
||||
force:
|
||||
|
||||
# The rule for 'includes' is written funny so that the if statement
|
||||
# always returns TRUE unless there really was an error installing the
|
||||
# include files.
|
||||
install: installdirs libreadline.a
|
||||
for file in $(INSTALLED_HEADERS) ; do \
|
||||
$(INSTALL_DATA) $(srcdir)/$$file $(includedir)/readline ; \
|
||||
done
|
||||
-${MV} $(libdir)/libreadline.a $(libdir)/libreadline.old
|
||||
${INSTALL_DATA} libreadline.a $(libdir)/libreadline.a
|
||||
-test -n "$(RANLIB)" && $(RANLIB) -t $(bindir)/libreadline.a
|
||||
|
||||
installdirs: $(topdir)/support/mkdirs
|
||||
$(SHELL) $(topdir)/support/mkdirs $(includedir) \
|
||||
$(includedir)/readline $(libdir) $(infodir) $(man3dir)
|
||||
|
||||
uninstall:
|
||||
cd $(includedir)/readline && ${RM} -f ${INSTALLED_HEADERS}
|
||||
cd $(libdir) && ${RM} -f libreadline.a libreadline.old
|
||||
|
||||
tags: force
|
||||
etags $(CSOURCES) $(HSOURCES)
|
||||
|
||||
TAGS: force
|
||||
ctags -x $(CSOURCES) $(HSOURCES) > $@
|
||||
|
||||
readline: readline.h rldefs.h chardefs.h
|
||||
readline: $(OBJECTS)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(READLINE_DEFINES) \
|
||||
$(LOCAL_INCLUDES) -DTEST -o readline readline.c vi_mode.o funmap.o \
|
||||
keymaps.o -ltermcap
|
||||
|
||||
clean: force
|
||||
$(RM) $(OBJECTS) *.a
|
||||
-( cd doc && $(MAKE) $(MFLAGS) $@ )
|
||||
|
||||
distclean realclean maintainer-clean: clean
|
||||
-( cd doc && $(MAKE) $(MFLAGS) $@ )
|
||||
$(RM) Makefile
|
||||
|
||||
mostlyclean: clean
|
||||
-( cd doc && $(MAKE) $(MFLAGS) $@ )
|
||||
|
||||
# Dependencies
|
||||
readline.o: readline.c readline.h rldefs.h rlconf.h chardefs.h tcap.h
|
||||
readline.o: keymaps.h history.h
|
||||
vi_mode.o: rldefs.h rlconf.h readline.h history.h
|
||||
funmap.o: funmap.c readline.h rlconf.h
|
||||
keymaps.o: keymaps.c emacs_keymap.c vi_keymap.c keymaps.h chardefs.h rlconf.h
|
||||
history.o: history.h histlib.h
|
||||
histexpand.o: history.h histlib.h
|
||||
histsearch.o: history.h histlib.h
|
||||
histfile.o: history.h histlib.h
|
||||
isearch.o: readline.h history.h
|
||||
search.o: readline.h history.h
|
||||
display.o: readline.h history.h rldefs.h rlconf.h tcap.h
|
||||
complete.o: readline.h rldefs.h rlconf.h posixdir.h posixstat.h
|
||||
rltty.o: rldefs.h rlconf.h readline.h rltty.h
|
||||
bind.o: rldefs.h rlconf.h readline.h history.h
|
||||
signals.o: rldefs.h rlconf.h readline.h history.h
|
||||
parens.o: readline.h
|
||||
kill.o: rldefs.h rlconf.h readline.h history.h
|
||||
macro.o: rldefs.h rlconf.h readline.h history.h
|
||||
undo.o: rldefs.h rlconf.h readline.h history.h
|
||||
input.o: rldefs.h rlconf.h readline.h history.h
|
||||
callback.o: rlconf.h rldefs.h readline.h
|
||||
terminal.o: rlconf.h rldefs.h readline.h tcap.h history.h
|
||||
|
||||
bind.o: $(BUILD_DIR)/config.h
|
||||
callback.o: $(BUILD_DIR)/config.h
|
||||
complete.o: $(BUILD_DIR)/config.h
|
||||
display.o: $(BUILD_DIR)/config.h
|
||||
funmap.o: $(BUILD_DIR)/config.h
|
||||
histexpand.o: $(BUILD_DIR)/config.h
|
||||
histfile.o: $(BUILD_DIR)/config.h
|
||||
history.o: $(BUILD_DIR)/config.h
|
||||
histsearch.o: $(BUILD_DIR)/config.h
|
||||
input.o: $(BUILD_DIR)/config.h
|
||||
isearch.o: $(BUILD_DIR)/config.h
|
||||
keymaps.o: $(BUILD_DIR)/config.h
|
||||
kill.o: $(BUILD_DIR)/config.h
|
||||
macro.o: $(BUILD_DIR)/config.h
|
||||
parens.o: $(BUILD_DIR)/config.h
|
||||
readline.o: $(BUILD_DIR)/config.h
|
||||
rltty.o: $(BUILD_DIR)/config.h
|
||||
search.o: $(BUILD_DIR)/config.h
|
||||
signals.o: $(BUILD_DIR)/config.h
|
||||
tilde.o: $(BUILD_DIR)/config.h
|
||||
undo.o: $(BUILD_DIR)/config.h
|
||||
util.o: $(BUILD_DIR)/config.h
|
||||
vi_mode.o: $(BUILD_DIR)/config.h
|
||||
xmalloc.o: $(BUILD_DIR)/config.h
|
||||
@@ -15,6 +15,7 @@ HAVE_DIRENT_H <dirent.h> exists and is usable
|
||||
HAVE_SYS_PTEM_H <sys/ptem.h> exists
|
||||
HAVE_SYS_PTE_H <sys/pte.h> exists
|
||||
HAVE_SYS_STREAM_H <sys/stream.h> exists
|
||||
HAVE_SYS_SELECT_H <sys/select.h> exists
|
||||
|
||||
System-specific options:
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
144
lib/readline/callback.c
Normal file
144
lib/readline/callback.c
Normal file
@@ -0,0 +1,144 @@
|
||||
/* callback.c -- functions to use readline as an X `callback' mechanism. */
|
||||
|
||||
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library 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.
|
||||
|
||||
The GNU Readline Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#define READLINE_LIBRARY
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "rlconf.h"
|
||||
|
||||
#if defined (READLINE_CALLBACKS)
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* System-specific feature definitions and include files. */
|
||||
#include "rldefs.h"
|
||||
#include "readline.h"
|
||||
|
||||
extern void readline_internal_startup ();
|
||||
extern char *readline_internal_teardown ();
|
||||
extern int readline_internal_char ();
|
||||
|
||||
extern int _rl_meta_flag;
|
||||
extern char *rl_prompt;
|
||||
extern int rl_visible_prompt_length;
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Callback Readline Functions */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Allow using readline in situations where a program may have multiple
|
||||
things to handle at once, and dispatches them via select(). Call
|
||||
rl_callback_handler_install() with the prompt and a function to call
|
||||
whenever a complete line of input is ready. The user must then
|
||||
call readline_char() every time some input is available, and
|
||||
readline_char() will call the user's function with the complete text
|
||||
read in at each end of line. The terminal is kept prepped and signals
|
||||
handled all the time, except during calls to the user's function. */
|
||||
|
||||
VFunction *rl_linefunc; /* user callback function */
|
||||
static int in_handler; /* terminal_prepped and signals set? */
|
||||
|
||||
/* Make sure the terminal is set up, initialize readline, and prompt. */
|
||||
static void
|
||||
_rl_callback_newline ()
|
||||
{
|
||||
rl_initialize ();
|
||||
|
||||
if (in_handler == 0)
|
||||
{
|
||||
in_handler = 1;
|
||||
|
||||
(*rl_prep_term_function) (_rl_meta_flag);
|
||||
|
||||
#if defined (HANDLE_SIGNALS)
|
||||
rl_set_signals ();
|
||||
#endif
|
||||
}
|
||||
|
||||
readline_internal_setup ();
|
||||
}
|
||||
|
||||
/* Install a readline handler, set up the terminal, and issue the prompt. */
|
||||
void
|
||||
rl_callback_handler_install (prompt, linefunc)
|
||||
char *prompt;
|
||||
VFunction *linefunc;
|
||||
{
|
||||
rl_prompt = prompt;
|
||||
rl_visible_prompt_length = rl_prompt ? rl_expand_prompt (rl_prompt) : 0;
|
||||
rl_linefunc = linefunc;
|
||||
_rl_callback_newline ();
|
||||
}
|
||||
|
||||
/* Read one character, and dispatch to the handler if it ends the line. */
|
||||
void
|
||||
rl_callback_read_char ()
|
||||
{
|
||||
char *line;
|
||||
int eof;
|
||||
|
||||
if (rl_linefunc == NULL)
|
||||
{
|
||||
fprintf (stderr, "readline: readline_callback_read_char() called with no handler!\r\n");
|
||||
abort ();
|
||||
}
|
||||
|
||||
eof = readline_internal_char ();
|
||||
|
||||
if (rl_done)
|
||||
{
|
||||
line = readline_internal_teardown (eof);
|
||||
|
||||
(*rl_deprep_term_function) ();
|
||||
#if defined (HANDLE_SIGNALS)
|
||||
rl_clear_signals ();
|
||||
#endif
|
||||
in_handler = 0;
|
||||
(*rl_linefunc) (line);
|
||||
|
||||
/* Redisplay the prompt if readline_handler_{install,remove} not called. */
|
||||
if (in_handler == 0 && rl_linefunc)
|
||||
_rl_callback_newline ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove the handler, and make sure the terminal is in its normal state. */
|
||||
void
|
||||
rl_callback_handler_remove ()
|
||||
{
|
||||
rl_linefunc = NULL;
|
||||
if (in_handler)
|
||||
{
|
||||
in_handler = 0;
|
||||
(*rl_deprep_term_function) ();
|
||||
#if defined (HANDLE_SIGNALS)
|
||||
rl_clear_signals ();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -20,16 +20,20 @@
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifndef _CHARDEFS_H
|
||||
#define _CHARDEFS_H
|
||||
#ifndef _CHARDEFS_H_
|
||||
#define _CHARDEFS_H_
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#if defined (HAVE_STRING_H)
|
||||
# include <string.h>
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# if defined (HAVE_STRING_H)
|
||||
# include <string.h>
|
||||
# else
|
||||
# include <strings.h>
|
||||
# endif /* HAVE_STRING_H */
|
||||
#else
|
||||
# include <strings.h>
|
||||
#endif /* HAVE_STRING_H */
|
||||
# include <string.h>
|
||||
#endif /* !HAVE_CONFIG_H */
|
||||
|
||||
#ifndef whitespace
|
||||
#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
|
||||
@@ -47,39 +51,40 @@
|
||||
#define meta_character_bit 0x080 /* x0000000, must be on. */
|
||||
#define largest_char 255 /* Largest character value. */
|
||||
|
||||
#define CTRL_CHAR(c) ((c) < control_character_threshold)
|
||||
#define CTRL_CHAR(c) ((c) < control_character_threshold && (c) >= 0)
|
||||
#define META_CHAR(c) ((c) > meta_character_threshold && (c) <= largest_char)
|
||||
|
||||
#define CTRL(c) ((c) & control_character_mask)
|
||||
#define META(c) ((c) | meta_character_bit)
|
||||
|
||||
#define UNMETA(c) ((c) & (~meta_character_bit))
|
||||
#define UNCTRL(c) to_upper(((c)|control_character_bit))
|
||||
#define UNCTRL(c) _rl_to_upper(((c)|control_character_bit))
|
||||
|
||||
/* Old versions
|
||||
#define lowercase_p(c) (((c) > ('a' - 1) && (c) < ('z' + 1)))
|
||||
#define uppercase_p(c) (((c) > ('A' - 1) && (c) < ('Z' + 1)))
|
||||
#define digit_p(c) ((c) >= '0' && (c) <= '9')
|
||||
#define _rl_lowercase_p(c) (((c) > ('a' - 1) && (c) < ('z' + 1)))
|
||||
#define _rl_uppercase_p(c) (((c) > ('A' - 1) && (c) < ('Z' + 1)))
|
||||
#define _rl_digit_p(c) ((c) >= '0' && (c) <= '9')
|
||||
*/
|
||||
|
||||
#define lowercase_p(c) (islower(c))
|
||||
#define uppercase_p(c) (isupper(c))
|
||||
#define digit_p(x) (isdigit (x))
|
||||
#define _rl_lowercase_p(c) (islower(c))
|
||||
#define _rl_uppercase_p(c) (isupper(c))
|
||||
#define _rl_digit_p(x) (isdigit (x))
|
||||
|
||||
#define pure_alphabetic(c) (lowercase_p(c) || uppercase_p(c))
|
||||
#define _rl_pure_alphabetic(c) (_rl_lowercase_p(c) || _rl_uppercase_p(c))
|
||||
#define ALPHABETIC(c) (_rl_lowercase_p(c) || _rl_uppercase_p(c) || _rl_digit_p(c))
|
||||
|
||||
/* Old versions
|
||||
# define to_upper(c) (lowercase_p(c) ? ((c) - 32) : (c))
|
||||
# define to_lower(c) (uppercase_p(c) ? ((c) + 32) : (c))
|
||||
# define _rl_to_upper(c) (_rl_lowercase_p(c) ? ((c) - 32) : (c))
|
||||
# define _rl_to_lower(c) (_rl_uppercase_p(c) ? ((c) + 32) : (c))
|
||||
*/
|
||||
|
||||
#ifndef to_upper
|
||||
# define to_upper(c) (islower(c) ? toupper(c) : (c))
|
||||
# define to_lower(c) (isupper(c) ? tolower(c) : (c))
|
||||
#ifndef _rl_to_upper
|
||||
# define _rl_to_upper(c) (islower(c) ? toupper(c) : (c))
|
||||
# define _rl_to_lower(c) (isupper(c) ? tolower(c) : (c))
|
||||
#endif
|
||||
|
||||
#ifndef digit_value
|
||||
#define digit_value(x) ((x) - '0')
|
||||
#ifndef _rl_digit_value
|
||||
#define _rl_digit_value(x) ((x) - '0')
|
||||
#endif
|
||||
|
||||
#ifndef NEWLINE
|
||||
@@ -119,4 +124,4 @@
|
||||
|
||||
#define ESC CTRL('[')
|
||||
|
||||
#endif /* _CHARDEFS_H */
|
||||
#endif /* _CHARDEFS_H_ */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -22,7 +22,7 @@
|
||||
#define READLINE_LIBRARY
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include "config.h"
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -43,6 +43,9 @@
|
||||
/* System-specific feature definitions and include files. */
|
||||
#include "rldefs.h"
|
||||
|
||||
/* Termcap library stuff. */
|
||||
#include "tcap.h"
|
||||
|
||||
/* Some standard library routines. */
|
||||
#include "readline.h"
|
||||
#include "history.h"
|
||||
@@ -55,20 +58,22 @@ extern char *strchr (), *strrchr ();
|
||||
imported from readline.c. */
|
||||
extern char *rl_prompt;
|
||||
extern int readline_echoing_p;
|
||||
extern char *term_clreol, *term_im, *term_ic, *term_ei, *term_DC;
|
||||
/* Termcap variables. */
|
||||
extern char *term_up, *term_dc, *term_cr, *term_IC;
|
||||
extern int screenheight, screenwidth, screenchars;
|
||||
extern int terminal_can_insert, term_xn;
|
||||
|
||||
extern void _rl_output_some_chars ();
|
||||
extern int _rl_output_character_function ();
|
||||
|
||||
extern int _rl_output_meta_chars;
|
||||
extern int _rl_horizontal_scroll_mode;
|
||||
extern int _rl_mark_modified_lines;
|
||||
extern int _rl_prefer_visible_bell;
|
||||
|
||||
/* Variables and functions imported from terminal.c */
|
||||
extern void _rl_output_some_chars ();
|
||||
extern int _rl_output_character_function ();
|
||||
extern int _rl_backspace ();
|
||||
|
||||
extern char *term_clreol, *term_im, *term_ic, *term_ei, *term_DC;
|
||||
extern char *term_up, *term_dc, *term_cr, *term_IC;
|
||||
extern int screenheight, screenwidth, screenchars;
|
||||
extern int terminal_can_insert, _rl_term_autowrap;
|
||||
|
||||
/* Pseudo-global functions (local to the readline library) exported
|
||||
by this file. */
|
||||
void _rl_move_cursor_relative (), _rl_output_some_chars ();
|
||||
@@ -76,6 +81,9 @@ void _rl_move_vert ();
|
||||
|
||||
static void update_line (), clear_to_eol (), space_to_eol ();
|
||||
static void delete_chars (), insert_some_chars ();
|
||||
static void cr ();
|
||||
|
||||
static int *inv_lbreaks, *vis_lbreaks;
|
||||
|
||||
extern char *xmalloc (), *xrealloc ();
|
||||
|
||||
@@ -110,10 +118,15 @@ extern char *xmalloc (), *xrealloc ();
|
||||
this function know that the display has been fixed by setting the
|
||||
RL_DISPLAY_FIXED variable. This is good for efficiency. */
|
||||
|
||||
/* Application-specific redisplay function. */
|
||||
VFunction *rl_redisplay_function = rl_redisplay;
|
||||
|
||||
/* Global variables declared here. */
|
||||
/* What YOU turn on when you have handled all redisplay yourself. */
|
||||
int rl_display_fixed = 0;
|
||||
|
||||
int _rl_suppress_redisplay = 0;
|
||||
|
||||
/* The stuff that gets printed out before the actual text of the line.
|
||||
This is usually pointing to rl_prompt. */
|
||||
char *rl_display_prompt = (char *)NULL;
|
||||
@@ -129,7 +142,7 @@ int _rl_vis_botlin = 0;
|
||||
/* Variables used only in this file. */
|
||||
/* The last left edge of text that was displayed. This is used when
|
||||
doing horizontal scrolling. It shifts in thirds of a screenwidth. */
|
||||
static int last_lmargin = 0;
|
||||
static int last_lmargin;
|
||||
|
||||
/* The line display buffers. One is the line currently displayed on
|
||||
the screen. The other is the line about to be displayed. */
|
||||
@@ -140,26 +153,32 @@ static char *invisible_line = (char *)NULL;
|
||||
static char msg_buf[128];
|
||||
|
||||
/* Non-zero forces the redisplay even if we thought it was unnecessary. */
|
||||
static int forced_display = 0;
|
||||
static int forced_display;
|
||||
|
||||
/* Default and initial buffer size. Can grow. */
|
||||
static int line_size = 1024;
|
||||
|
||||
static char *last_prompt_string = (char *)NULL;
|
||||
static char *local_prompt, *local_prompt_prefix;
|
||||
static int visible_length, prefix_length;
|
||||
|
||||
/* The number of invisible characters in the line currently being
|
||||
displayed on the screen. */
|
||||
static int visible_wrap_offset = 0;
|
||||
static int visible_wrap_offset;
|
||||
|
||||
/* static so it can be shared between rl_redisplay and update_line */
|
||||
static int wrap_offset;
|
||||
|
||||
/* The index of the last invisible_character in the prompt string. */
|
||||
static int last_invisible;
|
||||
|
||||
/* The length (buffer offset) of the first line of the last (possibly
|
||||
multi-line) buffer displayed on the screen. */
|
||||
static int visible_first_line_len = 0;
|
||||
static int visible_first_line_len;
|
||||
|
||||
/* Expand the prompt string S and return the number of visible
|
||||
characters in *LP, if LP is not null. This is currently more-or-less
|
||||
a placeholder for expansion. */
|
||||
a placeholder for expansion. LIP, if non-null is a place to store the
|
||||
index of the last invisible character in ther eturned string. */
|
||||
|
||||
/* Current implementation:
|
||||
\001 (^A) start non-visible characters
|
||||
@@ -169,12 +188,12 @@ static int visible_first_line_len = 0;
|
||||
\002 are assumed to be `visible'. */
|
||||
|
||||
static char *
|
||||
expand_prompt (pmt, lp)
|
||||
expand_prompt (pmt, lp, lip)
|
||||
char *pmt;
|
||||
int *lp;
|
||||
int *lp, *lip;
|
||||
{
|
||||
char *r, *ret, *p;
|
||||
int l, rl, ignoring;
|
||||
int l, rl, last, ignoring;
|
||||
|
||||
/* Short-circuit if we can. */
|
||||
if (strchr (pmt, RL_PROMPT_START_IGNORE) == 0)
|
||||
@@ -185,10 +204,10 @@ expand_prompt (pmt, lp)
|
||||
return r;
|
||||
}
|
||||
|
||||
l = pmt ? strlen (pmt) : 0;
|
||||
l = strlen (pmt);
|
||||
r = ret = xmalloc (l + 1);
|
||||
|
||||
for (rl = ignoring = 0, p = pmt; p && *p; p++)
|
||||
for (rl = ignoring = last = 0, p = pmt; p && *p; p++)
|
||||
{
|
||||
/* This code strips the invisible character string markers
|
||||
RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */
|
||||
@@ -200,6 +219,7 @@ expand_prompt (pmt, lp)
|
||||
else if (ignoring && *p == RL_PROMPT_END_IGNORE)
|
||||
{
|
||||
ignoring = 0;
|
||||
last = r - ret - 1;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
@@ -213,6 +233,8 @@ expand_prompt (pmt, lp)
|
||||
*r = '\0';
|
||||
if (lp)
|
||||
*lp = rl;
|
||||
if (lip)
|
||||
*lip = last;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -246,15 +268,16 @@ rl_expand_prompt (prompt)
|
||||
if (local_prompt_prefix)
|
||||
free (local_prompt_prefix);
|
||||
local_prompt = local_prompt_prefix = (char *)0;
|
||||
last_invisible = 0;
|
||||
|
||||
if (prompt == 0 || *prompt == '\0')
|
||||
if (prompt == 0 || *prompt == 0)
|
||||
return (0);
|
||||
|
||||
p = strrchr (prompt, '\n');
|
||||
if (!p)
|
||||
{
|
||||
/* The prompt is only one line. */
|
||||
local_prompt = expand_prompt (prompt, &visible_length);
|
||||
local_prompt = expand_prompt (prompt, &visible_length, &last_invisible);
|
||||
local_prompt_prefix = (char *)0;
|
||||
return (visible_length);
|
||||
}
|
||||
@@ -262,11 +285,11 @@ rl_expand_prompt (prompt)
|
||||
{
|
||||
/* The prompt spans multiple lines. */
|
||||
t = ++p;
|
||||
local_prompt = expand_prompt (p, &visible_length);
|
||||
local_prompt = expand_prompt (p, &visible_length, &last_invisible);
|
||||
c = *t; *t = '\0';
|
||||
/* The portion of the prompt string up to and including the
|
||||
final newline is now null-terminated. */
|
||||
local_prompt_prefix = expand_prompt (prompt, &prefix_length);
|
||||
local_prompt_prefix = expand_prompt (prompt, &prefix_length, (int *)NULL);
|
||||
*t = c;
|
||||
return (prefix_length);
|
||||
}
|
||||
@@ -276,9 +299,10 @@ rl_expand_prompt (prompt)
|
||||
void
|
||||
rl_redisplay ()
|
||||
{
|
||||
register int in, out, c, linenum;
|
||||
register char *line = invisible_line;
|
||||
int c_pos = 0, inv_botlin = 0, wrap_offset, wrap_column;
|
||||
register int in, out, c, linenum, cursor_linenum;
|
||||
register char *line;
|
||||
int c_pos, inv_botlin, lb_botlin, lb_linenum;
|
||||
int newlines, lpos;
|
||||
char *prompt_this_line;
|
||||
|
||||
if (!readline_echoing_p)
|
||||
@@ -287,25 +311,32 @@ rl_redisplay ()
|
||||
if (!rl_display_prompt)
|
||||
rl_display_prompt = "";
|
||||
|
||||
if (!invisible_line)
|
||||
if (invisible_line == 0)
|
||||
{
|
||||
visible_line = xmalloc (line_size);
|
||||
invisible_line = xmalloc (line_size);
|
||||
line = invisible_line;
|
||||
for (in = 0; in < line_size; in++)
|
||||
{
|
||||
visible_line[in] = 0;
|
||||
invisible_line[in] = 1;
|
||||
}
|
||||
|
||||
/* should be enough, but then again, this is just for testing. */
|
||||
inv_lbreaks = (int *)malloc (256 * sizeof (int));
|
||||
vis_lbreaks = (int *)malloc (256 * sizeof (int));
|
||||
inv_lbreaks[0] = vis_lbreaks[0] = 0;
|
||||
|
||||
rl_on_new_line ();
|
||||
}
|
||||
|
||||
/* Draw the line into the buffer. */
|
||||
c_pos = -1;
|
||||
|
||||
line = invisible_line;
|
||||
out = inv_botlin = 0;
|
||||
|
||||
/* Mark the line as modified or not. We only do this for history
|
||||
lines. */
|
||||
out = 0;
|
||||
if (_rl_mark_modified_lines && current_history () && rl_undo_list)
|
||||
{
|
||||
line[out++] = '*';
|
||||
@@ -322,15 +353,17 @@ rl_redisplay ()
|
||||
one passed to readline()), use the values we have already expanded.
|
||||
If not, use what's already in rl_display_prompt. WRAP_OFFSET is the
|
||||
number of non-visible characters in the prompt string. */
|
||||
if (rl_display_prompt == rl_prompt)
|
||||
if (rl_display_prompt == rl_prompt || local_prompt)
|
||||
{
|
||||
int local_len = local_prompt ? strlen (local_prompt) : 0;
|
||||
if (local_prompt_prefix && forced_display)
|
||||
_rl_output_some_chars (local_prompt_prefix, strlen (local_prompt_prefix));
|
||||
|
||||
if (local_len > 0)
|
||||
strncpy (line + out, local_prompt, local_len);
|
||||
out += local_len;
|
||||
{
|
||||
strncpy (line + out, local_prompt, local_len);
|
||||
out += local_len;
|
||||
}
|
||||
line[out] = '\0';
|
||||
wrap_offset = local_len - visible_length;
|
||||
}
|
||||
@@ -344,7 +377,13 @@ rl_redisplay ()
|
||||
{
|
||||
prompt_this_line++;
|
||||
if (forced_display)
|
||||
_rl_output_some_chars (rl_display_prompt, prompt_this_line - rl_display_prompt);
|
||||
{
|
||||
_rl_output_some_chars (rl_display_prompt, prompt_this_line - rl_display_prompt);
|
||||
/* Make sure we are at column zero even after a newline,
|
||||
regardless of the state of terminal output processing. */
|
||||
if (prompt_this_line[-2] != '\r')
|
||||
cr ();
|
||||
}
|
||||
}
|
||||
|
||||
pmtlen = strlen (prompt_this_line);
|
||||
@@ -354,7 +393,20 @@ rl_redisplay ()
|
||||
wrap_offset = 0;
|
||||
}
|
||||
|
||||
for (in = 0; in < rl_end; in++)
|
||||
#define CHECK_LPOS() \
|
||||
do { \
|
||||
lpos++; \
|
||||
if (lpos >= screenwidth) \
|
||||
{ \
|
||||
inv_lbreaks[++newlines] = out; \
|
||||
lpos = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* inv_lbreaks[i] is where line i starts in the buffer. */
|
||||
inv_lbreaks[newlines = 0] = 0;
|
||||
|
||||
for (in = 0, lpos = out - wrap_offset; in < rl_end; in++)
|
||||
{
|
||||
c = (unsigned char)rl_line_buffer[in];
|
||||
|
||||
@@ -367,42 +419,88 @@ rl_redisplay ()
|
||||
}
|
||||
|
||||
if (in == rl_point)
|
||||
c_pos = out;
|
||||
{
|
||||
c_pos = out;
|
||||
lb_linenum = newlines;
|
||||
}
|
||||
|
||||
if (META_CHAR (c))
|
||||
{
|
||||
if (_rl_output_meta_chars == 0)
|
||||
{
|
||||
sprintf (line + out, "\\%o", c);
|
||||
|
||||
if (lpos + 4 >= screenwidth)
|
||||
{
|
||||
register int temp;
|
||||
|
||||
temp = screenwidth - lpos;
|
||||
inv_lbreaks[++newlines] = out + temp;
|
||||
lpos = 4 - temp;
|
||||
}
|
||||
else
|
||||
lpos += 4;
|
||||
|
||||
out += 4;
|
||||
}
|
||||
else
|
||||
line[out++] = c;
|
||||
{
|
||||
line[out++] = c;
|
||||
CHECK_LPOS();
|
||||
}
|
||||
}
|
||||
#if defined (DISPLAY_TABS)
|
||||
else if (c == '\t')
|
||||
{
|
||||
register int newout = (out | (int)7) + 1;
|
||||
while (out < newout)
|
||||
line[out++] = ' ';
|
||||
register int temp, newout;
|
||||
newout = (out | (int)7) + 1;
|
||||
temp = newout - out;
|
||||
if (lpos + temp >= screenwidth)
|
||||
{
|
||||
register int temp2;
|
||||
temp2 = screenwidth - lpos;
|
||||
inv_lbreaks[++newlines] = out + temp2;
|
||||
lpos = temp - temp2;
|
||||
while (out < newout)
|
||||
line[out++] = ' ';
|
||||
}
|
||||
else
|
||||
{
|
||||
while (out < newout)
|
||||
line[out++] = ' ';
|
||||
lpos += temp;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else if (c < ' ')
|
||||
else if (c == '\n' && _rl_horizontal_scroll_mode == 0 && term_up && *term_up)
|
||||
{
|
||||
line[out++] = '\0'; /* XXX - sentinel */
|
||||
inv_lbreaks[++newlines] = out;
|
||||
lpos = 0;
|
||||
}
|
||||
else if (CTRL_CHAR (c) || c == RUBOUT)
|
||||
{
|
||||
line[out++] = '^';
|
||||
line[out++] = UNCTRL (c); /* XXX was c ^ 0x40 */
|
||||
}
|
||||
else if (c == 127)
|
||||
{
|
||||
line[out++] = '^';
|
||||
line[out++] = '?';
|
||||
CHECK_LPOS();
|
||||
line[out++] = CTRL_CHAR (c) ? UNCTRL (c) : '?';
|
||||
CHECK_LPOS();
|
||||
}
|
||||
else
|
||||
line[out++] = c;
|
||||
{
|
||||
line[out++] = c;
|
||||
CHECK_LPOS();
|
||||
}
|
||||
}
|
||||
line[out] = '\0';
|
||||
if (c_pos < 0)
|
||||
c_pos = out;
|
||||
{
|
||||
c_pos = out;
|
||||
lb_linenum = newlines;
|
||||
}
|
||||
|
||||
inv_botlin = lb_botlin = newlines;
|
||||
inv_lbreaks[newlines+1] = out;
|
||||
cursor_linenum = lb_linenum;
|
||||
|
||||
/* C_POS == position in buffer where cursor should be placed. */
|
||||
|
||||
@@ -415,10 +513,9 @@ rl_redisplay ()
|
||||
otherwise, let long lines display in a single terminal line, and
|
||||
horizontally scroll it. */
|
||||
|
||||
if (!_rl_horizontal_scroll_mode && term_up && *term_up)
|
||||
if (_rl_horizontal_scroll_mode == 0 && term_up && *term_up)
|
||||
{
|
||||
int total_screen_chars = screenchars;
|
||||
int nleft, cursor_linenum, pos, changed_screen_line;
|
||||
int nleft, pos, changed_screen_line;
|
||||
|
||||
if (!rl_display_fixed || forced_display)
|
||||
{
|
||||
@@ -426,42 +523,35 @@ rl_redisplay ()
|
||||
|
||||
/* If we have more than a screenful of material to display, then
|
||||
only display a screenful. We should display the last screen,
|
||||
not the first. I'll fix this in a minute. */
|
||||
if (out >= total_screen_chars)
|
||||
out = total_screen_chars - 1;
|
||||
|
||||
/* Number of screen lines to display. The first line wraps at
|
||||
(screenwidth + wrap_offset) chars, the rest of the lines have
|
||||
screenwidth chars. */
|
||||
nleft = out - wrap_offset + term_xn - 1;
|
||||
inv_botlin = (nleft > 0) ? nleft / screenwidth : 0;
|
||||
not the first. */
|
||||
if (out >= screenchars)
|
||||
out = screenchars - 1;
|
||||
|
||||
/* The first line is at character position 0 in the buffer. The
|
||||
second and subsequent lines start at N * screenwidth, offset by
|
||||
OFFSET. OFFSET is wrap_offset for the invisible line and
|
||||
visible_wrap_offset for the line currently displayed. */
|
||||
second and subsequent lines start at inv_lbreaks[N], offset by
|
||||
OFFSET (which has already been calculated above). */
|
||||
|
||||
#define W_OFFSET(line, offset) ((line) == 0 ? offset : 0)
|
||||
#define L_OFFSET(n, offset) ((n) > 0 ? ((n) * screenwidth) + (offset) : 0)
|
||||
#define VIS_CHARS(line) &visible_line[L_OFFSET((line), visible_wrap_offset)]
|
||||
#define VIS_LLEN(l) ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l]))
|
||||
#define INV_LLEN(l) (inv_lbreaks[l+1] - inv_lbreaks[l])
|
||||
#define VIS_CHARS(line) (visible_line + vis_lbreaks[line])
|
||||
#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line)
|
||||
#define INV_LINE(line) &invisible_line[L_OFFSET((line), wrap_offset)]
|
||||
#define INV_LINE(line) (invisible_line + inv_lbreaks[line])
|
||||
|
||||
/* For each line in the buffer, do the updating display. */
|
||||
for (linenum = 0; linenum <= inv_botlin; linenum++)
|
||||
{
|
||||
update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum,
|
||||
screenwidth + W_OFFSET(linenum, visible_wrap_offset),
|
||||
screenwidth + W_OFFSET(linenum, wrap_offset),
|
||||
inv_botlin);
|
||||
VIS_LLEN(linenum), INV_LLEN(linenum), inv_botlin);
|
||||
|
||||
/* If this is the line with the prompt, we might need to
|
||||
compensate for invisible characters in the new line. Do
|
||||
this only if there is not more than one new line (which
|
||||
implies that we completely overwrite the old visible line)
|
||||
and the new line is shorter than the old. */
|
||||
and the new line is shorter than the old. Make sure we are
|
||||
at the end of the new line before clearing. */
|
||||
if (linenum == 0 &&
|
||||
inv_botlin == 0 &&
|
||||
inv_botlin == 0 && _rl_last_c_pos == out &&
|
||||
(wrap_offset > visible_wrap_offset) &&
|
||||
(_rl_last_c_pos < visible_first_line_len))
|
||||
{
|
||||
@@ -472,7 +562,7 @@ rl_redisplay ()
|
||||
|
||||
/* Since the new first line is now visible, save its length. */
|
||||
if (linenum == 0)
|
||||
visible_first_line_len = (inv_botlin > 0) ? screenwidth : out - wrap_offset;
|
||||
visible_first_line_len = (inv_botlin > 0) ? inv_lbreaks[1] : out - wrap_offset;
|
||||
}
|
||||
|
||||
/* We may have deleted some lines. If so, clear the left over
|
||||
@@ -491,11 +581,6 @@ rl_redisplay ()
|
||||
}
|
||||
_rl_vis_botlin = inv_botlin;
|
||||
|
||||
/* Move the cursor where it should be. */
|
||||
/* Which line? */
|
||||
nleft = c_pos - wrap_offset + term_xn - 1;
|
||||
cursor_linenum = (nleft > 0) ? nleft / screenwidth : 0;
|
||||
|
||||
/* CHANGED_SCREEN_LINE is set to 1 if we have moved to a
|
||||
different screen line during this redisplay. */
|
||||
changed_screen_line = _rl_last_v_pos != cursor_linenum;
|
||||
@@ -512,10 +597,12 @@ rl_redisplay ()
|
||||
|
||||
/* We have to reprint the prompt if it contains invisible
|
||||
characters, since it's not generally OK to just reprint
|
||||
the characters from the current cursor position. */
|
||||
the characters from the current cursor position. But we
|
||||
only need to reprint it if the cursor is before the last
|
||||
invisible character in the prompt string. */
|
||||
nleft = visible_length + wrap_offset;
|
||||
if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 &&
|
||||
_rl_last_c_pos <= nleft && local_prompt)
|
||||
_rl_last_c_pos <= last_invisible && local_prompt)
|
||||
{
|
||||
if (term_cr)
|
||||
tputs (term_cr, 1, _rl_output_character_function);
|
||||
@@ -525,17 +612,17 @@ rl_redisplay ()
|
||||
|
||||
/* Where on that line? And where does that line start
|
||||
in the buffer? */
|
||||
pos = L_OFFSET(cursor_linenum, wrap_offset);
|
||||
pos = inv_lbreaks[cursor_linenum];
|
||||
/* nleft == number of characters in the line buffer between the
|
||||
start of the line and the cursor position. */
|
||||
nleft = c_pos - pos;
|
||||
|
||||
/* Since backspace() doesn't know about invisible characters in the
|
||||
/* Since _rl_backspace() doesn't know about invisible characters in the
|
||||
prompt, and there's no good way to tell it, we compensate for
|
||||
those characters here and call backspace() directly. */
|
||||
those characters here and call _rl_backspace() directly. */
|
||||
if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos)
|
||||
{
|
||||
backspace (_rl_last_c_pos - nleft);
|
||||
_rl_backspace (_rl_last_c_pos - nleft);
|
||||
_rl_last_c_pos = nleft;
|
||||
}
|
||||
|
||||
@@ -638,8 +725,11 @@ rl_redisplay ()
|
||||
/* Swap visible and non-visible lines. */
|
||||
{
|
||||
char *temp = visible_line;
|
||||
int *itemp = vis_lbreaks;
|
||||
visible_line = invisible_line;
|
||||
invisible_line = temp;
|
||||
vis_lbreaks = inv_lbreaks;
|
||||
inv_lbreaks = itemp;
|
||||
rl_display_fixed = 0;
|
||||
/* If we are displaying on a single line, and last_lmargin is > 0, we
|
||||
are not displaying any invisible characters, so set visible_wrap_offset
|
||||
@@ -670,10 +760,11 @@ new: eddie> Oh, my little buggy says to me, as lurgid as
|
||||
static void
|
||||
update_line (old, new, current_line, omax, nmax, inv_botlin)
|
||||
register char *old, *new;
|
||||
int current_line, omax, nmax;
|
||||
int current_line, omax, nmax, inv_botlin;
|
||||
{
|
||||
register char *ofd, *ols, *oe, *nfd, *nls, *ne;
|
||||
int temp, lendiff, wsatend, od, nd;
|
||||
int current_invis_chars;
|
||||
|
||||
/* If we're at the right edge of a terminal that supports xn, we're
|
||||
ready to wrap around, so do so. This fixes problems with knowing
|
||||
@@ -681,7 +772,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
|
||||
emulators. In this calculation, TEMP is the physical screen
|
||||
position of the cursor. */
|
||||
temp = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);
|
||||
if (temp == screenwidth && term_xn && !_rl_horizontal_scroll_mode
|
||||
if (temp == screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode
|
||||
&& _rl_last_v_pos == current_line - 1)
|
||||
{
|
||||
if (new[0])
|
||||
@@ -734,33 +825,53 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
|
||||
nls++;
|
||||
}
|
||||
|
||||
_rl_move_vert (current_line);
|
||||
/* count of invisible characters in the current invisible line. */
|
||||
current_invis_chars = W_OFFSET (current_line, wrap_offset);
|
||||
if (_rl_last_v_pos != current_line)
|
||||
{
|
||||
_rl_move_vert (current_line);
|
||||
if (current_line == 0 && visible_wrap_offset)
|
||||
_rl_last_c_pos += visible_wrap_offset;
|
||||
}
|
||||
|
||||
/* If this is the first line and there are invisible characters in the
|
||||
prompt string, and the prompt string has not changed, then redraw
|
||||
the entire prompt string. We can only do this reliably if the
|
||||
terminal supports a `cr' capability.
|
||||
prompt string, and the prompt string has not changed, and the current
|
||||
cursor position is before the last invisible character in the prompt,
|
||||
and the index of the character to move to is past the end of the prompt
|
||||
string, then redraw the entire prompt string. We can only do this
|
||||
reliably if the terminal supports a `cr' capability.
|
||||
|
||||
This is more than just an efficiency hack -- there is a problem with
|
||||
redrawing portions of the prompt string if they contain terminal
|
||||
escape sequences (like drawing the `unbold' sequence without a
|
||||
corresponding `bold') that manifests itself on certain terminals. */
|
||||
This is not an efficiency hack -- there is a problem with redrawing
|
||||
portions of the prompt string if they contain terminal escape
|
||||
sequences (like drawing the `unbold' sequence without a corresponding
|
||||
`bold') that manifests itself on certain terminals. */
|
||||
|
||||
lendiff = local_prompt ? strlen (local_prompt) : 0;
|
||||
od = ofd - old; /* index of first difference in visible line */
|
||||
if (current_line == 0 && !_rl_horizontal_scroll_mode &&
|
||||
lendiff > visible_length &&
|
||||
_rl_last_c_pos > 0 && (ofd - old) >= lendiff && term_cr)
|
||||
term_cr && lendiff > visible_length && _rl_last_c_pos > 0 &&
|
||||
od > lendiff && _rl_last_c_pos < last_invisible)
|
||||
{
|
||||
tputs (term_cr, 1, _rl_output_character_function);
|
||||
_rl_output_some_chars (local_prompt, lendiff);
|
||||
_rl_last_c_pos = lendiff;
|
||||
}
|
||||
|
||||
_rl_move_cursor_relative (ofd - old, old);
|
||||
_rl_move_cursor_relative (od, old);
|
||||
|
||||
/* if (len (new) > len (old)) */
|
||||
lendiff = (nls - nfd) - (ols - ofd);
|
||||
|
||||
/* If we are changing the number of invisible characters in a line, and
|
||||
the spot of first difference is before the end of the invisible chars,
|
||||
lendiff needs to be adjusted. */
|
||||
if (current_line == 0 && !_rl_horizontal_scroll_mode &&
|
||||
current_invis_chars != visible_wrap_offset)
|
||||
{
|
||||
temp = visible_wrap_offset - current_invis_chars;
|
||||
lendiff += temp;
|
||||
}
|
||||
|
||||
/* Insert (diff (len (old), len (new)) ch. */
|
||||
temp = ne - nfd;
|
||||
if (lendiff > 0)
|
||||
@@ -771,25 +882,36 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
|
||||
use the terminal's capabilities. If we're growing the number
|
||||
of lines, make sure we actually cause the new line to wrap
|
||||
around on auto-wrapping terminals. */
|
||||
if (terminal_can_insert && ((2 * temp) >= lendiff || term_IC) && (!term_xn || !gl))
|
||||
if (terminal_can_insert && ((2 * temp) >= lendiff || term_IC) && (!_rl_term_autowrap || !gl))
|
||||
{
|
||||
/* If lendiff > visible_length and _rl_last_c_pos == 0 and
|
||||
_rl_horizontal_scroll_mode == 1, inserting the characters with
|
||||
term_IC or term_ic will screw up the screen because of the
|
||||
invisible characters. We need to just draw them. */
|
||||
if (*ols && (!_rl_horizontal_scroll_mode || _rl_last_c_pos > 0 ||
|
||||
lendiff <= visible_length))
|
||||
lendiff <= visible_length || !current_invis_chars))
|
||||
{
|
||||
insert_some_chars (nfd, lendiff);
|
||||
_rl_last_c_pos += lendiff;
|
||||
}
|
||||
else
|
||||
else if (*ols == 0)
|
||||
{
|
||||
/* At the end of a line the characters do not have to
|
||||
be "inserted". They can just be placed on the screen. */
|
||||
/* However, this screws up the rest of this block, which
|
||||
assumes you've done the insert because you can. */
|
||||
_rl_output_some_chars (nfd, lendiff);
|
||||
_rl_last_c_pos += lendiff;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We have horizontal scrolling and we are not inserting at
|
||||
the end. We have invisible characters in this line. This
|
||||
is a dumb update. */
|
||||
_rl_output_some_chars (nfd, temp);
|
||||
_rl_last_c_pos += temp;
|
||||
return;
|
||||
}
|
||||
/* Copy (new) chars to screen from first diff to last match. */
|
||||
temp = nls - nfd;
|
||||
if ((temp - lendiff) > 0)
|
||||
@@ -837,7 +959,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
|
||||
_rl_last_c_pos += temp;
|
||||
}
|
||||
lendiff = (oe - old) - (ne - new);
|
||||
if (term_xn && current_line < inv_botlin)
|
||||
if (_rl_term_autowrap && current_line < inv_botlin)
|
||||
space_to_eol (lendiff);
|
||||
else
|
||||
clear_to_eol (lendiff);
|
||||
@@ -846,6 +968,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
|
||||
}
|
||||
|
||||
/* Tell the update routines that we have moved onto a new (empty) line. */
|
||||
int
|
||||
rl_on_new_line ()
|
||||
{
|
||||
if (visible_line)
|
||||
@@ -853,21 +976,26 @@ rl_on_new_line ()
|
||||
|
||||
_rl_last_c_pos = _rl_last_v_pos = 0;
|
||||
_rl_vis_botlin = last_lmargin = 0;
|
||||
if (vis_lbreaks)
|
||||
vis_lbreaks[0] = vis_lbreaks[1] = 0;
|
||||
visible_wrap_offset = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Actually update the display, period. */
|
||||
int
|
||||
rl_forced_update_display ()
|
||||
{
|
||||
if (visible_line)
|
||||
{
|
||||
register char *temp = visible_line;
|
||||
|
||||
while (*temp) *temp++ = '\0';
|
||||
while (*temp)
|
||||
*temp++ = '\0';
|
||||
}
|
||||
rl_on_new_line ();
|
||||
forced_display++;
|
||||
rl_redisplay ();
|
||||
(*rl_redisplay_function) ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -888,7 +1016,8 @@ _rl_move_cursor_relative (new, data)
|
||||
of moving backwards. */
|
||||
/* i == current physical cursor position. */
|
||||
i = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);
|
||||
if (CR_FASTER (new, _rl_last_c_pos) || (term_xn && i == screenwidth))
|
||||
if (new == 0 || CR_FASTER (new, _rl_last_c_pos) ||
|
||||
(_rl_term_autowrap && i == screenwidth))
|
||||
{
|
||||
#if defined (__MSDOS__)
|
||||
putc ('\r', rl_outstream);
|
||||
@@ -924,7 +1053,7 @@ _rl_move_cursor_relative (new, data)
|
||||
#endif /* HACK_TERMCAP_MOTION */
|
||||
}
|
||||
else if (_rl_last_c_pos != new)
|
||||
backspace (_rl_last_c_pos - new);
|
||||
_rl_backspace (_rl_last_c_pos - new);
|
||||
_rl_last_c_pos = new;
|
||||
}
|
||||
|
||||
@@ -966,6 +1095,7 @@ _rl_move_vert (to)
|
||||
|
||||
/* Physically print C on rl_outstream. This is for functions which know
|
||||
how to optimize the display. Return the number of characters output. */
|
||||
int
|
||||
rl_show_char (c)
|
||||
int c;
|
||||
{
|
||||
@@ -978,14 +1108,14 @@ rl_show_char (c)
|
||||
}
|
||||
|
||||
#if defined (DISPLAY_TABS)
|
||||
if (c < 32 && c != '\t')
|
||||
if ((CTRL_CHAR (c) && c != '\t') || c == RUBOUT)
|
||||
#else
|
||||
if (c < 32)
|
||||
if (CTRL_CHAR (c) || c == RUBOUT)
|
||||
#endif /* !DISPLAY_TABS */
|
||||
{
|
||||
fprintf (rl_outstream, "C-");
|
||||
n += 2;
|
||||
c += 64;
|
||||
c = CTRL_CHAR (c) ? UNCTRL (c) : '?';
|
||||
}
|
||||
|
||||
putc (c, rl_outstream);
|
||||
@@ -1013,47 +1143,65 @@ rl_character_len (c, pos)
|
||||
#endif /* !DISPLAY_TABS */
|
||||
}
|
||||
|
||||
if (CTRL_CHAR (c) || c == RUBOUT)
|
||||
return (2);
|
||||
|
||||
return ((isprint (uc)) ? 1 : 2);
|
||||
}
|
||||
|
||||
/* How to print things in the "echo-area". The prompt is treated as a
|
||||
mini-modeline. */
|
||||
|
||||
#if defined (HAVE_VARARGS_H)
|
||||
#if defined (USE_VARARGS)
|
||||
int
|
||||
#if defined (PREFER_STDARG)
|
||||
rl_message (const char *format, ...)
|
||||
#else
|
||||
rl_message (va_alist)
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
char *format;
|
||||
va_list args;
|
||||
#if defined (PREFER_VARARGS)
|
||||
char *format;
|
||||
#endif
|
||||
|
||||
#if defined (PREFER_STDARG)
|
||||
va_start (args, format);
|
||||
#else
|
||||
va_start (args);
|
||||
format = va_arg (args, char *);
|
||||
#endif
|
||||
|
||||
vsprintf (msg_buf, format, args);
|
||||
va_end (args);
|
||||
|
||||
rl_display_prompt = msg_buf;
|
||||
rl_redisplay ();
|
||||
(*rl_redisplay_function) ();
|
||||
return 0;
|
||||
}
|
||||
#else /* !HAVE_VARARGS_H */
|
||||
#else /* !USE_VARARGS */
|
||||
int
|
||||
rl_message (format, arg1, arg2)
|
||||
char *format;
|
||||
{
|
||||
sprintf (msg_buf, format, arg1, arg2);
|
||||
rl_display_prompt = msg_buf;
|
||||
rl_redisplay ();
|
||||
(*rl_redisplay_function) ();
|
||||
return 0;
|
||||
}
|
||||
#endif /* !HAVE_VARARGS_H */
|
||||
#endif /* !USE_VARARGS */
|
||||
|
||||
/* How to clear things from the "echo-area". */
|
||||
int
|
||||
rl_clear_message ()
|
||||
{
|
||||
rl_display_prompt = rl_prompt;
|
||||
rl_redisplay ();
|
||||
(*rl_redisplay_function) ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rl_reset_line_state ()
|
||||
{
|
||||
rl_on_new_line ();
|
||||
@@ -1063,6 +1211,70 @@ rl_reset_line_state ()
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *saved_local_prompt;
|
||||
static char *saved_local_prefix;
|
||||
static int saved_last_invisible;
|
||||
static int saved_visible_length;
|
||||
|
||||
void
|
||||
_rl_save_prompt ()
|
||||
{
|
||||
saved_local_prompt = local_prompt;
|
||||
saved_local_prefix = local_prompt_prefix;
|
||||
saved_last_invisible = last_invisible;
|
||||
saved_visible_length = visible_length;
|
||||
|
||||
local_prompt = local_prompt_prefix = (char *)0;
|
||||
last_invisible = visible_length = 0;
|
||||
}
|
||||
|
||||
void
|
||||
_rl_restore_prompt ()
|
||||
{
|
||||
if (local_prompt)
|
||||
free (local_prompt);
|
||||
if (local_prompt_prefix)
|
||||
free (local_prompt_prefix);
|
||||
|
||||
local_prompt = saved_local_prompt;
|
||||
local_prompt_prefix = saved_local_prefix;
|
||||
last_invisible = saved_last_invisible;
|
||||
visible_length = saved_visible_length;
|
||||
}
|
||||
|
||||
char *
|
||||
_rl_make_prompt_for_search (pchar)
|
||||
int pchar;
|
||||
{
|
||||
int len;
|
||||
char *pmt;
|
||||
|
||||
_rl_save_prompt ();
|
||||
|
||||
if (saved_local_prompt == 0)
|
||||
{
|
||||
len = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0;
|
||||
pmt = xmalloc (len + 2);
|
||||
if (len)
|
||||
strcpy (pmt, rl_prompt);
|
||||
pmt[len] = pchar;
|
||||
pmt[len+1] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
len = *saved_local_prompt ? strlen (saved_local_prompt) : 0;
|
||||
pmt = xmalloc (len + 2);
|
||||
if (len)
|
||||
strcpy (pmt, saved_local_prompt);
|
||||
pmt[len] = pchar;
|
||||
pmt[len+1] = '\0';
|
||||
local_prompt = savestring (pmt);
|
||||
last_invisible = saved_last_invisible;
|
||||
visible_length = saved_visible_length + 1;
|
||||
}
|
||||
return pmt;
|
||||
}
|
||||
|
||||
/* Quick redisplay hack when erasing characters at the end of the line. */
|
||||
void
|
||||
_rl_erase_at_end_of_line (l)
|
||||
@@ -1070,10 +1282,10 @@ _rl_erase_at_end_of_line (l)
|
||||
{
|
||||
register int i;
|
||||
|
||||
backspace (l);
|
||||
_rl_backspace (l);
|
||||
for (i = 0; i < l; i++)
|
||||
putc (' ', rl_outstream);
|
||||
backspace (l);
|
||||
_rl_backspace (l);
|
||||
for (i = 0; i < l; i++)
|
||||
visible_line[--_rl_last_c_pos] = '\0';
|
||||
rl_display_fixed++;
|
||||
@@ -1132,7 +1344,7 @@ insert_some_chars (string, count)
|
||||
/* If IC is defined, then we do not have to "enter" insert mode. */
|
||||
if (term_IC)
|
||||
{
|
||||
char *tgoto (), *buffer;
|
||||
char *buffer;
|
||||
buffer = tgoto (term_IC, 0, count);
|
||||
tputs (buffer, 1, _rl_output_character_function);
|
||||
_rl_output_some_chars (string, count);
|
||||
@@ -1186,7 +1398,7 @@ delete_chars (count)
|
||||
|
||||
if (term_DC && *term_DC)
|
||||
{
|
||||
char *tgoto (), *buffer;
|
||||
char *buffer;
|
||||
buffer = tgoto (term_DC, count, count);
|
||||
tputs (buffer, count, _rl_output_character_function);
|
||||
}
|
||||
@@ -1205,17 +1417,20 @@ _rl_update_final ()
|
||||
int full_lines;
|
||||
|
||||
full_lines = 0;
|
||||
if (_rl_vis_botlin && visible_line[screenwidth * _rl_vis_botlin] == 0)
|
||||
/* If the cursor is the only thing on an otherwise-blank last line,
|
||||
compensate so we don't print an extra CRLF. */
|
||||
if (_rl_vis_botlin && _rl_last_c_pos == 0 &&
|
||||
visible_line[inv_lbreaks[_rl_vis_botlin]+1] == 0)
|
||||
{
|
||||
_rl_vis_botlin--;
|
||||
full_lines = 1;
|
||||
}
|
||||
_rl_move_vert (_rl_vis_botlin);
|
||||
if (full_lines && term_xn)
|
||||
/* If we've wrapped lines, remove the final xterm line-wrap flag. */
|
||||
if (full_lines && _rl_term_autowrap && (VIS_LLEN(_rl_vis_botlin) == screenwidth))
|
||||
{
|
||||
/* Remove final line-wrap flag in xterm. */
|
||||
char *last_line;
|
||||
last_line = &visible_line[screenwidth * _rl_vis_botlin];
|
||||
last_line = &visible_line[inv_lbreaks[_rl_vis_botlin]];
|
||||
_rl_move_cursor_relative (screenwidth - 1, last_line);
|
||||
clear_to_eol (0);
|
||||
putc (last_line[screenwidth - 1], rl_outstream);
|
||||
@@ -1274,3 +1489,15 @@ _rl_redisplay_after_sigwinch ()
|
||||
else
|
||||
rl_forced_update_display ();
|
||||
}
|
||||
|
||||
void
|
||||
_rl_clean_up_for_exit ()
|
||||
{
|
||||
if (readline_echoing_p)
|
||||
{
|
||||
_rl_move_vert (_rl_vis_botlin);
|
||||
_rl_vis_botlin = 0;
|
||||
fflush (rl_outstream);
|
||||
rl_restart_output ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
# This makefile for History library documentation is in -*- text -*- mode.
|
||||
# This makefile for Readline library documentation is in -*- text -*- mode.
|
||||
# Emacs likes it that way.
|
||||
TEXI2DVI = texi2dvi
|
||||
|
||||
DOC_SUPPORT = ../../doc-support/
|
||||
TEXINDEX = $(DOC_SUPPORT)/texindex
|
||||
RM = rm -f
|
||||
|
||||
TEX = tex
|
||||
INSTALL_DATA = cp
|
||||
infodir = /usr/local/info
|
||||
|
||||
RLSRC = rlman.texinfo rluser.texinfo rltech.texinfo
|
||||
HISTSRC = hist.texinfo hsuser.texinfo hstech.texinfo
|
||||
@@ -12,26 +13,23 @@ HISTSRC = hist.texinfo hsuser.texinfo hstech.texinfo
|
||||
DVIOBJ = readline.dvi history.dvi
|
||||
INFOOBJ = readline.info history.info
|
||||
PSOBJ = readline.ps history.ps
|
||||
HTMLOBJ = readline.html history.html
|
||||
|
||||
all: info dvi
|
||||
all: info dvi html
|
||||
|
||||
readline.dvi: $(RLSRC)
|
||||
$(TEX) rlman.texinfo
|
||||
$(TEXINDEX) rlman.??
|
||||
$(TEX) rlman.texinfo
|
||||
$(TEXI2DVI) rlman.texinfo
|
||||
mv rlman.dvi readline.dvi
|
||||
|
||||
readline.info: $(RLSRC)
|
||||
makeinfo rlman.texinfo
|
||||
makeinfo --no-split -o $@ rlman.texinfo
|
||||
|
||||
history.dvi: ${HISTSRC}
|
||||
$(TEX) hist.texinfo
|
||||
$(TEXINDEX) hist.??
|
||||
$(TEX) hist.texinfo
|
||||
$(TEXI2DVI) hist.texinfo
|
||||
mv hist.dvi history.dvi
|
||||
|
||||
history.info: ${HISTSRC}
|
||||
makeinfo hist.texinfo
|
||||
makeinfo --no-split -o $@ hist.texinfo
|
||||
|
||||
readline.ps: readline.dvi
|
||||
dvips -D 300 -o $@ readline.dvi
|
||||
@@ -39,17 +37,33 @@ readline.ps: readline.dvi
|
||||
history.ps: history.dvi
|
||||
dvips -D 300 -o $@ history.dvi
|
||||
|
||||
readline.html: ${RLSRC}
|
||||
texi2html rlman.texinfo
|
||||
sed -e 's:rlman.html:readline.html:' -e 's:rlman_toc.html:readline_toc.html:' rlman.html > readline.html
|
||||
sed -e 's:rlman.html:readline.html:' -e 's:rlman_toc.html:readline_toc.html:' rlman_toc.html > readline_toc.html
|
||||
rm -f rlman.html rlman_toc.html
|
||||
|
||||
history.html: ${HISTSRC}
|
||||
texi2html hist.texinfo
|
||||
sed -e 's:hist.html:history.html:' -e 's:hist_toc.html:history_toc.html:' hist.html > history.html
|
||||
sed -e 's:hist.html:history.html:' -e 's:hist_toc.html:history_toc.html:' hist_toc.html > history_toc.html
|
||||
rm -f hist.html hist_toc.html
|
||||
|
||||
info: $(INFOOBJ)
|
||||
dvi: $(DVIOBJ)
|
||||
ps: $(PSOBJ)
|
||||
html: $(HTMLOBJ)
|
||||
|
||||
|
||||
$(TEXINDEX):
|
||||
(cd $(DOC_SUPPORT); $(MAKE) $(MFLAGS) CFLAGS='$(CFLAGS)' texindex)
|
||||
|
||||
distclean mostlyclean clean:
|
||||
rm -f *.aux *.cp *.fn *.ky *.log *.pg *.toc *.tp *.vr *.cps *.pgs \
|
||||
clean:
|
||||
$(RM) *.aux *.cp *.fn *.ky *.log *.pg *.toc *.tp *.vr *.cps *.pgs \
|
||||
*.fns *.kys *.tps *.vrs *.o core
|
||||
|
||||
maintainer-clean realclean: clean
|
||||
rm -f *.dvi *.info *.info-* *.ps
|
||||
distclean: clean
|
||||
mostlyclean: clean
|
||||
|
||||
maintainer-clean: clean
|
||||
$(RM) *.dvi *.info *.info-* *.ps *.html
|
||||
|
||||
install: info
|
||||
${INSTALL_DATA} readline.info $(infodir)/readline.info
|
||||
${INSTALL_DATA} history.info $(infodir)/history.info
|
||||
|
||||
@@ -7,20 +7,20 @@
|
||||
@setchapternewpage odd
|
||||
|
||||
@ignore
|
||||
last change: Wed Jul 20 09:57:17 EDT 1994
|
||||
last change: Thu Mar 21 16:07:29 EST 1996
|
||||
@end ignore
|
||||
|
||||
@set EDITION 2.0
|
||||
@set VERSION 2.0
|
||||
@set UPDATED 20 July 1994
|
||||
@set UPDATE-MONTH July 1994
|
||||
@set EDITION 2.1
|
||||
@set VERSION 2.1
|
||||
@set UPDATED 21 March 1996
|
||||
@set UPDATE-MONTH March 1996
|
||||
|
||||
@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.
|
||||
Copyright (C) 1988, 1991, 1993, 1995, 1996 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
@@ -45,7 +45,6 @@ by the Foundation.
|
||||
@end ifinfo
|
||||
|
||||
@titlepage
|
||||
@sp 10
|
||||
@title GNU History Library
|
||||
@subtitle Edition @value{EDITION}, for @code{History Library} Version @value{VERSION}.
|
||||
@subtitle @value{UPDATE-MONTH}
|
||||
|
||||
Binary file not shown.
@@ -1,744 +0,0 @@
|
||||
This is Info file history.info, produced by Makeinfo-1.55 from the
|
||||
input file hist.texinfo.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
File: history.info, Node: Top, Next: Using History Interactively, Prev: (DIR), Up: (DIR)
|
||||
|
||||
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.
|
||||
|
||||
|
||||
File: history.info, Node: Using History Interactively, Next: Programming with GNU History, Prev: Top, Up: Top
|
||||
|
||||
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, *note Programming with GNU History::..
|
||||
|
||||
* Menu:
|
||||
|
||||
* History Interaction:: What it feels like using History as a user.
|
||||
|
||||
|
||||
File: history.info, Node: History Interaction, Up: Using History Interactively
|
||||
|
||||
History Interaction
|
||||
===================
|
||||
|
||||
The History library provides a history expansion feature that is
|
||||
similar to the history expansion provided by `csh'. The following text
|
||||
describes the syntax used 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 "event", and the portions of that line that are
|
||||
acted upon are called "words". The line is broken into words in the
|
||||
same fashion that Bash 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 substitution.
|
||||
|
||||
|
||||
File: history.info, Node: Event Designators, Next: Word Designators, Up: History Interaction
|
||||
|
||||
Event Designators
|
||||
-----------------
|
||||
|
||||
An event designator is a reference to a command line entry in the
|
||||
history list.
|
||||
|
||||
`!'
|
||||
Start a history substitution, except when followed by a space, tab,
|
||||
the end of the line, = or (.
|
||||
|
||||
`!!'
|
||||
Refer to the previous command. This is a synonym for `!-1'.
|
||||
|
||||
`!n'
|
||||
Refer to command line N.
|
||||
|
||||
`!-n'
|
||||
Refer to the command N lines back.
|
||||
|
||||
`!string'
|
||||
Refer to the most recent command starting with STRING.
|
||||
|
||||
`!?string'[`?']
|
||||
Refer to the most recent command containing STRING.
|
||||
|
||||
`!#'
|
||||
The entire command line typed so far.
|
||||
|
||||
`^string1^string2^'
|
||||
Quick Substitution. Repeat the last command, replacing STRING1
|
||||
with STRING2. Equivalent to `!!:s/string1/string2/'.
|
||||
|
||||
|
||||
File: history.info, Node: Word Designators, Next: Modifiers, Prev: Event Designators, Up: History Interaction
|
||||
|
||||
Word Designators
|
||||
----------------
|
||||
|
||||
A : separates the event specification from the word designator. It
|
||||
can be omitted if the word designator begins with a ^, $, * or %.
|
||||
Words are numbered from the beginning of the line, with the first word
|
||||
being denoted by a 0 (zero).
|
||||
|
||||
`0 (zero)'
|
||||
The `0'th word. For many applications, this is the command word.
|
||||
|
||||
`n'
|
||||
The Nth word.
|
||||
|
||||
`^'
|
||||
The first argument; that is, word 1.
|
||||
|
||||
`$'
|
||||
The last argument.
|
||||
|
||||
`%'
|
||||
The word matched by the most recent `?string?' search.
|
||||
|
||||
`x-y'
|
||||
A range of words; `-Y' abbreviates `0-Y'.
|
||||
|
||||
`*'
|
||||
All of the words, except the `0'th. This is a synonym for `1-$'.
|
||||
It is not an error to use * if there is just one word in the event;
|
||||
the empty string is returned in that case.
|
||||
|
||||
`x*'
|
||||
Abbreviates `x-$'
|
||||
|
||||
`x-'
|
||||
Abbreviates `x-$' like `x*', but omits the last word.
|
||||
|
||||
|
||||
File: history.info, Node: Modifiers, Prev: Word Designators, Up: History Interaction
|
||||
|
||||
Modifiers
|
||||
---------
|
||||
|
||||
After the optional word designator, you can add a sequence of one or
|
||||
more of the following modifiers, each preceded by a :.
|
||||
|
||||
`h'
|
||||
Remove a trailing pathname component, leaving only the head.
|
||||
|
||||
`r'
|
||||
Remove a trailing suffix of the form `.'SUFFIX, leaving the
|
||||
basename.
|
||||
|
||||
`e'
|
||||
Remove all but the trailing suffix.
|
||||
|
||||
`t'
|
||||
Remove all leading pathname components, leaving the tail.
|
||||
|
||||
`p'
|
||||
Print the new command but do not execute it.
|
||||
|
||||
`s/old/new/'
|
||||
Substitute NEW for the first occurrence of OLD in the event line.
|
||||
Any delimiter may be used in place of /. The delimiter may be
|
||||
quoted in OLD and NEW with a single backslash. If & appears in
|
||||
NEW, it is replaced by OLD. A single backslash will quote the &.
|
||||
The final delimiter is optional if it is the last character on the
|
||||
input line.
|
||||
|
||||
`&'
|
||||
Repeat the previous substitution.
|
||||
|
||||
`g'
|
||||
Cause changes to be applied over the entire event line. Used in
|
||||
conjunction with `s', as in `gs/old/new/', or with `&'.
|
||||
|
||||
|
||||
File: history.info, Node: Programming with GNU History, Next: Concept Index, Prev: Using History Interactively, Up: Top
|
||||
|
||||
Programming with GNU History
|
||||
****************************
|
||||
|
||||
This chapter describes how to interface programs that you write with
|
||||
the GNU History Library. It should be considered a technical guide.
|
||||
For information on the interactive use of GNU History, *note 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.
|
||||
|
||||
|
||||
File: history.info, Node: Introduction to History, Next: History Storage, Up: Programming with GNU History
|
||||
|
||||
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 composing new ones.
|
||||
|
||||
The programmer using the History library has available functions for
|
||||
remembering lines on a history list, associating arbitrary data with a
|
||||
line, removing lines from the list, searching through the list for a
|
||||
line containing an arbitrary text string, and referencing any line in
|
||||
the list directly. In addition, a history "expansion" function is
|
||||
available which provides for a consistent user interface across
|
||||
different programs.
|
||||
|
||||
The user using programs written with the History library has the
|
||||
benefit 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 provided by `csh'.
|
||||
|
||||
If the programmer desires, he can use the Readline library, which
|
||||
includes some history manipulation by default, and has the added
|
||||
advantage of command line editing.
|
||||
|
||||
|
||||
File: history.info, Node: History Storage, Next: History Functions, Prev: Introduction to History, Up: Programming with GNU History
|
||||
|
||||
History Storage
|
||||
===============
|
||||
|
||||
The history list is an array of history entries. A history entry is
|
||||
declared as follows:
|
||||
|
||||
typedef struct _hist_entry {
|
||||
char *line;
|
||||
char *data;
|
||||
} HIST_ENTRY;
|
||||
|
||||
The history list itself might therefore be declared as
|
||||
|
||||
HIST_ENTRY **the_history_list;
|
||||
|
||||
The state of the History library is encapsulated into a single
|
||||
structure:
|
||||
|
||||
/* A structure used to pass the current state of the history stuff around. */
|
||||
typedef struct _hist_state {
|
||||
HIST_ENTRY **entries; /* Pointer to the entries themselves. */
|
||||
int offset; /* The location pointer within this array. */
|
||||
int length; /* Number of elements within this array. */
|
||||
int size; /* Number of slots allocated to this array. */
|
||||
int flags;
|
||||
} HISTORY_STATE;
|
||||
|
||||
If the flags member includes `HS_STIFLED', the history has been
|
||||
stifled.
|
||||
|
||||
|
||||
File: history.info, Node: History Functions, Next: History Variables, Prev: History Storage, Up: Programming with GNU History
|
||||
|
||||
History Functions
|
||||
=================
|
||||
|
||||
This section describes the calling sequence for the various functions
|
||||
present in GNU History.
|
||||
|
||||
* Menu:
|
||||
|
||||
* Initializing History and State Management:: Functions to call when you
|
||||
want to use history in a
|
||||
program.
|
||||
* History List Management:: Functions used to manage the list
|
||||
of history entries.
|
||||
* Information About the History List:: Functions returning information about
|
||||
the history list.
|
||||
* Moving Around the History List:: Functions used to change the position
|
||||
in the history list.
|
||||
* Searching the History List:: Functions to search the history list
|
||||
for entries containing a string.
|
||||
* Managing the History File:: Functions that read and write a file
|
||||
containing the history list.
|
||||
* History Expansion:: Functions to perform csh-like history
|
||||
expansion.
|
||||
|
||||
|
||||
File: history.info, Node: Initializing History and State Management, Next: History List Management, Up: History Functions
|
||||
|
||||
Initializing History and State Management
|
||||
-----------------------------------------
|
||||
|
||||
This section describes functions used to initialize and manage the
|
||||
state of the History library when you want to use the history functions
|
||||
in your program.
|
||||
|
||||
- Function: void using_history ()
|
||||
Begin a session in which the history functions might be used. This
|
||||
initializes the interactive variables.
|
||||
|
||||
- Function: HISTORY_STATE * history_get_history_state ()
|
||||
Return a structure describing the current state of the input
|
||||
history.
|
||||
|
||||
- Function: void history_set_history_state (HISTORY_STATE *state)
|
||||
Set the state of the history list according to STATE.
|
||||
|
||||
|
||||
File: history.info, Node: History List Management, Next: Information About the History List, Prev: Initializing History and State Management, Up: History Functions
|
||||
|
||||
History List Management
|
||||
-----------------------
|
||||
|
||||
These functions manage individual entries on the history list, or set
|
||||
parameters managing the list itself.
|
||||
|
||||
- Function: void add_history (char *string)
|
||||
Place STRING at the end of the history list. The associated data
|
||||
field (if any) is set to `NULL'.
|
||||
|
||||
- Function: HIST_ENTRY * remove_history (int which)
|
||||
Remove history entry at offset WHICH from the history. The
|
||||
removed element is returned so you can free the line, data, and
|
||||
containing structure.
|
||||
|
||||
- Function: HIST_ENTRY * replace_history_entry (int which, char *line,
|
||||
char *data)
|
||||
Make the history entry at offset WHICH have LINE and DATA. This
|
||||
returns the old entry so you can dispose of the data. In the case
|
||||
of an invalid WHICH, a `NULL' pointer is returned.
|
||||
|
||||
- Function: void stifle_history (int max)
|
||||
Stifle the history list, remembering only the last MAX entries.
|
||||
|
||||
- Function: int unstifle_history ()
|
||||
Stop stifling the history. This returns the previous amount the
|
||||
history was stifled. The value is positive if the history was
|
||||
stifled, negative if it wasn't.
|
||||
|
||||
- Function: int history_is_stifled ()
|
||||
Returns non-zero if the history is stifled, zero if it is not.
|
||||
|
||||
|
||||
File: history.info, Node: Information About the History List, Next: Moving Around the History List, Prev: History List Management, Up: History Functions
|
||||
|
||||
Information About the History List
|
||||
----------------------------------
|
||||
|
||||
These functions return information about the entire history list or
|
||||
individual list entries.
|
||||
|
||||
- Function: HIST_ENTRY ** history_list ()
|
||||
Return a `NULL' terminated array of `HIST_ENTRY' which is the
|
||||
current input history. Element 0 of this list is the beginning of
|
||||
time. If there is no history, return `NULL'.
|
||||
|
||||
- Function: int where_history ()
|
||||
Returns the offset of the current history element.
|
||||
|
||||
- Function: HIST_ENTRY * current_history ()
|
||||
Return the history entry at the current position, as determined by
|
||||
`where_history ()'. If there is no entry there, return a `NULL'
|
||||
pointer.
|
||||
|
||||
- Function: HIST_ENTRY * history_get (int offset)
|
||||
Return the history entry at position OFFSET, starting from
|
||||
`history_base'. If there is no entry there, or if OFFSET is
|
||||
greater than the history length, return a `NULL' pointer.
|
||||
|
||||
- Function: int history_total_bytes ()
|
||||
Return the number of bytes that the primary history entries are
|
||||
using. This function returns the sum of the lengths of all the
|
||||
lines in the history.
|
||||
|
||||
|
||||
File: history.info, Node: Moving Around the History List, Next: Searching the History List, Prev: Information About the History List, Up: History Functions
|
||||
|
||||
Moving Around the History List
|
||||
------------------------------
|
||||
|
||||
These functions allow the current index into the history list to be
|
||||
set or changed.
|
||||
|
||||
- Function: int history_set_pos (int pos)
|
||||
Set the position in the history list to POS, an absolute index
|
||||
into the list.
|
||||
|
||||
- Function: HIST_ENTRY * previous_history ()
|
||||
Back up the current history offset to the previous history entry,
|
||||
and return a pointer to that entry. If there is no previous
|
||||
entry, return a `NULL' pointer.
|
||||
|
||||
- Function: HIST_ENTRY * next_history ()
|
||||
Move the current history offset forward to the next history entry,
|
||||
and return the a pointer to that entry. If there is no next
|
||||
entry, return a `NULL' pointer.
|
||||
|
||||
|
||||
File: history.info, Node: Searching the History List, Next: Managing the History File, Prev: Moving Around the History List, Up: History Functions
|
||||
|
||||
Searching the History List
|
||||
--------------------------
|
||||
|
||||
These functions allow searching of the history list for entries
|
||||
containing a specific string. Searching may be performed both forward
|
||||
and backward from the current history position. The search may be
|
||||
"anchored", meaning that the string must match at the beginning of the
|
||||
history entry.
|
||||
|
||||
- Function: int history_search (char *string, int direction)
|
||||
Search the history for STRING, starting at the current history
|
||||
offset. If DIRECTION < 0, then the search is through previous
|
||||
entries, else through subsequent. If STRING is found, then the
|
||||
current history index is set to that history entry, and the value
|
||||
returned is the offset in the line of the entry where STRING was
|
||||
found. Otherwise, nothing is changed, and a -1 is returned.
|
||||
|
||||
- Function: int history_search_prefix (char *string, int direction)
|
||||
Search the history for STRING, starting at the current history
|
||||
offset. The search is anchored: matching lines must begin with
|
||||
STRING. If DIRECTION < 0, then the search is through previous
|
||||
entries, else through subsequent. If STRING is found, then the
|
||||
current history index is set to that entry, and the return value
|
||||
is 0. Otherwise, nothing is changed, and a -1 is returned.
|
||||
|
||||
- Function: int history_search_pos (char *string, int direction, int
|
||||
pos)
|
||||
Search for STRING in the history list, starting at POS, an
|
||||
absolute index into the list. If DIRECTION is negative, the search
|
||||
proceeds backward from POS, otherwise forward. Returns the
|
||||
absolute index of the history element where STRING was found, or
|
||||
-1 otherwise.
|
||||
|
||||
|
||||
File: history.info, Node: Managing the History File, Next: History Expansion, Prev: Searching the History List, Up: History Functions
|
||||
|
||||
Managing the History File
|
||||
-------------------------
|
||||
|
||||
The History library can read the history from and write it to a file.
|
||||
This section documents the functions for managing a history file.
|
||||
|
||||
- Function: int read_history (char *filename)
|
||||
Add the contents of FILENAME to the history list, a line at a
|
||||
time. If FILENAME is `NULL', then read from `~/.history'.
|
||||
Returns 0 if successful, or errno if not.
|
||||
|
||||
- Function: int read_history_range (char *filename, int from, int to)
|
||||
Read a range of lines from FILENAME, adding them to the history
|
||||
list. Start reading at line FROM and end at TO. If FROM is zero,
|
||||
start at the beginning. If TO is less than FROM, then read until
|
||||
the end of the file. If FILENAME is `NULL', then read from
|
||||
`~/.history'. Returns 0 if successful, or `errno' if not.
|
||||
|
||||
- Function: int write_history (char *filename)
|
||||
Write the current history to FILENAME, overwriting FILENAME if
|
||||
necessary. If FILENAME is `NULL', then write the history list to
|
||||
`~/.history'. Values returned are as in `read_history ()'.
|
||||
|
||||
- Function: int append_history (int nelements, char *filename)
|
||||
Append the last NELEMENTS of the history list to FILENAME.
|
||||
|
||||
- Function: int history_truncate_file (char *filename, int nlines)
|
||||
Truncate the history file FILENAME, leaving only the last NLINES
|
||||
lines.
|
||||
|
||||
|
||||
File: history.info, Node: History Expansion, Prev: Managing the History File, Up: History Functions
|
||||
|
||||
History Expansion
|
||||
-----------------
|
||||
|
||||
These functions implement `csh'-like history expansion.
|
||||
|
||||
- Function: int history_expand (char *string, char **output)
|
||||
Expand STRING, placing the result into OUTPUT, a pointer to a
|
||||
string (*note History Interaction::.). Returns:
|
||||
`0'
|
||||
If no expansions took place (or, if the only change in the
|
||||
text was the de-slashifying of the history expansion
|
||||
character);
|
||||
|
||||
`1'
|
||||
if expansions did take place;
|
||||
|
||||
`-1'
|
||||
if there was an error in expansion;
|
||||
|
||||
`2'
|
||||
if the returned line should only be displayed, but not
|
||||
executed, as with the `:p' modifier (*note Modifiers::.).
|
||||
|
||||
If an error ocurred in expansion, then OUTPUT contains a
|
||||
descriptive error message.
|
||||
|
||||
- Function: char * history_arg_extract (int first, int last, char
|
||||
*string)
|
||||
Extract a string segment consisting of the FIRST through LAST
|
||||
arguments present in STRING. Arguments are broken up as in Bash.
|
||||
|
||||
- Function: char * get_history_event (char *string, int *cindex, int
|
||||
qchar)
|
||||
Returns the text of the history event beginning at STRING +
|
||||
*CINDEX. *CINDEX is modified to point to after the event
|
||||
specifier. At function entry, CINDEX points to the index into
|
||||
STRING where the history event specification begins. QCHAR is a
|
||||
character that is allowed to end the event specification in
|
||||
addition to the "normal" terminating characters.
|
||||
|
||||
- Function: char ** history_tokenize (char *string)
|
||||
Return an array of tokens parsed out of STRING, much as the shell
|
||||
might. The tokens are split on white space and on the characters
|
||||
`()<>;&|$', and shell quoting conventions are obeyed.
|
||||
|
||||
|
||||
File: history.info, Node: History Variables, Next: History Programming Example, Prev: History Functions, Up: Programming with GNU History
|
||||
|
||||
History Variables
|
||||
=================
|
||||
|
||||
This section describes the externally visible variables exported by
|
||||
the GNU History Library.
|
||||
|
||||
- Variable: int history_base
|
||||
The logical offset of the first entry in the history list.
|
||||
|
||||
- Variable: int history_length
|
||||
The number of entries currently stored in the history list.
|
||||
|
||||
- Variable: int max_input_history
|
||||
The maximum number of history entries. This must be changed using
|
||||
`stifle_history ()'.
|
||||
|
||||
- Variable: char history_expansion_char
|
||||
The character that starts a history event. The default is `!'.
|
||||
|
||||
- Variable: char history_subst_char
|
||||
The character that invokes word substitution if found at the start
|
||||
of a line. The default is `^'.
|
||||
|
||||
- Variable: char history_comment_char
|
||||
During tokenization, if this character is seen as the first
|
||||
character of a word, then it and all subsequent characters up to a
|
||||
newline are ignored, suppressing history expansion for the
|
||||
remainder of the line. This is disabled by default.
|
||||
|
||||
- Variable: char * history_no_expand_chars
|
||||
The list of characters which inhibit history expansion if found
|
||||
immediately following HISTORY_EXPANSION_CHAR. The default is
|
||||
whitespace and `='.
|
||||
|
||||
|
||||
File: history.info, Node: History Programming Example, Prev: History Variables, Up: Programming with GNU History
|
||||
|
||||
History Programming Example
|
||||
===========================
|
||||
|
||||
The following program demonstrates simple use of the GNU History
|
||||
Library.
|
||||
|
||||
main ()
|
||||
{
|
||||
char line[1024], *t;
|
||||
int len, done = 0;
|
||||
|
||||
line[0] = 0;
|
||||
|
||||
using_history ();
|
||||
while (!done)
|
||||
{
|
||||
printf ("history$ ");
|
||||
fflush (stdout);
|
||||
t = fgets (line, sizeof (line) - 1, stdin);
|
||||
if (t && *t)
|
||||
{
|
||||
len = strlen (t);
|
||||
if (t[len - 1] == '\n')
|
||||
t[len - 1] = '\0';
|
||||
}
|
||||
|
||||
if (!t)
|
||||
strcpy (line, "quit");
|
||||
|
||||
if (line[0])
|
||||
{
|
||||
char *expansion;
|
||||
int result;
|
||||
|
||||
result = history_expand (line, &expansion);
|
||||
if (result)
|
||||
fprintf (stderr, "%s\n", expansion);
|
||||
|
||||
if (result < 0 || result == 2)
|
||||
{
|
||||
free (expansion);
|
||||
continue;
|
||||
}
|
||||
|
||||
add_history (expansion);
|
||||
strncpy (line, expansion, sizeof (line) - 1);
|
||||
free (expansion);
|
||||
}
|
||||
|
||||
if (strcmp (line, "quit") == 0)
|
||||
done = 1;
|
||||
else if (strcmp (line, "save") == 0)
|
||||
write_history ("history_file");
|
||||
else if (strcmp (line, "read") == 0)
|
||||
read_history ("history_file");
|
||||
else if (strcmp (line, "list") == 0)
|
||||
{
|
||||
register HIST_ENTRY **the_list;
|
||||
register int i;
|
||||
|
||||
the_list = history_list ();
|
||||
if (the_list)
|
||||
for (i = 0; the_list[i]; i++)
|
||||
printf ("%d: %s\n", i + history_base, the_list[i]->line);
|
||||
}
|
||||
else if (strncmp (line, "delete", 6) == 0)
|
||||
{
|
||||
int which;
|
||||
if ((sscanf (line + 6, "%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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File: history.info, Node: Concept Index, Next: Function and Variable Index, Prev: Programming with GNU History, Up: Top
|
||||
|
||||
Concept Index
|
||||
*************
|
||||
|
||||
* Menu:
|
||||
|
||||
* anchored search: Searching the History List.
|
||||
* event designators: Event Designators.
|
||||
* expansion: History Interaction.
|
||||
* history events: Event Designators.
|
||||
* History Searching: Searching the History List.
|
||||
|
||||
|
||||
File: history.info, Node: Function and Variable Index, Prev: Concept Index, Up: Top
|
||||
|
||||
Function and Variable Index
|
||||
***************************
|
||||
|
||||
* Menu:
|
||||
|
||||
* add_history: History List Management.
|
||||
* append_history: Managing the History File.
|
||||
* current_history: Information About the History List.
|
||||
* get_history_event: History Expansion.
|
||||
* history_arg_extract: History Expansion.
|
||||
* history_base: History Variables.
|
||||
* history_comment_char: History Variables.
|
||||
* history_expand: History Expansion.
|
||||
* history_expansion_char: History Variables.
|
||||
* history_get: Information About the History List.
|
||||
* history_get_history_state: Initializing History and State Management.
|
||||
* history_is_stifled: History List Management.
|
||||
* history_length: History Variables.
|
||||
* history_list: Information About the History List.
|
||||
* history_no_expand_chars: History Variables.
|
||||
* history_search: Searching the History List.
|
||||
* history_search_pos: Searching the History List.
|
||||
* history_search_prefix: Searching the History List.
|
||||
* history_set_history_state: Initializing History and State Management.
|
||||
* history_set_pos: Moving Around the History List.
|
||||
* history_subst_char: History Variables.
|
||||
* history_tokenize: History Expansion.
|
||||
* history_total_bytes: Information About the History List.
|
||||
* history_truncate_file: Managing the History File.
|
||||
* max_input_history: History Variables.
|
||||
* next_history: Moving Around the History List.
|
||||
* previous_history: Moving Around the History List.
|
||||
* read_history: Managing the History File.
|
||||
* read_history_range: Managing the History File.
|
||||
* remove_history: History List Management.
|
||||
* replace_history_entry: History List Management.
|
||||
* stifle_history: History List Management.
|
||||
* unstifle_history: History List Management.
|
||||
* using_history: Initializing History and State Management.
|
||||
* where_history: Information About the History List.
|
||||
* write_history: Managing the History File.
|
||||
|
||||
|
||||
|
||||
Tag Table:
|
||||
Node: Top975
|
||||
Node: Using History Interactively1569
|
||||
Node: History Interaction2077
|
||||
Node: Event Designators3122
|
||||
Node: Word Designators3952
|
||||
Node: Modifiers4936
|
||||
Node: Programming with GNU History6065
|
||||
Node: Introduction to History6791
|
||||
Node: History Storage8112
|
||||
Node: History Functions9205
|
||||
Node: Initializing History and State Management10176
|
||||
Node: History List Management10968
|
||||
Node: Information About the History List12396
|
||||
Node: Moving Around the History List13702
|
||||
Node: Searching the History List14587
|
||||
Node: Managing the History File16419
|
||||
Node: History Expansion17925
|
||||
Node: History Variables19769
|
||||
Node: History Programming Example21138
|
||||
Node: Concept Index23742
|
||||
Node: Function and Variable Index24223
|
||||
|
||||
End Tag Table
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
@ignore
|
||||
This file documents the user interface to the GNU History library.
|
||||
|
||||
Copyright (C) 1988, 1991 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988, 1991, 1994, 1996 Free Software Foundation, Inc.
|
||||
Authored by Brian Fox and Chet Ramey.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of this manual
|
||||
@@ -168,6 +168,10 @@ 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 deftypefun
|
||||
|
||||
@deftypefun void clear_history ()
|
||||
Clear the history list by deleting all the entries.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun void stifle_history (int max)
|
||||
Stifle the history list, remembering only the last @var{max} entries.
|
||||
@end deftypefun
|
||||
@@ -400,6 +404,17 @@ following @var{history_expansion_char}. The default is whitespace and
|
||||
@samp{=}.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar {char *} history_search_delimiter_chars
|
||||
The list of additional characters which can delimit a history search
|
||||
string, in addition to whitespace, @samp{:} and @samp{?} in the case of
|
||||
a substring search. The default is empty.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar int history_quotes_inhibit_expansion
|
||||
If non-zero, single-quoted words are not scanned for the history expansion
|
||||
character. The default value is 0.
|
||||
@end deftypevar
|
||||
|
||||
@node History Programming Example
|
||||
@section History Programming Example
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@ignore
|
||||
This file documents the user interface to the GNU History library.
|
||||
|
||||
Copyright (C) 1988, 1991 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988, 1991, 1996 Free Software Foundation, Inc.
|
||||
Authored by Brian Fox and Chet Ramey.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of this manual
|
||||
@@ -39,26 +39,124 @@ information on using the GNU History Library in your own programs,
|
||||
@pxref{Programming with GNU History}.
|
||||
@end ifclear
|
||||
|
||||
@ifset BashFeatures
|
||||
@menu
|
||||
* Bash History Facilities:: How Bash lets you manipulate your command
|
||||
history.
|
||||
* History Interaction:: What it feels like using History as a user.
|
||||
@end menu
|
||||
@end ifset
|
||||
@ifclear BashFeatures
|
||||
@menu
|
||||
* History Interaction:: What it feels like using History as a user.
|
||||
@end menu
|
||||
@end ifclear
|
||||
|
||||
@ifset BashFeatures
|
||||
@node Bash History Facilities
|
||||
@section Bash History Facilities
|
||||
@cindex command history
|
||||
@cindex history list
|
||||
|
||||
When the @samp{-o history} option to the @code{set} builtin
|
||||
is enabled (@pxref{The Set Builtin}),
|
||||
the shell provides access to the @var{command history},
|
||||
the list of commands previously typed. The text of the last
|
||||
@code{HISTSIZE}
|
||||
commands (default 500) is saved in a history list. The shell
|
||||
stores each command in the history list prior to parameter and
|
||||
variable expansion
|
||||
but after history expansion is performed, subject to the
|
||||
values of the shell variables
|
||||
@code{HISTIGNORE} and @code{HISTCONTROL}.
|
||||
When the shell starts up, the history is initialized from the
|
||||
file named by the @code{HISTFILE} variable (default @file{~/.bash_history}).
|
||||
@code{HISTFILE} is truncated, if necessary, to contain no more than
|
||||
the number of lines specified by the value of the @code{HISTFILESIZE}
|
||||
variable. When an interactive shell exits, the last
|
||||
@code{HISTSIZE} lines are copied from the history list to @code{HISTFILE}.
|
||||
If the @code{histappend} shell option is set (@pxref{Bash Builtins}),
|
||||
the lines are appended to the history file,
|
||||
otherwise the history file is overwritten.
|
||||
If @code{HISTFILE}
|
||||
is unset, or if the history file is unwritable, the history is
|
||||
not saved. After saving the history, the history file is truncated
|
||||
to contain no more than @code{$HISTFILESIZE}
|
||||
lines. If @code{HISTFILESIZE} is not set, no truncation is performed.
|
||||
|
||||
The builtin command @code{fc} (@pxref{Korn Shell Builtins})
|
||||
may be used to list or edit and re-execute a portion of
|
||||
the history list. The @code{history} builtin (@pxref{C Shell Builtins})
|
||||
can be used to display or modify the history list and
|
||||
manipulate the history file.
|
||||
When using the command-line editing, search commands
|
||||
are available in each editing mode that provide access to the
|
||||
history list.
|
||||
|
||||
The shell allows control over which commands are saved on the history
|
||||
list. The @code{HISTCONTROL} and @code{HISTIGNORE}
|
||||
variables may be set to cause the shell to save only a subset of the
|
||||
commands entered.
|
||||
The @code{cmdhist}
|
||||
shell option, if enabled, causes the shell to attempt to save each
|
||||
line of a multi-line command in the same history entry, adding
|
||||
semicolons where necessary to preserve syntactic correctness.
|
||||
The @code{lithist}
|
||||
shell option causes the shell to save the command with embedded newlines
|
||||
instead of semicolons.
|
||||
@xref{Bash Builtins} for a description of @code{shopt}.
|
||||
@end ifset
|
||||
|
||||
@node History Interaction
|
||||
@section History Interaction
|
||||
@cindex expansion
|
||||
@section Interactive History Expansion
|
||||
@cindex history expansion
|
||||
|
||||
The History library provides a history expansion feature that is similar
|
||||
to the history expansion provided by @code{csh}. The following text
|
||||
to the history expansion provided by @code{csh}. This section
|
||||
describes the syntax used to manipulate the history information.
|
||||
|
||||
History expansions introduce words from the history list into
|
||||
the input stream, making it easy to repeat commands, insert the
|
||||
arguments to a previous command into the current input line, or
|
||||
fix errors in previous commands quickly.
|
||||
|
||||
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
|
||||
called @dfn{words}. Various @dfn{modifiers} are available to manipulate
|
||||
the selected words. The line is broken into words in the same fashion
|
||||
that Bash does, so that several English (or Unix) words
|
||||
surrounded by quotes are considered as one word.
|
||||
History expansions are introduced by the appearance of the
|
||||
history expansion character, which is @samp{!} by default.
|
||||
@ifset BashFeatures
|
||||
Only @samp{\} and @samp{'} may be used to escape the history expansion
|
||||
character.
|
||||
@end ifset
|
||||
|
||||
@ifset BashFeatures
|
||||
Several shell options settable with the @code{shopt}
|
||||
builtin (@pxref{Bash Builtins}) may be used to tailor
|
||||
the behavior of history expansion. If the
|
||||
@code{histverify} shell option is enabled, and Readline
|
||||
is being used, history substitutions are not immediately passed to
|
||||
the shell parser.
|
||||
Instead, the expanded line is reloaded into the Readline
|
||||
editing buffer for further modification.
|
||||
If Readline is being used, and the @code{histreedit}
|
||||
shell option is enabled, a failed history expansion will be
|
||||
reloaded into the Readline editing buffer for correction.
|
||||
The @samp{-p} option to the @code{history} builtin command
|
||||
may be used to see what a history expansion will do before using it.
|
||||
The @samp{-s} option to the @code{history} builtin may be used to
|
||||
add commands to the end of the history list without actually executing
|
||||
them, so that they are available for subsequent recall.
|
||||
|
||||
The shell allows control of the various characters used by the
|
||||
history expansion mechanism with the @code{histchars} variable.
|
||||
@end ifset
|
||||
|
||||
@menu
|
||||
* Event Designators:: How to specify which history line to use.
|
||||
@@ -80,92 +178,100 @@ history list.
|
||||
Start a history substitution, except when followed by a space, tab,
|
||||
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}
|
||||
@item @code{!@var{n}}
|
||||
Refer to command line @var{n}.
|
||||
|
||||
@item @code{!-n}
|
||||
@item @code{!-@var{n}}
|
||||
Refer to the command @var{n} lines back.
|
||||
|
||||
@item @code{!string}
|
||||
@item @code{!!}
|
||||
Refer to the previous command. This is a synonym for @samp{!-1}.
|
||||
|
||||
@item @code{!@var{string}}
|
||||
Refer to the most recent command starting with @var{string}.
|
||||
|
||||
@item @code{!?string}[@code{?}]
|
||||
Refer to the most recent command containing @var{string}.
|
||||
@item @code{!?@var{string}[?]}
|
||||
Refer to the most recent command containing @var{string}. The trailing
|
||||
@samp{?} may be omitted if the @var{string} is followed immediately by
|
||||
a newline.
|
||||
|
||||
@item @code{^@var{string1}^@var{string2}^}
|
||||
Quick Substitution. Repeat the last command, replacing @var{string1}
|
||||
with @var{string2}. Equivalent to
|
||||
@code{!!:s/@var{string1}/@var{string2}/}.
|
||||
|
||||
@item @code{!#}
|
||||
The entire command line typed so far.
|
||||
|
||||
@item @code{^string1^string2^}
|
||||
Quick Substitution. Repeat the last command, replacing @var{string1}
|
||||
with @var{string2}. Equivalent to
|
||||
@code{!!:s/string1/string2/}.
|
||||
|
||||
@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).
|
||||
Word designators are used to select desired words from the event.
|
||||
A @samp{:} separates the event specification from the word designator. It
|
||||
can be omitted if the word designator begins with a @samp{^}, @samp{$},
|
||||
@samp{*}, @samp{-}, or @samp{%}. Words are numbered from the beginning
|
||||
of the line, with the first word being denoted by 0 (zero). Words are
|
||||
inserted into the current line separated by single spaces.
|
||||
|
||||
@table @code
|
||||
|
||||
@item 0 (zero)
|
||||
The @code{0}th word. For many applications, this is the command word.
|
||||
|
||||
@item n
|
||||
@item @var{n}
|
||||
The @var{n}th word.
|
||||
|
||||
@item ^
|
||||
The first argument; that is, word 1.
|
||||
The first argument; that is, word 1.
|
||||
|
||||
@item $
|
||||
The last argument.
|
||||
|
||||
@item %
|
||||
The word matched by the most recent @code{?string?} search.
|
||||
The word matched by the most recent @samp{?@var{string}?} search.
|
||||
|
||||
@item x-y
|
||||
A range of words; @code{-@var{y}} abbreviates @code{0-@var{y}}.
|
||||
@item @var{x}-@var{y}
|
||||
A range of words; @samp{-@var{y}} abbreviates @samp{0-@var{y}}.
|
||||
|
||||
@item *
|
||||
All of the words, except the @code{0}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;
|
||||
All of the words, except the @code{0}th. This is a synonym for @samp{1-$}.
|
||||
It is not an error to use @samp{*} if there is just one word in the event;
|
||||
the empty string is returned in that case.
|
||||
|
||||
@item x*
|
||||
Abbreviates @code{x-$}
|
||||
@item @var{x}*
|
||||
Abbreviates @samp{@var{x}-$}
|
||||
|
||||
@item x-
|
||||
Abbreviates @code{x-$} like @code{x*}, but omits the last word.
|
||||
@item @var{x}-
|
||||
Abbreviates @samp{@var{x}-$} like @samp{@var{x}*}, but omits the last word.
|
||||
|
||||
@end table
|
||||
|
||||
If a word designator is supplied without an event specification, the
|
||||
previous command is used as the event.
|
||||
|
||||
@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{:}.
|
||||
of the following modifiers, each preceded by a @samp{:}.
|
||||
|
||||
@table @code
|
||||
|
||||
@item h
|
||||
Remove a trailing pathname component, leaving only the head.
|
||||
|
||||
@item t
|
||||
Remove all leading pathname components, leaving the tail.
|
||||
|
||||
@item r
|
||||
Remove a trailing suffix of the form @samp{.}@var{suffix}, leaving the basename.
|
||||
Remove a trailing suffix of the form @samp{.@var{suffix}}, leaving
|
||||
the basename.
|
||||
|
||||
@item e
|
||||
Remove all but the trailing suffix.
|
||||
|
||||
@item t
|
||||
Remove all leading pathname components, leaving the tail.
|
||||
|
||||
@item p
|
||||
Print the new command but do not execute it.
|
||||
|
||||
@@ -174,17 +280,17 @@ Print the new command but do not execute it.
|
||||
Quote the substituted words, escaping further substitutions.
|
||||
|
||||
@item x
|
||||
Quote the substituted words as with @code{q},
|
||||
Quote the substituted words as with @samp{q},
|
||||
but break into words at spaces, tabs, and newlines.
|
||||
@end ifset
|
||||
|
||||
@item s/old/new/
|
||||
@item s/@var{old}/@var{new}/
|
||||
Substitute @var{new} for the first occurrence of @var{old} in the
|
||||
event line. Any delimiter may be used in place of @key{/}.
|
||||
event line. Any delimiter may be used in place of @samp{/}.
|
||||
The delimiter may be quoted in @var{old} and @var{new}
|
||||
with a single backslash. If @key{&} appears in @var{new},
|
||||
with a single backslash. If @samp{&} appears in @var{new},
|
||||
it is replaced by @var{old}. A single backslash will quote
|
||||
the @key{&}. The final delimiter is optional if it is the last
|
||||
the @samp{&}. The final delimiter is optional if it is the last
|
||||
character on the input line.
|
||||
|
||||
@item &
|
||||
@@ -192,7 +298,7 @@ Repeat the previous substitution.
|
||||
|
||||
@item g
|
||||
Cause changes to be applied over the entire event line. Used in
|
||||
conjunction with @code{s}, as in @code{gs/old/new/}, or with
|
||||
@code{&}.
|
||||
conjunction with @samp{s}, as in @code{gs/@var{old}/@var{new}/},
|
||||
or with @samp{&}.
|
||||
|
||||
@end table
|
||||
|
||||
Binary file not shown.
@@ -1,744 +0,0 @@
|
||||
This is Info file history.info, produced by Makeinfo-1.55 from the
|
||||
input file hist.texinfo.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
File: history.info, Node: Top, Next: Using History Interactively, Prev: (DIR), Up: (DIR)
|
||||
|
||||
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.
|
||||
|
||||
|
||||
File: history.info, Node: Using History Interactively, Next: Programming with GNU History, Prev: Top, Up: Top
|
||||
|
||||
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, *note Programming with GNU History::..
|
||||
|
||||
* Menu:
|
||||
|
||||
* History Interaction:: What it feels like using History as a user.
|
||||
|
||||
|
||||
File: history.info, Node: History Interaction, Up: Using History Interactively
|
||||
|
||||
History Interaction
|
||||
===================
|
||||
|
||||
The History library provides a history expansion feature that is
|
||||
similar to the history expansion provided by `csh'. The following text
|
||||
describes the syntax used 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 "event", and the portions of that line that are
|
||||
acted upon are called "words". The line is broken into words in the
|
||||
same fashion that Bash 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 substitution.
|
||||
|
||||
|
||||
File: history.info, Node: Event Designators, Next: Word Designators, Up: History Interaction
|
||||
|
||||
Event Designators
|
||||
-----------------
|
||||
|
||||
An event designator is a reference to a command line entry in the
|
||||
history list.
|
||||
|
||||
`!'
|
||||
Start a history substitution, except when followed by a space, tab,
|
||||
the end of the line, = or (.
|
||||
|
||||
`!!'
|
||||
Refer to the previous command. This is a synonym for `!-1'.
|
||||
|
||||
`!n'
|
||||
Refer to command line N.
|
||||
|
||||
`!-n'
|
||||
Refer to the command N lines back.
|
||||
|
||||
`!string'
|
||||
Refer to the most recent command starting with STRING.
|
||||
|
||||
`!?string'[`?']
|
||||
Refer to the most recent command containing STRING.
|
||||
|
||||
`!#'
|
||||
The entire command line typed so far.
|
||||
|
||||
`^string1^string2^'
|
||||
Quick Substitution. Repeat the last command, replacing STRING1
|
||||
with STRING2. Equivalent to `!!:s/string1/string2/'.
|
||||
|
||||
|
||||
File: history.info, Node: Word Designators, Next: Modifiers, Prev: Event Designators, Up: History Interaction
|
||||
|
||||
Word Designators
|
||||
----------------
|
||||
|
||||
A : separates the event specification from the word designator. It
|
||||
can be omitted if the word designator begins with a ^, $, * or %.
|
||||
Words are numbered from the beginning of the line, with the first word
|
||||
being denoted by a 0 (zero).
|
||||
|
||||
`0 (zero)'
|
||||
The `0'th word. For many applications, this is the command word.
|
||||
|
||||
`n'
|
||||
The Nth word.
|
||||
|
||||
`^'
|
||||
The first argument; that is, word 1.
|
||||
|
||||
`$'
|
||||
The last argument.
|
||||
|
||||
`%'
|
||||
The word matched by the most recent `?string?' search.
|
||||
|
||||
`x-y'
|
||||
A range of words; `-Y' abbreviates `0-Y'.
|
||||
|
||||
`*'
|
||||
All of the words, except the `0'th. This is a synonym for `1-$'.
|
||||
It is not an error to use * if there is just one word in the event;
|
||||
the empty string is returned in that case.
|
||||
|
||||
`x*'
|
||||
Abbreviates `x-$'
|
||||
|
||||
`x-'
|
||||
Abbreviates `x-$' like `x*', but omits the last word.
|
||||
|
||||
|
||||
File: history.info, Node: Modifiers, Prev: Word Designators, Up: History Interaction
|
||||
|
||||
Modifiers
|
||||
---------
|
||||
|
||||
After the optional word designator, you can add a sequence of one or
|
||||
more of the following modifiers, each preceded by a :.
|
||||
|
||||
`h'
|
||||
Remove a trailing pathname component, leaving only the head.
|
||||
|
||||
`r'
|
||||
Remove a trailing suffix of the form `.'SUFFIX, leaving the
|
||||
basename.
|
||||
|
||||
`e'
|
||||
Remove all but the trailing suffix.
|
||||
|
||||
`t'
|
||||
Remove all leading pathname components, leaving the tail.
|
||||
|
||||
`p'
|
||||
Print the new command but do not execute it.
|
||||
|
||||
`s/old/new/'
|
||||
Substitute NEW for the first occurrence of OLD in the event line.
|
||||
Any delimiter may be used in place of /. The delimiter may be
|
||||
quoted in OLD and NEW with a single backslash. If & appears in
|
||||
NEW, it is replaced by OLD. A single backslash will quote the &.
|
||||
The final delimiter is optional if it is the last character on the
|
||||
input line.
|
||||
|
||||
`&'
|
||||
Repeat the previous substitution.
|
||||
|
||||
`g'
|
||||
Cause changes to be applied over the entire event line. Used in
|
||||
conjunction with `s', as in `gs/old/new/', or with `&'.
|
||||
|
||||
|
||||
File: history.info, Node: Programming with GNU History, Next: Concept Index, Prev: Using History Interactively, Up: Top
|
||||
|
||||
Programming with GNU History
|
||||
****************************
|
||||
|
||||
This chapter describes how to interface programs that you write with
|
||||
the GNU History Library. It should be considered a technical guide.
|
||||
For information on the interactive use of GNU History, *note 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.
|
||||
|
||||
|
||||
File: history.info, Node: Introduction to History, Next: History Storage, Up: Programming with GNU History
|
||||
|
||||
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 composing new ones.
|
||||
|
||||
The programmer using the History library has available functions for
|
||||
remembering lines on a history list, associating arbitrary data with a
|
||||
line, removing lines from the list, searching through the list for a
|
||||
line containing an arbitrary text string, and referencing any line in
|
||||
the list directly. In addition, a history "expansion" function is
|
||||
available which provides for a consistent user interface across
|
||||
different programs.
|
||||
|
||||
The user using programs written with the History library has the
|
||||
benefit 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 provided by `csh'.
|
||||
|
||||
If the programmer desires, he can use the Readline library, which
|
||||
includes some history manipulation by default, and has the added
|
||||
advantage of command line editing.
|
||||
|
||||
|
||||
File: history.info, Node: History Storage, Next: History Functions, Prev: Introduction to History, Up: Programming with GNU History
|
||||
|
||||
History Storage
|
||||
===============
|
||||
|
||||
The history list is an array of history entries. A history entry is
|
||||
declared as follows:
|
||||
|
||||
typedef struct _hist_entry {
|
||||
char *line;
|
||||
char *data;
|
||||
} HIST_ENTRY;
|
||||
|
||||
The history list itself might therefore be declared as
|
||||
|
||||
HIST_ENTRY **the_history_list;
|
||||
|
||||
The state of the History library is encapsulated into a single
|
||||
structure:
|
||||
|
||||
/* A structure used to pass the current state of the history stuff around. */
|
||||
typedef struct _hist_state {
|
||||
HIST_ENTRY **entries; /* Pointer to the entries themselves. */
|
||||
int offset; /* The location pointer within this array. */
|
||||
int length; /* Number of elements within this array. */
|
||||
int size; /* Number of slots allocated to this array. */
|
||||
int flags;
|
||||
} HISTORY_STATE;
|
||||
|
||||
If the flags member includes `HS_STIFLED', the history has been
|
||||
stifled.
|
||||
|
||||
|
||||
File: history.info, Node: History Functions, Next: History Variables, Prev: History Storage, Up: Programming with GNU History
|
||||
|
||||
History Functions
|
||||
=================
|
||||
|
||||
This section describes the calling sequence for the various functions
|
||||
present in GNU History.
|
||||
|
||||
* Menu:
|
||||
|
||||
* Initializing History and State Management:: Functions to call when you
|
||||
want to use history in a
|
||||
program.
|
||||
* History List Management:: Functions used to manage the list
|
||||
of history entries.
|
||||
* Information About the History List:: Functions returning information about
|
||||
the history list.
|
||||
* Moving Around the History List:: Functions used to change the position
|
||||
in the history list.
|
||||
* Searching the History List:: Functions to search the history list
|
||||
for entries containing a string.
|
||||
* Managing the History File:: Functions that read and write a file
|
||||
containing the history list.
|
||||
* History Expansion:: Functions to perform csh-like history
|
||||
expansion.
|
||||
|
||||
|
||||
File: history.info, Node: Initializing History and State Management, Next: History List Management, Up: History Functions
|
||||
|
||||
Initializing History and State Management
|
||||
-----------------------------------------
|
||||
|
||||
This section describes functions used to initialize and manage the
|
||||
state of the History library when you want to use the history functions
|
||||
in your program.
|
||||
|
||||
- Function: void using_history ()
|
||||
Begin a session in which the history functions might be used. This
|
||||
initializes the interactive variables.
|
||||
|
||||
- Function: HISTORY_STATE * history_get_history_state ()
|
||||
Return a structure describing the current state of the input
|
||||
history.
|
||||
|
||||
- Function: void history_set_history_state (HISTORY_STATE *state)
|
||||
Set the state of the history list according to STATE.
|
||||
|
||||
|
||||
File: history.info, Node: History List Management, Next: Information About the History List, Prev: Initializing History and State Management, Up: History Functions
|
||||
|
||||
History List Management
|
||||
-----------------------
|
||||
|
||||
These functions manage individual entries on the history list, or set
|
||||
parameters managing the list itself.
|
||||
|
||||
- Function: void add_history (char *string)
|
||||
Place STRING at the end of the history list. The associated data
|
||||
field (if any) is set to `NULL'.
|
||||
|
||||
- Function: HIST_ENTRY * remove_history (int which)
|
||||
Remove history entry at offset WHICH from the history. The
|
||||
removed element is returned so you can free the line, data, and
|
||||
containing structure.
|
||||
|
||||
- Function: HIST_ENTRY * replace_history_entry (int which, char *line,
|
||||
char *data)
|
||||
Make the history entry at offset WHICH have LINE and DATA. This
|
||||
returns the old entry so you can dispose of the data. In the case
|
||||
of an invalid WHICH, a `NULL' pointer is returned.
|
||||
|
||||
- Function: void stifle_history (int max)
|
||||
Stifle the history list, remembering only the last MAX entries.
|
||||
|
||||
- Function: int unstifle_history ()
|
||||
Stop stifling the history. This returns the previous amount the
|
||||
history was stifled. The value is positive if the history was
|
||||
stifled, negative if it wasn't.
|
||||
|
||||
- Function: int history_is_stifled ()
|
||||
Returns non-zero if the history is stifled, zero if it is not.
|
||||
|
||||
|
||||
File: history.info, Node: Information About the History List, Next: Moving Around the History List, Prev: History List Management, Up: History Functions
|
||||
|
||||
Information About the History List
|
||||
----------------------------------
|
||||
|
||||
These functions return information about the entire history list or
|
||||
individual list entries.
|
||||
|
||||
- Function: HIST_ENTRY ** history_list ()
|
||||
Return a `NULL' terminated array of `HIST_ENTRY' which is the
|
||||
current input history. Element 0 of this list is the beginning of
|
||||
time. If there is no history, return `NULL'.
|
||||
|
||||
- Function: int where_history ()
|
||||
Returns the offset of the current history element.
|
||||
|
||||
- Function: HIST_ENTRY * current_history ()
|
||||
Return the history entry at the current position, as determined by
|
||||
`where_history ()'. If there is no entry there, return a `NULL'
|
||||
pointer.
|
||||
|
||||
- Function: HIST_ENTRY * history_get (int offset)
|
||||
Return the history entry at position OFFSET, starting from
|
||||
`history_base'. If there is no entry there, or if OFFSET is
|
||||
greater than the history length, return a `NULL' pointer.
|
||||
|
||||
- Function: int history_total_bytes ()
|
||||
Return the number of bytes that the primary history entries are
|
||||
using. This function returns the sum of the lengths of all the
|
||||
lines in the history.
|
||||
|
||||
|
||||
File: history.info, Node: Moving Around the History List, Next: Searching the History List, Prev: Information About the History List, Up: History Functions
|
||||
|
||||
Moving Around the History List
|
||||
------------------------------
|
||||
|
||||
These functions allow the current index into the history list to be
|
||||
set or changed.
|
||||
|
||||
- Function: int history_set_pos (int pos)
|
||||
Set the position in the history list to POS, an absolute index
|
||||
into the list.
|
||||
|
||||
- Function: HIST_ENTRY * previous_history ()
|
||||
Back up the current history offset to the previous history entry,
|
||||
and return a pointer to that entry. If there is no previous
|
||||
entry, return a `NULL' pointer.
|
||||
|
||||
- Function: HIST_ENTRY * next_history ()
|
||||
Move the current history offset forward to the next history entry,
|
||||
and return the a pointer to that entry. If there is no next
|
||||
entry, return a `NULL' pointer.
|
||||
|
||||
|
||||
File: history.info, Node: Searching the History List, Next: Managing the History File, Prev: Moving Around the History List, Up: History Functions
|
||||
|
||||
Searching the History List
|
||||
--------------------------
|
||||
|
||||
These functions allow searching of the history list for entries
|
||||
containing a specific string. Searching may be performed both forward
|
||||
and backward from the current history position. The search may be
|
||||
"anchored", meaning that the string must match at the beginning of the
|
||||
history entry.
|
||||
|
||||
- Function: int history_search (char *string, int direction)
|
||||
Search the history for STRING, starting at the current history
|
||||
offset. If DIRECTION < 0, then the search is through previous
|
||||
entries, else through subsequent. If STRING is found, then the
|
||||
current history index is set to that history entry, and the value
|
||||
returned is the offset in the line of the entry where STRING was
|
||||
found. Otherwise, nothing is changed, and a -1 is returned.
|
||||
|
||||
- Function: int history_search_prefix (char *string, int direction)
|
||||
Search the history for STRING, starting at the current history
|
||||
offset. The search is anchored: matching lines must begin with
|
||||
STRING. If DIRECTION < 0, then the search is through previous
|
||||
entries, else through subsequent. If STRING is found, then the
|
||||
current history index is set to that entry, and the return value
|
||||
is 0. Otherwise, nothing is changed, and a -1 is returned.
|
||||
|
||||
- Function: int history_search_pos (char *string, int direction, int
|
||||
pos)
|
||||
Search for STRING in the history list, starting at POS, an
|
||||
absolute index into the list. If DIRECTION is negative, the search
|
||||
proceeds backward from POS, otherwise forward. Returns the
|
||||
absolute index of the history element where STRING was found, or
|
||||
-1 otherwise.
|
||||
|
||||
|
||||
File: history.info, Node: Managing the History File, Next: History Expansion, Prev: Searching the History List, Up: History Functions
|
||||
|
||||
Managing the History File
|
||||
-------------------------
|
||||
|
||||
The History library can read the history from and write it to a file.
|
||||
This section documents the functions for managing a history file.
|
||||
|
||||
- Function: int read_history (char *filename)
|
||||
Add the contents of FILENAME to the history list, a line at a
|
||||
time. If FILENAME is `NULL', then read from `~/.history'.
|
||||
Returns 0 if successful, or errno if not.
|
||||
|
||||
- Function: int read_history_range (char *filename, int from, int to)
|
||||
Read a range of lines from FILENAME, adding them to the history
|
||||
list. Start reading at line FROM and end at TO. If FROM is zero,
|
||||
start at the beginning. If TO is less than FROM, then read until
|
||||
the end of the file. If FILENAME is `NULL', then read from
|
||||
`~/.history'. Returns 0 if successful, or `errno' if not.
|
||||
|
||||
- Function: int write_history (char *filename)
|
||||
Write the current history to FILENAME, overwriting FILENAME if
|
||||
necessary. If FILENAME is `NULL', then write the history list to
|
||||
`~/.history'. Values returned are as in `read_history ()'.
|
||||
|
||||
- Function: int append_history (int nelements, char *filename)
|
||||
Append the last NELEMENTS of the history list to FILENAME.
|
||||
|
||||
- Function: int history_truncate_file (char *filename, int nlines)
|
||||
Truncate the history file FILENAME, leaving only the last NLINES
|
||||
lines.
|
||||
|
||||
|
||||
File: history.info, Node: History Expansion, Prev: Managing the History File, Up: History Functions
|
||||
|
||||
History Expansion
|
||||
-----------------
|
||||
|
||||
These functions implement `csh'-like history expansion.
|
||||
|
||||
- Function: int history_expand (char *string, char **output)
|
||||
Expand STRING, placing the result into OUTPUT, a pointer to a
|
||||
string (*note History Interaction::.). Returns:
|
||||
`0'
|
||||
If no expansions took place (or, if the only change in the
|
||||
text was the de-slashifying of the history expansion
|
||||
character);
|
||||
|
||||
`1'
|
||||
if expansions did take place;
|
||||
|
||||
`-1'
|
||||
if there was an error in expansion;
|
||||
|
||||
`2'
|
||||
if the returned line should only be displayed, but not
|
||||
executed, as with the `:p' modifier (*note Modifiers::.).
|
||||
|
||||
If an error ocurred in expansion, then OUTPUT contains a
|
||||
descriptive error message.
|
||||
|
||||
- Function: char * history_arg_extract (int first, int last, char
|
||||
*string)
|
||||
Extract a string segment consisting of the FIRST through LAST
|
||||
arguments present in STRING. Arguments are broken up as in Bash.
|
||||
|
||||
- Function: char * get_history_event (char *string, int *cindex, int
|
||||
qchar)
|
||||
Returns the text of the history event beginning at STRING +
|
||||
*CINDEX. *CINDEX is modified to point to after the event
|
||||
specifier. At function entry, CINDEX points to the index into
|
||||
STRING where the history event specification begins. QCHAR is a
|
||||
character that is allowed to end the event specification in
|
||||
addition to the "normal" terminating characters.
|
||||
|
||||
- Function: char ** history_tokenize (char *string)
|
||||
Return an array of tokens parsed out of STRING, much as the shell
|
||||
might. The tokens are split on white space and on the characters
|
||||
`()<>;&|$', and shell quoting conventions are obeyed.
|
||||
|
||||
|
||||
File: history.info, Node: History Variables, Next: History Programming Example, Prev: History Functions, Up: Programming with GNU History
|
||||
|
||||
History Variables
|
||||
=================
|
||||
|
||||
This section describes the externally visible variables exported by
|
||||
the GNU History Library.
|
||||
|
||||
- Variable: int history_base
|
||||
The logical offset of the first entry in the history list.
|
||||
|
||||
- Variable: int history_length
|
||||
The number of entries currently stored in the history list.
|
||||
|
||||
- Variable: int max_input_history
|
||||
The maximum number of history entries. This must be changed using
|
||||
`stifle_history ()'.
|
||||
|
||||
- Variable: char history_expansion_char
|
||||
The character that starts a history event. The default is `!'.
|
||||
|
||||
- Variable: char history_subst_char
|
||||
The character that invokes word substitution if found at the start
|
||||
of a line. The default is `^'.
|
||||
|
||||
- Variable: char history_comment_char
|
||||
During tokenization, if this character is seen as the first
|
||||
character of a word, then it and all subsequent characters up to a
|
||||
newline are ignored, suppressing history expansion for the
|
||||
remainder of the line. This is disabled by default.
|
||||
|
||||
- Variable: char * history_no_expand_chars
|
||||
The list of characters which inhibit history expansion if found
|
||||
immediately following HISTORY_EXPANSION_CHAR. The default is
|
||||
whitespace and `='.
|
||||
|
||||
|
||||
File: history.info, Node: History Programming Example, Prev: History Variables, Up: Programming with GNU History
|
||||
|
||||
History Programming Example
|
||||
===========================
|
||||
|
||||
The following program demonstrates simple use of the GNU History
|
||||
Library.
|
||||
|
||||
main ()
|
||||
{
|
||||
char line[1024], *t;
|
||||
int len, done = 0;
|
||||
|
||||
line[0] = 0;
|
||||
|
||||
using_history ();
|
||||
while (!done)
|
||||
{
|
||||
printf ("history$ ");
|
||||
fflush (stdout);
|
||||
t = fgets (line, sizeof (line) - 1, stdin);
|
||||
if (t && *t)
|
||||
{
|
||||
len = strlen (t);
|
||||
if (t[len - 1] == '\n')
|
||||
t[len - 1] = '\0';
|
||||
}
|
||||
|
||||
if (!t)
|
||||
strcpy (line, "quit");
|
||||
|
||||
if (line[0])
|
||||
{
|
||||
char *expansion;
|
||||
int result;
|
||||
|
||||
result = history_expand (line, &expansion);
|
||||
if (result)
|
||||
fprintf (stderr, "%s\n", expansion);
|
||||
|
||||
if (result < 0 || result == 2)
|
||||
{
|
||||
free (expansion);
|
||||
continue;
|
||||
}
|
||||
|
||||
add_history (expansion);
|
||||
strncpy (line, expansion, sizeof (line) - 1);
|
||||
free (expansion);
|
||||
}
|
||||
|
||||
if (strcmp (line, "quit") == 0)
|
||||
done = 1;
|
||||
else if (strcmp (line, "save") == 0)
|
||||
write_history ("history_file");
|
||||
else if (strcmp (line, "read") == 0)
|
||||
read_history ("history_file");
|
||||
else if (strcmp (line, "list") == 0)
|
||||
{
|
||||
register HIST_ENTRY **the_list;
|
||||
register int i;
|
||||
|
||||
the_list = history_list ();
|
||||
if (the_list)
|
||||
for (i = 0; the_list[i]; i++)
|
||||
printf ("%d: %s\n", i + history_base, the_list[i]->line);
|
||||
}
|
||||
else if (strncmp (line, "delete", 6) == 0)
|
||||
{
|
||||
int which;
|
||||
if ((sscanf (line + 6, "%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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File: history.info, Node: Concept Index, Next: Function and Variable Index, Prev: Programming with GNU History, Up: Top
|
||||
|
||||
Concept Index
|
||||
*************
|
||||
|
||||
* Menu:
|
||||
|
||||
* anchored search: Searching the History List.
|
||||
* event designators: Event Designators.
|
||||
* expansion: History Interaction.
|
||||
* history events: Event Designators.
|
||||
* History Searching: Searching the History List.
|
||||
|
||||
|
||||
File: history.info, Node: Function and Variable Index, Prev: Concept Index, Up: Top
|
||||
|
||||
Function and Variable Index
|
||||
***************************
|
||||
|
||||
* Menu:
|
||||
|
||||
* add_history: History List Management.
|
||||
* append_history: Managing the History File.
|
||||
* current_history: Information About the History List.
|
||||
* get_history_event: History Expansion.
|
||||
* history_arg_extract: History Expansion.
|
||||
* history_base: History Variables.
|
||||
* history_comment_char: History Variables.
|
||||
* history_expand: History Expansion.
|
||||
* history_expansion_char: History Variables.
|
||||
* history_get: Information About the History List.
|
||||
* history_get_history_state: Initializing History and State Management.
|
||||
* history_is_stifled: History List Management.
|
||||
* history_length: History Variables.
|
||||
* history_list: Information About the History List.
|
||||
* history_no_expand_chars: History Variables.
|
||||
* history_search: Searching the History List.
|
||||
* history_search_pos: Searching the History List.
|
||||
* history_search_prefix: Searching the History List.
|
||||
* history_set_history_state: Initializing History and State Management.
|
||||
* history_set_pos: Moving Around the History List.
|
||||
* history_subst_char: History Variables.
|
||||
* history_tokenize: History Expansion.
|
||||
* history_total_bytes: Information About the History List.
|
||||
* history_truncate_file: Managing the History File.
|
||||
* max_input_history: History Variables.
|
||||
* next_history: Moving Around the History List.
|
||||
* previous_history: Moving Around the History List.
|
||||
* read_history: Managing the History File.
|
||||
* read_history_range: Managing the History File.
|
||||
* remove_history: History List Management.
|
||||
* replace_history_entry: History List Management.
|
||||
* stifle_history: History List Management.
|
||||
* unstifle_history: History List Management.
|
||||
* using_history: Initializing History and State Management.
|
||||
* where_history: Information About the History List.
|
||||
* write_history: Managing the History File.
|
||||
|
||||
|
||||
|
||||
Tag Table:
|
||||
Node: Top975
|
||||
Node: Using History Interactively1569
|
||||
Node: History Interaction2077
|
||||
Node: Event Designators3122
|
||||
Node: Word Designators3952
|
||||
Node: Modifiers4936
|
||||
Node: Programming with GNU History6065
|
||||
Node: Introduction to History6791
|
||||
Node: History Storage8112
|
||||
Node: History Functions9205
|
||||
Node: Initializing History and State Management10176
|
||||
Node: History List Management10968
|
||||
Node: Information About the History List12396
|
||||
Node: Moving Around the History List13702
|
||||
Node: Searching the History List14587
|
||||
Node: Managing the History File16419
|
||||
Node: History Expansion17925
|
||||
Node: History Variables19769
|
||||
Node: History Programming Example21138
|
||||
Node: Concept Index23742
|
||||
Node: Function and Variable Index24223
|
||||
|
||||
End Tag Table
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,13 +7,13 @@
|
||||
@setchapternewpage odd
|
||||
|
||||
@ignore
|
||||
last change: Thu Jul 21 16:02:40 EDT 1994
|
||||
last change: Thu Mar 21 16:06:39 EST 1996
|
||||
@end ignore
|
||||
|
||||
@set EDITION 2.0
|
||||
@set VERSION 2.0
|
||||
@set UPDATED 21 July 1994
|
||||
@set UPDATE-MONTH July 1994
|
||||
@set EDITION 2.1
|
||||
@set VERSION 2.1
|
||||
@set UPDATED 21 March 1996
|
||||
@set UPDATE-MONTH March 1996
|
||||
|
||||
@ifinfo
|
||||
This document describes the GNU Readline Library, a utility which aids
|
||||
@@ -45,7 +45,6 @@ by the Foundation.
|
||||
@end ifinfo
|
||||
|
||||
@titlepage
|
||||
@sp 10
|
||||
@title GNU Readline Library
|
||||
@subtitle Edition @value{EDITION}, for @code{Readline Library} Version @value{VERSION}.
|
||||
@subtitle @value{UPDATE-MONTH}
|
||||
|
||||
@@ -8,7 +8,7 @@ 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, 1994 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988, 1994, 1996 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
@@ -273,6 +273,10 @@ The prompt Readline uses. This is set from the argument to
|
||||
@code{readline ()}, and should not be assigned to directly.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar {char *} rl_library_version
|
||||
The version number of this revision of the library.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar {char *} rl_terminal_name
|
||||
The terminal type, used for initialization.
|
||||
@end deftypevar
|
||||
@@ -301,6 +305,30 @@ If non-zero, this is the address of a function to call periodically
|
||||
when readline is waiting for terminal input.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar {Function *} rl_getc_function
|
||||
If non-zero, @code{readline} will call indirectly through this pointer
|
||||
to get a character from the input stream. By default, it is set to
|
||||
@code{rl_getc}, the default @code{readline} character input function
|
||||
(@pxref{Utility Functions}).
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar {Function *} rl_redisplay_function
|
||||
If non-zero, @code{readline} will call indirectly through this pointer
|
||||
to update the display with the current contents of the editing buffer.
|
||||
By default, it is set to @code{rl_redisplay}, the default @code{readline}
|
||||
redisplay function (@pxref{Redisplay}).
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar {Keymap} rl_executing_keymap
|
||||
This variable is set to the keymap (@pxref{Keymaps}) in which the
|
||||
currently executing readline function was found.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar {Keymap} rl_binding_keymap
|
||||
This variable is set to the keymap (@pxref{Keymaps}) in which the
|
||||
last key binding occurred.
|
||||
@end deftypevar
|
||||
|
||||
@node Readline Convenience Functions
|
||||
@section Readline Convenience Functions
|
||||
|
||||
@@ -314,6 +342,7 @@ when readline is waiting for terminal input.
|
||||
* Redisplay:: Functions to control line display.
|
||||
* Modifying Text:: Functions to modify @code{rl_line_buffer}.
|
||||
* Utility Functions:: Generally useful functions and hooks.
|
||||
* Alternate Interface:: Using Readline in a `callback' fashion.
|
||||
@end menu
|
||||
|
||||
@node Function Naming
|
||||
@@ -611,6 +640,10 @@ the input stream via @var{pending input} (@pxref{Readline Variables})
|
||||
and @code{rl_stuff_char ()}, macros, and characters read from the keyboard.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun int rl_getc (FILE *)
|
||||
Return the next character available from the keyboard.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun int rl_stuff_char (int c)
|
||||
Insert @var{c} into the Readline input stream. It will be "read"
|
||||
before Readline attempts to read characters from the terminal with
|
||||
@@ -666,6 +699,37 @@ lowercase character.
|
||||
If @var{c} is a number, return the value it represents.
|
||||
@end deftypefun
|
||||
|
||||
@node Alternate Interface
|
||||
@subsection Alternate Interface
|
||||
|
||||
An alternate interface is available to plain @code{readline()}. Some
|
||||
applications need to interleave keyboard I/O with file, device, or
|
||||
window system I/O, typically by using a main loop to @code{select()}
|
||||
on various file descriptors. To accomodate this need, readline can
|
||||
also be invoked as a `callback' function from an event loop. There
|
||||
are functions available to make this easy.
|
||||
|
||||
@deftypefun void rl_callback_handler_install (char *prompt, Vfunction *lhandler)
|
||||
Set up the terminal for readline I/O and display the initial
|
||||
expanded value of @var{prompt}. Save the value of @var{lhandler} to
|
||||
use as a callback when a complete line of input has been entered.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun void rl_callback_read_char ()
|
||||
Whenever an application determines that keyboard input is available, it
|
||||
should call @code{rl_callback_read_char()}, which will read the next
|
||||
character from the current input source. If that character completes the
|
||||
line, @code{rl_callback_read_char} will invoke the @var{lhandler}
|
||||
function saved by @code{rl_callback_handler_install} to process the
|
||||
line. @code{EOF} is indicated by calling @var{lhandler} with a
|
||||
@code{NULL} line.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun void rl_callback_handler_remove ()
|
||||
Restore the terminal to its initial state and remove the line handler.
|
||||
This may be called from within a callback as well as independently.
|
||||
@end deftypefun
|
||||
|
||||
@subsection An Example
|
||||
|
||||
Here is a function which changes lowercase characters to their uppercase
|
||||
@@ -894,6 +958,40 @@ returns @code{NULL}, or if this variable is set to @code{NULL}, then
|
||||
array of strings returned will be used.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar {CPFunction *} rl_filename_quoting_function
|
||||
A pointer to a function that will quote a filename in an application-
|
||||
specific fashion. This is called if filename completion is being
|
||||
attempted and one of the characters in @code{rl_filename_quote_characters}
|
||||
appears in a completed filename. The function is called with
|
||||
@var{text}, @var{match_type}, and @var{quote_pointer}. The @var{text}
|
||||
is the filename to be quoted. The @var{match_type} is either
|
||||
@code{SINGLE_MATCH}, if there is only one completion match, or
|
||||
@code{MULT_MATCH}. Some functions use this to decide whether or not to
|
||||
insert a closing quote character. The @var{quote_pointer} is a pointer
|
||||
to any opening quote character the user typed. Some functions choose
|
||||
to reset this character.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar {CPFunction *} rl_filename_dequoting_function
|
||||
A pointer to a function that will remove application-specific quoting
|
||||
characters from a filename before completion is attempted, so those
|
||||
characters do not interfere with matching the text against names in
|
||||
the filesystem. It is called with @var{text}, the text of the word
|
||||
to be dequoted, and @var{quote_char}, which is the quoting character
|
||||
that delimits the filename (usually @samp{'} or @samp{"}). If
|
||||
@var{quote_char} is zero, the filename was not in an embedded string.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar {Function *} rl_char_is_quoted_p
|
||||
A pointer to a function to call that determines whether or not a specific
|
||||
character in the line buffer is quoted, according to whatever quoting
|
||||
mechanism the program calling readline uses. The function is called with
|
||||
two arguments: @var{text}, the text of the line, and @var{index}, the
|
||||
index of the character in the line. It is used to decide whether a
|
||||
character found in @code{rl_completer_word_break_characters} should be
|
||||
used to break words for the completer.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar int rl_completion_query_items
|
||||
Up to this many items will be displayed in response to a
|
||||
possible-completions call. After that, we ask the user if she is sure
|
||||
@@ -907,6 +1005,10 @@ which break words for completion in Bash, i.e.,
|
||||
@code{" \t\n\"\\'`@@$><=;|&@{("}.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar {char *} rl_basic_quote_characters
|
||||
List of quote characters which can cause a word break.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar {char *} rl_completer_word_break_characters
|
||||
The list of characters that signal a break between words for
|
||||
@code{rl_complete_internal ()}. The default list is the value of
|
||||
@@ -920,6 +1022,11 @@ Completion occurs on the entire substring, and within the substring
|
||||
unless they also appear within this list.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar {char *} rl_filename_quote_characters
|
||||
A list of characters that cause a filename to be quoted by the completer
|
||||
when they appear in a completed filename. The default is empty.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar {char *} rl_special_prefixes
|
||||
The list of characters that are word break characters, but should be
|
||||
left in @var{text} when it is passed to the completion function.
|
||||
@@ -928,6 +1035,16 @@ For instance, Bash sets this variable to "$@@" so that it can complete
|
||||
shell variables and hostnames.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar {int} rl_completion_append_character
|
||||
When a single completion alternative matches at the end of the command
|
||||
line, this character is appended to the inserted completion text. The
|
||||
default is a space character (@samp{ }). Setting this to the null
|
||||
character (@samp{\0}) prevents anything being appended automatically.
|
||||
This can be changed in custom completion functions to
|
||||
provide the ``most sensible word separator character'' according to
|
||||
an application-specific command line syntax specification.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar int rl_ignore_completion_duplicates
|
||||
If non-zero, then disallow duplicates in the matches. Default is 1.
|
||||
@end deftypevar
|
||||
@@ -945,9 +1062,15 @@ characters.
|
||||
Non-zero means that the results of the matches are to be quoted using
|
||||
double quotes (or an application-specific quoting mechanism) if the
|
||||
completed filename contains any characters in
|
||||
@code{rl_completer_word_break_chars}. This is @emph{always} non-zero
|
||||
@code{rl_filename_quote_chars}. This is @emph{always} non-zero
|
||||
on entry, and can only be changed within a completion entry generator
|
||||
function.
|
||||
function. The quoting is effected via a call to the function pointed to
|
||||
by @code{rl_filename_quoting_function}.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar int rl_inhibit_completion
|
||||
If this variable is non-zero, completion is inhibited. The completion
|
||||
character will be inserted as any other bound to @code{self-insert}.
|
||||
@end deftypevar
|
||||
|
||||
@deftypevar {Function *} rl_ignore_some_completions_function
|
||||
@@ -1174,10 +1297,11 @@ initialize_readline ()
|
||||
rl_attempted_completion_function = (CPPFunction *)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. */
|
||||
/* Attempt to complete on the contents of TEXT. START and END bound the
|
||||
region of rl_line_buffer that contains the word to complete. TEXT is
|
||||
the word to complete. We can use the entire contents of rl_line_buffer
|
||||
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;
|
||||
|
||||
@@ -10,7 +10,7 @@ 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.
|
||||
Copyright (C) 1988, 1991, 1993, 1996 Free Software Foundation, Inc.
|
||||
|
||||
Authored by Brian Fox and Chet Ramey.
|
||||
|
||||
@@ -39,7 +39,7 @@ into another language, under the above conditions for modified versions.
|
||||
@node Command Line Editing
|
||||
@chapter Command Line Editing
|
||||
|
||||
This chapter describes the basic features of the GNU
|
||||
This chapter describes the basic features of the @sc{GNU}
|
||||
command line editing interface.
|
||||
|
||||
@menu
|
||||
@@ -59,11 +59,12 @@ The following paragraphs describe the notation used to represent
|
||||
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.
|
||||
produced when the @key{k} key is pressed while the Control key
|
||||
is depressed.
|
||||
|
||||
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
|
||||
key is pressed. 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.
|
||||
|
||||
@@ -73,7 +74,7 @@ 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).
|
||||
(@pxref{Readline Init File}).
|
||||
|
||||
@node Readline Interaction
|
||||
@section Readline Interaction
|
||||
@@ -95,10 +96,14 @@ regardless of the location of the cursor within the line.
|
||||
* 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
|
||||
* Searching:: Searching through previous lines.
|
||||
@end menu
|
||||
|
||||
@node Readline Bare Essentials
|
||||
@subsection Readline Bare Essentials
|
||||
@cindex notation, readline
|
||||
@cindex command editing
|
||||
@cindex editing command lines
|
||||
|
||||
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
|
||||
@@ -164,8 +169,8 @@ operate on characters while meta keystrokes operate on words.
|
||||
@node Readline Killing Commands
|
||||
@subsection Readline Killing Commands
|
||||
|
||||
@cindex Killing text
|
||||
@cindex Yanking text
|
||||
@cindex killing text
|
||||
@cindex yanking text
|
||||
|
||||
@dfn{Killing} text means to delete the text from the line, but to save
|
||||
it away for later use, usually by @dfn{yanking} (re-inserting)
|
||||
@@ -180,7 +185,7 @@ that when you yank it back, you get it all. 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.
|
||||
@cindex Kill ring
|
||||
@cindex kill ring
|
||||
|
||||
Here is the list of commands for killing text.
|
||||
|
||||
@@ -222,24 +227,59 @@ 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}.
|
||||
start of the line, you might type @w{@kbd{M-- 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}.
|
||||
the @key{C-d} command an argument of 10, you could type @samp{M-1 0 C-d}.
|
||||
|
||||
@node Searching
|
||||
@subsection Searching for Commands in the History
|
||||
|
||||
Readline provides commands for searching through the command history
|
||||
@ifset BashFeatures
|
||||
(@pxref{Bash History Facilities})
|
||||
@end ifset
|
||||
for lines containing a specified string.
|
||||
There are two search modes: @var{incremental} and @var{non-incremental}.
|
||||
|
||||
Incremental searches begin before the user has finished typing the
|
||||
search string.
|
||||
As each character of the search string is typed, readline displays
|
||||
the next entry from the history matching the string typed so far.
|
||||
An incremental search requires only as many characters as needed to
|
||||
find the desired history entry.
|
||||
The Escape character is used to terminate an incremental search.
|
||||
Control-J will also terminate the search.
|
||||
Control-G will abort an incremental search and restore the original
|
||||
line.
|
||||
When the search is terminated, the history entry containing the
|
||||
search string becomes the current line.
|
||||
To find other matching entries in the history list, type Control-S or
|
||||
Control-R as appropriate.
|
||||
This will search backward or forward in the history for the next
|
||||
entry matching the search string typed so far.
|
||||
Any other key sequence bound to a readline command will terminate
|
||||
the search and execute that command.
|
||||
For instance, a @code{newline} will terminate the search and accept
|
||||
the line, thereby executing the command from the history list.
|
||||
|
||||
Non-incremental searches read the entire search string before starting
|
||||
to search for matching history lines. The search string may be
|
||||
typed by the user or part of the contents of the current line.
|
||||
|
||||
@node Readline Init File
|
||||
@section Readline Init File
|
||||
@cindex initialization file, readline
|
||||
|
||||
Although the Readline library comes with a set of Emacs-like
|
||||
Although the Readline library comes with a set of @code{emacs}-like
|
||||
keybindings installed by default,
|
||||
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
|
||||
commands in an @dfn{inputrc} file in your home directory. The name of this
|
||||
@ifset BashFeatures
|
||||
file is taken from the value of the shell variable @code{INPUTRC}. If
|
||||
@end ifset
|
||||
@@ -255,17 +295,20 @@ In addition, the @code{C-x C-r} command re-reads this init file, thus
|
||||
incorporating any changes that you might have made to it.
|
||||
|
||||
@menu
|
||||
* Readline Init Syntax:: Syntax for the commands in the inputrc file.
|
||||
* Readline Init File Syntax:: Syntax for the commands in the inputrc file.
|
||||
|
||||
* Conditional Init Constructs:: Conditional key bindings in the inputrc file.
|
||||
|
||||
* Sample Init File:: An example inputrc file.
|
||||
@end menu
|
||||
|
||||
@node Readline Init Syntax
|
||||
@subsection Readline Init Syntax
|
||||
@node Readline Init File Syntax
|
||||
@subsection Readline Init File Syntax
|
||||
|
||||
There are only a few basic constructs allowed in the
|
||||
Readline init file. Blank lines are ignored.
|
||||
Lines beginning with a @key{#} are comments.
|
||||
Lines beginning with a @key{$} indicate conditional
|
||||
Lines beginning with a @samp{#} are comments.
|
||||
Lines beginning with a @samp{$} indicate conditional
|
||||
constructs (@pxref{Conditional Init Constructs}). Other lines
|
||||
denote variable settings and key bindings.
|
||||
|
||||
@@ -284,61 +327,20 @@ so few, in fact, that we just list them here:
|
||||
|
||||
@table @code
|
||||
|
||||
@item editing-mode
|
||||
@vindex editing-mode
|
||||
The @code{editing-mode} variable controls which editing mode you are
|
||||
using. By default, Readline starts up in Emacs editing mode, where
|
||||
the keystrokes are most similar to Emacs. This variable can be
|
||||
set to either @code{emacs} or @code{vi}.
|
||||
|
||||
@item horizontal-scroll-mode
|
||||
@vindex horizontal-scroll-mode
|
||||
This variable can be set to either @code{On} or @code{Off}. Setting it
|
||||
to @code{On} means that the text of the lines that you edit will scroll
|
||||
horizontally on a single screen line when they are longer than the width
|
||||
of the screen, instead of wrapping onto a new screen line. By default,
|
||||
this variable is set to @code{Off}.
|
||||
|
||||
@item mark-modified-lines
|
||||
@vindex mark-modified-lines
|
||||
This variable, when set to @code{On}, says to display an asterisk
|
||||
(@samp{*}) at the start of history lines which have been modified.
|
||||
This variable is @code{off} by default.
|
||||
|
||||
@item bell-style
|
||||
@vindex bell-style
|
||||
Controls what happens when Readline wants to ring the terminal bell.
|
||||
If set to @code{none}, Readline never rings the bell. If set to
|
||||
@code{visible}, Readline uses a visible bell if one is available.
|
||||
If set to @code{audible} (the default), Readline attempts to ring
|
||||
If set to @samp{none}, Readline never rings the bell. If set to
|
||||
@samp{visible}, Readline uses a visible bell if one is available.
|
||||
If set to @samp{audible} (the default), Readline attempts to ring
|
||||
the terminal's bell.
|
||||
|
||||
@item comment-begin
|
||||
@vindex comment-begin
|
||||
The string to insert at the beginning of the line when the
|
||||
@code{vi-comment} command is executed. The default value
|
||||
@code{insert-comment} command is executed. The default value
|
||||
is @code{"#"}.
|
||||
|
||||
@item meta-flag
|
||||
@vindex meta-flag
|
||||
If set to @code{on}, Readline will enable eight-bit input (it
|
||||
will not strip the eighth bit from the characters it reads),
|
||||
regardless of what the terminal claims it can support. The
|
||||
default value is @code{off}.
|
||||
|
||||
@item convert-meta
|
||||
@vindex convert-meta
|
||||
If set to @code{on}, Readline will convert characters with the
|
||||
eigth bit set to an ASCII key sequence by stripping the eigth
|
||||
bit and prepending an @key{ESC} character, converting them to a
|
||||
meta-prefixed key sequence. The default value is @code{on}.
|
||||
|
||||
@item output-meta
|
||||
@vindex output-meta
|
||||
If set to @code{on}, Readline will display characters with the
|
||||
eighth bit set directly rather than as a meta-prefixed escape
|
||||
sequence. The default is @code{off}.
|
||||
|
||||
@item completion-query-items
|
||||
@vindex completion-query-items
|
||||
The number of possible completions that determines when the user is
|
||||
@@ -348,6 +350,45 @@ Readline will ask the user whether or not he wishes to view
|
||||
them; otherwise, they are simply listed. The default limit is
|
||||
@code{100}.
|
||||
|
||||
@item convert-meta
|
||||
@vindex convert-meta
|
||||
If set to @samp{on}, Readline will convert characters with the
|
||||
eigth bit set to an ASCII key sequence by stripping the eigth
|
||||
bit and prepending an @key{ESC} character, converting them to a
|
||||
meta-prefixed key sequence. The default value is @samp{on}.
|
||||
|
||||
@item disable-completion
|
||||
@vindex disable-completion
|
||||
If set to @samp{On}, readline will inhibit word completion.
|
||||
Completion characters will be inserted into the line as if they had
|
||||
been mapped to @code{self-insert}. The default is @samp{off}.
|
||||
|
||||
@item editing-mode
|
||||
@vindex editing-mode
|
||||
The @code{editing-mode} variable controls which editing mode you are
|
||||
using. By default, Readline starts up in Emacs editing mode, where
|
||||
the keystrokes are most similar to Emacs. This variable can be
|
||||
set to either @samp{emacs} or @samp{vi}.
|
||||
|
||||
@item enable-keypad
|
||||
@vindex enable-keypad
|
||||
When set to @samp{on}, readline will try to enable the application
|
||||
keypad when it is called. Some systems need this to enable the
|
||||
arrow keys. The default is @samp{off}.
|
||||
|
||||
@item expand-tilde
|
||||
@vindex expand-tilde
|
||||
If set to @samp{on}, tilde expansion is performed when Readline
|
||||
attempts word completion. The default is @samp{off}.
|
||||
|
||||
@item horizontal-scroll-mode
|
||||
@vindex horizontal-scroll-mode
|
||||
This variable can be set to either @samp{on} or @samp{off}. Setting it
|
||||
to @samp{on} means that the text of the lines that you edit will scroll
|
||||
horizontally on a single screen line when they are longer than the width
|
||||
of the screen, instead of wrapping onto a new screen line. By default,
|
||||
this variable is set to @samp{off}.
|
||||
|
||||
@item keymap
|
||||
@vindex keymap
|
||||
Sets Readline's idea of the current keymap for key binding commands.
|
||||
@@ -357,7 +398,6 @@ Acceptable @code{keymap} names are
|
||||
@code{emacs-meta},
|
||||
@code{emacs-ctlx},
|
||||
@code{vi},
|
||||
@code{vi-move},
|
||||
@code{vi-command}, and
|
||||
@code{vi-insert}.
|
||||
@code{vi} is equivalent to @code{vi-command}; @code{emacs} is
|
||||
@@ -365,18 +405,44 @@ equivalent to @code{emacs-standard}. The default value is @code{emacs}.
|
||||
The value of the @code{editing-mode} variable also affects the
|
||||
default keymap.
|
||||
|
||||
@item mark-directories
|
||||
If set to @samp{on}, completed directory names have a slash
|
||||
appended. The default is @samp{on}.
|
||||
|
||||
@item mark-modified-lines
|
||||
@vindex mark-modified-lines
|
||||
This variable, when set to @samp{on}, says to display an asterisk
|
||||
(@samp{*}) at the start of history lines which have been modified.
|
||||
This variable is @samp{off} by default.
|
||||
|
||||
@item input-meta
|
||||
@vindex input-meta
|
||||
@vindex meta-flag
|
||||
If set to @samp{on}, Readline will enable eight-bit input (it
|
||||
will not strip the eighth bit from the characters it reads),
|
||||
regardless of what the terminal claims it can support. The
|
||||
default value is @samp{off}. The name @code{meta-flag} is a
|
||||
synonym for this variable.
|
||||
|
||||
@item output-meta
|
||||
@vindex output-meta
|
||||
If set to @samp{on}, Readline will display characters with the
|
||||
eighth bit set directly rather than as a meta-prefixed escape
|
||||
sequence. The default is @samp{off}.
|
||||
|
||||
@item show-all-if-ambiguous
|
||||
@vindex show-all-if-ambiguous
|
||||
This alters the default behavior of the completion functions. If
|
||||
set to @code{on},
|
||||
set to @samp{on},
|
||||
words which have more than one possible completion cause the
|
||||
matches to be listed immediately instead of ringing the bell.
|
||||
The default value is @code{off}.
|
||||
The default value is @samp{off}.
|
||||
|
||||
@item expand-tilde
|
||||
@vindex expand-tilde
|
||||
If set to @code{on}, tilde expansion is performed when Readline
|
||||
attempts word completion. The default is @code{off}.
|
||||
@item visible-stats
|
||||
@vindex visible-stats
|
||||
If set to @samp{on}, a character denoting a file's type
|
||||
is appended to the filename when listing possible
|
||||
completions. The default is @samp{off}.
|
||||
|
||||
@end table
|
||||
|
||||
@@ -399,13 +465,13 @@ comfortable for you.
|
||||
@example
|
||||
Control-u: universal-argument
|
||||
Meta-Rubout: backward-kill-word
|
||||
Control-o: ">&output"
|
||||
Control-o: "> output"
|
||||
@end example
|
||||
|
||||
In the above example, @samp{C-u} is bound to the function
|
||||
@code{universal-argument}, and @samp{C-o} is bound to run the macro
|
||||
expressed on the right hand side (that is, to insert the text
|
||||
@samp{>&output} into the line).
|
||||
@samp{> output} into the line).
|
||||
|
||||
@item @w{"@var{keyseq}": @var{function-name} or @var{macro}}
|
||||
@var{keyseq} differs from @var{keyname} above in that strings
|
||||
@@ -445,10 +511,10 @@ backslash
|
||||
When entering the text of a macro, single or double quotes should
|
||||
be used to indicate a macro definition. Unquoted text
|
||||
is assumed to be a function name. Backslash
|
||||
will quote any character in the macro text, including @key{"}
|
||||
and @key{'}.
|
||||
For example, the following binding will make @kbd{C-x \}
|
||||
insert a single @key{\} into the line:
|
||||
will quote any character in the macro text, including @samp{"}
|
||||
and @samp{'}.
|
||||
For example, the following binding will make @samp{C-x \}
|
||||
insert a single @samp{\} into the line:
|
||||
@example
|
||||
"\C-x\\": "\\"
|
||||
@end example
|
||||
@@ -464,7 +530,7 @@ compilation features of the C preprocessor which allows key
|
||||
bindings and variable settings to be performed as the result
|
||||
of tests. There are three parser directives used.
|
||||
|
||||
@ftable @code
|
||||
@table @code
|
||||
@item $if
|
||||
The @code{$if} construct allows bindings to be made based on the
|
||||
editing mode, the terminal being used, or the application using
|
||||
@@ -486,7 +552,7 @@ key bindings, perhaps to bind the key sequences output by the
|
||||
terminal's function keys. The word on the right side of the
|
||||
@samp{=} is tested against the full name of the terminal and the
|
||||
portion of the terminal name before the first @samp{-}. This
|
||||
allows @var{sun} to match both @var{sun} and @var{sun-cmd},
|
||||
allows @code{sun} to match both @code{sun} and @code{sun-cmd},
|
||||
for instance.
|
||||
|
||||
@item application
|
||||
@@ -497,7 +563,7 @@ This could be used to bind key sequences to functions useful for
|
||||
a specific program. For instance, the following command adds a
|
||||
key sequence that quotes the current or previous word in Bash:
|
||||
@example
|
||||
$if bash
|
||||
$if Bash
|
||||
# Quote the current or previous word
|
||||
"\C-xq": "\eb\"\ef\""
|
||||
$endif
|
||||
@@ -511,7 +577,109 @@ This command, as you saw in the previous example, terminates an
|
||||
@item $else
|
||||
Commands in this branch of the @code{$if} directive are executed if
|
||||
the test fails.
|
||||
@end ftable
|
||||
@end table
|
||||
|
||||
@node Sample Init File
|
||||
@subsection Sample Init File
|
||||
|
||||
Here is an example of an inputrc file. This illustrates key
|
||||
binding, variable assignment, and conditional syntax.
|
||||
|
||||
@example
|
||||
@page
|
||||
# This file controls the behaviour of line input editing for
|
||||
# programs that use the Gnu Readline library. Existing programs
|
||||
# include FTP, Bash, and Gdb.
|
||||
#
|
||||
# You can re-read the inputrc file with C-x C-r.
|
||||
# Lines beginning with '#' are comments.
|
||||
#
|
||||
# Set various bindings for emacs mode.
|
||||
|
||||
set editing-mode emacs
|
||||
|
||||
$if mode=emacs
|
||||
|
||||
Meta-Control-h: backward-kill-word Text after the function name is ignored
|
||||
|
||||
#
|
||||
# Arrow keys in keypad mode
|
||||
#
|
||||
#"\M-OD" backward-char
|
||||
#"\M-OC" forward-char
|
||||
#"\M-OA" previous-history
|
||||
#"\M-OB" next-history
|
||||
#
|
||||
# Arrow keys in ANSI mode
|
||||
#
|
||||
"\M-[D" backward-char
|
||||
"\M-[C" forward-char
|
||||
"\M-[A" previous-history
|
||||
"\M-[B" next-history
|
||||
#
|
||||
# Arrow keys in 8 bit keypad mode
|
||||
#
|
||||
#"\M-\C-OD" backward-char
|
||||
#"\M-\C-OC" forward-char
|
||||
#"\M-\C-OA" previous-history
|
||||
#"\M-\C-OB" next-history
|
||||
#
|
||||
# Arrow keys in 8 bit ANSI mode
|
||||
#
|
||||
#"\M-\C-[D" backward-char
|
||||
#"\M-\C-[C" forward-char
|
||||
#"\M-\C-[A" previous-history
|
||||
#"\M-\C-[B" next-history
|
||||
|
||||
C-q: quoted-insert
|
||||
|
||||
$endif
|
||||
|
||||
# An old-style binding. This happens to be the default.
|
||||
TAB: complete
|
||||
|
||||
# Macros that are convenient for shell interaction
|
||||
$if Bash
|
||||
# edit the path
|
||||
"\C-xp": "PATH=$@{PATH@}\e\C-e\C-a\ef\C-f"
|
||||
# prepare to type a quoted word -- insert open and close double quotes
|
||||
# and move to just after the open quote
|
||||
"\C-x\"": "\"\"\C-b"
|
||||
# insert a backslash (testing backslash escapes in sequences and macros)
|
||||
"\C-x\\": "\\"
|
||||
# Quote the current or previous word
|
||||
"\C-xq": "\eb\"\ef\""
|
||||
# Add a binding to refresh the line, which is unbound
|
||||
"\C-xr": redraw-current-line
|
||||
# Edit variable on current line.
|
||||
"\M-\C-v": "\C-a\C-k$\C-y\M-\C-e\C-a\C-y="
|
||||
$endif
|
||||
|
||||
# use a visible bell if one is available
|
||||
set bell-style visible
|
||||
|
||||
# don't strip characters to 7 bits when reading
|
||||
set input-meta on
|
||||
|
||||
# allow iso-latin1 characters to be inserted rather than converted to
|
||||
# prefix-meta sequences
|
||||
set convert-meta off
|
||||
|
||||
# display characters with the eighth bit set directly rather than
|
||||
# as meta-prefixed characters
|
||||
set output-meta on
|
||||
|
||||
# if there are more than 150 possible completions for a word, ask the
|
||||
# user if he wants to see all of them
|
||||
set completion-query-items 150
|
||||
|
||||
# For FTP
|
||||
$if Ftp
|
||||
"\C-xg": "get \M-?"
|
||||
"\C-xt": "put \M-?"
|
||||
"\M-.": yank-last-arg
|
||||
$endif
|
||||
@end example
|
||||
|
||||
@node Bindable Readline Commands
|
||||
@section Bindable Readline Commands
|
||||
@@ -527,6 +695,9 @@ the test fails.
|
||||
* Miscellaneous Commands:: Other miscellaneous commands.
|
||||
@end menu
|
||||
|
||||
This section describes Readline commands that may be bound to key
|
||||
sequences.
|
||||
|
||||
@node Commands For Moving
|
||||
@subsection Commands For Moving
|
||||
@ftable @code
|
||||
@@ -608,12 +779,13 @@ for a string supplied by the user.
|
||||
|
||||
@item history-search-forward ()
|
||||
Search forward through the history for the string of characters
|
||||
between the start of the current line and the current point. This
|
||||
is a non-incremental search. By default, this command is unbound.
|
||||
between the start of the current line and the current cursor
|
||||
position (the `point'). This is a non-incremental search. By
|
||||
default, this command is unbound.
|
||||
|
||||
@item history-search-backward ()
|
||||
Search backward through the history for the string of characters
|
||||
between the start of the current line and the current point. This
|
||||
between the start of the current line and the point. This
|
||||
is a non-incremental search. By default, this command is unbound.
|
||||
|
||||
@item yank-nth-arg (M-C-y)
|
||||
@@ -624,8 +796,8 @@ in the previous command begin with word 0). A negative argument
|
||||
inserts the @var{n}th word from the end of the previous command.
|
||||
|
||||
@item yank-last-arg (M-., M-_)
|
||||
Insert last argument to the previous command (the last word on the
|
||||
previous line). With an
|
||||
Insert last argument to the previous command (the last word of the
|
||||
previous history entry). With an
|
||||
argument, behave exactly like @code{yank-nth-arg}.
|
||||
|
||||
@end ftable
|
||||
@@ -637,7 +809,7 @@ argument, behave exactly like @code{yank-nth-arg}.
|
||||
@item delete-char (C-d)
|
||||
Delete the character under the cursor. If the cursor is at the
|
||||
beginning of the line, there are no characters in the line, and
|
||||
the last character typed was not C-d, then return EOF.
|
||||
the last character typed was not @kbd{C-d}, then return @code{EOF}.
|
||||
|
||||
@item backward-delete-char (Rubout)
|
||||
Delete the character behind the cursor. A numeric arg says to kill
|
||||
@@ -714,6 +886,23 @@ boundary. The killed text is saved on the kill-ring.
|
||||
@item delete-horizontal-space ()
|
||||
Delete all spaces and tabs around point. By default, this is unbound.
|
||||
|
||||
@item kill-region ()
|
||||
Kill the text between the point and the @emph{mark} (saved
|
||||
cursor position. This text is referred to as the @var{region}.
|
||||
By default, this command is unbound.
|
||||
|
||||
@item copy-region-as-kill ()
|
||||
Copy the text in the region to the kill buffer, so you can yank it
|
||||
right away. By default, this command is unbound.
|
||||
|
||||
@item copy-backward-word ()
|
||||
Copy the word before point to the kill buffer.
|
||||
By default, this command is unbound.
|
||||
|
||||
@item copy-forward-word ()
|
||||
Copy the word following point to the kill buffer.
|
||||
By default, this command is unbound.
|
||||
|
||||
@item yank (C-y)
|
||||
Yank the top of the kill ring into the buffer at the current
|
||||
cursor position.
|
||||
@@ -729,7 +918,7 @@ the prior command is yank or yank-pop.
|
||||
|
||||
@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.
|
||||
argument. @key{M--} starts a negative argument.
|
||||
|
||||
@item universal-argument ()
|
||||
Each time this is executed, the argument count is multiplied by four.
|
||||
@@ -750,18 +939,74 @@ 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, and so on.
|
||||
@ifset BashFeatures
|
||||
See the Bash manual page for a complete list of available completion
|
||||
functions.
|
||||
Bash attempts completion treating the text as a variable (if the
|
||||
text begins with @samp{$}), username (if the text begins with
|
||||
@samp{~}), hostname (if the text begins with @samp{@@}), or
|
||||
command (including aliases and functions) in turn. If none
|
||||
of these produces a match, filename completion is attempted.
|
||||
@end ifset
|
||||
|
||||
@item possible-completions (M-?)
|
||||
List the possible completions of the text before the cursor.
|
||||
|
||||
@item insert-completions ()
|
||||
@item insert-completions (M-*)
|
||||
Insert all completions of the text before point that would have
|
||||
been generated by @code{possible-completions}. By default, this
|
||||
is not bound to a key.
|
||||
been generated by @code{possible-completions}.
|
||||
|
||||
@ifset BashFeatures
|
||||
@item complete-filename (M-/)
|
||||
Attempt filename completion on the text before point.
|
||||
|
||||
@item possible-filename-completions (C-x /)
|
||||
List the possible completions of the text before point,
|
||||
treating it as a filename.
|
||||
|
||||
@item complete-username (M-~)
|
||||
Attempt completion on the text before point, treating
|
||||
it as a username.
|
||||
|
||||
@item possible-username-completions (C-x ~)
|
||||
List the possible completions of the text before point,
|
||||
treating it as a username.
|
||||
|
||||
@item complete-variable (M-$)
|
||||
Attempt completion on the text before point, treating
|
||||
it as a shell variable.
|
||||
|
||||
@item possible-variable-completions (C-x $)
|
||||
List the possible completions of the text before point,
|
||||
treating it as a shell variable.
|
||||
|
||||
@item complete-hostname (M-@@)
|
||||
Attempt completion on the text before point, treating
|
||||
it as a hostname.
|
||||
|
||||
@item possible-hostname-completions (C-x @@)
|
||||
List the possible completions of the text before point,
|
||||
treating it as a hostname.
|
||||
|
||||
@item complete-command (M-!)
|
||||
Attempt completion on the text before point, treating
|
||||
it as a command name. Command completion attempts to
|
||||
match the text against aliases, reserved words, shell
|
||||
functions, builtins, and finally executable filenames,
|
||||
in that order.
|
||||
|
||||
@item possible-command-completions (C-x !)
|
||||
List the possible completions of the text before point,
|
||||
treating it as a command name.
|
||||
|
||||
@item dynamic-complete-history (M-TAB)
|
||||
Attempt completion on the text before point, comparing
|
||||
the text against lines from the history list for possible
|
||||
completion matches.
|
||||
|
||||
@item complete-into-braces (M-@{)
|
||||
Perform filename completion and return the list of possible completions
|
||||
enclosed within braces so the list is available to the shell
|
||||
(@pxref{Brace Expansion}).
|
||||
|
||||
@end ifset
|
||||
@end ftable
|
||||
|
||||
@node Keyboard Macros
|
||||
@@ -786,7 +1031,7 @@ in the macro appear as if typed at the keyboard.
|
||||
@ftable @code
|
||||
|
||||
@item re-read-init-file (C-x C-r)
|
||||
Read in the contents of your init file, and incorporate
|
||||
Read in the contents of the inputrc file, and incorporate
|
||||
any bindings or variable assignments found there.
|
||||
|
||||
@item abort (C-g)
|
||||
@@ -794,9 +1039,9 @@ Abort the current editing command and
|
||||
ring the terminal's bell (subject to the setting of
|
||||
@code{bell-style}).
|
||||
|
||||
@item do-uppercase-version (M-a, M-b, ...)
|
||||
Run the command that is bound to the corresoponding uppercase
|
||||
character.
|
||||
@item do-uppercase-version (M-a, M-b, M-@var{x}, @dots{})
|
||||
If the metafied character @var{x} is lowercase, run the command
|
||||
that is bound to the corresponding uppercase character.
|
||||
|
||||
@item prefix-meta (ESC)
|
||||
Make the next character that you type be metafied. This is for people
|
||||
@@ -813,13 +1058,59 @@ command enough times to get back to the beginning.
|
||||
@item tilde-expand (M-~)
|
||||
Perform tilde expansion on the current word.
|
||||
|
||||
@item set-mark (C-@@)
|
||||
Set the mark to the current point. If a
|
||||
numeric argument is supplied, the mark is set to that position.
|
||||
|
||||
@item exchange-point-and-mark (C-x C-x)
|
||||
Swap the point with the mark. The current cursor position is set to
|
||||
the saved position, and the old cursor position is saved as the mark.
|
||||
|
||||
@item character-search (C-])
|
||||
A character is read and point is moved to the next occurrence of that
|
||||
character. A negative count searches for previous occurrences.
|
||||
|
||||
@item character-search-backward (M-C-])
|
||||
A character is read and point is moved to the previous occurrence
|
||||
of that character. A negative count searches for subsequent
|
||||
occurrences.
|
||||
|
||||
@item insert-comment (M-#)
|
||||
The value of the @code{comment-begin}
|
||||
variable is inserted at the beginning of the current line,
|
||||
and the line is accepted as if a newline had been typed.
|
||||
@ifset BashFeatures
|
||||
This makes the current line a shell comment.
|
||||
@end ifset
|
||||
|
||||
@item dump-functions ()
|
||||
Print all of the functions and their key bindings to the
|
||||
readline output stream. If a numeric argument is supplied,
|
||||
the output is formatted in such a way that it can be made part
|
||||
of an @var{inputrc} file.
|
||||
of an @var{inputrc} file. This command is unbound by default.
|
||||
|
||||
@item dump-variables ()
|
||||
Print all of the settable variables and their values to the
|
||||
readline output stream. If a numeric argument is supplied,
|
||||
the output is formatted in such a way that it can be made part
|
||||
of an @var{inputrc} file. This command is unbound by default.
|
||||
|
||||
@item dump-macros ()
|
||||
Print all of the readline key sequences bound to macros and the
|
||||
strings they ouput. If a numeric argument is supplied,
|
||||
the output is formatted in such a way that it can be made part
|
||||
of an @var{inputrc} file. This command is unbound by default.
|
||||
|
||||
@ifset BashFeatures
|
||||
@item glob-expand-word (C-x *)
|
||||
The word before point is treated as a pattern for pathname expansion,
|
||||
and the list of matching file names is inserted, replacing the word.
|
||||
|
||||
@item glob-list-expansions (C-x g)
|
||||
The list of expansions that would have been generated by
|
||||
@code{glob-expand-word}
|
||||
is inserted into the line, replacing the word before point.
|
||||
|
||||
@item display-shell-version (C-x C-v)
|
||||
Display version information about the current instance of Bash.
|
||||
|
||||
@@ -841,7 +1132,7 @@ argument is ignored.
|
||||
|
||||
@item emacs-editing-mode (C-e)
|
||||
When in @code{vi} editing mode, this causes a switch back to
|
||||
emacs editing mode, as if the command @code{set -o emacs} had
|
||||
@code{emacs} editing mode, as if the command @samp{set -o emacs} had
|
||||
been executed.
|
||||
|
||||
@end ifset
|
||||
@@ -854,15 +1145,15 @@ been executed.
|
||||
While the Readline library does not have a full set of @code{vi}
|
||||
editing functions, it does contain enough to allow simple editing
|
||||
of the line. The Readline @code{vi} mode behaves as specified in
|
||||
the Posix 1003.2 standard.
|
||||
the @sc{POSIX} 1003.2 standard.
|
||||
|
||||
@ifset BashFeatures
|
||||
In order to switch interactively between @code{Emacs} and @code{Vi}
|
||||
editing modes, use the @code{set -o emacs} and @code{set -o vi}
|
||||
In order to switch interactively between @code{emacs} and @code{vi}
|
||||
editing modes, use the @samp{set -o emacs} and @samp{set -o vi}
|
||||
commands (@pxref{The Set Builtin}).
|
||||
@end ifset
|
||||
@ifclear BashFeatures
|
||||
In order to switch interactively between @code{Emacs} and @code{Vi}
|
||||
In order to switch interactively between @code{emacs} and @code{vi}
|
||||
editing modes, use the command M-C-j (toggle-editing-mode).
|
||||
@end ifclear
|
||||
The Readline default is @code{emacs} mode.
|
||||
@@ -871,5 +1162,5 @@ When you enter a line in @code{vi} mode, you are already placed in
|
||||
`insertion' mode, as if you had typed an @samp{i}. Pressing @key{ESC}
|
||||
switches you into `command' mode, where you can edit the text of the
|
||||
line with the standard @code{vi} movement keys, move to previous
|
||||
history lines with @samp{k}, and following lines with @samp{j}, and
|
||||
history lines with @samp{k} and subsequent lines with @samp{j}, and
|
||||
so forth.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -33,7 +33,7 @@
|
||||
KEYMAP_ENTRY_ARRAY emacs_standard_keymap = {
|
||||
|
||||
/* Control keys. */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Control-@ */
|
||||
{ ISFUNC, rl_set_mark }, /* Control-@ */
|
||||
{ ISFUNC, rl_beg_of_line }, /* Control-a */
|
||||
{ ISFUNC, rl_backward }, /* Control-b */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Control-c */
|
||||
@@ -62,7 +62,7 @@ KEYMAP_ENTRY_ARRAY emacs_standard_keymap = {
|
||||
{ ISFUNC, (Function *)0x0 }, /* Control-z */
|
||||
{ ISKMAP, (Function *)emacs_meta_keymap }, /* Control-[ */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Control-\ */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Control-] */
|
||||
{ ISFUNC, rl_char_search }, /* Control-] */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Control-^ */
|
||||
{ ISFUNC, rl_undo_command }, /* Control-_ */
|
||||
|
||||
@@ -358,22 +358,22 @@ KEYMAP_ENTRY_ARRAY emacs_meta_keymap = {
|
||||
|
||||
{ ISFUNC, rl_complete }, /* Meta-Control-[ */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-\ */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-] */
|
||||
{ ISFUNC, rl_backward_char_search }, /* Meta-Control-] */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-^ */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-_ */
|
||||
|
||||
/* The start of printing characters. */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Meta-SPACE */
|
||||
{ ISFUNC, rl_set_mark }, /* Meta-SPACE */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Meta-! */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Meta-" */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Meta-# */
|
||||
{ ISFUNC, rl_insert_comment },/* Meta-# */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Meta-$ */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Meta-% */
|
||||
{ ISFUNC, rl_tilde_expand }, /* Meta-& */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Meta-' */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Meta-( */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Meta-) */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Meta-* */
|
||||
{ ISFUNC, rl_insert_completions }, /* Meta-* */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Meta-+ */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Meta-, */
|
||||
{ ISFUNC, rl_digit_argument }, /* Meta-- */
|
||||
@@ -396,7 +396,7 @@ KEYMAP_ENTRY_ARRAY emacs_meta_keymap = {
|
||||
{ ISFUNC, (Function *)0x0 }, /* Meta-: */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Meta-; */
|
||||
{ ISFUNC, rl_beginning_of_history }, /* Meta-< */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Meta-= */
|
||||
{ ISFUNC, rl_possible_completions }, /* Meta-= */
|
||||
{ ISFUNC, rl_end_of_history }, /* Meta-> */
|
||||
{ ISFUNC, rl_possible_completions }, /* Meta-? */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Meta-@ */
|
||||
@@ -632,7 +632,7 @@ KEYMAP_ENTRY_ARRAY emacs_ctlx_keymap = {
|
||||
{ ISFUNC, rl_undo_command }, /* Control-u */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Control-v */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Control-w */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Control-x */
|
||||
{ ISFUNC, rl_exchange_point_and_mark },/* Control-x */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Control-y */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Control-z */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Control-[ */
|
||||
|
||||
@@ -1,12 +1,19 @@
|
||||
# This is the Makefile for the examples subdirectory of readline. -*- text -*-
|
||||
#
|
||||
|
||||
EXECUTABLES = fileman
|
||||
CFLAGS = -g -I../..
|
||||
EXECUTABLES = fileman rltest
|
||||
CFLAGS = -g -I../.. -I..
|
||||
LDFLAGS = -g -L..
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
|
||||
all: $(EXECUTABLES)
|
||||
|
||||
fileman: fileman.o
|
||||
$(CC) $(LDFLAGS) -o fileman fileman.o -lreadline -ltermcap
|
||||
$(CC) $(LDFLAGS) -o $@ fileman.o -lreadline -ltermcap
|
||||
|
||||
rltest: rltest.o
|
||||
$(CC) $(LDFLAGS) -o $@ rltest.o -lreadline -ltermcap
|
||||
|
||||
fileman.o: fileman.c
|
||||
|
||||
rltest.o: rltest.c
|
||||
|
||||
@@ -194,10 +194,11 @@ initialize_readline ()
|
||||
rl_attempted_completion_function = (CPPFunction *)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. */
|
||||
/* Attempt to complete on the contents of TEXT. START and END bound the
|
||||
region of rl_line_buffer that contains the word to complete. TEXT is
|
||||
the word to complete. We can use the entire contents of rl_line_buffer
|
||||
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;
|
||||
|
||||
54
lib/readline/examples/rltest.c
Normal file
54
lib/readline/examples/rltest.c
Normal file
@@ -0,0 +1,54 @@
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Testing Readline */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include "../readline.h"
|
||||
#include "../history.h"
|
||||
|
||||
main ()
|
||||
{
|
||||
HIST_ENTRY **history_list ();
|
||||
char *temp = (char *)NULL;
|
||||
char *prompt = "readline$ ";
|
||||
int done = 0;
|
||||
|
||||
while (!done)
|
||||
{
|
||||
temp = readline (prompt);
|
||||
|
||||
/* Test for EOF. */
|
||||
if (!temp)
|
||||
exit (1);
|
||||
|
||||
/* If there is anything on the line, print it and remember it. */
|
||||
if (*temp)
|
||||
{
|
||||
fprintf (stderr, "%s\r\n", temp);
|
||||
add_history (temp);
|
||||
}
|
||||
|
||||
/* Check for `command' that we handle. */
|
||||
if (strcmp (temp, "quit") == 0)
|
||||
done = 1;
|
||||
|
||||
if (strcmp (temp, "list") == 0)
|
||||
{
|
||||
HIST_ENTRY **list = history_list ();
|
||||
register int i;
|
||||
if (list)
|
||||
{
|
||||
for (i = 0; list[i]; i++)
|
||||
{
|
||||
fprintf (stderr, "%d: %s\r\n", i, list[i]->line);
|
||||
free (list[i]->line);
|
||||
}
|
||||
free (list);
|
||||
}
|
||||
}
|
||||
free (temp);
|
||||
}
|
||||
}
|
||||
@@ -21,11 +21,11 @@
|
||||
675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#define READLINE_LIBRARY
|
||||
|
||||
#if defined (STATIC_MALLOC)
|
||||
static char *xmalloc (), *xrealloc ();
|
||||
#else
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
extern char *xmalloc (), *xrealloc ();
|
||||
#endif /* STATIC_MALLOC */
|
||||
|
||||
#if !defined (BUFSIZ)
|
||||
#include <stdio.h>
|
||||
@@ -40,18 +40,17 @@ extern char *xmalloc (), *xrealloc ();
|
||||
#include "rlconf.h"
|
||||
#include "readline.h"
|
||||
|
||||
static int qsort_string_compare ();
|
||||
extern int _rl_qsort_string_compare ();
|
||||
|
||||
FUNMAP **funmap = (FUNMAP **)NULL;
|
||||
static int funmap_size = 0;
|
||||
static int funmap_entry = 0;
|
||||
FUNMAP **funmap;
|
||||
static int funmap_size;
|
||||
static int funmap_entry;
|
||||
|
||||
/* After initializing the function map, this is the index of the first
|
||||
program specific function. */
|
||||
int funmap_program_specific_entry_start;
|
||||
|
||||
static FUNMAP default_funmap[] = {
|
||||
|
||||
{ "abort", rl_abort },
|
||||
{ "accept-line", rl_newline },
|
||||
{ "arrow-key-prefix", rl_arrow_keys },
|
||||
@@ -64,26 +63,35 @@ static FUNMAP default_funmap[] = {
|
||||
{ "beginning-of-line", rl_beg_of_line },
|
||||
{ "call-last-kbd-macro", rl_call_last_kbd_macro },
|
||||
{ "capitalize-word", rl_capitalize_word },
|
||||
{ "character-search", rl_char_search },
|
||||
{ "character-search-backward", rl_backward_char_search },
|
||||
{ "clear-screen", rl_clear_screen },
|
||||
{ "complete", rl_complete },
|
||||
{ "copy-backward-word", rl_copy_backward_word },
|
||||
{ "copy-forward-word", rl_copy_forward_word },
|
||||
{ "copy-region-as-kill", rl_copy_region_to_kill },
|
||||
{ "delete-char", rl_delete },
|
||||
{ "delete-horizontal-space", rl_delete_horizontal_space },
|
||||
{ "digit-argument", rl_digit_argument },
|
||||
{ "do-lowercase-version", rl_do_lowercase_version },
|
||||
{ "downcase-word", rl_downcase_word },
|
||||
{ "dump-functions", rl_dump_functions },
|
||||
{ "dump-variables", rl_dump_variables },
|
||||
{ "emacs-editing-mode", rl_emacs_editing_mode },
|
||||
{ "end-kbd-macro", rl_end_kbd_macro },
|
||||
{ "end-of-history", rl_end_of_history },
|
||||
{ "end-of-line", rl_end_of_line },
|
||||
{ "exchange-point-and-mark", rl_exchange_point_and_mark },
|
||||
{ "forward-char", rl_forward },
|
||||
{ "forward-search-history", rl_forward_search_history },
|
||||
{ "forward-word", rl_forward_word },
|
||||
{ "history-search-backward", rl_history_search_backward },
|
||||
{ "history-search-forward", rl_history_search_forward },
|
||||
{ "insert-comment", rl_insert_comment },
|
||||
{ "insert-completions", rl_insert_completions },
|
||||
{ "kill-whole-line", rl_kill_full_line },
|
||||
{ "kill-line", rl_kill_line },
|
||||
{ "kill-region", rl_kill_region },
|
||||
{ "kill-word", rl_kill_word },
|
||||
{ "next-history", rl_get_next_history },
|
||||
{ "non-incremental-forward-search-history", rl_noninc_forward_search },
|
||||
@@ -98,6 +106,7 @@ static FUNMAP default_funmap[] = {
|
||||
{ "reverse-search-history", rl_reverse_search_history },
|
||||
{ "revert-line", rl_revert_line },
|
||||
{ "self-insert", rl_insert },
|
||||
{ "set-mark", rl_set_mark },
|
||||
{ "start-kbd-macro", rl_start_kbd_macro },
|
||||
{ "tab-insert", rl_tab_insert },
|
||||
{ "tilde-expand", rl_tilde_expand },
|
||||
@@ -118,6 +127,7 @@ static FUNMAP default_funmap[] = {
|
||||
{ "vi-append-eol", rl_vi_append_eol },
|
||||
{ "vi-append-mode", rl_vi_append_mode },
|
||||
{ "vi-arg-digit", rl_vi_arg_digit },
|
||||
{ "vi-back-to-indent", rl_vi_back_to_indent },
|
||||
{ "vi-bWord", rl_vi_bWord },
|
||||
{ "vi-bracktype", rl_vi_bracktype },
|
||||
{ "vi-bword", rl_vi_bword },
|
||||
@@ -126,7 +136,6 @@ static FUNMAP default_funmap[] = {
|
||||
{ "vi-change-to", rl_vi_change_to },
|
||||
{ "vi-char-search", rl_vi_char_search },
|
||||
{ "vi-column", rl_vi_column },
|
||||
{ "vi-comment", rl_vi_comment },
|
||||
{ "vi-complete", rl_vi_complete },
|
||||
{ "vi-delete", rl_vi_delete },
|
||||
{ "vi-delete-to", rl_vi_delete_to },
|
||||
@@ -136,8 +145,10 @@ static FUNMAP default_funmap[] = {
|
||||
{ "vi-eof-maybe", rl_vi_eof_maybe },
|
||||
{ "vi-eword", rl_vi_eword },
|
||||
{ "vi-fWord", rl_vi_fWord },
|
||||
{ "vi-fetch-history", rl_vi_fetch_history },
|
||||
{ "vi-first-print", rl_vi_first_print },
|
||||
{ "vi-fword", rl_vi_fword },
|
||||
{ "vi-goto-mark", rl_vi_goto_mark },
|
||||
{ "vi-insert-beg", rl_vi_insert_beg },
|
||||
{ "vi-insertion-mode", rl_vi_insertion_mode },
|
||||
{ "vi-match", rl_vi_match },
|
||||
@@ -151,6 +162,7 @@ static FUNMAP default_funmap[] = {
|
||||
{ "vi-replace", rl_vi_replace },
|
||||
{ "vi-search", rl_vi_search },
|
||||
{ "vi-search-again", rl_vi_search_again },
|
||||
{ "vi-set-mark", rl_vi_set_mark },
|
||||
{ "vi-subst", rl_vi_subst },
|
||||
{ "vi-tilde-expand", rl_vi_tilde_expand },
|
||||
{ "vi-yank-arg", rl_vi_yank_arg },
|
||||
@@ -160,16 +172,16 @@ static FUNMAP default_funmap[] = {
|
||||
{(char *)NULL, (Function *)NULL }
|
||||
};
|
||||
|
||||
int
|
||||
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_size += 64;
|
||||
funmap = (FUNMAP **)xrealloc (funmap, funmap_size * sizeof (FUNMAP *));
|
||||
}
|
||||
|
||||
funmap[funmap_entry] = (FUNMAP *)xmalloc (sizeof (FUNMAP));
|
||||
funmap[funmap_entry]->name = name;
|
||||
@@ -179,7 +191,7 @@ rl_add_funmap_entry (name, function)
|
||||
return funmap_entry;
|
||||
}
|
||||
|
||||
static int funmap_initialized = 0;
|
||||
static int funmap_initialized;
|
||||
|
||||
/* Make the funmap contain all of the default entries. */
|
||||
void
|
||||
@@ -203,46 +215,28 @@ rl_initialize_funmap ()
|
||||
char **
|
||||
rl_funmap_names ()
|
||||
{
|
||||
char **result = (char **)NULL;
|
||||
char **result;
|
||||
int result_size, result_index;
|
||||
|
||||
result_size = result_index = 0;
|
||||
|
||||
/* Make sure that the function map has been initialized. */
|
||||
rl_initialize_funmap ();
|
||||
|
||||
for (result_index = 0; funmap[result_index]; result_index++)
|
||||
for (result_index = result_size = 0, result = (char **)NULL; funmap[result_index]; result_index++)
|
||||
{
|
||||
if (result_index + 2 > result_size)
|
||||
{
|
||||
if (!result)
|
||||
result = (char **)xmalloc ((result_size = 20) * sizeof (char *));
|
||||
else
|
||||
result = (char **)
|
||||
xrealloc (result, (result_size += 20) * sizeof (char *));
|
||||
result_size += 20;
|
||||
result = (char **)xrealloc (result, result_size * sizeof (char *));
|
||||
}
|
||||
|
||||
result[result_index] = funmap[result_index]->name;
|
||||
result[result_index + 1] = (char *)NULL;
|
||||
}
|
||||
|
||||
qsort (result, result_index, sizeof (char *), qsort_string_compare);
|
||||
qsort (result, result_index, sizeof (char *), _rl_qsort_string_compare);
|
||||
return (result);
|
||||
}
|
||||
|
||||
/* Stupid comparison routine for qsort () ing strings. */
|
||||
static int
|
||||
qsort_string_compare (s1, s2)
|
||||
register char **s1, **s2;
|
||||
{
|
||||
int r;
|
||||
|
||||
r = **s1 - **s2;
|
||||
if (r == 0)
|
||||
r = strcmp (*s1, *s2);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Things that mean `Control'. */
|
||||
char *possible_control_prefixes[] = {
|
||||
"Control-", "C-", "CTRL-", (char *)NULL
|
||||
@@ -251,49 +245,3 @@ char *possible_control_prefixes[] = {
|
||||
char *possible_meta_prefixes[] = {
|
||||
"Meta", "M-", (char *)NULL
|
||||
};
|
||||
|
||||
#if defined (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;
|
||||
|
||||
if (!pointer)
|
||||
temp = (char *)malloc (bytes);
|
||||
else
|
||||
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 */
|
||||
|
||||
1358
lib/readline/histexpand.c
Normal file
1358
lib/readline/histexpand.c
Normal file
File diff suppressed because it is too large
Load Diff
324
lib/readline/histfile.c
Normal file
324
lib/readline/histfile.c
Normal file
@@ -0,0 +1,324 @@
|
||||
/* histfile.c - functions to manipulate the history file. */
|
||||
|
||||
/* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
|
||||
|
||||
This file contains the GNU History Library (the Library), a set of
|
||||
routines for managing the text of previously typed lines.
|
||||
|
||||
The Library 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.
|
||||
|
||||
The Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* The goal is to make the implementation transparent, so that you
|
||||
don't have to know what data types are used, just what functions
|
||||
you can call. I think I have done that. */
|
||||
#define READLINE_LIBRARY
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#if defined (HAVE_STDLIB_H)
|
||||
# include <stdlib.h>
|
||||
#else
|
||||
# include "ansi_stdlib.h"
|
||||
#endif /* HAVE_STDLIB_H */
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_STRING_H)
|
||||
# include <string.h>
|
||||
#else
|
||||
# include <strings.h>
|
||||
#endif /* !HAVE_STRING_H */
|
||||
|
||||
#include <errno.h>
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif /* !errno */
|
||||
|
||||
#include "history.h"
|
||||
#include "histlib.h"
|
||||
|
||||
extern char *xmalloc (), *xrealloc ();
|
||||
|
||||
/* Return the string that should be used in the place of this
|
||||
filename. This only matters when you don't specify the
|
||||
filename to read_history (), or write_history (). */
|
||||
static char *
|
||||
history_filename (filename)
|
||||
char *filename;
|
||||
{
|
||||
char *return_val, *home;
|
||||
int home_len;
|
||||
|
||||
return_val = filename ? savestring (filename) : (char *)NULL;
|
||||
|
||||
if (return_val)
|
||||
return (return_val);
|
||||
|
||||
home = getenv ("HOME");
|
||||
|
||||
if (home == 0)
|
||||
{
|
||||
home = ".";
|
||||
home_len = 1;
|
||||
}
|
||||
else
|
||||
home_len = strlen (home);
|
||||
|
||||
return_val = xmalloc (2 + home_len + 8); /* strlen(".history") == 8 */
|
||||
strcpy (return_val, home);
|
||||
return_val[home_len] = '/';
|
||||
strcpy (return_val + home_len + 1, ".history");
|
||||
|
||||
return (return_val);
|
||||
}
|
||||
|
||||
/* Add the contents of FILENAME to the history list, a line at a time.
|
||||
If FILENAME is NULL, then read from ~/.history. Returns 0 if
|
||||
successful, or errno if not. */
|
||||
int
|
||||
read_history (filename)
|
||||
char *filename;
|
||||
{
|
||||
return (read_history_range (filename, 0, -1));
|
||||
}
|
||||
|
||||
/* Read a range of lines from FILENAME, adding them to the history list.
|
||||
Start reading at the FROM'th line and end at the TO'th. If FROM
|
||||
is zero, start at the beginning. If TO is less than FROM, read
|
||||
until the end of the file. If FILENAME is NULL, then read from
|
||||
~/.history. Returns 0 if successful, or errno if not. */
|
||||
int
|
||||
read_history_range (filename, from, to)
|
||||
char *filename;
|
||||
int from, to;
|
||||
{
|
||||
register int line_start, line_end;
|
||||
char *input, *buffer = (char *)NULL;
|
||||
int file, current_line;
|
||||
struct stat finfo;
|
||||
|
||||
input = history_filename (filename);
|
||||
file = open (input, O_RDONLY, 0666);
|
||||
|
||||
if ((file < 0) || (fstat (file, &finfo) == -1))
|
||||
goto error_and_exit;
|
||||
|
||||
buffer = xmalloc ((int)finfo.st_size + 1);
|
||||
|
||||
if (read (file, buffer, finfo.st_size) != finfo.st_size)
|
||||
{
|
||||
error_and_exit:
|
||||
if (file >= 0)
|
||||
close (file);
|
||||
|
||||
FREE (input);
|
||||
FREE (buffer);
|
||||
|
||||
return (errno);
|
||||
}
|
||||
|
||||
close (file);
|
||||
|
||||
/* Set TO to larger than end of file if negative. */
|
||||
if (to < 0)
|
||||
to = finfo.st_size;
|
||||
|
||||
/* Start at beginning of file, work to end. */
|
||||
line_start = line_end = current_line = 0;
|
||||
|
||||
/* Skip lines until we are at FROM. */
|
||||
while (line_start < finfo.st_size && current_line < from)
|
||||
{
|
||||
for (line_end = line_start; line_end < finfo.st_size; line_end++)
|
||||
if (buffer[line_end] == '\n')
|
||||
{
|
||||
current_line++;
|
||||
line_start = line_end + 1;
|
||||
if (current_line == from)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If there are lines left to gobble, then gobble them now. */
|
||||
for (line_end = line_start; line_end < finfo.st_size; line_end++)
|
||||
if (buffer[line_end] == '\n')
|
||||
{
|
||||
buffer[line_end] = '\0';
|
||||
|
||||
if (buffer[line_start])
|
||||
add_history (buffer + line_start);
|
||||
|
||||
current_line++;
|
||||
|
||||
if (current_line >= to)
|
||||
break;
|
||||
|
||||
line_start = line_end + 1;
|
||||
}
|
||||
|
||||
FREE (input);
|
||||
FREE (buffer);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Truncate the history file FNAME, leaving only LINES trailing lines.
|
||||
If FNAME is NULL, then use ~/.history. */
|
||||
int
|
||||
history_truncate_file (fname, lines)
|
||||
char *fname;
|
||||
register int lines;
|
||||
{
|
||||
register int i;
|
||||
int file, chars_read;
|
||||
char *buffer = (char *)NULL, *filename;
|
||||
struct stat finfo;
|
||||
|
||||
filename = history_filename (fname);
|
||||
file = open (filename, O_RDONLY, 0666);
|
||||
|
||||
if (file == -1 || fstat (file, &finfo) == -1)
|
||||
goto truncate_exit;
|
||||
|
||||
buffer = xmalloc ((int)finfo.st_size + 1);
|
||||
chars_read = read (file, buffer, finfo.st_size);
|
||||
close (file);
|
||||
|
||||
if (chars_read <= 0)
|
||||
goto truncate_exit;
|
||||
|
||||
/* Count backwards from the end of buffer until we have passed
|
||||
LINES lines. */
|
||||
for (i = chars_read - 1; lines && i; i--)
|
||||
{
|
||||
if (buffer[i] == '\n')
|
||||
lines--;
|
||||
}
|
||||
|
||||
/* If this is the first line, then the file contains exactly the
|
||||
number of lines we want to truncate to, so we don't need to do
|
||||
anything. It's the first line if we don't find a newline between
|
||||
the current value of i and 0. Otherwise, write from the start of
|
||||
this line until the end of the buffer. */
|
||||
for ( ; i; i--)
|
||||
if (buffer[i] == '\n')
|
||||
{
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Write only if there are more lines in the file than we want to
|
||||
truncate to. */
|
||||
if (i && ((file = open (filename, O_WRONLY|O_TRUNC, 0666)) != -1))
|
||||
{
|
||||
write (file, buffer + i, finfo.st_size - i);
|
||||
close (file);
|
||||
}
|
||||
|
||||
truncate_exit:
|
||||
|
||||
FREE (buffer);
|
||||
|
||||
free (filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Workhorse function for writing history. Writes NELEMENT entries
|
||||
from the history list to FILENAME. OVERWRITE is non-zero if you
|
||||
wish to replace FILENAME with the entries. */
|
||||
static int
|
||||
history_do_write (filename, nelements, overwrite)
|
||||
char *filename;
|
||||
int nelements, overwrite;
|
||||
{
|
||||
register int i;
|
||||
char *output = history_filename (filename);
|
||||
int file, mode;
|
||||
|
||||
mode = overwrite ? O_WRONLY | O_CREAT | O_TRUNC : O_WRONLY | O_APPEND;
|
||||
|
||||
if ((file = open (output, mode, 0666)) == -1)
|
||||
{
|
||||
FREE (output);
|
||||
return (errno);
|
||||
}
|
||||
|
||||
if (nelements > history_length)
|
||||
nelements = history_length;
|
||||
|
||||
/* Build a buffer of all the lines to write, and write them in one syscall.
|
||||
Suggested by Peter Ho (peter@robosts.oxford.ac.uk). */
|
||||
{
|
||||
HIST_ENTRY **the_history; /* local */
|
||||
register int j;
|
||||
int buffer_size;
|
||||
char *buffer;
|
||||
|
||||
the_history = history_list ();
|
||||
/* Calculate the total number of bytes to write. */
|
||||
for (buffer_size = 0, i = history_length - nelements; i < history_length; i++)
|
||||
buffer_size += 1 + strlen (the_history[i]->line);
|
||||
|
||||
/* Allocate the buffer, and fill it. */
|
||||
buffer = xmalloc (buffer_size);
|
||||
|
||||
for (j = 0, i = history_length - nelements; i < history_length; i++)
|
||||
{
|
||||
strcpy (buffer + j, the_history[i]->line);
|
||||
j += strlen (the_history[i]->line);
|
||||
buffer[j++] = '\n';
|
||||
}
|
||||
|
||||
write (file, buffer, buffer_size);
|
||||
free (buffer);
|
||||
}
|
||||
|
||||
close (file);
|
||||
|
||||
FREE (output);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Append NELEMENT entries to FILENAME. The entries appended are from
|
||||
the end of the list minus NELEMENTs up to the end of the list. */
|
||||
int
|
||||
append_history (nelements, filename)
|
||||
int nelements;
|
||||
char *filename;
|
||||
{
|
||||
return (history_do_write (filename, nelements, HISTORY_APPEND));
|
||||
}
|
||||
|
||||
/* Overwrite FILENAME with the current history. If FILENAME is NULL,
|
||||
then write the history list to ~/.history. Values returned
|
||||
are as in read_history ().*/
|
||||
int
|
||||
write_history (filename)
|
||||
char *filename;
|
||||
{
|
||||
return (history_do_write (filename, history_length, HISTORY_OVERWRITE));
|
||||
}
|
||||
81
lib/readline/histlib.h
Normal file
81
lib/readline/histlib.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/* histlib.h -- internal definitions for the history library. */
|
||||
/* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
|
||||
|
||||
This file contains the GNU History Library (the Library), a set of
|
||||
routines for managing the text of previously typed lines.
|
||||
|
||||
The Library 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.
|
||||
|
||||
The Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#if !defined (_HISTLIB_H_)
|
||||
#define _HISTLIB_H_
|
||||
|
||||
/* Function pointers can be declared as (Function *)foo. */
|
||||
#if !defined (_FUNCTION_DEF)
|
||||
# define _FUNCTION_DEF
|
||||
typedef int Function ();
|
||||
typedef void VFunction ();
|
||||
typedef char *CPFunction ();
|
||||
typedef char **CPPFunction ();
|
||||
#endif /* _FUNCTION_DEF */
|
||||
|
||||
#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0))
|
||||
#define STREQN(a, b, n) (((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0))
|
||||
|
||||
#ifndef savestring
|
||||
# ifndef strcpy
|
||||
extern char *strcpy ();
|
||||
# endif
|
||||
#define savestring(x) strcpy (xmalloc (1 + strlen (x)), (x))
|
||||
#endif
|
||||
|
||||
#ifndef whitespace
|
||||
#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
|
||||
#endif
|
||||
|
||||
#ifndef _rl_digit_p
|
||||
#define _rl_digit_p(c) ((c) >= '0' && (c) <= '9')
|
||||
#endif
|
||||
|
||||
#ifndef _rl_digit_value
|
||||
#define _rl_digit_value(c) ((c) - '0')
|
||||
#endif
|
||||
|
||||
#ifndef member
|
||||
# ifndef strchr
|
||||
extern char *strchr ();
|
||||
# endif
|
||||
#define member(c, s) ((c) ? ((char *)strchr ((s), (c)) != (char *)NULL) : 0)
|
||||
#endif
|
||||
|
||||
#ifndef FREE
|
||||
# define FREE(x) if (x) free (x)
|
||||
#endif
|
||||
|
||||
/* Possible history errors passed to hist_error. */
|
||||
#define EVENT_NOT_FOUND 0
|
||||
#define BAD_WORD_SPEC 1
|
||||
#define SUBST_FAILED 2
|
||||
#define BAD_MODIFIER 3
|
||||
|
||||
/* Possible definitions for history starting point specification. */
|
||||
#define ANCHORED_SEARCH 1
|
||||
#define NON_ANCHORED_SEARCH 0
|
||||
|
||||
/* Possible definitions for what style of writing the history file we want. */
|
||||
#define HISTORY_APPEND 0
|
||||
#define HISTORY_OVERWRITE 1
|
||||
|
||||
#endif /* !_HISTLIB_H_ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,26 @@
|
||||
/* History.h -- the names of functions that you can call in history. */
|
||||
/* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
|
||||
|
||||
This file contains the GNU History Library (the Library), a set of
|
||||
routines for managing the text of previously typed lines.
|
||||
|
||||
The Library 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.
|
||||
|
||||
The Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifndef _HISTORY_H_
|
||||
#define _HISTORY_H_
|
||||
|
||||
/* The structure used to store a history entry. */
|
||||
typedef struct _hist_entry {
|
||||
@@ -46,6 +68,9 @@ extern HIST_ENTRY *remove_history ();
|
||||
invalid WHICH, a NULL pointer is returned. */
|
||||
extern HIST_ENTRY *replace_history_entry ();
|
||||
|
||||
/* Clear the history list and start over. */
|
||||
extern void clear_history ();
|
||||
|
||||
/* Stifle the history list, remembering only MAX number of entries. */
|
||||
extern void stifle_history ();
|
||||
|
||||
@@ -179,3 +204,7 @@ extern char history_expansion_char;
|
||||
extern char history_subst_char;
|
||||
extern char history_comment_char;
|
||||
extern char *history_no_expand_chars;
|
||||
extern char *history_search_delimiter_chars;
|
||||
extern int history_quotes_inhibit_expansion;
|
||||
|
||||
#endif /* !_HISTORY_H_ */
|
||||
|
||||
197
lib/readline/histsearch.c
Normal file
197
lib/readline/histsearch.c
Normal file
@@ -0,0 +1,197 @@
|
||||
/* histsearch.c -- searching the history list. */
|
||||
|
||||
/* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
|
||||
|
||||
This file contains the GNU History Library (the Library), a set of
|
||||
routines for managing the text of previously typed lines.
|
||||
|
||||
The Library 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.
|
||||
|
||||
The Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#define READLINE_LIBRARY
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined (HAVE_STDLIB_H)
|
||||
# include <stdlib.h>
|
||||
#else
|
||||
# include "ansi_stdlib.h"
|
||||
#endif /* HAVE_STDLIB_H */
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#if defined (HAVE_STRING_H)
|
||||
# include <string.h>
|
||||
#else
|
||||
# include <strings.h>
|
||||
#endif /* !HAVE_STRING_H */
|
||||
|
||||
#include "history.h"
|
||||
#include "histlib.h"
|
||||
|
||||
/* Variables imported from other history library files. */
|
||||
extern int history_offset;
|
||||
|
||||
/* The list of alternate characters that can delimit a history search
|
||||
string. */
|
||||
char *history_search_delimiter_chars = (char *)NULL;
|
||||
|
||||
/* Search the history for STRING, starting at history_offset.
|
||||
If DIRECTION < 0, then the search is through previous entries, else
|
||||
through subsequent. If ANCHORED is non-zero, the string must
|
||||
appear at the beginning of a history line, otherwise, the string
|
||||
may appear anywhere in the line. If the string is found, then
|
||||
current_history () is the history entry, and the value of this
|
||||
function is the offset in the line of that history entry that the
|
||||
string was found in. Otherwise, nothing is changed, and a -1 is
|
||||
returned. */
|
||||
|
||||
static int
|
||||
history_search_internal (string, direction, anchored)
|
||||
char *string;
|
||||
int direction, anchored;
|
||||
{
|
||||
register int i, reverse;
|
||||
register char *line;
|
||||
register int line_index;
|
||||
int string_len;
|
||||
HIST_ENTRY **the_history; /* local */
|
||||
|
||||
i = history_offset;
|
||||
reverse = (direction < 0);
|
||||
|
||||
/* Take care of trivial cases first. */
|
||||
if (string == 0 || *string == '\0')
|
||||
return (-1);
|
||||
|
||||
if (!history_length || ((i == history_length) && !reverse))
|
||||
return (-1);
|
||||
|
||||
if (reverse && (i == history_length))
|
||||
i--;
|
||||
|
||||
#define NEXT_LINE() do { if (reverse) i--; else i++; } while (0)
|
||||
|
||||
the_history = history_list ();
|
||||
string_len = strlen (string);
|
||||
while (1)
|
||||
{
|
||||
/* Search each line in the history list for STRING. */
|
||||
|
||||
/* At limit for direction? */
|
||||
if ((reverse && i < 0) || (!reverse && i == history_length))
|
||||
return (-1);
|
||||
|
||||
line = the_history[i]->line;
|
||||
line_index = strlen (line);
|
||||
|
||||
/* If STRING is longer than line, no match. */
|
||||
if (string_len > line_index)
|
||||
{
|
||||
NEXT_LINE ();
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Handle anchored searches first. */
|
||||
if (anchored == ANCHORED_SEARCH)
|
||||
{
|
||||
if (STREQN (string, line, string_len))
|
||||
{
|
||||
history_offset = i;
|
||||
return (0);
|
||||
}
|
||||
|
||||
NEXT_LINE ();
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Do substring search. */
|
||||
if (reverse)
|
||||
{
|
||||
line_index -= string_len;
|
||||
|
||||
while (line_index >= 0)
|
||||
{
|
||||
if (STREQN (string, line + line_index, string_len))
|
||||
{
|
||||
history_offset = i;
|
||||
return (line_index);
|
||||
}
|
||||
line_index--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
register int limit;
|
||||
|
||||
limit = line_index - string_len + 1;
|
||||
line_index = 0;
|
||||
|
||||
while (line_index < limit)
|
||||
{
|
||||
if (STREQN (string, line + line_index, string_len))
|
||||
{
|
||||
history_offset = i;
|
||||
return (line_index);
|
||||
}
|
||||
line_index++;
|
||||
}
|
||||
}
|
||||
NEXT_LINE ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Do a non-anchored search for STRING through the history in DIRECTION. */
|
||||
int
|
||||
history_search (string, direction)
|
||||
char *string;
|
||||
int direction;
|
||||
{
|
||||
return (history_search_internal (string, direction, NON_ANCHORED_SEARCH));
|
||||
}
|
||||
|
||||
/* Do an anchored search for string through the history in DIRECTION. */
|
||||
int
|
||||
history_search_prefix (string, direction)
|
||||
char *string;
|
||||
int direction;
|
||||
{
|
||||
return (history_search_internal (string, direction, ANCHORED_SEARCH));
|
||||
}
|
||||
|
||||
/* Search for STRING in the history list. DIR is < 0 for searching
|
||||
backwards. POS is an absolute index into the history list at
|
||||
which point to begin searching. */
|
||||
int
|
||||
history_search_pos (string, dir, pos)
|
||||
char *string;
|
||||
int dir, pos;
|
||||
{
|
||||
int ret, old;
|
||||
|
||||
old = where_history ();
|
||||
history_set_pos (pos);
|
||||
if (history_search (string, dir) == -1)
|
||||
{
|
||||
history_set_pos (old);
|
||||
return (-1);
|
||||
}
|
||||
ret = where_history ();
|
||||
history_set_pos (old);
|
||||
return ret;
|
||||
}
|
||||
449
lib/readline/input.c
Normal file
449
lib/readline/input.c
Normal file
@@ -0,0 +1,449 @@
|
||||
/* input.c -- character input functions for readline. */
|
||||
|
||||
/* Copyright (C) 1994 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library 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 2, or
|
||||
(at your option) any later version.
|
||||
|
||||
The GNU Readline Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#define READLINE_LIBRARY
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#if defined (HAVE_SYS_FILE_H)
|
||||
# include <sys/file.h>
|
||||
#endif /* HAVE_SYS_FILE_H */
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif /* HAVE_UNISTD_H */
|
||||
|
||||
#if defined (HAVE_STDLIB_H)
|
||||
# include <stdlib.h>
|
||||
#else
|
||||
# include "ansi_stdlib.h"
|
||||
#endif /* HAVE_STDLIB_H */
|
||||
|
||||
#if defined (HAVE_SELECT)
|
||||
# if !defined (HAVE_SYS_SELECT_H) || !defined (M_UNIX)
|
||||
# include <sys/time.h>
|
||||
# endif
|
||||
#endif /* HAVE_SELECT */
|
||||
#if defined (HAVE_SYS_SELECT_H)
|
||||
# include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#if defined (FIONREAD_IN_SYS_IOCTL)
|
||||
# include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif /* !errno */
|
||||
|
||||
/* System-specific feature definitions and include files. */
|
||||
#include "rldefs.h"
|
||||
|
||||
/* Some standard library routines. */
|
||||
#include "readline.h"
|
||||
|
||||
/* What kind of non-blocking I/O do we have? */
|
||||
#if !defined (O_NDELAY) && defined (O_NONBLOCK)
|
||||
# define O_NDELAY O_NONBLOCK /* Posix style */
|
||||
#endif
|
||||
|
||||
/* Functions imported from other files in the library. */
|
||||
extern char *xmalloc (), *xrealloc ();
|
||||
|
||||
/* Variables and functions from macro.c. */
|
||||
extern void _rl_add_macro_char ();
|
||||
extern void _rl_with_macro_input ();
|
||||
extern int _rl_next_macro_key ();
|
||||
extern int _rl_defining_kbd_macro;
|
||||
|
||||
#if defined (VI_MODE)
|
||||
extern void _rl_vi_set_last ();
|
||||
extern int _rl_vi_textmod_command ();
|
||||
#endif /* VI_MODE */
|
||||
|
||||
extern FILE *rl_instream, *rl_outstream;
|
||||
extern Function *rl_last_func;
|
||||
extern int rl_key_sequence_length;
|
||||
extern int rl_pending_input;
|
||||
extern int rl_editing_mode;
|
||||
|
||||
extern Keymap _rl_keymap;
|
||||
|
||||
extern int _rl_convert_meta_chars_to_ascii;
|
||||
|
||||
#if defined (__GO32__)
|
||||
# include <pc.h>
|
||||
#endif /* __GO32__ */
|
||||
|
||||
/* Non-null means it is a pointer to a function to run while waiting for
|
||||
character input. */
|
||||
Function *rl_event_hook = (Function *)NULL;
|
||||
|
||||
Function *rl_getc_function = rl_getc;
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Character Input Buffering */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
static int pop_index, push_index;
|
||||
static unsigned char ibuffer[512];
|
||||
static int ibuffer_len = sizeof (ibuffer) - 1;
|
||||
|
||||
#define any_typein (push_index != pop_index)
|
||||
|
||||
int
|
||||
_rl_any_typein ()
|
||||
{
|
||||
return any_typein;
|
||||
}
|
||||
|
||||
/* Add KEY to the buffer of characters to be read. */
|
||||
int
|
||||
rl_stuff_char (key)
|
||||
int key;
|
||||
{
|
||||
if (key == EOF)
|
||||
{
|
||||
key = NEWLINE;
|
||||
rl_pending_input = EOF;
|
||||
}
|
||||
ibuffer[push_index++] = key;
|
||||
if (push_index >= ibuffer_len)
|
||||
push_index = 0;
|
||||
return push_index;
|
||||
}
|
||||
|
||||
/* Make C be the next command to be executed. */
|
||||
int
|
||||
rl_execute_next (c)
|
||||
int c;
|
||||
{
|
||||
rl_pending_input = c;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return the amount of space available in the
|
||||
buffer for stuffing characters. */
|
||||
static int
|
||||
ibuffer_space ()
|
||||
{
|
||||
if (pop_index > push_index)
|
||||
return (pop_index - push_index);
|
||||
else
|
||||
return (ibuffer_len - (push_index - pop_index));
|
||||
}
|
||||
|
||||
/* Get a key from the buffer of characters to be read.
|
||||
Return the key in KEY.
|
||||
Result is KEY if there was a key, or 0 if there wasn't. */
|
||||
static int
|
||||
rl_get_char (key)
|
||||
int *key;
|
||||
{
|
||||
if (push_index == pop_index)
|
||||
return (0);
|
||||
|
||||
*key = ibuffer[pop_index++];
|
||||
|
||||
if (pop_index >= ibuffer_len)
|
||||
pop_index = 0;
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Stuff KEY into the *front* of the input buffer.
|
||||
Returns non-zero if successful, zero if there is
|
||||
no space left in the buffer. */
|
||||
static int
|
||||
rl_unget_char (key)
|
||||
int key;
|
||||
{
|
||||
if (ibuffer_space ())
|
||||
{
|
||||
pop_index--;
|
||||
if (pop_index < 0)
|
||||
pop_index = ibuffer_len - 1;
|
||||
ibuffer[pop_index] = key;
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* If a character is available to be read, then read it
|
||||
and stuff it into IBUFFER. Otherwise, just return. */
|
||||
static void
|
||||
rl_gather_tyi ()
|
||||
{
|
||||
#if defined (__GO32__)
|
||||
char input;
|
||||
|
||||
if (isatty (0) && kbhit () && ibuffer_space ())
|
||||
{
|
||||
int i;
|
||||
i = (*rl_getc_function) (rl_instream);
|
||||
rl_stuff_char (i);
|
||||
}
|
||||
#else /* !__GO32__ */
|
||||
|
||||
int tty;
|
||||
register int tem, result;
|
||||
int chars_avail;
|
||||
char input;
|
||||
#if defined(HAVE_SELECT)
|
||||
fd_set readfds, exceptfds;
|
||||
struct timeval timeout;
|
||||
#endif
|
||||
|
||||
tty = fileno (rl_instream);
|
||||
|
||||
#if defined (HAVE_SELECT)
|
||||
FD_ZERO (&readfds);
|
||||
FD_ZERO (&exceptfds);
|
||||
FD_SET (tty, &readfds);
|
||||
FD_SET (tty, &exceptfds);
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 100000; /* 0.1 seconds */
|
||||
if (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) <= 0)
|
||||
return; /* Nothing to read. */
|
||||
#endif
|
||||
|
||||
result = -1;
|
||||
#if defined (FIONREAD)
|
||||
result = ioctl (tty, FIONREAD, &chars_avail);
|
||||
#endif
|
||||
|
||||
#if defined (O_NDELAY)
|
||||
if (result == -1)
|
||||
{
|
||||
tem = fcntl (tty, F_GETFL, 0);
|
||||
|
||||
fcntl (tty, F_SETFL, (tem | O_NDELAY));
|
||||
chars_avail = read (tty, &input, 1);
|
||||
|
||||
fcntl (tty, F_SETFL, tem);
|
||||
if (chars_avail == -1 && errno == EAGAIN)
|
||||
return;
|
||||
}
|
||||
#endif /* O_NDELAY */
|
||||
|
||||
/* If there's nothing available, don't waste time trying to read
|
||||
something. */
|
||||
if (chars_avail <= 0)
|
||||
return;
|
||||
|
||||
tem = ibuffer_space ();
|
||||
|
||||
if (chars_avail > tem)
|
||||
chars_avail = tem;
|
||||
|
||||
/* One cannot read all of the available input. I can only read a single
|
||||
character at a time, or else programs which require input can be
|
||||
thwarted. If the buffer is larger than one character, I lose.
|
||||
Damn! */
|
||||
if (tem < ibuffer_len)
|
||||
chars_avail = 0;
|
||||
|
||||
if (result != -1)
|
||||
{
|
||||
while (chars_avail--)
|
||||
rl_stuff_char ((*rl_getc_function) (rl_instream));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (chars_avail)
|
||||
rl_stuff_char (input);
|
||||
}
|
||||
#endif /* !__GO32__ */
|
||||
}
|
||||
|
||||
/* Is there input available to be read on the readline input file
|
||||
descriptor? Only works if the system has select(2) or FIONREAD. */
|
||||
int
|
||||
_rl_input_available ()
|
||||
{
|
||||
#if defined(HAVE_SELECT)
|
||||
fd_set readfds, exceptfds;
|
||||
struct timeval timeout;
|
||||
#endif
|
||||
#if defined(FIONREAD)
|
||||
int chars_avail;
|
||||
#endif
|
||||
int tty;
|
||||
|
||||
tty = fileno (rl_instream);
|
||||
|
||||
#if defined (HAVE_SELECT)
|
||||
FD_ZERO (&readfds);
|
||||
FD_ZERO (&exceptfds);
|
||||
FD_SET (tty, &readfds);
|
||||
FD_SET (tty, &exceptfds);
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 100000; /* 0.1 seconds */
|
||||
return (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) > 0);
|
||||
#endif
|
||||
|
||||
#if defined (FIONREAD)
|
||||
if (ioctl (tty, FIONREAD, &chars_avail) == 0)
|
||||
return (chars_avail);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
_rl_insert_typein (c)
|
||||
int c;
|
||||
{
|
||||
int key, t, i;
|
||||
char *string;
|
||||
|
||||
i = key = 0;
|
||||
string = xmalloc (ibuffer_len + 1);
|
||||
string[i++] = (char) c;
|
||||
|
||||
while ((t = rl_get_char (&key)) &&
|
||||
_rl_keymap[key].type == ISFUNC &&
|
||||
_rl_keymap[key].function == rl_insert)
|
||||
string[i++] = key;
|
||||
|
||||
if (t)
|
||||
rl_unget_char (key);
|
||||
|
||||
string[i] = '\0';
|
||||
rl_insert_text (string);
|
||||
free (string);
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Character Input */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Read a key, including pending input. */
|
||||
int
|
||||
rl_read_key ()
|
||||
{
|
||||
int c;
|
||||
|
||||
rl_key_sequence_length++;
|
||||
|
||||
if (rl_pending_input)
|
||||
{
|
||||
c = rl_pending_input;
|
||||
rl_pending_input = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If input is coming from a macro, then use that. */
|
||||
if (c = _rl_next_macro_key ())
|
||||
return (c);
|
||||
|
||||
/* If the user has an event function, then call it periodically. */
|
||||
if (rl_event_hook)
|
||||
{
|
||||
while (rl_event_hook && rl_get_char (&c) == 0)
|
||||
{
|
||||
(*rl_event_hook) ();
|
||||
rl_gather_tyi ();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rl_get_char (&c) == 0)
|
||||
c = (*rl_getc_function) (rl_instream);
|
||||
}
|
||||
}
|
||||
|
||||
return (c);
|
||||
}
|
||||
|
||||
int
|
||||
rl_getc (stream)
|
||||
FILE *stream;
|
||||
{
|
||||
int result, flags;
|
||||
unsigned char c;
|
||||
|
||||
#if defined (__GO32__)
|
||||
if (isatty (0))
|
||||
return (getkey () & 0x7F);
|
||||
#endif /* __GO32__ */
|
||||
|
||||
while (1)
|
||||
{
|
||||
result = read (fileno (stream), &c, sizeof (unsigned char));
|
||||
|
||||
if (result == sizeof (unsigned char))
|
||||
return (c);
|
||||
|
||||
/* If zero characters are returned, then the file that we are
|
||||
reading from is empty! Return EOF in that case. */
|
||||
if (result == 0)
|
||||
return (EOF);
|
||||
|
||||
#if defined (EWOULDBLOCK)
|
||||
if (errno == EWOULDBLOCK)
|
||||
{
|
||||
if ((flags = fcntl (fileno (stream), F_GETFL, 0)) < 0)
|
||||
return (EOF);
|
||||
if (flags & O_NDELAY)
|
||||
{
|
||||
flags &= ~O_NDELAY;
|
||||
fcntl (fileno (stream), F_SETFL, flags);
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
#endif /* EWOULDBLOCK */
|
||||
|
||||
#if defined (_POSIX_VERSION) && defined (EAGAIN) && defined (O_NONBLOCK)
|
||||
if (errno == EAGAIN)
|
||||
{
|
||||
if ((flags = fcntl (fileno (stream), F_GETFL, 0)) < 0)
|
||||
return (EOF);
|
||||
if (flags & O_NONBLOCK)
|
||||
{
|
||||
flags &= ~O_NONBLOCK;
|
||||
fcntl (fileno (stream), F_SETFL, flags);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif /* _POSIX_VERSION && EAGAIN && O_NONBLOCK */
|
||||
|
||||
#if !defined (__GO32__)
|
||||
/* If the error that we received was SIGINT, then try again,
|
||||
this is simply an interrupted system call to read ().
|
||||
Otherwise, some error ocurred, also signifying EOF. */
|
||||
if (errno != EINTR)
|
||||
return (EOF);
|
||||
#endif /* !__GO32__ */
|
||||
}
|
||||
}
|
||||
@@ -26,19 +26,22 @@
|
||||
675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#define READLINE_LIBRARY
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "memalloc.h"
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "rldefs.h"
|
||||
#include "readline.h"
|
||||
#include "history.h"
|
||||
|
||||
#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0))
|
||||
#define STREQN(a, b, n) (((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0))
|
||||
|
||||
/* Variables imported from other files in the readline library. */
|
||||
extern Keymap _rl_keymap;
|
||||
extern HIST_ENTRY *saved_line_for_history;
|
||||
@@ -46,6 +49,14 @@ extern int rl_line_buffer_len;
|
||||
extern int rl_point, rl_end;
|
||||
extern char *rl_line_buffer;
|
||||
|
||||
extern void _rl_save_prompt ();
|
||||
extern void _rl_restore_prompt ();
|
||||
|
||||
extern int rl_execute_next ();
|
||||
extern void rl_extend_line_buffer ();
|
||||
|
||||
extern int _rl_input_available ();
|
||||
|
||||
extern char *xmalloc (), *xrealloc ();
|
||||
|
||||
static int rl_search_history ();
|
||||
@@ -56,18 +67,18 @@ static char *prev_line_found;
|
||||
|
||||
/* Search backwards through the history looking for a string which is typed
|
||||
interactively. Start with the current line. */
|
||||
int
|
||||
rl_reverse_search_history (sign, key)
|
||||
int sign;
|
||||
int key;
|
||||
int sign, key;
|
||||
{
|
||||
return (rl_search_history (-sign, key));
|
||||
}
|
||||
|
||||
/* Search forwards through the history looking for a string which is typed
|
||||
interactively. Start with the current line. */
|
||||
int
|
||||
rl_forward_search_history (sign, key)
|
||||
int sign;
|
||||
int key;
|
||||
int sign, key;
|
||||
{
|
||||
return (rl_search_history (sign, key));
|
||||
}
|
||||
@@ -83,29 +94,43 @@ rl_display_search (search_string, reverse_p, where)
|
||||
int reverse_p, where;
|
||||
{
|
||||
char *message;
|
||||
int msglen, searchlen;
|
||||
|
||||
message = xmalloc (1 + (search_string ? strlen (search_string) : 0) + 30);
|
||||
*message = '\0';
|
||||
searchlen = (search_string && *search_string) ? strlen (search_string) : 0;
|
||||
|
||||
message = xmalloc (searchlen + 33);
|
||||
msglen = 0;
|
||||
|
||||
#if defined (NOTDEF)
|
||||
if (where != -1)
|
||||
sprintf (message, "[%d]", where + history_base);
|
||||
{
|
||||
sprintf (message, "[%d]", where + history_base);
|
||||
msglen = strlen (message);
|
||||
}
|
||||
#endif /* NOTDEF */
|
||||
|
||||
strcat (message, "(");
|
||||
message[msglen++] = '(';
|
||||
|
||||
if (reverse_p)
|
||||
strcat (message, "reverse-");
|
||||
{
|
||||
strcpy (message + msglen, "reverse-");
|
||||
msglen += 8;
|
||||
}
|
||||
|
||||
strcat (message, "i-search)`");
|
||||
strcpy (message + msglen, "i-search)`");
|
||||
msglen += 10;
|
||||
|
||||
if (search_string)
|
||||
strcat (message, search_string);
|
||||
{
|
||||
strcpy (message + msglen, search_string);
|
||||
msglen += searchlen;
|
||||
}
|
||||
|
||||
strcpy (message + msglen, "': ");
|
||||
|
||||
strcat (message, "': ");
|
||||
rl_message ("%s", message, 0);
|
||||
free (message);
|
||||
rl_redisplay ();
|
||||
(*rl_redisplay_function) ();
|
||||
}
|
||||
|
||||
/* Search through the history looking for an interactively typed string.
|
||||
@@ -114,8 +139,7 @@ rl_display_search (search_string, reverse_p, where)
|
||||
backwards. */
|
||||
static int
|
||||
rl_search_history (direction, invoking_key)
|
||||
int direction;
|
||||
int invoking_key;
|
||||
int direction, invoking_key;
|
||||
{
|
||||
/* The string that the user types in to search for. */
|
||||
char *search_string;
|
||||
@@ -127,19 +151,17 @@ rl_search_history (direction, invoking_key)
|
||||
int search_string_size;
|
||||
|
||||
/* The list of lines to search through. */
|
||||
char **lines, *allocated_line = (char *)NULL;
|
||||
char **lines, *allocated_line;
|
||||
|
||||
/* The length of LINES. */
|
||||
int hlen;
|
||||
|
||||
/* Where we get LINES from. */
|
||||
HIST_ENTRY **hlist = history_list ();
|
||||
HIST_ENTRY **hlist;
|
||||
|
||||
register int i = 0;
|
||||
int orig_point = rl_point;
|
||||
int orig_line = where_history ();
|
||||
int last_found_line = orig_line;
|
||||
int c, done = 0, found, failed, sline_len;
|
||||
register int i;
|
||||
int orig_point, orig_line, last_found_line;
|
||||
int c, found, failed, sline_len;
|
||||
|
||||
/* The line currently being searched. */
|
||||
char *sline;
|
||||
@@ -148,10 +170,17 @@ rl_search_history (direction, invoking_key)
|
||||
int line_index;
|
||||
|
||||
/* Non-zero if we are doing a reverse search. */
|
||||
int reverse = (direction < 0);
|
||||
int reverse;
|
||||
|
||||
orig_point = rl_point;
|
||||
last_found_line = orig_line = where_history ();
|
||||
reverse = direction < 0;
|
||||
hlist = history_list ();
|
||||
allocated_line = (char *)NULL;
|
||||
|
||||
/* Create an arrary of pointers to the lines that we want to search. */
|
||||
maybe_replace_line ();
|
||||
i = 0;
|
||||
if (hlist)
|
||||
for (i = 0; hlist[i]; i++);
|
||||
|
||||
@@ -176,6 +205,8 @@ rl_search_history (direction, invoking_key)
|
||||
/* The line where we start the search. */
|
||||
i = orig_line;
|
||||
|
||||
_rl_save_prompt ();
|
||||
|
||||
/* Initialize search parameters. */
|
||||
search_string = xmalloc (search_string_size = 128);
|
||||
*search_string = '\0';
|
||||
@@ -192,14 +223,13 @@ rl_search_history (direction, invoking_key)
|
||||
line_index = rl_point;
|
||||
|
||||
found = failed = 0;
|
||||
while (!done)
|
||||
for (;;)
|
||||
{
|
||||
Function *f = (Function *)NULL;
|
||||
|
||||
/* Read a key and decide how to proceed. */
|
||||
c = rl_read_key ();
|
||||
|
||||
/* Hack C to Do What I Mean. */
|
||||
if (_rl_keymap[c].type == ISFUNC)
|
||||
{
|
||||
f = _rl_keymap[c].function;
|
||||
@@ -210,78 +240,81 @@ rl_search_history (direction, invoking_key)
|
||||
c = !reverse ? -1 : -2;
|
||||
}
|
||||
|
||||
/* Let NEWLINE (^J) terminate the search for people who don't like
|
||||
using ESC. ^M can still be used to terminate the search and
|
||||
immediately execute the command. */
|
||||
if (c == ESC || c == NEWLINE)
|
||||
{
|
||||
/* ESC still terminates the search, but if there is pending
|
||||
input or if input arrives within 0.1 seconds (on systems
|
||||
with select(2)) it is used as a prefix character
|
||||
with rl_execute_next. WATCH OUT FOR THIS! This is intended
|
||||
to allow the arrow keys to be used like ^F and ^B are used
|
||||
to terminate the search and execute the movement command. */
|
||||
if (c == ESC && _rl_input_available ()) /* XXX */
|
||||
rl_execute_next (ESC);
|
||||
break;
|
||||
}
|
||||
|
||||
if (c >= 0 && (CTRL_CHAR (c) || META_CHAR (c) || c == RUBOUT))
|
||||
{
|
||||
rl_execute_next (c);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case ESC:
|
||||
done = 1;
|
||||
continue;
|
||||
|
||||
case -1:
|
||||
if (!search_string_index)
|
||||
if (search_string_index == 0)
|
||||
continue;
|
||||
else if (reverse)
|
||||
--line_index;
|
||||
else if (line_index != sline_len)
|
||||
++line_index;
|
||||
else
|
||||
{
|
||||
if (reverse)
|
||||
--line_index;
|
||||
else
|
||||
{
|
||||
if (line_index != sline_len)
|
||||
++line_index;
|
||||
else
|
||||
ding ();
|
||||
}
|
||||
}
|
||||
ding ();
|
||||
break;
|
||||
|
||||
/* switch directions */
|
||||
case -2:
|
||||
direction = -direction;
|
||||
reverse = (direction < 0);
|
||||
reverse = direction < 0;
|
||||
break;
|
||||
|
||||
case CTRL ('G'):
|
||||
strcpy (rl_line_buffer, lines[orig_line]);
|
||||
rl_point = orig_point;
|
||||
rl_end = strlen (rl_line_buffer);
|
||||
_rl_restore_prompt();
|
||||
rl_clear_message ();
|
||||
free (allocated_line);
|
||||
free (lines);
|
||||
return 0;
|
||||
|
||||
default:
|
||||
if (CTRL_CHAR (c) || META_CHAR (c) || c == RUBOUT)
|
||||
/* Add character to search string and continue search. */
|
||||
if (search_string_index + 2 >= search_string_size)
|
||||
{
|
||||
rl_execute_next (c);
|
||||
done = 1;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Add character to search string and continue search. */
|
||||
if (search_string_index + 2 >= search_string_size)
|
||||
{
|
||||
search_string_size += 128;
|
||||
search_string = xrealloc (search_string, search_string_size);
|
||||
}
|
||||
search_string[search_string_index++] = c;
|
||||
search_string[search_string_index] = '\0';
|
||||
break;
|
||||
search_string_size += 128;
|
||||
search_string = xrealloc (search_string, search_string_size);
|
||||
}
|
||||
search_string[search_string_index++] = c;
|
||||
search_string[search_string_index] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
found = failed = 0;
|
||||
while (1)
|
||||
for (found = failed = 0;;)
|
||||
{
|
||||
int limit = sline_len - search_string_index + 1;
|
||||
|
||||
/* Search the current line. */
|
||||
while (reverse ? (line_index >= 0) : (line_index < limit))
|
||||
{
|
||||
if (STREQN(search_string, sline + line_index, search_string_index))
|
||||
{
|
||||
found++;
|
||||
break;
|
||||
}
|
||||
if (STREQN (search_string, sline + line_index, search_string_index))
|
||||
{
|
||||
found++;
|
||||
break;
|
||||
}
|
||||
else
|
||||
line_index += direction;
|
||||
}
|
||||
@@ -314,10 +347,7 @@ rl_search_history (direction, invoking_key)
|
||||
break;
|
||||
|
||||
/* Now set up the line for searching... */
|
||||
if (reverse)
|
||||
line_index = sline_len - search_string_index;
|
||||
else
|
||||
line_index = 0;
|
||||
line_index = reverse ? sline_len - search_string_index : 0;
|
||||
}
|
||||
|
||||
if (failed)
|
||||
@@ -357,6 +387,8 @@ rl_search_history (direction, invoking_key)
|
||||
/* First put back the original state. */
|
||||
strcpy (rl_line_buffer, lines[orig_line]);
|
||||
|
||||
_rl_restore_prompt ();
|
||||
|
||||
/* Free the search string. */
|
||||
free (search_string);
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#define READLINE_LIBRARY
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include "config.h"
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_STDLIB_H)
|
||||
@@ -41,11 +41,7 @@
|
||||
extern int rl_do_lowercase_version ();
|
||||
extern int rl_rubout (), rl_insert ();
|
||||
|
||||
#if defined (STATIC_MALLOC)
|
||||
static char *xmalloc (), *xrealloc ();
|
||||
#else
|
||||
extern char *xmalloc (), *xrealloc ();
|
||||
#endif /* STATIC_MALLOC */
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
@@ -109,7 +105,7 @@ rl_make_keymap ()
|
||||
newmap[i].function = rl_insert;
|
||||
|
||||
newmap[TAB].function = rl_insert;
|
||||
newmap[RUBOUT].function = rl_rubout;
|
||||
newmap[RUBOUT].function = rl_rubout; /* RUBOUT == 127 */
|
||||
newmap[CTRL('H')].function = rl_rubout;
|
||||
|
||||
#if KEYMAP_SIZE > 128
|
||||
@@ -152,49 +148,3 @@ rl_discard_keymap (map)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined (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;
|
||||
|
||||
if (!pointer)
|
||||
temp = (char *)malloc (bytes);
|
||||
else
|
||||
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 */
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
# include <readline/chardefs.h>
|
||||
#endif
|
||||
|
||||
#if !defined (__FUNCTION_DEF)
|
||||
# define __FUNCTION_DEF
|
||||
#if !defined (_FUNCTION_DEF)
|
||||
# define _FUNCTION_DEF
|
||||
typedef int Function ();
|
||||
typedef void VFunction ();
|
||||
typedef char *CPFunction ();
|
||||
|
||||
547
lib/readline/kill.c
Normal file
547
lib/readline/kill.c
Normal file
@@ -0,0 +1,547 @@
|
||||
/* kill.c -- kill ring management. */
|
||||
|
||||
/* Copyright (C) 1994 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library 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.
|
||||
|
||||
The GNU Readline Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#define READLINE_LIBRARY
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h> /* for _POSIX_VERSION */
|
||||
#endif /* HAVE_UNISTD_H */
|
||||
|
||||
#if defined (HAVE_STDLIB_H)
|
||||
# include <stdlib.h>
|
||||
#else
|
||||
# include "ansi_stdlib.h"
|
||||
#endif /* HAVE_STDLIB_H */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* System-specific feature definitions and include files. */
|
||||
#include "rldefs.h"
|
||||
|
||||
/* Some standard library routines. */
|
||||
#include "readline.h"
|
||||
#include "history.h"
|
||||
|
||||
extern int _rl_last_command_was_kill;
|
||||
extern int rl_editing_mode;
|
||||
extern int rl_explicit_arg;
|
||||
extern Function *rl_last_func;
|
||||
|
||||
extern void _rl_init_argument ();
|
||||
extern int _rl_set_mark_at_pos ();
|
||||
extern void _rl_abort_internal ();
|
||||
|
||||
extern char *xmalloc (), *xrealloc ();
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Killing Mechanism */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* What we assume for a max number of kills. */
|
||||
#define DEFAULT_MAX_KILLS 10
|
||||
|
||||
/* The real variable to look at to find out when to flush kills. */
|
||||
static int rl_max_kills = DEFAULT_MAX_KILLS;
|
||||
|
||||
/* Where to store killed text. */
|
||||
static char **rl_kill_ring = (char **)NULL;
|
||||
|
||||
/* Where we are in the kill ring. */
|
||||
static int rl_kill_index;
|
||||
|
||||
/* How many slots we have in the kill ring. */
|
||||
static int rl_kill_ring_length;
|
||||
|
||||
/* How to say that you only want to save a certain amount
|
||||
of kill material. */
|
||||
int
|
||||
rl_set_retained_kills (num)
|
||||
int num;
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Add TEXT to the kill ring, allocating a new kill ring slot as necessary.
|
||||
This uses TEXT directly, so the caller must not free it. If APPEND is
|
||||
non-zero, and the last command was a kill, the text is appended to the
|
||||
current kill ring slot, otherwise prepended. */
|
||||
static int
|
||||
_rl_copy_to_kill_ring (text, append)
|
||||
char *text;
|
||||
int append;
|
||||
{
|
||||
char *old, *new;
|
||||
int slot;
|
||||
|
||||
/* First, find the slot to work with. */
|
||||
if (_rl_last_command_was_kill == 0)
|
||||
{
|
||||
/* Get a new slot. */
|
||||
if (rl_kill_ring == 0)
|
||||
{
|
||||
/* If we don't have any defined, then make one. */
|
||||
rl_kill_ring = (char **)
|
||||
xmalloc (((rl_kill_ring_length = 1) + 1) * sizeof (char *));
|
||||
rl_kill_ring[slot = 0] = (char *)NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We have to add a new slot on the end, unless we have
|
||||
exceeded the max limit for remembering kills. */
|
||||
slot = rl_kill_ring_length;
|
||||
if (slot == rl_max_kills)
|
||||
{
|
||||
register int i;
|
||||
free (rl_kill_ring[0]);
|
||||
for (i = 0; i < slot; i++)
|
||||
rl_kill_ring[i] = rl_kill_ring[i + 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
slot = rl_kill_ring_length += 1;
|
||||
rl_kill_ring = (char **)xrealloc (rl_kill_ring, slot * sizeof (char *));
|
||||
}
|
||||
rl_kill_ring[--slot] = (char *)NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
slot = rl_kill_ring_length - 1;
|
||||
|
||||
/* If the last command was a kill, prepend or append. */
|
||||
if (_rl_last_command_was_kill && rl_editing_mode != vi_mode)
|
||||
{
|
||||
old = rl_kill_ring[slot];
|
||||
new = xmalloc (1 + strlen (old) + strlen (text));
|
||||
|
||||
if (append)
|
||||
{
|
||||
strcpy (new, old);
|
||||
strcat (new, text);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy (new, text);
|
||||
strcat (new, old);
|
||||
}
|
||||
free (old);
|
||||
free (text);
|
||||
rl_kill_ring[slot] = new;
|
||||
}
|
||||
else
|
||||
rl_kill_ring[slot] = text;
|
||||
|
||||
rl_kill_index = slot;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The way to kill something. This appends or prepends to the last
|
||||
kill, if the last command was a kill command. if FROM is less
|
||||
than TO, then the text is appended, otherwise prepended. If the
|
||||
last command was not a kill command, then a new slot is made for
|
||||
this kill. */
|
||||
int
|
||||
rl_kill_text (from, to)
|
||||
int from, to;
|
||||
{
|
||||
char *text;
|
||||
|
||||
/* Is there anything to kill? */
|
||||
if (from == to)
|
||||
{
|
||||
_rl_last_command_was_kill++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
text = rl_copy_text (from, to);
|
||||
|
||||
/* Delete the copied text from the line. */
|
||||
rl_delete_text (from, to);
|
||||
|
||||
_rl_copy_to_kill_ring (text, from < to);
|
||||
|
||||
_rl_last_command_was_kill++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Now REMEMBER! In order to do prepending or appending correctly, kill
|
||||
commands always make rl_point's original position be the FROM argument,
|
||||
and rl_point's extent be the TO argument. */
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Killing Commands */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Delete the word at point, saving the text in the kill ring. */
|
||||
int
|
||||
rl_kill_word (count, key)
|
||||
int count, key;
|
||||
{
|
||||
int orig_point = rl_point;
|
||||
|
||||
if (count < 0)
|
||||
return (rl_backward_kill_word (-count, key));
|
||||
else
|
||||
{
|
||||
rl_forward_word (count, key);
|
||||
|
||||
if (rl_point != orig_point)
|
||||
rl_kill_text (orig_point, rl_point);
|
||||
|
||||
rl_point = orig_point;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Rubout the word before point, placing it on the kill ring. */
|
||||
int
|
||||
rl_backward_kill_word (count, ignore)
|
||||
int count, ignore;
|
||||
{
|
||||
int orig_point = rl_point;
|
||||
|
||||
if (count < 0)
|
||||
return (rl_kill_word (-count, ignore));
|
||||
else
|
||||
{
|
||||
rl_backward_word (count, ignore);
|
||||
|
||||
if (rl_point != orig_point)
|
||||
rl_kill_text (orig_point, rl_point);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Kill from here to the end of the line. If DIRECTION is negative, kill
|
||||
back to the line start instead. */
|
||||
int
|
||||
rl_kill_line (direction, ignore)
|
||||
int direction, ignore;
|
||||
{
|
||||
int orig_point = rl_point;
|
||||
|
||||
if (direction < 0)
|
||||
return (rl_backward_kill_line (1, ignore));
|
||||
else
|
||||
{
|
||||
rl_end_of_line (1, ignore);
|
||||
if (orig_point != rl_point)
|
||||
rl_kill_text (orig_point, rl_point);
|
||||
rl_point = orig_point;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Kill backwards to the start of the line. If DIRECTION is negative, kill
|
||||
forwards to the line end instead. */
|
||||
int
|
||||
rl_backward_kill_line (direction, ignore)
|
||||
int direction, ignore;
|
||||
{
|
||||
int orig_point = rl_point;
|
||||
|
||||
if (direction < 0)
|
||||
return (rl_kill_line (1, ignore));
|
||||
else
|
||||
{
|
||||
if (!rl_point)
|
||||
ding ();
|
||||
else
|
||||
{
|
||||
rl_beg_of_line (1, ignore);
|
||||
rl_kill_text (orig_point, rl_point);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Kill the whole line, no matter where point is. */
|
||||
int
|
||||
rl_kill_full_line (count, ignore)
|
||||
int count, ignore;
|
||||
{
|
||||
rl_begin_undo_group ();
|
||||
rl_point = 0;
|
||||
rl_kill_text (rl_point, rl_end);
|
||||
rl_end_undo_group ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The next two functions mimic unix line editing behaviour, except they
|
||||
save the deleted text on the kill ring. This is safer than not saving
|
||||
it, and since we have a ring, nobody should get screwed. */
|
||||
|
||||
/* This does what C-w does in Unix. We can't prevent people from
|
||||
using behaviour that they expect. */
|
||||
int
|
||||
rl_unix_word_rubout (count, key)
|
||||
int count, key;
|
||||
{
|
||||
int orig_point;
|
||||
|
||||
if (rl_point == 0)
|
||||
ding ();
|
||||
else
|
||||
{
|
||||
orig_point = rl_point;
|
||||
if (count <= 0)
|
||||
count = 1;
|
||||
|
||||
while (count--)
|
||||
{
|
||||
while (rl_point && whitespace (rl_line_buffer[rl_point - 1]))
|
||||
rl_point--;
|
||||
|
||||
while (rl_point && (whitespace (rl_line_buffer[rl_point - 1]) == 0))
|
||||
rl_point--;
|
||||
}
|
||||
|
||||
rl_kill_text (orig_point, rl_point);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Here is C-u doing what Unix does. You don't *have* to use these
|
||||
key-bindings. We have a choice of killing the entire line, or
|
||||
killing from where we are to the start of the line. We choose the
|
||||
latter, because if you are a Unix weenie, then you haven't backspaced
|
||||
into the line at all, and if you aren't, then you know what you are
|
||||
doing. */
|
||||
int
|
||||
rl_unix_line_discard (count, key)
|
||||
int count, key;
|
||||
{
|
||||
if (rl_point == 0)
|
||||
ding ();
|
||||
else
|
||||
{
|
||||
rl_kill_text (rl_point, 0);
|
||||
rl_point = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Copy the text in the `region' to the kill ring. If DELETE is non-zero,
|
||||
delete the text from the line as well. */
|
||||
static int
|
||||
region_kill_internal (delete)
|
||||
int delete;
|
||||
{
|
||||
char *text;
|
||||
|
||||
if (rl_mark == rl_point)
|
||||
{
|
||||
_rl_last_command_was_kill++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
text = rl_copy_text (rl_point, rl_mark);
|
||||
if (delete)
|
||||
rl_delete_text (rl_point, rl_mark);
|
||||
_rl_copy_to_kill_ring (text, rl_point < rl_mark);
|
||||
|
||||
_rl_last_command_was_kill++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Copy the text in the region to the kill ring. */
|
||||
int
|
||||
rl_copy_region_to_kill (count, ignore)
|
||||
int count, ignore;
|
||||
{
|
||||
return (region_kill_internal (0));
|
||||
}
|
||||
|
||||
/* Kill the text between the point and mark. */
|
||||
int
|
||||
rl_kill_region (count, ignore)
|
||||
int count, ignore;
|
||||
{
|
||||
return (region_kill_internal (1));
|
||||
}
|
||||
|
||||
/* Copy COUNT words to the kill ring. DIR says which direction we look
|
||||
to find the words. */
|
||||
static int
|
||||
_rl_copy_word_as_kill (count, dir)
|
||||
int count, dir;
|
||||
{
|
||||
int om, op, r;
|
||||
|
||||
om = rl_mark;
|
||||
op = rl_point;
|
||||
|
||||
if (dir > 0)
|
||||
rl_forward_word (count, 0);
|
||||
else
|
||||
rl_backward_word (count, 0);
|
||||
|
||||
rl_mark = rl_point;
|
||||
|
||||
if (dir > 0)
|
||||
rl_backward_word (count, 0);
|
||||
else
|
||||
rl_forward_word (count, 0);
|
||||
|
||||
r = region_kill_internal (0);
|
||||
|
||||
rl_mark = om;
|
||||
rl_point = op;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
rl_copy_forward_word (count, key)
|
||||
int count, key;
|
||||
{
|
||||
if (count < 0)
|
||||
return (rl_copy_backward_word (-count, key));
|
||||
|
||||
return (_rl_copy_word_as_kill (count, 1));
|
||||
}
|
||||
|
||||
int
|
||||
rl_copy_backward_word (count, key)
|
||||
int count, key;
|
||||
{
|
||||
if (count < 0)
|
||||
return (rl_copy_forward_word (-count, key));
|
||||
|
||||
return (_rl_copy_word_as_kill (count, -1));
|
||||
}
|
||||
|
||||
/* Yank back the last killed text. This ignores arguments. */
|
||||
int
|
||||
rl_yank (count, ignore)
|
||||
int count, ignore;
|
||||
{
|
||||
if (rl_kill_ring == 0)
|
||||
{
|
||||
_rl_abort_internal ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
_rl_set_mark_at_pos (rl_point);
|
||||
rl_insert_text (rl_kill_ring[rl_kill_index]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If the last command was yank, or yank_pop, and the text just
|
||||
before point is identical to the current kill item, then
|
||||
delete that text from the line, rotate the index down, and
|
||||
yank back some other text. */
|
||||
int
|
||||
rl_yank_pop (count, key)
|
||||
int count, key;
|
||||
{
|
||||
int l, n;
|
||||
|
||||
if (((rl_last_func != rl_yank_pop) && (rl_last_func != rl_yank)) ||
|
||||
!rl_kill_ring)
|
||||
{
|
||||
_rl_abort_internal ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
l = strlen (rl_kill_ring[rl_kill_index]);
|
||||
n = rl_point - l;
|
||||
if (n >= 0 && STREQN (rl_line_buffer + n, rl_kill_ring[rl_kill_index], l))
|
||||
{
|
||||
rl_delete_text (n, rl_point);
|
||||
rl_point = n;
|
||||
rl_kill_index--;
|
||||
if (rl_kill_index < 0)
|
||||
rl_kill_index = rl_kill_ring_length - 1;
|
||||
rl_yank (1, 0);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_rl_abort_internal ();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Yank the COUNTth argument from the previous history line. */
|
||||
int
|
||||
rl_yank_nth_arg (count, ignore)
|
||||
int count, ignore;
|
||||
{
|
||||
register HIST_ENTRY *entry;
|
||||
char *arg;
|
||||
|
||||
entry = previous_history ();
|
||||
if (entry)
|
||||
next_history ();
|
||||
else
|
||||
{
|
||||
ding ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
arg = history_arg_extract (count, count, entry->line);
|
||||
if (!arg || !*arg)
|
||||
{
|
||||
ding ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
rl_begin_undo_group ();
|
||||
|
||||
#if defined (VI_MODE)
|
||||
/* Vi mode always inserts a space before yanking the argument, and it
|
||||
inserts it right *after* rl_point. */
|
||||
if (rl_editing_mode == vi_mode)
|
||||
{
|
||||
rl_vi_append_mode ();
|
||||
rl_insert_text (" ");
|
||||
}
|
||||
#endif /* VI_MODE */
|
||||
|
||||
rl_insert_text (arg);
|
||||
free (arg);
|
||||
|
||||
rl_end_undo_group ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Yank the last argument from the previous history line. This `knows'
|
||||
how rl_yank_nth_arg treats a count of `$'. With an argument, this
|
||||
behaves the same as rl_yank_nth_arg. */
|
||||
int
|
||||
rl_yank_last_arg (count, key)
|
||||
int count, key;
|
||||
{
|
||||
if (rl_explicit_arg)
|
||||
return (rl_yank_nth_arg (count, key));
|
||||
else
|
||||
return (rl_yank_nth_arg ('$', key));
|
||||
}
|
||||
277
lib/readline/macro.c
Normal file
277
lib/readline/macro.c
Normal file
@@ -0,0 +1,277 @@
|
||||
/* macro.c -- keyboard macros for readline. */
|
||||
|
||||
/* Copyright (C) 1994 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library 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.
|
||||
|
||||
The GNU Readline Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#define READLINE_LIBRARY
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h> /* for _POSIX_VERSION */
|
||||
#endif /* HAVE_UNISTD_H */
|
||||
|
||||
#if defined (HAVE_STDLIB_H)
|
||||
# include <stdlib.h>
|
||||
#else
|
||||
# include "ansi_stdlib.h"
|
||||
#endif /* HAVE_STDLIB_H */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* System-specific feature definitions and include files. */
|
||||
#include "rldefs.h"
|
||||
|
||||
/* Some standard library routines. */
|
||||
#include "readline.h"
|
||||
#include "history.h"
|
||||
|
||||
#define SWAP(s, e) do { int t; t = s; s = e; e = t; } while (0)
|
||||
|
||||
/* Forward definitions. */
|
||||
void _rl_push_executing_macro (), _rl_pop_executing_macro ();
|
||||
void _rl_add_macro_char ();
|
||||
|
||||
/* Extern declarations. */
|
||||
extern int rl_explicit_arg;
|
||||
extern int rl_key_sequence_length;
|
||||
|
||||
extern void _rl_abort_internal ();
|
||||
|
||||
extern char *xmalloc (), *xrealloc ();
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Hacking Keyboard Macros */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Non-zero means to save keys that we dispatch on in a kbd macro. */
|
||||
int _rl_defining_kbd_macro = 0;
|
||||
|
||||
/* The currently executing macro string. If this is non-zero,
|
||||
then it is a malloc ()'ed string where input is coming from. */
|
||||
char *_rl_executing_macro = (char *)NULL;
|
||||
|
||||
/* The offset in the above string to the next character to be read. */
|
||||
static int executing_macro_index;
|
||||
|
||||
/* The current macro string being built. Characters get stuffed
|
||||
in here by add_macro_char (). */
|
||||
static char *current_macro = (char *)NULL;
|
||||
|
||||
/* The size of the buffer allocated to current_macro. */
|
||||
static int current_macro_size;
|
||||
|
||||
/* The index at which characters are being added to current_macro. */
|
||||
static int current_macro_index;
|
||||
|
||||
/* A structure used to save nested macro strings.
|
||||
It is a linked list of string/index for each saved macro. */
|
||||
struct saved_macro {
|
||||
struct saved_macro *next;
|
||||
char *string;
|
||||
int sindex;
|
||||
};
|
||||
|
||||
/* The list of saved macros. */
|
||||
static struct saved_macro *macro_list = (struct saved_macro *)NULL;
|
||||
|
||||
/* Set up to read subsequent input from STRING.
|
||||
STRING is free ()'ed when we are done with it. */
|
||||
void
|
||||
_rl_with_macro_input (string)
|
||||
char *string;
|
||||
{
|
||||
_rl_push_executing_macro ();
|
||||
_rl_executing_macro = string;
|
||||
executing_macro_index = 0;
|
||||
}
|
||||
|
||||
/* Return the next character available from a macro, or 0 if
|
||||
there are no macro characters. */
|
||||
int
|
||||
_rl_next_macro_key ()
|
||||
{
|
||||
if (_rl_executing_macro == 0)
|
||||
return (0);
|
||||
|
||||
if (_rl_executing_macro[executing_macro_index] == 0)
|
||||
{
|
||||
_rl_pop_executing_macro ();
|
||||
return (_rl_next_macro_key ());
|
||||
}
|
||||
|
||||
return (_rl_executing_macro[executing_macro_index++]);
|
||||
}
|
||||
|
||||
/* Save the currently executing macro on a stack of saved macros. */
|
||||
void
|
||||
_rl_push_executing_macro ()
|
||||
{
|
||||
struct saved_macro *saver;
|
||||
|
||||
saver = (struct saved_macro *)xmalloc (sizeof (struct saved_macro));
|
||||
saver->next = macro_list;
|
||||
saver->sindex = executing_macro_index;
|
||||
saver->string = _rl_executing_macro;
|
||||
|
||||
macro_list = saver;
|
||||
}
|
||||
|
||||
/* Discard the current macro, replacing it with the one
|
||||
on the top of the stack of saved macros. */
|
||||
void
|
||||
_rl_pop_executing_macro ()
|
||||
{
|
||||
struct saved_macro *macro;
|
||||
|
||||
if (_rl_executing_macro)
|
||||
free (_rl_executing_macro);
|
||||
|
||||
_rl_executing_macro = (char *)NULL;
|
||||
executing_macro_index = 0;
|
||||
|
||||
if (macro_list)
|
||||
{
|
||||
macro = macro_list;
|
||||
_rl_executing_macro = macro_list->string;
|
||||
executing_macro_index = macro_list->sindex;
|
||||
macro_list = macro_list->next;
|
||||
free (macro);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add a character to the macro being built. */
|
||||
void
|
||||
_rl_add_macro_char (c)
|
||||
int c;
|
||||
{
|
||||
if (current_macro_index + 1 >= current_macro_size)
|
||||
{
|
||||
if (current_macro == 0)
|
||||
current_macro = xmalloc (current_macro_size = 25);
|
||||
else
|
||||
current_macro = xrealloc (current_macro, current_macro_size += 25);
|
||||
}
|
||||
|
||||
current_macro[current_macro_index++] = c;
|
||||
current_macro[current_macro_index] = '\0';
|
||||
}
|
||||
|
||||
void
|
||||
_rl_kill_kbd_macro ()
|
||||
{
|
||||
if (current_macro)
|
||||
{
|
||||
free (current_macro);
|
||||
current_macro = (char *) NULL;
|
||||
}
|
||||
current_macro_size = current_macro_index = 0;
|
||||
|
||||
if (_rl_executing_macro)
|
||||
{
|
||||
free (_rl_executing_macro);
|
||||
_rl_executing_macro = (char *) NULL;
|
||||
}
|
||||
executing_macro_index = 0;
|
||||
|
||||
_rl_defining_kbd_macro = 0;
|
||||
}
|
||||
|
||||
/* Begin defining a keyboard macro.
|
||||
Keystrokes are recorded as they are executed.
|
||||
End the definition with rl_end_kbd_macro ().
|
||||
If a numeric argument was explicitly typed, then append this
|
||||
definition to the end of the existing macro, and start by
|
||||
re-executing the existing macro. */
|
||||
int
|
||||
rl_start_kbd_macro (ignore1, ignore2)
|
||||
int ignore1, ignore2;
|
||||
{
|
||||
if (_rl_defining_kbd_macro)
|
||||
{
|
||||
_rl_abort_internal ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rl_explicit_arg)
|
||||
{
|
||||
if (current_macro)
|
||||
_rl_with_macro_input (savestring (current_macro));
|
||||
}
|
||||
else
|
||||
current_macro_index = 0;
|
||||
|
||||
_rl_defining_kbd_macro = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Stop defining a keyboard macro.
|
||||
A numeric argument says to execute the macro right now,
|
||||
that many times, counting the definition as the first time. */
|
||||
int
|
||||
rl_end_kbd_macro (count, ignore)
|
||||
int count, ignore;
|
||||
{
|
||||
if (_rl_defining_kbd_macro == 0)
|
||||
{
|
||||
_rl_abort_internal ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
current_macro_index -= rl_key_sequence_length - 1;
|
||||
current_macro[current_macro_index] = '\0';
|
||||
|
||||
_rl_defining_kbd_macro = 0;
|
||||
|
||||
return (rl_call_last_kbd_macro (--count, 0));
|
||||
}
|
||||
|
||||
/* Execute the most recently defined keyboard macro.
|
||||
COUNT says how many times to execute it. */
|
||||
int
|
||||
rl_call_last_kbd_macro (count, ignore)
|
||||
int count, ignore;
|
||||
{
|
||||
if (current_macro == 0)
|
||||
_rl_abort_internal ();
|
||||
|
||||
if (_rl_defining_kbd_macro)
|
||||
{
|
||||
ding (); /* no recursive macros */
|
||||
current_macro[--current_macro_index] = '\0'; /* erase this char */
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (count--)
|
||||
_rl_with_macro_input (savestring (current_macro));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
rl_push_macro_input (macro)
|
||||
char *macro;
|
||||
{
|
||||
_rl_with_macro_input (macro);
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/* memalloc.h -- consolidate code for including alloca.h or malloc.h and
|
||||
defining alloca. */
|
||||
|
||||
/* Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash 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 2, or (at your option) any later
|
||||
version.
|
||||
|
||||
Bash 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 Bash; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#if !defined (__MEMALLOC_H__)
|
||||
# define __MEMALLOC_H__
|
||||
|
||||
#if defined (sparc) && defined (sun) && !defined (HAVE_ALLOCA_H)
|
||||
# define HAVE_ALLOCA_H
|
||||
#endif
|
||||
|
||||
#if defined (__GNUC__) && !defined (HAVE_ALLOCA)
|
||||
# define HAVE_ALLOCA
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_ALLOCA_H) && !defined (HAVE_ALLOCA)
|
||||
# define HAVE_ALLOCA
|
||||
#endif /* HAVE_ALLOCA_H && !HAVE_ALLOCA */
|
||||
|
||||
#if !defined (BUILDING_MAKEFILE)
|
||||
|
||||
#if defined (__GNUC__)
|
||||
# undef alloca
|
||||
# define alloca __builtin_alloca
|
||||
#else /* !__GNUC__ */
|
||||
# if defined (HAVE_ALLOCA_H)
|
||||
# if defined (IBMESA)
|
||||
# include <malloc.h>
|
||||
# else /* !IBMESA */
|
||||
# include <alloca.h>
|
||||
# endif /* !IBMESA */
|
||||
# else
|
||||
extern char *alloca ();
|
||||
# endif /* !HAVE_ALLOCA_H */
|
||||
#endif /* !__GNUC__ */
|
||||
|
||||
#endif /* !BUILDING_MAKEFILE */
|
||||
|
||||
#endif /* __MEMALLOC_H__ */
|
||||
198
lib/readline/nls.c
Normal file
198
lib/readline/nls.c
Normal file
@@ -0,0 +1,198 @@
|
||||
/* nls.c -- skeletal internationalization code. */
|
||||
|
||||
/* Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library 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.
|
||||
|
||||
The GNU Readline Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#define READLINE_LIBRARY
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif /* HAVE_UNISTD_H */
|
||||
|
||||
#if defined (HAVE_STDLIB_H)
|
||||
# include <stdlib.h>
|
||||
#else
|
||||
# include "ansi_stdlib.h"
|
||||
#endif /* HAVE_STDLIB_H */
|
||||
|
||||
#if defined (HAVE_LOCALE_H)
|
||||
# include <locale.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "rldefs.h"
|
||||
|
||||
extern int _rl_convert_meta_chars_to_ascii;
|
||||
extern int _rl_output_meta_chars;
|
||||
extern int _rl_meta_flag;
|
||||
|
||||
/* A list of legal values for the LANG or LC_CTYPE environment variables.
|
||||
If a locale name in this list is the value for the LC_ALL, LC_CTYPE,
|
||||
or LANG environment variable (using the first of those with a value),
|
||||
readline eight-bit mode is enabled. */
|
||||
static char *legal_lang_values[] =
|
||||
{
|
||||
"iso88591",
|
||||
"iso88592",
|
||||
"iso88593",
|
||||
"iso88594",
|
||||
"iso88595",
|
||||
"iso88596",
|
||||
"iso88597",
|
||||
"iso88598",
|
||||
"iso88599",
|
||||
"iso885910",
|
||||
"koi8r",
|
||||
0
|
||||
};
|
||||
|
||||
static char *normalize_codeset ();
|
||||
static char *find_codeset ();
|
||||
|
||||
/* Check for LC_ALL, LC_CTYPE, and LANG and use the first with a value
|
||||
to decide the defaults for 8-bit character input and output. Returns
|
||||
1 if we set eight-bit mode. */
|
||||
int
|
||||
_rl_init_eightbit ()
|
||||
{
|
||||
char *lspec, *t;
|
||||
int i;
|
||||
|
||||
lspec = getenv ("LC_ALL");
|
||||
if (lspec == 0) lspec = getenv ("LC_CTYPE");
|
||||
if (lspec == 0) lspec = getenv ("LANG");
|
||||
if (lspec == 0 || (t = normalize_codeset (lspec)) == 0)
|
||||
return (0);
|
||||
for (i = 0; t && legal_lang_values[i]; i++)
|
||||
if (STREQ (t, legal_lang_values[i]))
|
||||
{
|
||||
_rl_meta_flag = 1;
|
||||
_rl_convert_meta_chars_to_ascii = 0;
|
||||
_rl_output_meta_chars = 1;
|
||||
#if defined (HAVE_SETLOCALE)
|
||||
setlocale (LC_CTYPE, lspec);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
free (t);
|
||||
return (legal_lang_values[i] ? 1 : 0);
|
||||
}
|
||||
|
||||
static char *
|
||||
normalize_codeset (codeset)
|
||||
char *codeset;
|
||||
{
|
||||
size_t namelen, i;
|
||||
int len, all_digits;
|
||||
char *wp, *retval;
|
||||
|
||||
codeset = find_codeset (codeset, &namelen);
|
||||
|
||||
if (codeset == 0)
|
||||
return (codeset);
|
||||
|
||||
all_digits = 1;
|
||||
for (len = 0, i = 0; i < namelen; i++)
|
||||
{
|
||||
if (isalnum (codeset[i]))
|
||||
{
|
||||
len++;
|
||||
all_digits &= isdigit (codeset[i]);
|
||||
}
|
||||
}
|
||||
|
||||
retval = (char *)malloc ((all_digits ? 3 : 0) + len + 1);
|
||||
if (retval == 0)
|
||||
return ((char *)0);
|
||||
|
||||
wp = retval;
|
||||
/* Add `iso' to beginning of an all-digit codeset */
|
||||
if (all_digits)
|
||||
{
|
||||
*wp++ = 'i';
|
||||
*wp++ = 's';
|
||||
*wp++ = 'o';
|
||||
}
|
||||
|
||||
for (i = 0; i < namelen; i++)
|
||||
if (isalpha (codeset[i]))
|
||||
*wp++ = (isupper (codeset[i])) ? tolower (codeset[i]) : codeset[i];
|
||||
else if (isdigit (codeset[i]))
|
||||
*wp++ = codeset[i];
|
||||
*wp = '\0';
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Isolate codeset portion of locale specification. */
|
||||
static char *
|
||||
find_codeset (name, lenp)
|
||||
char *name;
|
||||
size_t *lenp;
|
||||
{
|
||||
char *cp, *language, *result;
|
||||
|
||||
cp = language = name;
|
||||
result = (char *)0;
|
||||
|
||||
while (*cp && *cp != '_' && *cp != '@' && *cp != '+' && *cp != ',')
|
||||
cp++;
|
||||
|
||||
/* This does not make sense: language has to be specified. As
|
||||
an exception we allow the variable to contain only the codeset
|
||||
name. Perhaps there are funny codeset names. */
|
||||
if (language == cp)
|
||||
{
|
||||
*lenp = strlen (language);
|
||||
result = language;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Next is the territory. */
|
||||
if (*cp == '_')
|
||||
do
|
||||
++cp;
|
||||
while (*cp && *cp != '.' && *cp != '@' && *cp != '+' && *cp != ',' && *cp != '_');
|
||||
|
||||
/* Now, finally, is the codeset. */
|
||||
result = cp;
|
||||
if (*cp == '.')
|
||||
do
|
||||
++cp;
|
||||
while (*cp && *cp != '@');
|
||||
|
||||
if (cp - result > 2)
|
||||
{
|
||||
result++;
|
||||
*lenp = cp - result;
|
||||
}
|
||||
else
|
||||
{
|
||||
*lenp = strlen (language);
|
||||
result = language;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
/* parens.c -- Implemenation of matching parenthesis feature. */
|
||||
/* parens.c -- Implementation of matching parentheses feature. */
|
||||
|
||||
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
|
||||
|
||||
@@ -24,7 +24,9 @@
|
||||
#include "rlconf.h"
|
||||
|
||||
#if !defined (PAREN_MATCHING)
|
||||
extern int rl_insert ();
|
||||
|
||||
int
|
||||
rl_insert_close (count, invoking_key)
|
||||
int count, invoking_key;
|
||||
{
|
||||
@@ -33,25 +35,49 @@ rl_insert_close (count, invoking_key)
|
||||
|
||||
#else /* PAREN_MATCHING */
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#if defined (FD_SET)
|
||||
|
||||
#if defined (FD_SET) && !defined (HAVE_SELECT)
|
||||
# define HAVE_SELECT
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_SELECT)
|
||||
# include <sys/time.h>
|
||||
#endif /* FD_SET */
|
||||
#endif /* HAVE_SELECT */
|
||||
#if defined (HAVE_SYS_SELECT_H)
|
||||
# include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_STRING_H)
|
||||
# include <string.h>
|
||||
#else /* !HAVE_STRING_H */
|
||||
# include <strings.h>
|
||||
#endif /* !HAVE_STRING_H */
|
||||
|
||||
#if !defined (strchr) && !defined (__STDC__)
|
||||
extern char *strchr (), *strrchr ();
|
||||
#endif /* !strchr && !__STDC__ */
|
||||
|
||||
#include "readline.h"
|
||||
|
||||
extern int rl_explicit_arg;
|
||||
|
||||
/* Non-zero means try to blink the matching open parenthesis when the
|
||||
close parenthesis is inserted. */
|
||||
#if defined (FD_SET)
|
||||
#if defined (HAVE_SELECT)
|
||||
int rl_blink_matching_paren = 1;
|
||||
#else /* !FD_SET */
|
||||
#else /* !HAVE_SELECT */
|
||||
int rl_blink_matching_paren = 0;
|
||||
#endif /* !FD_SET */
|
||||
#endif /* !HAVE_SELECT */
|
||||
|
||||
static int find_matching_open ();
|
||||
|
||||
int
|
||||
rl_insert_close (count, invoking_key)
|
||||
int count, invoking_key;
|
||||
{
|
||||
@@ -59,13 +85,13 @@ rl_insert_close (count, invoking_key)
|
||||
rl_insert (count, invoking_key);
|
||||
else
|
||||
{
|
||||
#if defined (FD_SET)
|
||||
#if defined (HAVE_SELECT)
|
||||
int orig_point, match_point, ready;
|
||||
struct timeval timer;
|
||||
fd_set readfds;
|
||||
|
||||
rl_insert (1, invoking_key);
|
||||
rl_redisplay ();
|
||||
(*rl_redisplay_function) ();
|
||||
match_point =
|
||||
find_matching_open (rl_line_buffer, rl_point - 2, invoking_key);
|
||||
|
||||
@@ -80,12 +106,12 @@ rl_insert_close (count, invoking_key)
|
||||
|
||||
orig_point = rl_point;
|
||||
rl_point = match_point;
|
||||
rl_redisplay ();
|
||||
(*rl_redisplay_function) ();
|
||||
ready = select (1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer);
|
||||
rl_point = orig_point;
|
||||
#else /* !FD_SET */
|
||||
#else /* !HAVE_SELECT */
|
||||
rl_insert (count, invoking_key);
|
||||
#endif /* !FD_SET */
|
||||
#endif /* !HAVE_SELECT */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -114,8 +140,8 @@ find_matching_open (string, from, closer)
|
||||
{
|
||||
if (delimiter && (string[i] == delimiter))
|
||||
delimiter = 0;
|
||||
else if ((string[i] == '\'') || (string[i] == '"'))
|
||||
delimiter = rl_line_buffer[i];
|
||||
else if (rl_basic_quote_characters && strchr (rl_basic_quote_characters, string[i]))
|
||||
delimiter = string[i];
|
||||
else if (!delimiter && (string[i] == closer))
|
||||
level++;
|
||||
else if (!delimiter && (string[i] == opener))
|
||||
|
||||
49
lib/readline/posixdir.h
Normal file
49
lib/readline/posixdir.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/* posixdir.h -- Posix directory reading includes and defines. */
|
||||
|
||||
/* Copyright (C) 1987,1991 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash 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.
|
||||
|
||||
Bash 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 Bash; see the file COPYING. If not, write to the Free
|
||||
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* This file should be included instead of <dirent.h> or <sys/dir.h>. */
|
||||
|
||||
#if !defined (_POSIXDIR_H_)
|
||||
#define _POSIXDIR_H_
|
||||
|
||||
#if defined (HAVE_DIRENT_H)
|
||||
# include <dirent.h>
|
||||
# define D_NAMLEN(d) (strlen ((d)->d_name))
|
||||
#else
|
||||
# if defined (HAVE_SYS_NDIR_H)
|
||||
# include <sys/ndir.h>
|
||||
# endif
|
||||
# if defined (HAVE_SYS_DIR_H)
|
||||
# include <sys/dir.h>
|
||||
# endif
|
||||
# if defined (HAVE_NDIR_H)
|
||||
# include <ndir.h>
|
||||
# endif
|
||||
# if !defined (dirent)
|
||||
# define dirent direct
|
||||
# endif /* !dirent */
|
||||
# define D_NAMLEN(d) ((d)->d_namlen)
|
||||
#endif /* !HAVE_DIRENT_H */
|
||||
|
||||
#if defined (STRUCT_DIRENT_HAS_D_INO)
|
||||
# define d_fileno d_ino
|
||||
#endif
|
||||
|
||||
#endif /* !_POSIXDIR_H_ */
|
||||
@@ -21,34 +21,27 @@
|
||||
|
||||
/* This file should be included instead of <sys/stat.h>.
|
||||
It relies on the local sys/stat.h to work though. */
|
||||
#if !defined (_POSIXSTAT_H)
|
||||
#define _POSIXSTAT_H
|
||||
#if !defined (_POSIXSTAT_H_)
|
||||
#define _POSIXSTAT_H_
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if defined (isc386)
|
||||
# if !defined (S_IFDIR)
|
||||
# define S_IFDIR 0040000
|
||||
# endif /* !S_IFDIR */
|
||||
# if !defined (S_IFMT)
|
||||
# define S_IFMT 0170000
|
||||
# endif /* !S_IFMT */
|
||||
#endif /* isc386 */
|
||||
|
||||
/* This text is taken directly from the Cadmus I was trying to
|
||||
compile on:
|
||||
the following MACROs are defined for X/OPEN compatibility
|
||||
however, is the param correct ??
|
||||
#define S_ISBLK(s) ((s.st_mode & S_IFMT) == S_IFBLK)
|
||||
|
||||
Well, the answer is no. Thus... */
|
||||
#if defined (BrainDeath)
|
||||
#if defined (STAT_MACROS_BROKEN)
|
||||
# undef S_ISBLK
|
||||
# undef S_ISCHR
|
||||
# undef S_ISDIR
|
||||
# undef S_ISFIFO
|
||||
# undef S_ISREG
|
||||
#endif /* BrainDeath */
|
||||
# undef S_ISLNK
|
||||
#endif /* STAT_MACROS_BROKEN */
|
||||
|
||||
/* These are guaranteed to work only on isc386 */
|
||||
#if !defined (S_IFDIR) && !defined (S_ISDIR)
|
||||
# define S_IFDIR 0040000
|
||||
#endif /* !S_IFDIR && !S_ISDIR */
|
||||
#if !defined (S_IFMT)
|
||||
# define S_IFMT 0170000
|
||||
#endif /* !S_IFMT */
|
||||
|
||||
/* Posix 1003.1 5.6.1.1 <sys/stat.h> file types */
|
||||
|
||||
@@ -114,7 +107,7 @@
|
||||
/*
|
||||
* POSIX 1003.1 5.6.1.2 <sys/stat.h> File Modes
|
||||
*/
|
||||
|
||||
|
||||
#if !defined (S_IRWXU)
|
||||
# if !defined (S_IREAD)
|
||||
# define S_IREAD 00400
|
||||
@@ -146,4 +139,4 @@
|
||||
#define S_IWUGO (S_IWUSR | S_IWGRP | S_IWOTH)
|
||||
#define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH)
|
||||
|
||||
#endif /* _POSIXSTAT_H */
|
||||
#endif /* _POSIXSTAT_H_ */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,76 +31,7 @@
|
||||
# include <readline/tilde.h>
|
||||
#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_tilde_expand (),
|
||||
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_insert_completions (),
|
||||
rl_do_lowercase_version (), rl_kill_full_line (),
|
||||
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 (), rl_dump_functions (),
|
||||
rl_delete_horizontal_space (), rl_history_search_forward (),
|
||||
rl_history_search_backward (), rl_tty_status (), rl_yank_last_arg ();
|
||||
|
||||
/* `Public' utility functions. */
|
||||
extern int rl_insert_text (), rl_delete_text (), rl_kill_text ();
|
||||
extern int rl_complete_internal ();
|
||||
extern int rl_expand_prompt ();
|
||||
extern int rl_initialize ();
|
||||
extern int rl_set_signals (), rl_clear_signals ();
|
||||
extern int rl_init_argument (), rl_digit_argument ();
|
||||
extern int rl_read_key (), rl_getc (), rl_stuff_char ();
|
||||
extern int maybe_save_line (), maybe_unsave_line (), maybe_replace_line ();
|
||||
extern int rl_modifying ();
|
||||
|
||||
extern int rl_begin_undo_group (), rl_end_undo_group ();
|
||||
extern void rl_add_undo (), free_undo_list ();
|
||||
extern int rl_do_undo ();
|
||||
|
||||
/* Not available unless readline is compiled -DPAREN_MATCHING. */
|
||||
extern int rl_insert_close ();
|
||||
|
||||
/* These are *both* defined even when VI_MODE is not. */
|
||||
extern int rl_vi_editing_mode (), rl_emacs_editing_mode ();
|
||||
|
||||
/* Non incremental history searching. */
|
||||
extern int
|
||||
rl_noninc_forward_search (), rl_noninc_reverse_search (),
|
||||
rl_noninc_forward_search_again (), rl_noninc_reverse_search_again ();
|
||||
|
||||
/* Things for vi mode. Not available unless readline is compiled -DVI_MODE. */
|
||||
extern int rl_vi_check (), rl_vi_textmod_command ();
|
||||
extern int
|
||||
rl_vi_redo (), rl_vi_tilde_expand (),
|
||||
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_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 (), rl_vi_fetch_history ();
|
||||
|
||||
/* Keyboard macro commands. */
|
||||
extern int rl_start_kbd_macro (), rl_end_kbd_macro ();
|
||||
extern int rl_call_last_kbd_macro ();
|
||||
|
||||
extern int rl_arrow_keys(), rl_refresh_line ();
|
||||
/* Readline data structures. */
|
||||
|
||||
/* Maintaining the state of undo. We remember individual deletes and inserts
|
||||
on a chain of things to do. */
|
||||
@@ -122,19 +53,185 @@ typedef struct undo_list {
|
||||
extern UNDO_LIST *rl_undo_list;
|
||||
|
||||
/* The data structure for mapping textual names to code addresses. */
|
||||
typedef struct {
|
||||
typedef struct _funmap {
|
||||
char *name;
|
||||
Function *function;
|
||||
} FUNMAP;
|
||||
|
||||
extern FUNMAP **funmap;
|
||||
|
||||
/* Functions available to bind to key sequences. */
|
||||
extern int
|
||||
rl_tilde_expand (), rl_set_mark (), rl_exchange_point_and_mark (),
|
||||
rl_beg_of_line (), rl_backward (), rl_delete (), rl_end_of_line (),
|
||||
rl_forward (), ding (), rl_newline (), rl_kill_line (),
|
||||
rl_copy_region_to_kill (), rl_kill_region (), rl_char_search (),
|
||||
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_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_insert_completions (),
|
||||
rl_do_lowercase_version (), rl_kill_full_line (),
|
||||
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 (),
|
||||
rl_dump_functions (), rl_dump_variables (), rl_dump_macros (),
|
||||
rl_delete_horizontal_space (), rl_history_search_forward (),
|
||||
rl_history_search_backward (), rl_tty_status (), rl_yank_last_arg (),
|
||||
rl_insert_comment (), rl_backward_char_search (),
|
||||
rl_copy_forward_word (), rl_copy_backward_word ();
|
||||
|
||||
/* Not available unless readline is compiled -DPAREN_MATCHING. */
|
||||
extern int rl_insert_close ();
|
||||
|
||||
/* Not available unless READLINE_CALLBACKS is defined. */
|
||||
extern void rl_callback_handler_install ();
|
||||
extern void rl_callback_read_char ();
|
||||
extern void rl_callback_handler_remove ();
|
||||
|
||||
/* These are *both* defined even when VI_MODE is not. */
|
||||
extern int rl_vi_editing_mode (), rl_emacs_editing_mode ();
|
||||
|
||||
/* Non incremental history searching. */
|
||||
extern int
|
||||
rl_noninc_forward_search (), rl_noninc_reverse_search (),
|
||||
rl_noninc_forward_search_again (), rl_noninc_reverse_search_again ();
|
||||
|
||||
/* Things for vi mode. Not available unless readline is compiled -DVI_MODE. */
|
||||
extern int rl_vi_check (), rl_vi_textmod_command ();
|
||||
extern int
|
||||
rl_vi_undo (), rl_vi_redo (), rl_vi_tilde_expand (),
|
||||
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_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_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 (), rl_vi_fetch_history (), rl_vi_set_mark (),
|
||||
rl_vi_goto_mark (), rl_vi_back_to_indent ();
|
||||
|
||||
/* Keyboard macro commands. */
|
||||
extern int rl_start_kbd_macro (), rl_end_kbd_macro ();
|
||||
extern int rl_call_last_kbd_macro ();
|
||||
extern void rl_push_macro_input ();
|
||||
|
||||
extern int rl_arrow_keys(), rl_refresh_line ();
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Well Published Functions */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Readline functions. */
|
||||
/* Read a line of input. Prompt with PROMPT. A NULL PROMPT means none. */
|
||||
extern char *readline ();
|
||||
|
||||
/* These functions are from bind.c. */
|
||||
/* 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 ();
|
||||
|
||||
extern Keymap rl_make_bare_keymap ();
|
||||
extern Keymap rl_copy_keymap ();
|
||||
extern Keymap rl_make_keymap ();
|
||||
extern void rl_discard_keymap ();
|
||||
extern Keymap rl_get_keymap (), rl_get_keymap_by_name ();
|
||||
extern void rl_set_keymap ();
|
||||
extern char *rl_get_keymap_name ();
|
||||
|
||||
extern int rl_bind_key (), rl_bind_key_in_map ();
|
||||
extern int rl_unbind_key (), rl_unbind_key_in_map ();
|
||||
extern int rl_set_key ();
|
||||
extern int rl_generic_bind ();
|
||||
extern int rl_parse_and_bind ();
|
||||
/* Backwards compatibility, use rl_generic_bind instead. */
|
||||
extern int rl_macro_bind (), rl_variable_bind ();
|
||||
|
||||
extern int rl_read_init_file ();
|
||||
|
||||
extern Function *rl_named_function (), *rl_function_of_keyseq ();
|
||||
extern char **rl_invoking_keyseqs (), **rl_invoking_keyseqs_in_map ();
|
||||
extern void rl_function_dumper ();
|
||||
extern void rl_variable_dumper ();
|
||||
extern void rl_macro_dumper ();
|
||||
extern void rl_list_funmap_names ();
|
||||
|
||||
/* Undocumented in the texinfo manual; not really useful to programs. */
|
||||
extern int rl_translate_keyseq ();
|
||||
extern void rl_initialize_funmap ();
|
||||
|
||||
/* Functions for undoing. */
|
||||
extern int rl_begin_undo_group (), rl_end_undo_group ();
|
||||
extern void rl_add_undo (), free_undo_list ();
|
||||
extern int rl_do_undo ();
|
||||
extern int rl_modifying ();
|
||||
|
||||
/* Functions for redisplay. */
|
||||
extern void rl_redisplay ();
|
||||
extern int rl_forced_update_display ();
|
||||
extern int rl_clear_message ();
|
||||
extern int rl_reset_line_state ();
|
||||
extern int rl_on_new_line ();
|
||||
|
||||
#if defined (__STDC__) && defined (USE_VARARGS) && defined (PREFER_STDARG)
|
||||
extern int rl_message (const char *, ...);
|
||||
#else
|
||||
extern int rl_message ();
|
||||
#endif
|
||||
|
||||
/* Undocumented in texinfo manual. */
|
||||
extern int rl_character_len ();
|
||||
extern int rl_show_char ();
|
||||
extern int crlf ();
|
||||
|
||||
/* Modifying text. */
|
||||
extern int rl_insert_text (), rl_delete_text ();
|
||||
extern int rl_kill_text ();
|
||||
extern char *rl_copy_text ();
|
||||
|
||||
/* `Public' utility functions. */
|
||||
extern int rl_reset_terminal ();
|
||||
extern int rl_stuff_char ();
|
||||
extern int rl_read_key (), rl_getc ();
|
||||
|
||||
extern int rl_initialize ();
|
||||
|
||||
/* Undocumented. */
|
||||
extern int rl_expand_prompt ();
|
||||
extern int rl_set_signals (), rl_clear_signals ();
|
||||
extern int maybe_save_line (), maybe_unsave_line (), maybe_replace_line ();
|
||||
|
||||
/* Completion functions. */
|
||||
/* These functions are from complete.c. */
|
||||
extern int rl_complete_internal ();
|
||||
|
||||
/* Return an array of strings which are the result of repeatadly calling
|
||||
FUNC with TEXT. */
|
||||
extern char **completion_matches ();
|
||||
extern char *username_completion_function ();
|
||||
extern char *filename_completion_function ();
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Well Published Variables */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* The version of this incarnation of the readline library. */
|
||||
extern char *rl_library_version;
|
||||
|
||||
/* 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;
|
||||
@@ -145,33 +242,36 @@ extern char *rl_line_buffer;
|
||||
/* The location of point, and end. */
|
||||
extern int rl_point, rl_end;
|
||||
|
||||
extern int rl_mark;
|
||||
|
||||
extern int rl_done;
|
||||
|
||||
extern int rl_pending_input;
|
||||
|
||||
/* 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;
|
||||
/* 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;
|
||||
|
||||
/* 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;
|
||||
/* The address of a function to call periodically while Readline is
|
||||
awaiting character input, or NULL, for no event handling. */
|
||||
extern Function *rl_event_hook;
|
||||
|
||||
/* List of characters which can be used to quote a substring of the line.
|
||||
Completion occurs on the entire substring, and within the substring
|
||||
rl_completer_word_break_characters are treated as any other character,
|
||||
unless they also appear within this list. */
|
||||
extern char *rl_completer_quote_characters;
|
||||
extern Function *rl_getc_function;
|
||||
extern VFunction *rl_redisplay_function;
|
||||
extern VFunction *rl_prep_term_function;
|
||||
extern VFunction *rl_deprep_term_function;
|
||||
|
||||
/* 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;
|
||||
/* Dispatch variables. */
|
||||
extern Keymap rl_executing_keymap;
|
||||
extern Keymap rl_binding_keymap;
|
||||
|
||||
/* Completion variables. */
|
||||
/* Pointer to the generator function for completion_matches ().
|
||||
NULL means to use filename_entry_function (), the default filename
|
||||
completer. */
|
||||
@@ -194,9 +294,32 @@ extern Function *rl_ignore_some_completions_function;
|
||||
array of strings returned. */
|
||||
extern CPPFunction *rl_attempted_completion_function;
|
||||
|
||||
/* 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;
|
||||
/* 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 which can be used to quote a substring of the line.
|
||||
Completion occurs on the entire substring, and within the substring
|
||||
rl_completer_word_break_characters are treated as any other character,
|
||||
unless they also appear within this list. */
|
||||
extern char *rl_completer_quote_characters;
|
||||
|
||||
/* List of quote characters which cause a word break. */
|
||||
extern char *rl_basic_quote_characters;
|
||||
|
||||
/* List of characters that need to be quoted in filenames by the completer. */
|
||||
extern char *rl_filename_quote_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;
|
||||
|
||||
/* If non-zero, then this is the address of a function to call when
|
||||
completing on a directory name. The function is called with
|
||||
@@ -206,14 +329,6 @@ extern Function *rl_directory_completion_hook;
|
||||
/* Backwards compatibility with previous versions of readline. */
|
||||
#define rl_symbolic_link_hook rl_directory_completion_hook
|
||||
|
||||
/* The address of a function to call periodically while Readline is
|
||||
awaiting character input, or NULL, for no event handling. */
|
||||
extern Function *rl_event_hook;
|
||||
|
||||
/* Non-zero means that modified history lines are preceded
|
||||
with an asterisk. */
|
||||
extern int rl_show_star;
|
||||
|
||||
/* Non-zero means that the results of the matches are to be treated
|
||||
as filenames. This is ALWAYS zero on entry, and can only be changed
|
||||
within a completion entry finder function. */
|
||||
@@ -226,62 +341,49 @@ extern int rl_filename_completion_desired;
|
||||
entry finder function. */
|
||||
extern int rl_filename_quoting_desired;
|
||||
|
||||
/* Set to a function to quote a filename in an application-specific fashion.
|
||||
Called with the text to quote, the type of match found (single or multiple)
|
||||
and a pointer to the quoting character to be used, which the function can
|
||||
reset if desired. */
|
||||
extern CPFunction *rl_filename_quoting_function;
|
||||
|
||||
/* Function to call to remove quoting characters from a filename. Called
|
||||
before completion is attempted, so the embedded quotes do not interfere
|
||||
with matching names in the file system. */
|
||||
extern CPFunction *rl_filename_dequoting_function;
|
||||
|
||||
/* Function to call to decide whether or not a word break character is
|
||||
quoted. If a character is quoted, it does not break words for the
|
||||
completer. */
|
||||
extern Function *rl_char_is_quoted_p;
|
||||
|
||||
/* Non-zero means to suppress normal filename completion after the
|
||||
user-specified completion function has been called. */
|
||||
extern int rl_attempted_completion_over;
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Well Published Functions */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
/* Set to a character describing the type of completion being attempted by
|
||||
rl_complete_internal; available for use by application completion
|
||||
functions. */
|
||||
extern int rl_completion_type;
|
||||
|
||||
/* Read a line of input. Prompt with PROMPT. A NULL PROMPT means none. */
|
||||
extern char *readline ();
|
||||
|
||||
/* These functions are from complete.c. */
|
||||
/* Return an array of strings which are the result of repeatadly calling
|
||||
FUNC with TEXT. */
|
||||
extern char **completion_matches ();
|
||||
extern char *username_completion_function ();
|
||||
extern char *filename_completion_function ();
|
||||
|
||||
/* These functions are from bind.c. */
|
||||
/* 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 ();
|
||||
extern int rl_bind_key (), rl_bind_key_in_map ();
|
||||
extern int rl_unbind_key (), rl_unbind_key_in_map ();
|
||||
extern int rl_set_key ();
|
||||
extern int rl_macro_bind (), rl_generic_bind (), rl_variable_bind ();
|
||||
extern int rl_translate_keyseq ();
|
||||
extern Function *rl_named_function (), *rl_function_of_keyseq ();
|
||||
extern int rl_parse_and_bind ();
|
||||
extern Keymap rl_get_keymap (), rl_get_keymap_by_name ();
|
||||
extern void rl_set_keymap ();
|
||||
extern char **rl_invoking_keyseqs (), **rl_invoking_keyseqs_in_map ();
|
||||
extern void rl_function_dumper ();
|
||||
extern int rl_read_init_file ();
|
||||
|
||||
/* Functions in funmap.c */
|
||||
extern void rl_list_funmap_names ();
|
||||
extern void rl_initialize_funmap ();
|
||||
|
||||
/* Functions in display.c */
|
||||
extern void rl_redisplay ();
|
||||
extern int rl_message (), rl_clear_message ();
|
||||
extern int rl_reset_line_state ();
|
||||
extern int rl_character_len ();
|
||||
extern int rl_show_char ();
|
||||
extern int crlf (), rl_on_new_line ();
|
||||
extern int rl_forced_update_display ();
|
||||
/* Character appended to completed words when at the end of the line. The
|
||||
default is a space. Nothing is added if this is '\0'. */
|
||||
extern int rl_completion_append_character;
|
||||
|
||||
/* If this is non-zero, completion is (temporarily) inhibited, and the
|
||||
completion character will be inserted as any other. */
|
||||
extern int rl_inhibit_completion;
|
||||
|
||||
/* Definitions available for use by readline clients. */
|
||||
#define RL_PROMPT_START_IGNORE '\001'
|
||||
#define RL_PROMPT_END_IGNORE '\002'
|
||||
|
||||
/* Possible values for do_replace argument to rl_filename_quoting_function,
|
||||
called by rl_complete_internal. */
|
||||
#define NO_MATCH 0
|
||||
#define SINGLE_MATCH 1
|
||||
#define MULT_MATCH 2
|
||||
|
||||
#if !defined (savestring)
|
||||
extern char *savestring (); /* XXX backwards compatibility */
|
||||
#endif
|
||||
|
||||
@@ -51,7 +51,13 @@
|
||||
over a character when updating the line rather than rewriting it. */
|
||||
/* #define HACK_TERMCAP_MOTION */
|
||||
|
||||
/* The string inserted by the vi-mode `insert comment' command. */
|
||||
#define VI_COMMENT_BEGIN_DEFAULT "#"
|
||||
/* The string inserted by the `insert comment' command. */
|
||||
#define RL_COMMENT_BEGIN_DEFAULT "#"
|
||||
|
||||
/* Define this if you want code that allows readline to be used in an
|
||||
X `callback' style. */
|
||||
#if !defined (SHELL)
|
||||
# define READLINE_CALLBACKS
|
||||
#endif
|
||||
|
||||
#endif /* _RLCONF_H_ */
|
||||
|
||||
@@ -23,106 +23,33 @@
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#if !defined (_RLDEFS_H)
|
||||
#define _RLDEFS_H
|
||||
#if !defined (_RLDEFS_H_)
|
||||
#define _RLDEFS_H_
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#if !defined (PRAGMA_ALLOCA)
|
||||
# include "memalloc.h"
|
||||
#endif
|
||||
|
||||
#define NEW_TTY_DRIVER
|
||||
#define HAVE_BSD_SIGNALS
|
||||
/* #define USE_XON_XOFF */
|
||||
|
||||
#if defined (__linux__) || defined (HAVE_TERMCAP_H)
|
||||
# include <termcap.h>
|
||||
#endif /* __linux__ || HAVE_TERMCAP_H */
|
||||
|
||||
/* Some USG machines have BSD signal handling (sigblock, sigsetmask, etc.) */
|
||||
#if defined (USG) && !defined (hpux)
|
||||
# undef HAVE_BSD_SIGNALS
|
||||
#endif
|
||||
|
||||
/* System V machines use termio. */
|
||||
#if !defined (_POSIX_VERSION)
|
||||
# if defined (USG) || defined (hpux) || defined (Xenix) || defined (sgi) || \
|
||||
defined (DGUX) || defined (HAVE_TERMIO_H)
|
||||
# undef NEW_TTY_DRIVER
|
||||
#if defined (_POSIX_VERSION) && !defined (TERMIOS_MISSING)
|
||||
# define TERMIOS_TTY_DRIVER
|
||||
#else
|
||||
# if defined (HAVE_TERMIO_H)
|
||||
# define TERMIO_TTY_DRIVER
|
||||
# include <termio.h>
|
||||
# if !defined (TCOON)
|
||||
# define TCOON 1
|
||||
# endif
|
||||
# endif /* USG || hpux || Xenix || sgi || DUGX || HAVE_TERMIO_H */
|
||||
#endif /* !_POSIX_VERSION */
|
||||
|
||||
/* Posix systems use termios and the Posix signal functions. */
|
||||
#if defined (_POSIX_VERSION)
|
||||
# if !defined (TERMIOS_MISSING)
|
||||
# undef NEW_TTY_DRIVER
|
||||
# define TERMIOS_TTY_DRIVER
|
||||
# include <termios.h>
|
||||
# endif /* !TERMIOS_MISSING */
|
||||
# define HAVE_POSIX_SIGNALS
|
||||
# if !defined (O_NDELAY)
|
||||
# define O_NDELAY O_NONBLOCK /* Posix-style non-blocking i/o */
|
||||
# endif /* O_NDELAY */
|
||||
#endif /* _POSIX_VERSION */
|
||||
|
||||
/* System V.3 machines have the old 4.1 BSD `reliable' signal interface. */
|
||||
#if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
|
||||
# if defined (USGr3) && !defined (XENIX_22)
|
||||
# if !defined (HAVE_USG_SIGHOLD)
|
||||
# define HAVE_USG_SIGHOLD
|
||||
# endif /* !HAVE_USG_SIGHOLD */
|
||||
# endif /* USGr3 && !XENIX_22 */
|
||||
#endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */
|
||||
|
||||
/* Other (BSD) machines use sgtty. */
|
||||
#if defined (NEW_TTY_DRIVER)
|
||||
# include <sgtty.h>
|
||||
# else
|
||||
# define NEW_TTY_DRIVER
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined (SHELL) && (defined (_POSIX_VERSION) || defined (USGr3))
|
||||
# if !defined (HAVE_DIRENT_H)
|
||||
# define HAVE_DIRENT_H
|
||||
# endif /* !HAVE_DIRENT_H */
|
||||
#endif /* !SHELL && (_POSIX_VERSION || USGr3) */
|
||||
|
||||
#if defined (HAVE_DIRENT_H)
|
||||
# include <dirent.h>
|
||||
# define D_NAMLEN(d) strlen ((d)->d_name)
|
||||
#else /* !HAVE_DIRENT_H */
|
||||
# define D_NAMLEN(d) ((d)->d_namlen)
|
||||
# if defined (USG)
|
||||
# if defined (Xenix)
|
||||
# include <sys/ndir.h>
|
||||
# else /* !Xenix (but USG...) */
|
||||
# include "ndir.h"
|
||||
# endif /* !Xenix */
|
||||
# else /* !USG */
|
||||
# include <sys/dir.h>
|
||||
# endif /* !USG */
|
||||
# if !defined (dirent)
|
||||
# define dirent direct
|
||||
# endif /* !dirent */
|
||||
#endif /* !HAVE_DIRENT_H */
|
||||
|
||||
#if defined (USG) && defined (TIOCGWINSZ) && !defined (Linux)
|
||||
# if defined (HAVE_SYS_STREAM_H)
|
||||
# include <sys/stream.h>
|
||||
# endif /* HAVE_SYS_STREAM_H */
|
||||
# if defined (HAVE_SYS_PTEM_H)
|
||||
# include <sys/ptem.h>
|
||||
# endif /* HAVE_SYS_PTEM_H */
|
||||
# if defined (HAVE_SYS_PTE_H)
|
||||
# include <sys/pte.h>
|
||||
# endif /* HAVE_SYS_PTE_H */
|
||||
#endif /* USG && TIOCGWINSZ && !Linux */
|
||||
#if defined (HAVE_SYS_STREAM_H)
|
||||
# include <sys/stream.h>
|
||||
#endif /* HAVE_SYS_STREAM_H */
|
||||
#if defined (HAVE_SYS_PTEM_H)
|
||||
# include <sys/ptem.h>
|
||||
# define _IO_PTEM_H /* work around SVR4.2 1.1.4 bug */
|
||||
#endif /* HAVE_SYS_PTEM_H */
|
||||
#if defined (HAVE_SYS_PTE_H)
|
||||
# include <sys/pte.h>
|
||||
#endif /* HAVE_SYS_PTE_H */
|
||||
|
||||
/* Posix macro to check file in statbuf for directory-ness.
|
||||
This requires that <sys/stat.h> be included before this test. */
|
||||
@@ -133,12 +60,6 @@
|
||||
/* Decide which flavor of the header file describing the C library
|
||||
string functions to include and include it. */
|
||||
|
||||
#if defined (USG) || defined (NeXT)
|
||||
# if !defined (HAVE_STRING_H)
|
||||
# define HAVE_STRING_H
|
||||
# endif /* !HAVE_STRING_H */
|
||||
#endif /* USG || NeXT */
|
||||
|
||||
#if defined (HAVE_STRING_H)
|
||||
# include <string.h>
|
||||
#else /* !HAVE_STRING_H */
|
||||
@@ -149,33 +70,20 @@
|
||||
extern char *strchr (), *strrchr ();
|
||||
#endif /* !strchr && !__STDC__ */
|
||||
|
||||
#if defined (HAVE_VARARGS_H)
|
||||
# include <varargs.h>
|
||||
#endif /* HAVE_VARARGS_H */
|
||||
|
||||
/* This is needed to include support for TIOCGWINSZ and window resizing. */
|
||||
#if defined (OSF1) || defined (BSD386) || defined (NetBSD) || \
|
||||
defined (__BSD_4_4__) || defined (FreeBSD) || defined (_386BSD) || \
|
||||
defined (AIX)
|
||||
# define GWINSZ_IN_SYS_IOCTL
|
||||
#if defined (PREFER_STDARG)
|
||||
# include <stdarg.h>
|
||||
#else
|
||||
# if defined (PREFER_VARARGS)
|
||||
# include <varargs.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Define _POSIX_VDISABLE if we are not using the `new' tty driver and
|
||||
it is not already defined. It is used both to determine if a
|
||||
special character is disabled and to disable certain special
|
||||
characters. Posix systems should set to 0, USG systems to -1. */
|
||||
#if !defined (NEW_TTY_DRIVER) && !defined (_POSIX_VDISABLE)
|
||||
# if defined (_SVR4_VDISABLE)
|
||||
# define _POSIX_VDISABLE _SVR4_VDISABLE
|
||||
# else
|
||||
# if defined (_POSIX_VERSION)
|
||||
# define _POSIX_VDISABLE 0
|
||||
# else /* !_POSIX_VERSION */
|
||||
# define _POSIX_VDISABLE -1
|
||||
# endif /* !_POSIX_VERSION */
|
||||
# endif /* !_SVR4_VDISABLE */
|
||||
#endif /* !NEW_TTY_DRIVER && !_POSIX_VDISABLE */
|
||||
|
||||
#if defined (HAVE_STRCASECMP)
|
||||
#define _rl_stricmp strcasecmp
|
||||
#define _rl_strnicmp strncasecmp
|
||||
#else
|
||||
extern int _rl_stricmp (), _rl_strnicmp ();
|
||||
#endif
|
||||
|
||||
#if !defined (emacs_mode)
|
||||
# define no_mode -1
|
||||
@@ -206,7 +114,33 @@ extern char *xmalloc ();
|
||||
#define AUDIBLE_BELL 1
|
||||
#define VISIBLE_BELL 2
|
||||
|
||||
/* Definitions used when searching the line for characters. */
|
||||
/* 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 */
|
||||
|
||||
/* Possible values for the found_quote flags word used by the completion
|
||||
functions. It says what kind of (shell-like) quoting we found anywhere
|
||||
in the line. */
|
||||
#define RL_QF_SINGLE_QUOTE 0x1
|
||||
#define RL_QF_DOUBLE_QUOTE 0x2
|
||||
#define RL_QF_BACKSLASH 0x4
|
||||
|
||||
/* Default readline line buffer length. */
|
||||
#define DEFAULT_BUFFER_SIZE 256
|
||||
|
||||
#if !defined (STREQ)
|
||||
#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0))
|
||||
#define STREQN(a, b, n) (((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0))
|
||||
#endif
|
||||
|
||||
#if !defined (FREE)
|
||||
# define FREE(x) if (x) free (x)
|
||||
#endif
|
||||
|
||||
/* CONFIGURATION SECTION */
|
||||
#include "rlconf.h"
|
||||
|
||||
#endif /* !_RLDEFS_H */
|
||||
#endif /* !_RLDEFS_H_ */
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#define READLINE_LIBRARY
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include "config.h"
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
@@ -36,6 +36,12 @@
|
||||
#endif /* HAVE_UNISTD_H */
|
||||
|
||||
#include "rldefs.h"
|
||||
|
||||
#if !defined (SHELL) && defined (GWINSZ_IN_SYS_IOCTL)
|
||||
# include <sys/ioctl.h>
|
||||
#endif /* !SHELL && GWINSZ_IN_SYS_IOCTL */
|
||||
|
||||
#include "rltty.h"
|
||||
#include "readline.h"
|
||||
|
||||
#if !defined (errno)
|
||||
@@ -45,11 +51,19 @@ extern int errno;
|
||||
extern int readline_echoing_p;
|
||||
extern int _rl_eof_char;
|
||||
|
||||
extern int _rl_enable_keypad, _rl_enable_meta;
|
||||
|
||||
#if defined (__GO32__)
|
||||
# include <sys/pc.h>
|
||||
# include <pc.h>
|
||||
# undef HANDLE_SIGNALS
|
||||
#endif /* __GO32__ */
|
||||
|
||||
/* Indirect functions to allow apps control over terminal management. */
|
||||
extern void rl_prep_terminal (), rl_deprep_terminal ();
|
||||
|
||||
VFunction *rl_prep_term_function = rl_prep_terminal;
|
||||
VFunction *rl_deprep_term_function = rl_deprep_terminal;
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Signal Management */
|
||||
@@ -64,7 +78,7 @@ static int sigint_oldmask;
|
||||
# endif /* HAVE_BSD_SIGNALS */
|
||||
#endif /* !HAVE_POSIX_SIGNALS */
|
||||
|
||||
static int sigint_blocked = 0;
|
||||
static int sigint_blocked;
|
||||
|
||||
/* Cause SIGINT to not be delivered until the corresponding call to
|
||||
release_sigint(). */
|
||||
@@ -113,52 +127,6 @@ release_sigint ()
|
||||
sigint_blocked = 0;
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Controlling the Meta Key and Keypad */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
extern int term_has_meta;
|
||||
extern char *term_mm;
|
||||
extern char *term_mo;
|
||||
|
||||
extern char *term_ks;
|
||||
extern char *term_ke;
|
||||
|
||||
static int
|
||||
outchar (c)
|
||||
int c;
|
||||
{
|
||||
return putc (c, rl_outstream);
|
||||
}
|
||||
|
||||
/* Turn on/off the meta key depending on ON. */
|
||||
static void
|
||||
control_meta_key (on)
|
||||
int on;
|
||||
{
|
||||
if (term_has_meta)
|
||||
{
|
||||
if (on && term_mm)
|
||||
tputs (term_mm, 1, outchar);
|
||||
else if (!on && term_mo)
|
||||
tputs (term_mo, 1, outchar);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
control_keypad (on)
|
||||
int on;
|
||||
{
|
||||
if (on && term_ks)
|
||||
tputs (term_ks, 1, outchar);
|
||||
else if (!on && term_ke)
|
||||
tputs (term_ke, 1, outchar);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Saving and Restoring the TTY */
|
||||
@@ -166,13 +134,30 @@ control_keypad (on)
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Non-zero means that the terminal is in a prepped state. */
|
||||
static int terminal_prepped = 0;
|
||||
static int terminal_prepped;
|
||||
|
||||
/* If non-zero, means that this process has called tcflow(fd, TCOOFF)
|
||||
and output is suspended. */
|
||||
#if defined (__ksr1__)
|
||||
static int ksrflow = 0;
|
||||
static int ksrflow;
|
||||
#endif
|
||||
|
||||
#if !defined (SHELL) && defined (TIOCGWINSZ)
|
||||
/* Dummy call to force a backgrounded readline to stop before it tries
|
||||
to get the tty settings. */
|
||||
static void
|
||||
set_winsize (tty)
|
||||
int tty;
|
||||
{
|
||||
struct winsize w;
|
||||
|
||||
if (ioctl (tty, TIOCGWINSZ, &w) == 0)
|
||||
(void) ioctl (tty, TIOCSWINSZ, &w);
|
||||
}
|
||||
#else /* SHELL || !TIOCGWINSZ */
|
||||
# define set_winsize(tty)
|
||||
#endif /* SHELL || !TIOCGWINSZ */
|
||||
|
||||
#if defined (NEW_TTY_DRIVER)
|
||||
|
||||
/* Values for the `flags' field of a struct bsdtty. This tells which
|
||||
@@ -204,12 +189,7 @@ get_tty_settings (tty, tiop)
|
||||
int tty;
|
||||
TIOTYPE *tiop;
|
||||
{
|
||||
#if !defined (SHELL) && defined (TIOCGWINSZ)
|
||||
struct winsize w;
|
||||
|
||||
if (ioctl (tty, TIOCGWINSZ, &w) == 0)
|
||||
(void) ioctl (tty, TIOCSWINSZ, &w);
|
||||
#endif
|
||||
set_winsize (tty);
|
||||
|
||||
tiop->flags = tiop->lflag = 0;
|
||||
|
||||
@@ -234,6 +214,7 @@ get_tty_settings (tty, tiop)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
set_tty_settings (tty, tiop)
|
||||
int tty;
|
||||
TIOTYPE *tiop;
|
||||
@@ -360,7 +341,11 @@ prepare_terminal_settings (meta_flag, otio, tiop)
|
||||
# define TIOTYPE struct termios
|
||||
# define DRAIN_OUTPUT(fd) tcdrain (fd)
|
||||
# define GETATTR(tty, tiop) (tcgetattr (tty, tiop))
|
||||
# define SETATTR(tty, tiop) (tcsetattr (tty, TCSANOW, tiop))
|
||||
# ifdef M_UNIX
|
||||
# define SETATTR(tty, tiop) (tcsetattr (tty, TCSANOW, tiop))
|
||||
# else
|
||||
# define SETATTR(tty, tiop) (tcsetattr (tty, TCSADRAIN, tiop))
|
||||
# endif /* !M_UNIX */
|
||||
#else
|
||||
# define TIOTYPE struct termio
|
||||
# define DRAIN_OUTPUT(fd)
|
||||
@@ -376,29 +361,61 @@ static TIOTYPE otio;
|
||||
# define OUTPUT_BEING_FLUSHED(tp) 0
|
||||
#endif
|
||||
|
||||
static void
|
||||
rltty_warning (msg)
|
||||
char *msg;
|
||||
{
|
||||
fprintf (stderr, "readline: warning: %s\n", msg);
|
||||
}
|
||||
|
||||
#if defined (_AIX)
|
||||
void
|
||||
setopost(tp)
|
||||
TIOTYPE *tp;
|
||||
{
|
||||
if ((tp->c_oflag & OPOST) == 0)
|
||||
{
|
||||
rltty_warning ("turning on OPOST for terminal\r");
|
||||
tp->c_oflag |= OPOST|ONLCR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
get_tty_settings (tty, tiop)
|
||||
int tty;
|
||||
TIOTYPE *tiop;
|
||||
{
|
||||
int ioctl_ret;
|
||||
#if !defined (SHELL) && defined (TIOCGWINSZ)
|
||||
struct winsize w;
|
||||
set_winsize (tty);
|
||||
|
||||
if (ioctl (tty, TIOCGWINSZ, &w) == 0)
|
||||
(void) ioctl (tty, TIOCSWINSZ, &w);
|
||||
while (1)
|
||||
{
|
||||
ioctl_ret = GETATTR (tty, tiop);
|
||||
if (ioctl_ret < 0)
|
||||
{
|
||||
if (errno != EINTR)
|
||||
return -1;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
if (OUTPUT_BEING_FLUSHED (tiop))
|
||||
{
|
||||
#if defined (FLUSHO) && defined (_AIX41)
|
||||
rltty_warning ("turning off output flushing");
|
||||
tiop->c_lflag &= ~FLUSHO;
|
||||
break;
|
||||
#else
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined (_AIX)
|
||||
setopost(tiop);
|
||||
#endif
|
||||
|
||||
/* Keep looping if output is being flushed after a ^O (or whatever
|
||||
the flush character is). */
|
||||
while ((ioctl_ret = GETATTR (tty, tiop)) < 0 || OUTPUT_BEING_FLUSHED (tiop))
|
||||
{
|
||||
if (ioctl_ret < 0 && errno != EINTR)
|
||||
return -1;
|
||||
if (OUTPUT_BEING_FLUSHED (tiop))
|
||||
continue;
|
||||
errno = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -503,7 +520,7 @@ rl_prep_terminal (meta_flag)
|
||||
int meta_flag;
|
||||
{
|
||||
#if !defined (__GO32__)
|
||||
int tty = fileno (rl_instream);
|
||||
int tty;
|
||||
TIOTYPE tio;
|
||||
|
||||
if (terminal_prepped)
|
||||
@@ -512,6 +529,8 @@ rl_prep_terminal (meta_flag)
|
||||
/* Try to keep this function from being INTerrupted. */
|
||||
block_sigint ();
|
||||
|
||||
tty = fileno (rl_instream);
|
||||
|
||||
if (get_tty_settings (tty, &tio) < 0)
|
||||
{
|
||||
release_sigint ();
|
||||
@@ -528,10 +547,9 @@ rl_prep_terminal (meta_flag)
|
||||
return;
|
||||
}
|
||||
|
||||
control_meta_key (1);
|
||||
#if 0
|
||||
control_keypad (1);
|
||||
#endif
|
||||
if (_rl_enable_keypad)
|
||||
_rl_control_keypad (1);
|
||||
|
||||
fflush (rl_outstream);
|
||||
terminal_prepped = 1;
|
||||
|
||||
@@ -544,18 +562,19 @@ void
|
||||
rl_deprep_terminal ()
|
||||
{
|
||||
#if !defined (__GO32__)
|
||||
int tty = fileno (rl_instream);
|
||||
int tty;
|
||||
|
||||
if (!terminal_prepped)
|
||||
return;
|
||||
|
||||
/* Try to keep this function from being INTerrupted. */
|
||||
/* Try to keep this function from being interrupted. */
|
||||
block_sigint ();
|
||||
|
||||
control_meta_key (0);
|
||||
#if 0
|
||||
control_keypad (0);
|
||||
#endif
|
||||
tty = fileno (rl_instream);
|
||||
|
||||
if (_rl_enable_keypad)
|
||||
_rl_control_keypad (0);
|
||||
|
||||
fflush (rl_outstream);
|
||||
|
||||
if (set_tty_settings (tty, &otio) < 0)
|
||||
@@ -576,6 +595,7 @@ rl_deprep_terminal ()
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
int
|
||||
rl_restart_output (count, key)
|
||||
int count, key;
|
||||
{
|
||||
@@ -608,6 +628,7 @@ rl_restart_output (count, key)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rl_stop_output (count, key)
|
||||
int count, key;
|
||||
{
|
||||
@@ -634,7 +655,7 @@ rl_stop_output (count, key)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Default Key Bindings */
|
||||
|
||||
61
lib/readline/rltty.h
Normal file
61
lib/readline/rltty.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/* rltty.h - tty driver-related definitions used by some library files. */
|
||||
|
||||
/* Copyright (C) 1995 Free Software Foundation, Inc.
|
||||
|
||||
This file contains the Readline Library (the Library), a set of
|
||||
routines for providing Emacs style line input to programs that ask
|
||||
for it.
|
||||
|
||||
The Library 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.
|
||||
|
||||
The Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#if !defined (_RLTTY_H_)
|
||||
#define _RLTTY_H
|
||||
|
||||
/* Posix systems use termios and the Posix signal functions. */
|
||||
#if defined (TERMIOS_TTY_DRIVER)
|
||||
# include <termios.h>
|
||||
#endif /* TERMIOS_TTY_DRIVER */
|
||||
|
||||
/* System V machines use termio. */
|
||||
#if defined (TERMIO_TTY_DRIVER)
|
||||
# include <termio.h>
|
||||
# if !defined (TCOON)
|
||||
# define TCOON 1
|
||||
# endif
|
||||
#endif /* TERMIO_TTY_DRIVER */
|
||||
|
||||
/* Other (BSD) machines use sgtty. */
|
||||
#if defined (NEW_TTY_DRIVER)
|
||||
# include <sgtty.h>
|
||||
#endif
|
||||
|
||||
/* Define _POSIX_VDISABLE if we are not using the `new' tty driver and
|
||||
it is not already defined. It is used both to determine if a
|
||||
special character is disabled and to disable certain special
|
||||
characters. Posix systems should set to 0, USG systems to -1. */
|
||||
#if !defined (NEW_TTY_DRIVER) && !defined (_POSIX_VDISABLE)
|
||||
# if defined (_SVR4_VDISABLE)
|
||||
# define _POSIX_VDISABLE _SVR4_VDISABLE
|
||||
# else
|
||||
# if defined (_POSIX_VERSION)
|
||||
# define _POSIX_VDISABLE 0
|
||||
# else /* !_POSIX_VERSION */
|
||||
# define _POSIX_VDISABLE -1
|
||||
# endif /* !_POSIX_VERSION */
|
||||
# endif /* !_SVR4_DISABLE */
|
||||
#endif /* !NEW_TTY_DRIVER && !_POSIX_VDISABLE */
|
||||
|
||||
#endif /* _RLTTY_H_ */
|
||||
@@ -22,6 +22,10 @@
|
||||
675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#define READLINE_LIBRARY
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -33,16 +37,12 @@
|
||||
#include "readline.h"
|
||||
#include "history.h"
|
||||
|
||||
#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0))
|
||||
#define STREQN(a, b, n) (((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0))
|
||||
|
||||
#define abs(x) (((x) > 0) ? (x) : -(x))
|
||||
|
||||
extern char *xmalloc (), *xrealloc ();
|
||||
|
||||
/* Variables imported from readline.c */
|
||||
extern int rl_point, rl_end, rl_line_buffer_len;
|
||||
extern Keymap _rl_keymap;
|
||||
extern int rl_editing_mode;
|
||||
extern char *rl_prompt;
|
||||
extern char *rl_line_buffer;
|
||||
@@ -51,9 +51,12 @@ extern Function *rl_last_func;
|
||||
|
||||
/* Functions imported from the rest of the library. */
|
||||
extern int _rl_free_history_entry ();
|
||||
extern char *_rl_make_prompt_for_search ();
|
||||
extern void _rl_restore_prompt ();
|
||||
extern void rl_extend_line_buffer ();
|
||||
|
||||
static char *noninc_search_string = (char *) NULL;
|
||||
static int noninc_history_pos = 0;
|
||||
static int noninc_history_pos;
|
||||
static char *prev_line_found = (char *) NULL;
|
||||
|
||||
/* Search the history list for STRING starting at absolute history position
|
||||
@@ -91,7 +94,7 @@ noninc_dosearch (string, dir)
|
||||
char *string;
|
||||
int dir;
|
||||
{
|
||||
int oldpos, pos;
|
||||
int oldpos, pos, line_len;
|
||||
HIST_ENTRY *entry;
|
||||
|
||||
if (string == 0 || *string == '\0' || noninc_history_pos < 0)
|
||||
@@ -121,14 +124,10 @@ noninc_dosearch (string, dir)
|
||||
#endif
|
||||
history_set_pos (oldpos);
|
||||
|
||||
{
|
||||
int line_len;
|
||||
|
||||
line_len = strlen (entry->line);
|
||||
if (line_len >= rl_line_buffer_len)
|
||||
rl_extend_line_buffer (line_len);
|
||||
strcpy (rl_line_buffer, entry->line);
|
||||
}
|
||||
line_len = strlen (entry->line);
|
||||
if (line_len >= rl_line_buffer_len)
|
||||
rl_extend_line_buffer (line_len);
|
||||
strcpy (rl_line_buffer, entry->line);
|
||||
|
||||
rl_undo_list = (UNDO_LIST *)entry->data;
|
||||
rl_end = strlen (rl_line_buffer);
|
||||
@@ -150,7 +149,7 @@ noninc_search (dir, pchar)
|
||||
int dir;
|
||||
int pchar;
|
||||
{
|
||||
int saved_point, c, pmtlen;
|
||||
int saved_point, c;
|
||||
char *p;
|
||||
|
||||
maybe_save_line ();
|
||||
@@ -160,17 +159,12 @@ noninc_search (dir, pchar)
|
||||
rl_line_buffer[0] = 0;
|
||||
rl_end = rl_point = 0;
|
||||
|
||||
/* XXX - this needs fixing to work with the prompt expansion stuff - XXX */
|
||||
pmtlen = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0;
|
||||
p = xmalloc (2 + pmtlen);
|
||||
if (pmtlen)
|
||||
strcpy (p, rl_prompt);
|
||||
p[pmtlen] = pchar ? pchar : ':';
|
||||
p[pmtlen + 1] = '\0';
|
||||
|
||||
p = _rl_make_prompt_for_search (pchar ? pchar : ':');
|
||||
rl_message (p, 0, 0);
|
||||
free (p);
|
||||
|
||||
#define SEARCH_RETURN _rl_restore_prompt (); return
|
||||
|
||||
/* Read the search string. */
|
||||
while (c = rl_read_key ())
|
||||
{
|
||||
@@ -183,9 +177,9 @@ noninc_search (dir, pchar)
|
||||
maybe_unsave_line ();
|
||||
rl_clear_message ();
|
||||
rl_point = saved_point;
|
||||
return;
|
||||
SEARCH_RETURN;
|
||||
}
|
||||
rl_rubout (1);
|
||||
rl_rubout (1, c);
|
||||
break;
|
||||
|
||||
case CTRL('W'):
|
||||
@@ -208,13 +202,13 @@ noninc_search (dir, pchar)
|
||||
rl_clear_message ();
|
||||
rl_point = saved_point;
|
||||
ding ();
|
||||
return;
|
||||
SEARCH_RETURN;
|
||||
|
||||
default:
|
||||
rl_insert (1, c);
|
||||
break;
|
||||
}
|
||||
rl_redisplay ();
|
||||
(*rl_redisplay_function) ();
|
||||
}
|
||||
|
||||
dosearch:
|
||||
@@ -226,7 +220,7 @@ noninc_search (dir, pchar)
|
||||
if (!noninc_search_string)
|
||||
{
|
||||
ding ();
|
||||
return;
|
||||
SEARCH_RETURN;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -238,35 +232,33 @@ noninc_search (dir, pchar)
|
||||
noninc_search_string = savestring (rl_line_buffer);
|
||||
}
|
||||
|
||||
_rl_restore_prompt ();
|
||||
noninc_dosearch (noninc_search_string, dir);
|
||||
}
|
||||
|
||||
/* Search forward through the history list for a string. If the vi-mode
|
||||
code calls this, KEY will be `?'. */
|
||||
int
|
||||
rl_noninc_forward_search (count, key)
|
||||
int count, key;
|
||||
{
|
||||
if (key == '?')
|
||||
noninc_search (1, '?');
|
||||
else
|
||||
noninc_search (1, 0);
|
||||
noninc_search (1, (key == '?') ? '?' : 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Reverse search the history list for a string. If the vi-mode code
|
||||
calls this, KEY will be `/'. */
|
||||
int
|
||||
rl_noninc_reverse_search (count, key)
|
||||
int count, key;
|
||||
{
|
||||
if (key == '/')
|
||||
noninc_search (-1, '/');
|
||||
else
|
||||
noninc_search (-1, 0);
|
||||
noninc_search (-1, (key == '/') ? '/' : 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Search forward through the history list for the last string searched
|
||||
for. If there is no saved search string, abort. */
|
||||
int
|
||||
rl_noninc_forward_search_again (count, key)
|
||||
int count, key;
|
||||
{
|
||||
@@ -281,6 +273,7 @@ rl_noninc_forward_search_again (count, key)
|
||||
|
||||
/* Reverse search in the history list for the last string searched
|
||||
for. If there is no saved search string, abort. */
|
||||
int
|
||||
rl_noninc_reverse_search_again (count, key)
|
||||
int count, key;
|
||||
{
|
||||
@@ -306,8 +299,14 @@ rl_history_search_internal (count, direction)
|
||||
while (count)
|
||||
{
|
||||
temp = (direction < 0) ? previous_history () : next_history ();
|
||||
if (!temp)
|
||||
if (temp == 0)
|
||||
break;
|
||||
/* On an empty prefix, make this the same as previous-history. */
|
||||
if (rl_point == 0)
|
||||
{
|
||||
count--;
|
||||
continue;
|
||||
}
|
||||
if (STREQN (rl_line_buffer, temp->line, rl_point))
|
||||
{
|
||||
/* Don't find multiple instances of the same line. */
|
||||
@@ -320,7 +319,7 @@ rl_history_search_internal (count, direction)
|
||||
}
|
||||
}
|
||||
|
||||
if (!temp)
|
||||
if (temp == 0)
|
||||
{
|
||||
if (direction < 0 && old_temp)
|
||||
temp = old_temp;
|
||||
|
||||
@@ -21,32 +21,18 @@
|
||||
675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#define READLINE_LIBRARY
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h> /* Just for NULL. Yuck. */
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#if !defined (NO_SYS_FILE)
|
||||
# include <sys/file.h>
|
||||
#endif /* !NO_SYS_FILE */
|
||||
#include <signal.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif /* HAVE_UNISTD_H */
|
||||
|
||||
#if defined (HAVE_STDLIB_H)
|
||||
# include <stdlib.h>
|
||||
#else
|
||||
# include "ansi_stdlib.h"
|
||||
#endif /* HAVE_STDLIB_H */
|
||||
|
||||
#include <errno.h>
|
||||
/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif /* !errno */
|
||||
|
||||
#include "posixstat.h"
|
||||
|
||||
/* System-specific feature definitions and include files. */
|
||||
#include "rldefs.h"
|
||||
|
||||
@@ -54,6 +40,11 @@ extern int errno;
|
||||
# include <sys/ioctl.h>
|
||||
#endif /* GWINSZ_IN_SYS_IOCTL */
|
||||
|
||||
#if defined (__GO32__)
|
||||
# undef HANDLE_SIGNALS
|
||||
#endif /* __GO32__ */
|
||||
|
||||
#if defined (HANDLE_SIGNALS)
|
||||
/* Some standard library routines. */
|
||||
#include "readline.h"
|
||||
#include "history.h"
|
||||
@@ -63,72 +54,60 @@ extern int rl_pending_input;
|
||||
extern int _rl_meta_flag;
|
||||
|
||||
extern void free_undo_list ();
|
||||
extern void _rl_get_screen_size ();
|
||||
extern void _rl_redisplay_after_sigwinch ();
|
||||
extern void _rl_clean_up_for_exit ();
|
||||
extern void _rl_kill_kbd_macro ();
|
||||
extern void _rl_init_argument ();
|
||||
extern void rl_deprep_terminal (), rl_prep_terminal ();
|
||||
|
||||
#if !defined (RETSIGTYPE)
|
||||
# if defined (VOID_SIGHANDLER)
|
||||
# define RETSIGTYPE void
|
||||
# else
|
||||
# define RETSIGTYPE int
|
||||
# endif /* !VOID_SIGHANDLER */
|
||||
#endif /* !RETSIGTYPE */
|
||||
|
||||
#if defined (VOID_SIGHANDLER)
|
||||
# define sighandler void
|
||||
# define SIGHANDLER_RETURN return
|
||||
#else
|
||||
# define sighandler int
|
||||
#endif /* VOID_SIGHANDLER */
|
||||
# define SIGHANDLER_RETURN return (0)
|
||||
#endif
|
||||
|
||||
/* This typedef is equivalant to the one for Function; it allows us
|
||||
to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
|
||||
typedef sighandler SigHandler ();
|
||||
typedef RETSIGTYPE SigHandler ();
|
||||
|
||||
#if defined (__GO32__)
|
||||
# undef HANDLE_SIGNALS
|
||||
#endif /* __GO32__ */
|
||||
static SigHandler *rl_set_sighandler ();
|
||||
|
||||
#if defined (STATIC_MALLOC)
|
||||
static char *xmalloc (), *xrealloc ();
|
||||
#else
|
||||
extern char *xmalloc (), *xrealloc ();
|
||||
#endif /* STATIC_MALLOC */
|
||||
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Signal Handling */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
#if defined (SIGWINCH)
|
||||
static SigHandler *old_sigwinch = (SigHandler *)NULL;
|
||||
#if defined (HAVE_POSIX_SIGNALS)
|
||||
typedef struct sigaction sighandler_cxt;
|
||||
# define rl_sigaction(s, nh, oh) sigaction(s, nh, oh)
|
||||
#else
|
||||
typedef struct { SigHandler *sa_handler; } sighandler_cxt;
|
||||
# define sigemptyset(m)
|
||||
#endif /* !HAVE_POSIX_SIGNALS */
|
||||
|
||||
static sighandler
|
||||
rl_handle_sigwinch (sig)
|
||||
int sig;
|
||||
{
|
||||
if (readline_echoing_p)
|
||||
{
|
||||
_rl_set_screen_size (fileno (rl_instream), 1);
|
||||
_rl_redisplay_after_sigwinch ();
|
||||
}
|
||||
static sighandler_cxt old_int, old_alrm;
|
||||
|
||||
if (old_sigwinch &&
|
||||
old_sigwinch != (SigHandler *)SIG_IGN &&
|
||||
old_sigwinch != (SigHandler *)SIG_DFL)
|
||||
(*old_sigwinch) (sig);
|
||||
#if !defined (VOID_SIGHANDLER)
|
||||
return (0);
|
||||
#endif /* VOID_SIGHANDLER */
|
||||
}
|
||||
#endif /* SIGWINCH */
|
||||
|
||||
#if defined (HANDLE_SIGNALS)
|
||||
/* Interrupt handling. */
|
||||
static SigHandler
|
||||
*old_int = (SigHandler *)NULL,
|
||||
*old_alrm = (SigHandler *)NULL;
|
||||
#if !defined (SHELL)
|
||||
static SigHandler
|
||||
*old_tstp = (SigHandler *)NULL,
|
||||
*old_ttou = (SigHandler *)NULL,
|
||||
*old_ttin = (SigHandler *)NULL,
|
||||
*old_cont = (SigHandler *)NULL;
|
||||
static sighandler_cxt old_tstp, old_ttou, old_ttin, old_term;
|
||||
#endif /* !SHELL */
|
||||
|
||||
/* Handle an interrupt character. */
|
||||
static sighandler
|
||||
#if defined (SIGWINCH)
|
||||
static sighandler_cxt old_winch;
|
||||
#endif
|
||||
|
||||
/* Readline signal handler functions. */
|
||||
|
||||
static RETSIGTYPE
|
||||
rl_signal_handler (sig)
|
||||
int sig;
|
||||
{
|
||||
@@ -143,9 +122,9 @@ rl_signal_handler (sig)
|
||||
#if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
|
||||
/* Since the signal will not be blocked while we are in the signal
|
||||
handler, ignore it until rl_clear_signals resets the catcher. */
|
||||
if (sig == SIGINT)
|
||||
signal (sig, SIG_IGN);
|
||||
#endif /* !HAVE_BSD_SIGNALS */
|
||||
if (sig == SIGINT || sig == SIGALRM)
|
||||
rl_set_sighandler (sig, SIG_IGN, (sighandler_cxt *)NULL);
|
||||
#endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */
|
||||
|
||||
switch (sig)
|
||||
{
|
||||
@@ -161,7 +140,7 @@ rl_signal_handler (sig)
|
||||
}
|
||||
_rl_kill_kbd_macro ();
|
||||
rl_clear_message ();
|
||||
rl_init_argument ();
|
||||
_rl_init_argument ();
|
||||
|
||||
#if defined (SIGTSTP)
|
||||
case SIGTSTP:
|
||||
@@ -169,8 +148,9 @@ rl_signal_handler (sig)
|
||||
case SIGTTIN:
|
||||
#endif /* SIGTSTP */
|
||||
case SIGALRM:
|
||||
rl_clean_up_for_exit ();
|
||||
rl_deprep_terminal ();
|
||||
case SIGTERM:
|
||||
_rl_clean_up_for_exit ();
|
||||
(*rl_deprep_term_function) ();
|
||||
rl_clear_signals ();
|
||||
rl_pending_input = 0;
|
||||
|
||||
@@ -194,92 +174,159 @@ rl_signal_handler (sig)
|
||||
# endif /* HAVE_BSD_SIGNALS */
|
||||
#endif /* !HAVE_POSIX_SIGNALS */
|
||||
|
||||
rl_prep_terminal (_rl_meta_flag);
|
||||
(*rl_prep_term_function) (_rl_meta_flag);
|
||||
rl_set_signals ();
|
||||
}
|
||||
|
||||
#if !defined (VOID_SIGHANDLER)
|
||||
return (0);
|
||||
#endif /* !VOID_SIGHANDLER */
|
||||
SIGHANDLER_RETURN;
|
||||
}
|
||||
|
||||
#if defined (HAVE_POSIX_SIGNALS)
|
||||
#if defined (SIGWINCH)
|
||||
static RETSIGTYPE
|
||||
rl_handle_sigwinch (sig)
|
||||
int sig;
|
||||
{
|
||||
SigHandler *oh;
|
||||
|
||||
if (readline_echoing_p)
|
||||
{
|
||||
_rl_get_screen_size (fileno (rl_instream), 1);
|
||||
_rl_redisplay_after_sigwinch ();
|
||||
}
|
||||
|
||||
/* If another sigwinch handler has been installed, call it. */
|
||||
oh = (SigHandler *)old_winch.sa_handler;
|
||||
if (oh && oh != (SigHandler *)SIG_IGN && oh != (SigHandler *)SIG_DFL)
|
||||
(*oh) (sig);
|
||||
|
||||
SIGHANDLER_RETURN;
|
||||
}
|
||||
#endif /* SIGWINCH */
|
||||
|
||||
/* Functions to manage signal handling. */
|
||||
|
||||
#if !defined (HAVE_POSIX_SIGNALS)
|
||||
static int
|
||||
rl_sigaction (sig, nh, oh)
|
||||
int sig;
|
||||
sighandler_cxt *nh, *oh;
|
||||
{
|
||||
oh->sa_handler = signal (sig, nh->sa_handler);
|
||||
return 0;
|
||||
}
|
||||
#endif /* !HAVE_POSIX_SIGNALS */
|
||||
|
||||
/* Set up a readline-specific signal handler, saving the old signal
|
||||
information in OHANDLER. Return the old signal handler, like
|
||||
signal(). */
|
||||
static SigHandler *
|
||||
rl_set_sighandler (sig, handler)
|
||||
rl_set_sighandler (sig, handler, ohandler)
|
||||
int sig;
|
||||
SigHandler *handler;
|
||||
sighandler_cxt *ohandler;
|
||||
{
|
||||
struct sigaction act, oact;
|
||||
#if defined (HAVE_POSIX_SIGNALS)
|
||||
struct sigaction act;
|
||||
|
||||
act.sa_handler = handler;
|
||||
act.sa_flags = 0;
|
||||
sigemptyset (&act.sa_mask);
|
||||
sigemptyset (&oact.sa_mask);
|
||||
sigaction (sig, &act, &oact);
|
||||
return (oact.sa_handler);
|
||||
sigemptyset (&ohandler->sa_mask);
|
||||
sigaction (sig, &act, ohandler);
|
||||
#else
|
||||
ohandler->sa_handler = (SigHandler *)signal (sig, handler);
|
||||
#endif /* !HAVE_POSIX_SIGNALS */
|
||||
return (ohandler->sa_handler);
|
||||
}
|
||||
|
||||
#else /* !HAVE_POSIX_SIGNALS */
|
||||
# define rl_set_sighandler(sig, handler) (SigHandler *)signal (sig, handler)
|
||||
#endif /* !HAVE_POSIX_SIGNALS */
|
||||
|
||||
int
|
||||
rl_set_signals ()
|
||||
{
|
||||
old_int = (SigHandler *)rl_set_sighandler (SIGINT, rl_signal_handler);
|
||||
if (old_int == (SigHandler *)SIG_IGN)
|
||||
rl_set_sighandler (SIGINT, SIG_IGN);
|
||||
sighandler_cxt dummy;
|
||||
SigHandler *oh;
|
||||
|
||||
old_alrm = (SigHandler *)rl_set_sighandler (SIGALRM, rl_signal_handler);
|
||||
if (old_alrm == (SigHandler *)SIG_IGN)
|
||||
rl_set_sighandler (SIGALRM, SIG_IGN);
|
||||
#if defined (HAVE_POSIX_SIGNALS)
|
||||
sigemptyset (&dummy.sa_mask);
|
||||
#endif
|
||||
|
||||
oh = rl_set_sighandler (SIGINT, rl_signal_handler, &old_int);
|
||||
if (oh == (SigHandler *)SIG_IGN)
|
||||
rl_sigaction (SIGINT, &old_int, &dummy);
|
||||
|
||||
oh = rl_set_sighandler (SIGALRM, rl_signal_handler, &old_alrm);
|
||||
if (oh == (SigHandler *)SIG_IGN)
|
||||
rl_sigaction (SIGALRM, &old_alrm, &dummy);
|
||||
#if defined (HAVE_POSIX_SIGNALS) && defined (SA_RESTART)
|
||||
/* If the application using readline has already installed a signal
|
||||
handler with SA_RESTART, SIGALRM will cause reads to be restarted
|
||||
automatically, so readline should just get out of the way. Since
|
||||
we tested for SIG_IGN above, we can just test for SIG_DFL here. */
|
||||
if (oh != (SigHandler *)SIG_DFL && (old_alrm.sa_flags & SA_RESTART))
|
||||
rl_sigaction (SIGALRM, &old_alrm, &dummy);
|
||||
#endif /* HAVE_POSIX_SIGNALS */
|
||||
|
||||
#if !defined (SHELL)
|
||||
|
||||
#if defined (SIGTSTP)
|
||||
old_tstp = (SigHandler *)rl_set_sighandler (SIGTSTP, rl_signal_handler);
|
||||
if (old_tstp == (SigHandler *)SIG_IGN)
|
||||
rl_set_sighandler (SIGTSTP, SIG_IGN);
|
||||
oh = rl_set_sighandler (SIGTSTP, rl_signal_handler, &old_tstp);
|
||||
if (oh == (SigHandler *)SIG_IGN)
|
||||
rl_sigaction (SIGTSTP, &old_tstp, &dummy);
|
||||
#else
|
||||
oh = (SigHandler *)NULL;
|
||||
#endif /* SIGTSTP */
|
||||
#if defined (SIGTTOU)
|
||||
old_ttou = (SigHandler *)rl_set_sighandler (SIGTTOU, rl_signal_handler);
|
||||
old_ttin = (SigHandler *)rl_set_sighandler (SIGTTIN, rl_signal_handler);
|
||||
|
||||
if (old_tstp == (SigHandler *)SIG_IGN)
|
||||
#if defined (SIGTTOU)
|
||||
rl_set_sighandler (SIGTTOU, rl_signal_handler, &old_ttou);
|
||||
rl_set_sighandler (SIGTTIN, rl_signal_handler, &old_ttin);
|
||||
|
||||
if (oh == (SigHandler *)SIG_IGN)
|
||||
{
|
||||
rl_set_sighandler (SIGTTOU, SIG_IGN);
|
||||
rl_set_sighandler (SIGTTIN, SIG_IGN);
|
||||
rl_set_sighandler (SIGTTOU, SIG_IGN, &dummy);
|
||||
rl_set_sighandler (SIGTTIN, SIG_IGN, &dummy);
|
||||
}
|
||||
#endif /* SIGTTOU */
|
||||
|
||||
/* Handle SIGTERM if we're not being compiled as part of bash. */
|
||||
rl_set_sighandler (SIGTERM, rl_signal_handler, &old_term);
|
||||
#endif /* !SHELL */
|
||||
|
||||
#if defined (SIGWINCH)
|
||||
old_sigwinch =
|
||||
(SigHandler *) rl_set_sighandler (SIGWINCH, rl_handle_sigwinch);
|
||||
rl_set_sighandler (SIGWINCH, rl_handle_sigwinch, &old_winch);
|
||||
#endif /* SIGWINCH */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rl_clear_signals ()
|
||||
{
|
||||
rl_set_sighandler (SIGINT, old_int);
|
||||
rl_set_sighandler (SIGALRM, old_alrm);
|
||||
sighandler_cxt dummy;
|
||||
|
||||
#if defined (HAVE_POSIX_SIGNALS)
|
||||
sigemptyset (&dummy.sa_mask);
|
||||
#endif
|
||||
|
||||
rl_sigaction (SIGINT, &old_int, &dummy);
|
||||
rl_sigaction (SIGALRM, &old_alrm, &dummy);
|
||||
|
||||
#if !defined (SHELL)
|
||||
|
||||
#if defined (SIGTSTP)
|
||||
rl_set_sighandler (SIGTSTP, old_tstp);
|
||||
rl_sigaction (SIGTSTP, &old_tstp, &dummy);
|
||||
#endif
|
||||
|
||||
#if defined (SIGTTOU)
|
||||
rl_set_sighandler (SIGTTOU, old_ttou);
|
||||
rl_set_sighandler (SIGTTIN, old_ttin);
|
||||
rl_sigaction (SIGTTOU, &old_ttou, &dummy);
|
||||
rl_sigaction (SIGTTIN, &old_ttin, &dummy);
|
||||
#endif /* SIGTTOU */
|
||||
|
||||
rl_sigaction (SIGTERM, &old_term, &dummy);
|
||||
|
||||
#endif /* !SHELL */
|
||||
|
||||
#if defined (SIGWINCH)
|
||||
rl_set_sighandler (SIGWINCH, old_sigwinch);
|
||||
sigemptyset (&dummy.sa_mask);
|
||||
rl_sigaction (SIGWINCH, &old_winch, &dummy);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
57
lib/readline/tcap.h
Normal file
57
lib/readline/tcap.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/* tcap.h -- termcap library functions and variables. */
|
||||
|
||||
/* Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
|
||||
This file contains the Readline Library (the Library), a set of
|
||||
routines for providing Emacs style line input to programs that ask
|
||||
for it.
|
||||
|
||||
The Library 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.
|
||||
|
||||
The Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#if !defined (_RLTCAP_H_)
|
||||
#define _RLTCAP_H_
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_TERMCAP_H)
|
||||
# include <termcap.h>
|
||||
#else
|
||||
|
||||
/* On Solaris2, sys/types.h #includes sys/reg.h, which #defines PC.
|
||||
Unfortunately, PC is a global variable used by the termcap library. */
|
||||
#ifdef PC
|
||||
# undef PC
|
||||
#endif
|
||||
|
||||
extern char PC;
|
||||
extern char *UP, *BC;
|
||||
|
||||
extern short ospeed;
|
||||
|
||||
extern int tgetent ();
|
||||
extern int tgetflag ();
|
||||
extern int tgetnum ();
|
||||
extern char *tgetstr ();
|
||||
|
||||
extern int tputs ();
|
||||
|
||||
extern char *tgoto ();
|
||||
|
||||
#endif /* HAVE_TERMCAP_H */
|
||||
|
||||
#endif /* !_RLTCAP_H_ */
|
||||
554
lib/readline/terminal.c
Normal file
554
lib/readline/terminal.c
Normal file
@@ -0,0 +1,554 @@
|
||||
/* terminal.c -- controlling the terminal with termcap. */
|
||||
|
||||
/* Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library 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.
|
||||
|
||||
The GNU Readline Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#define READLINE_LIBRARY
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "posixstat.h"
|
||||
#include <fcntl.h>
|
||||
#if defined (HAVE_SYS_FILE_H)
|
||||
# include <sys/file.h>
|
||||
#endif /* HAVE_SYS_FILE_H */
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif /* HAVE_UNISTD_H */
|
||||
|
||||
#if defined (HAVE_STDLIB_H)
|
||||
# include <stdlib.h>
|
||||
#else
|
||||
# include "ansi_stdlib.h"
|
||||
#endif /* HAVE_STDLIB_H */
|
||||
|
||||
#if defined (HAVE_LOCALE_H)
|
||||
# include <locale.h>
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
/* System-specific feature definitions and include files. */
|
||||
#include "rldefs.h"
|
||||
|
||||
#include "tcap.h"
|
||||
|
||||
#if defined (GWINSZ_IN_SYS_IOCTL)
|
||||
# include <sys/ioctl.h>
|
||||
#endif /* GWINSZ_IN_SYS_IOCTL */
|
||||
|
||||
/* Some standard library routines. */
|
||||
#include "readline.h"
|
||||
#include "history.h"
|
||||
|
||||
/* Variables and functions imported from readline.c */
|
||||
extern FILE *_rl_in_stream, *_rl_out_stream;
|
||||
extern int readline_echoing_p;
|
||||
extern int _rl_bell_preference;
|
||||
extern Keymap _rl_keymap;
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Terminal and Termcap */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
static char *term_buffer = (char *)NULL;
|
||||
static char *term_string_buffer = (char *)NULL;
|
||||
|
||||
static int tcap_initialized;
|
||||
|
||||
/* Non-zero means this terminal can't really do anything. */
|
||||
static int dumb_term;
|
||||
|
||||
#if !defined (__linux__)
|
||||
/* If this causes problems, add back the `extern'. */
|
||||
/*extern*/ char PC, *BC, *UP;
|
||||
#endif /* __linux__ */
|
||||
|
||||
/* Some strings to control terminal actions. These are output by tputs (). */
|
||||
char *term_goto, *term_clreol, *term_cr, *term_clrpag, *term_backspace;
|
||||
char *term_pc;
|
||||
|
||||
/* Non-zero if we determine that the terminal can do character insertion. */
|
||||
int terminal_can_insert = 0;
|
||||
|
||||
/* How to insert characters. */
|
||||
char *term_im, *term_ei, *term_ic, *term_ip, *term_IC;
|
||||
|
||||
/* How to delete characters. */
|
||||
char *term_dc, *term_DC;
|
||||
|
||||
#if defined (HACK_TERMCAP_MOTION)
|
||||
char *term_forward_char;
|
||||
#endif /* HACK_TERMCAP_MOTION */
|
||||
|
||||
/* How to go up a line. */
|
||||
char *term_up;
|
||||
|
||||
/* A visible bell, if the terminal can be made to flash the screen. */
|
||||
static char *visible_bell;
|
||||
|
||||
/* Non-zero means the terminal can auto-wrap lines. */
|
||||
int _rl_term_autowrap;
|
||||
|
||||
/* Non-zero means that this terminal has a meta key. */
|
||||
static int term_has_meta;
|
||||
|
||||
/* The sequences to write to turn on and off the meta key, if this
|
||||
terminal has one. */
|
||||
static char *term_mm, *term_mo;
|
||||
|
||||
/* The key sequences output by the arrow keys, if this terminal has any. */
|
||||
static char *term_ku, *term_kd, *term_kr, *term_kl;
|
||||
|
||||
/* How to initialize and reset the arrow keys, if this terminal has any. */
|
||||
static char *term_ks, *term_ke;
|
||||
|
||||
/* The key sequences sent by the Home and End keys, if any. */
|
||||
static char *term_kh, *term_kH;
|
||||
|
||||
/* Variables that hold the screen dimensions, used by the display code. */
|
||||
int screenwidth, screenheight, screenchars;
|
||||
|
||||
/* Non-zero means the user wants to enable the keypad. */
|
||||
int _rl_enable_keypad;
|
||||
|
||||
/* Non-zero means the user wants to enable a meta key. */
|
||||
int _rl_enable_meta = 1;
|
||||
|
||||
/* Re-initialize the terminal considering that the TERM/TERMCAP variable
|
||||
has changed. */
|
||||
int
|
||||
rl_reset_terminal (terminal_name)
|
||||
char *terminal_name;
|
||||
{
|
||||
_rl_init_terminal_io (terminal_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined (SHELL)
|
||||
static void
|
||||
set_lines_and_columns (lines, cols)
|
||||
int lines, cols;
|
||||
{
|
||||
char *b;
|
||||
|
||||
#if defined (HAVE_PUTENV)
|
||||
b = xmalloc (24);
|
||||
sprintf (b, "LINES=%d", lines);
|
||||
putenv (b);
|
||||
b = xmalloc (24);
|
||||
sprintf (b, "COLUMNS=%d", cols);
|
||||
putenv (b);
|
||||
#else /* !HAVE_PUTENV */
|
||||
# if defined (HAVE_SETENV)
|
||||
b = xmalloc (8);
|
||||
sprintf (b, "%d", lines);
|
||||
setenv ("LINES", b, 1);
|
||||
b = xmalloc (8);
|
||||
sprintf (b, "%d", cols);
|
||||
setenv ("COLUMNS", b, 1);
|
||||
# endif /* HAVE_SETENV */
|
||||
#endif /* !HAVE_PUTENV */
|
||||
}
|
||||
#else /* SHELL */
|
||||
extern void set_lines_and_columns ();
|
||||
#endif /* SHELL */
|
||||
|
||||
/* Get readline's idea of the screen size. TTY is a file descriptor open
|
||||
to the terminal. If IGNORE_ENV is true, we do not pay attention to the
|
||||
values of $LINES and $COLUMNS. The tests for TERM_STRING_BUFFER being
|
||||
non-null serve to check whether or not we have initialized termcap. */
|
||||
void
|
||||
_rl_get_screen_size (tty, ignore_env)
|
||||
int tty, ignore_env;
|
||||
{
|
||||
char *ss;
|
||||
#if defined (TIOCGWINSZ)
|
||||
struct winsize window_size;
|
||||
#endif /* TIOCGWINSZ */
|
||||
|
||||
#if defined (TIOCGWINSZ)
|
||||
if (ioctl (tty, TIOCGWINSZ, &window_size) == 0)
|
||||
{
|
||||
screenwidth = (int) window_size.ws_col;
|
||||
screenheight = (int) window_size.ws_row;
|
||||
}
|
||||
#endif /* TIOCGWINSZ */
|
||||
|
||||
/* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV
|
||||
is unset. */
|
||||
if (screenwidth <= 0)
|
||||
{
|
||||
if (ignore_env == 0 && (ss = getenv ("COLUMNS")))
|
||||
screenwidth = atoi (ss);
|
||||
|
||||
if (screenwidth <= 0 && term_string_buffer)
|
||||
screenwidth = tgetnum ("co");
|
||||
}
|
||||
|
||||
/* Environment variable LINES overrides setting of "li" if IGNORE_ENV
|
||||
is unset. */
|
||||
if (screenheight <= 0)
|
||||
{
|
||||
if (ignore_env == 0 && (ss = getenv ("LINES")))
|
||||
screenheight = atoi (ss);
|
||||
|
||||
if (screenheight <= 0 && term_string_buffer)
|
||||
screenheight = tgetnum ("li");
|
||||
}
|
||||
|
||||
/* If all else fails, default to 80x24 terminal. */
|
||||
if (screenwidth <= 1)
|
||||
screenwidth = 80;
|
||||
|
||||
if (screenheight <= 0)
|
||||
screenheight = 24;
|
||||
|
||||
/* If we're being compiled as part of bash, set the environment
|
||||
variables $LINES and $COLUMNS to new values. Otherwise, just
|
||||
do a pair of putenv () or setenv () calls. */
|
||||
set_lines_and_columns (screenheight, screenwidth);
|
||||
|
||||
if (!_rl_term_autowrap)
|
||||
screenwidth--;
|
||||
|
||||
screenchars = screenwidth * screenheight;
|
||||
}
|
||||
|
||||
void
|
||||
_rl_set_screen_size (rows, cols)
|
||||
int rows, cols;
|
||||
{
|
||||
screenheight = rows;
|
||||
screenwidth = cols;
|
||||
|
||||
if (_rl_term_autowrap == 0)
|
||||
screenwidth--;
|
||||
|
||||
screenchars = screenwidth * screenheight;
|
||||
}
|
||||
|
||||
struct _tc_string {
|
||||
char *tc_var;
|
||||
char **tc_value;
|
||||
};
|
||||
|
||||
/* This should be kept sorted, just in case we decide to change the
|
||||
search algorithm to something smarter. */
|
||||
static struct _tc_string tc_strings[] =
|
||||
{
|
||||
"DC", &term_DC,
|
||||
"IC", &term_IC,
|
||||
"ce", &term_clreol,
|
||||
"cl", &term_clrpag,
|
||||
"cr", &term_cr,
|
||||
"dc", &term_dc,
|
||||
"ei", &term_ei,
|
||||
"ic", &term_ic,
|
||||
"im", &term_im,
|
||||
"kd", &term_kd,
|
||||
"kh", &term_kh, /* home */
|
||||
"kH", &term_kH, /* end */
|
||||
"kl", &term_kl,
|
||||
"kr", &term_kr,
|
||||
"ku", &term_ku,
|
||||
"ks", &term_ks,
|
||||
"ke", &term_ke,
|
||||
"le", &term_backspace,
|
||||
"mm", &term_mm,
|
||||
"mo", &term_mo,
|
||||
#if defined (HACK_TERMCAP_MOTION)
|
||||
"nd", &term_forward_char,
|
||||
#endif
|
||||
"pc", &term_pc,
|
||||
"up", &term_up,
|
||||
"vb", &visible_bell,
|
||||
};
|
||||
|
||||
#define NUM_TC_STRINGS (sizeof (tc_strings) / sizeof (struct _tc_string))
|
||||
|
||||
/* Read the desired terminal capability strings into BP. The capabilities
|
||||
are described in the TC_STRINGS table. */
|
||||
static void
|
||||
get_term_capabilities (bp)
|
||||
char **bp;
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < NUM_TC_STRINGS; i++)
|
||||
*(tc_strings[i].tc_value) = tgetstr (tc_strings[i].tc_var, bp);
|
||||
tcap_initialized = 1;
|
||||
}
|
||||
|
||||
int
|
||||
_rl_init_terminal_io (terminal_name)
|
||||
char *terminal_name;
|
||||
{
|
||||
#if defined (__GO32__)
|
||||
screenwidth = ScreenCols ();
|
||||
screenheight = ScreenRows ();
|
||||
screenchars = screenwidth * screenheight;
|
||||
term_cr = "\r";
|
||||
term_im = term_ei = term_ic = term_IC = (char *)NULL;
|
||||
term_up = term_dc = term_DC = visible_bell = (char *)NULL;
|
||||
|
||||
/* Does the __GO32__ have a meta key? I don't know. */
|
||||
term_has_meta = 0;
|
||||
term_mm = term_mo = (char *)NULL;
|
||||
|
||||
/* It probably has arrow keys, but I don't know what they are. */
|
||||
term_ku = term_kd = term_kr = term_kl = (char *)NULL;
|
||||
|
||||
#if defined (HACK_TERMCAP_MOTION)
|
||||
term_forward_char = (char *)NULL;
|
||||
#endif /* HACK_TERMCAP_MOTION */
|
||||
terminal_can_insert = _rl_term_autowrap = 0;
|
||||
return;
|
||||
#else /* !__GO32__ */
|
||||
|
||||
char *term, *buffer;
|
||||
int tty;
|
||||
Keymap xkeymap;
|
||||
|
||||
term = terminal_name ? terminal_name : getenv ("TERM");
|
||||
|
||||
if (term_string_buffer == 0)
|
||||
term_string_buffer = xmalloc (2032);
|
||||
|
||||
if (term_buffer == 0)
|
||||
term_buffer = xmalloc (4080);
|
||||
|
||||
buffer = term_string_buffer;
|
||||
|
||||
term_clrpag = term_cr = term_clreol = (char *)NULL;
|
||||
|
||||
if (term == 0)
|
||||
term = "dumb";
|
||||
|
||||
if (tgetent (term_buffer, term) <= 0)
|
||||
{
|
||||
dumb_term = 1;
|
||||
screenwidth = 79;
|
||||
screenheight = 24;
|
||||
screenchars = 79 * 24;
|
||||
term_cr = "\r";
|
||||
term_im = term_ei = term_ic = term_IC = (char *)NULL;
|
||||
term_up = term_dc = term_DC = visible_bell = (char *)NULL;
|
||||
term_ku = term_kd = term_kl = term_kr = (char *)NULL;
|
||||
#if defined (HACK_TERMCAP_MOTION)
|
||||
term_forward_char = (char *)NULL;
|
||||
#endif
|
||||
terminal_can_insert = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
get_term_capabilities (&buffer);
|
||||
|
||||
/* Set up the variables that the termcap library expects the application
|
||||
to provide. */
|
||||
PC = term_pc ? *term_pc : 0;
|
||||
BC = term_backspace;
|
||||
UP = term_up;
|
||||
|
||||
if (!term_cr)
|
||||
term_cr = "\r";
|
||||
|
||||
tty = rl_instream ? fileno (rl_instream) : 0;
|
||||
|
||||
screenwidth = screenheight = 0;
|
||||
|
||||
_rl_term_autowrap = tgetflag ("am") && tgetflag ("xn");
|
||||
|
||||
_rl_get_screen_size (tty, 0);
|
||||
|
||||
/* "An application program can assume that the terminal can do
|
||||
character insertion if *any one of* the capabilities `IC',
|
||||
`im', `ic' or `ip' is provided." But we can't do anything if
|
||||
only `ip' is provided, so... */
|
||||
terminal_can_insert = (term_IC || term_im || term_ic);
|
||||
|
||||
/* Check to see if this terminal has a meta key and clear the capability
|
||||
variables if there is none. */
|
||||
term_has_meta = (tgetflag ("km") || tgetflag ("MT"));
|
||||
if (!term_has_meta)
|
||||
term_mm = term_mo = (char *)NULL;
|
||||
|
||||
/* Attempt to find and bind the arrow keys. Do not override already
|
||||
bound keys in an overzealous attempt, however. */
|
||||
xkeymap = _rl_keymap;
|
||||
|
||||
_rl_keymap = emacs_standard_keymap;
|
||||
_rl_bind_if_unbound (term_ku, rl_get_previous_history);
|
||||
_rl_bind_if_unbound (term_kd, rl_get_next_history);
|
||||
_rl_bind_if_unbound (term_kr, rl_forward);
|
||||
_rl_bind_if_unbound (term_kl, rl_backward);
|
||||
|
||||
_rl_bind_if_unbound (term_kh, rl_beg_of_line); /* Home */
|
||||
_rl_bind_if_unbound (term_kH, rl_end_of_line); /* End */
|
||||
|
||||
#if defined (VI_MODE)
|
||||
_rl_keymap = vi_movement_keymap;
|
||||
_rl_bind_if_unbound (term_ku, rl_get_previous_history);
|
||||
_rl_bind_if_unbound (term_kd, rl_get_next_history);
|
||||
_rl_bind_if_unbound (term_kr, rl_forward);
|
||||
_rl_bind_if_unbound (term_kl, rl_backward);
|
||||
|
||||
_rl_bind_if_unbound (term_kh, rl_beg_of_line); /* Home */
|
||||
_rl_bind_if_unbound (term_kH, rl_end_of_line); /* End */
|
||||
#endif /* VI_MODE */
|
||||
|
||||
_rl_keymap = xkeymap;
|
||||
|
||||
#endif /* !__GO32__ */
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *
|
||||
rl_get_termcap (cap)
|
||||
char *cap;
|
||||
{
|
||||
register int i;
|
||||
|
||||
if (tcap_initialized == 0)
|
||||
return ((char *)NULL);
|
||||
for (i = 0; i < NUM_TC_STRINGS; i++)
|
||||
{
|
||||
if (tc_strings[i].tc_var[0] == cap[0] && strcmp (tc_strings[i].tc_var, cap) == 0)
|
||||
return *(tc_strings[i].tc_value);
|
||||
}
|
||||
return ((char *)NULL);
|
||||
}
|
||||
|
||||
/* A function for the use of tputs () */
|
||||
int
|
||||
_rl_output_character_function (c)
|
||||
int c;
|
||||
{
|
||||
return putc (c, _rl_out_stream);
|
||||
}
|
||||
|
||||
/* Write COUNT characters from STRING to the output stream. */
|
||||
void
|
||||
_rl_output_some_chars (string, count)
|
||||
char *string;
|
||||
int count;
|
||||
{
|
||||
fwrite (string, 1, count, _rl_out_stream);
|
||||
}
|
||||
|
||||
/* Move the cursor back. */
|
||||
int
|
||||
_rl_backspace (count)
|
||||
int count;
|
||||
{
|
||||
register int i;
|
||||
|
||||
#if !defined (__GO32__)
|
||||
if (term_backspace)
|
||||
for (i = 0; i < count; i++)
|
||||
tputs (term_backspace, 1, _rl_output_character_function);
|
||||
else
|
||||
#endif /* !__GO32__ */
|
||||
for (i = 0; i < count; i++)
|
||||
putc ('\b', _rl_out_stream);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Move to the start of the next line. */
|
||||
int
|
||||
crlf ()
|
||||
{
|
||||
#if defined (NEW_TTY_DRIVER)
|
||||
if (term_cr)
|
||||
tputs (term_cr, 1, _rl_output_character_function);
|
||||
#endif /* NEW_TTY_DRIVER */
|
||||
putc ('\n', _rl_out_stream);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Ring the terminal bell. */
|
||||
int
|
||||
ding ()
|
||||
{
|
||||
if (readline_echoing_p)
|
||||
{
|
||||
#if !defined (__GO32__)
|
||||
switch (_rl_bell_preference)
|
||||
{
|
||||
case NO_BELL:
|
||||
default:
|
||||
break;
|
||||
case VISIBLE_BELL:
|
||||
if (visible_bell)
|
||||
{
|
||||
tputs (visible_bell, 1, _rl_output_character_function);
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case AUDIBLE_BELL:
|
||||
fprintf (stderr, "\007");
|
||||
fflush (stderr);
|
||||
break;
|
||||
}
|
||||
#else /* __GO32__ */
|
||||
fprintf (stderr, "\007");
|
||||
fflush (stderr);
|
||||
#endif /* __GO32__ */
|
||||
return (0);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Controlling the Meta Key and Keypad */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
static int
|
||||
outchar (c)
|
||||
int c;
|
||||
{
|
||||
return putc (c, rl_outstream);
|
||||
}
|
||||
|
||||
int
|
||||
_rl_enable_meta_key ()
|
||||
{
|
||||
if (term_has_meta && term_mm)
|
||||
tputs (term_mm, 1, outchar);
|
||||
}
|
||||
|
||||
void
|
||||
_rl_control_keypad (on)
|
||||
int on;
|
||||
{
|
||||
if (on && term_ks)
|
||||
tputs (term_ks, 1, outchar);
|
||||
else if (!on && term_ke)
|
||||
tputs (term_ke, 1, outchar);
|
||||
}
|
||||
@@ -19,6 +19,10 @@
|
||||
along with Readline; see the file COPYING. If not, write to the Free
|
||||
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_STRING_H)
|
||||
# include <string.h>
|
||||
#else /* !HAVE_STRING_H */
|
||||
@@ -31,13 +35,14 @@
|
||||
# include "ansi_stdlib.h"
|
||||
#endif /* HAVE_STDLIB_H */
|
||||
|
||||
#include "tilde.h"
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#if defined (USG) && !defined (HAVE_GETPW_DECLS)
|
||||
#include "tilde.h"
|
||||
|
||||
#if !defined (HAVE_GETPW_DECLS)
|
||||
extern struct passwd *getpwuid (), *getpwnam ();
|
||||
#endif /* USG && !defined (HAVE_GETPW_DECLS) */
|
||||
#endif /* !HAVE_GETPW_DECLS */
|
||||
|
||||
#if !defined (savestring)
|
||||
extern char *xmalloc ();
|
||||
@@ -171,7 +176,7 @@ tilde_expand (string)
|
||||
|
||||
/* Copy the skipped text into the result. */
|
||||
if ((result_index + start + 1) > result_size)
|
||||
result = (char *)xrealloc (result, 1 + (result_size += (start + 20)));
|
||||
result = xrealloc (result, 1 + (result_size += (start + 20)));
|
||||
|
||||
strncpy (result + result_index, string, start);
|
||||
result_index += start;
|
||||
@@ -188,7 +193,7 @@ tilde_expand (string)
|
||||
break;
|
||||
|
||||
/* Expand the entire tilde word, and copy it into RESULT. */
|
||||
tilde_word = (char *)xmalloc (1 + end);
|
||||
tilde_word = xmalloc (1 + end);
|
||||
strncpy (tilde_word, string, end);
|
||||
tilde_word[end] = '\0';
|
||||
string += end;
|
||||
@@ -198,7 +203,7 @@ tilde_expand (string)
|
||||
|
||||
len = strlen (expansion);
|
||||
if ((result_index + len + 1) > result_size)
|
||||
result = (char *)xrealloc (result, 1 + (result_size += (len + 20)));
|
||||
result = xrealloc (result, 1 + (result_size += (len + 20)));
|
||||
|
||||
strcpy (result + result_index, expansion);
|
||||
result_index += len;
|
||||
@@ -217,85 +222,90 @@ tilde_expand_word (filename)
|
||||
char *filename;
|
||||
{
|
||||
char *dirname;
|
||||
char *temp_name;
|
||||
|
||||
dirname = filename ? savestring (filename) : (char *)NULL;
|
||||
if (filename == (char *)0)
|
||||
return ((char *)NULL);
|
||||
|
||||
if (dirname && *dirname == '~')
|
||||
dirname = savestring (filename);
|
||||
|
||||
if (*dirname != '~')
|
||||
return (dirname);
|
||||
|
||||
if (!dirname[1] || dirname[1] == '/')
|
||||
{
|
||||
char *temp_name;
|
||||
if (!dirname[1] || dirname[1] == '/')
|
||||
/* Prepend $HOME to the rest of the string. */
|
||||
char *temp_home = (char *)getenv ("HOME");
|
||||
int home_len;
|
||||
|
||||
/* If there is no HOME variable, look up the directory in
|
||||
the password database. */
|
||||
if (!temp_home)
|
||||
{
|
||||
/* Prepend $HOME to the rest of the string. */
|
||||
char *temp_home = (char *)getenv ("HOME");
|
||||
struct passwd *entry;
|
||||
|
||||
/* If there is no HOME variable, look up the directory in
|
||||
the password database. */
|
||||
if (!temp_home)
|
||||
entry = getpwuid (getuid ());
|
||||
if (entry)
|
||||
temp_home = entry->pw_dir;
|
||||
}
|
||||
|
||||
home_len = temp_home ? strlen (temp_home) : 0;
|
||||
temp_name = xmalloc (1 + strlen (dirname + 1) + home_len);
|
||||
|
||||
if (temp_home)
|
||||
strcpy (temp_name, temp_home);
|
||||
strcpy (temp_name + home_len, dirname + 1);
|
||||
free (dirname);
|
||||
dirname = temp_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *username;
|
||||
struct passwd *user_entry;
|
||||
int i, len;
|
||||
|
||||
username = xmalloc (strlen (dirname));
|
||||
for (i = 1; dirname[i] && dirname[i] != '/'; i++)
|
||||
username[i - 1] = dirname[i];
|
||||
username[i - 1] = '\0';
|
||||
|
||||
if ((user_entry = getpwnam (username)) == (struct passwd *)0)
|
||||
{
|
||||
/* If the calling program has a special syntax for
|
||||
expanding tildes, and we couldn't find a standard
|
||||
expansion, then let them try. */
|
||||
if (tilde_expansion_failure_hook)
|
||||
{
|
||||
struct passwd *entry;
|
||||
char *expansion;
|
||||
|
||||
entry = getpwuid (getuid ());
|
||||
if (entry)
|
||||
temp_home = entry->pw_dir;
|
||||
expansion = (*tilde_expansion_failure_hook) (username);
|
||||
|
||||
if (expansion)
|
||||
{
|
||||
len = strlen (expansion);
|
||||
temp_name = xmalloc (1 + len + strlen (dirname + i));
|
||||
strcpy (temp_name, expansion);
|
||||
strcpy (temp_name + len, dirname + i);
|
||||
free (expansion);
|
||||
free (dirname);
|
||||
dirname = temp_name;
|
||||
}
|
||||
}
|
||||
|
||||
temp_name = xmalloc (1 + strlen (&dirname[1])
|
||||
+ (temp_home ? strlen (temp_home) : 0));
|
||||
temp_name[0] = '\0';
|
||||
if (temp_home)
|
||||
strcpy (temp_name, temp_home);
|
||||
strcat (temp_name, dirname + 1);
|
||||
free (dirname);
|
||||
dirname = temp_name;
|
||||
/* We shouldn't report errors. */
|
||||
}
|
||||
else
|
||||
{
|
||||
char *username;
|
||||
struct passwd *user_entry;
|
||||
int i;
|
||||
|
||||
username = xmalloc (strlen (dirname));
|
||||
for (i = 1; dirname[i] && dirname[i] != '/'; i++)
|
||||
username[i - 1] = dirname[i];
|
||||
username[i - 1] = '\0';
|
||||
|
||||
if ((user_entry = getpwnam (username)) == 0)
|
||||
{
|
||||
/* If the calling program has a special syntax for
|
||||
expanding tildes, and we couldn't find a standard
|
||||
expansion, then let them try. */
|
||||
if (tilde_expansion_failure_hook)
|
||||
{
|
||||
char *expansion;
|
||||
|
||||
expansion = (*tilde_expansion_failure_hook) (username);
|
||||
|
||||
if (expansion)
|
||||
{
|
||||
temp_name = xmalloc (1 + strlen (expansion)
|
||||
+ strlen (&dirname[i]));
|
||||
strcpy (temp_name, expansion);
|
||||
strcat (temp_name, &dirname[i]);
|
||||
free (expansion);
|
||||
free (dirname);
|
||||
dirname = temp_name;
|
||||
}
|
||||
}
|
||||
/* We shouldn't report errors. */
|
||||
}
|
||||
else
|
||||
{
|
||||
temp_name = xmalloc (1 + strlen (user_entry->pw_dir)
|
||||
+ strlen (&dirname[i]));
|
||||
strcpy (temp_name, user_entry->pw_dir);
|
||||
strcat (temp_name, &dirname[i]);
|
||||
free (dirname);
|
||||
dirname = temp_name;
|
||||
}
|
||||
endpwent ();
|
||||
free (username);
|
||||
len = strlen (user_entry->pw_dir);
|
||||
temp_name = xmalloc (1 + len + strlen (dirname + i));
|
||||
strcpy (temp_name, user_entry->pw_dir);
|
||||
strcpy (temp_name + len, dirname + i);
|
||||
free (dirname);
|
||||
dirname = temp_name;
|
||||
}
|
||||
endpwent ();
|
||||
free (username);
|
||||
}
|
||||
|
||||
return (dirname);
|
||||
}
|
||||
|
||||
@@ -368,7 +378,7 @@ xrealloc (pointer, bytes)
|
||||
static void
|
||||
memory_error_and_abort ()
|
||||
{
|
||||
fprintf (stderr, "readline: Out of virtual memory!\n");
|
||||
fprintf (stderr, "readline: out of virtual memory\n");
|
||||
abort ();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,32 @@
|
||||
/* tilde.h: Externally available variables and function in libtilde.a. */
|
||||
|
||||
#if !defined (__TILDE_H__)
|
||||
# define __TILDE_H__
|
||||
/* Copyright (C) 1992 Free Software Foundation, Inc.
|
||||
|
||||
This file contains the Readline Library (the Library), a set of
|
||||
routines for providing Emacs style line input to programs that ask
|
||||
for it.
|
||||
|
||||
The Library 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.
|
||||
|
||||
The Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#if !defined (_TILDE_H_)
|
||||
# define _TILDE_H_
|
||||
|
||||
/* Function pointers can be declared as (Function *)foo. */
|
||||
#if !defined (__FUNCTION_DEF)
|
||||
# define __FUNCTION_DEF
|
||||
#if !defined (_FUNCTION_DEF)
|
||||
# define _FUNCTION_DEF
|
||||
typedef int Function ();
|
||||
typedef void VFunction ();
|
||||
typedef char *CPFunction ();
|
||||
@@ -35,4 +56,4 @@ extern char *tilde_expand ();
|
||||
tilde. If there is no expansion, call tilde_expansion_failure_hook. */
|
||||
extern char *tilde_expand_word ();
|
||||
|
||||
#endif /* __TILDE_H__ */
|
||||
#endif /* _TILDE_H_ */
|
||||
|
||||
261
lib/readline/undo.c
Normal file
261
lib/readline/undo.c
Normal file
@@ -0,0 +1,261 @@
|
||||
/* readline.c -- a general facility for reading lines of input
|
||||
with emacs style editing and completion. */
|
||||
|
||||
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library 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.
|
||||
|
||||
The GNU Readline Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#define READLINE_LIBRARY
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h> /* for _POSIX_VERSION */
|
||||
#endif /* HAVE_UNISTD_H */
|
||||
|
||||
#if defined (HAVE_STDLIB_H)
|
||||
# include <stdlib.h>
|
||||
#else
|
||||
# include "ansi_stdlib.h"
|
||||
#endif /* HAVE_STDLIB_H */
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* System-specific feature definitions and include files. */
|
||||
#include "rldefs.h"
|
||||
|
||||
/* Some standard library routines. */
|
||||
#include "readline.h"
|
||||
#include "history.h"
|
||||
|
||||
#define SWAP(s, e) do { int t; t = s; s = e; e = t; } while (0)
|
||||
|
||||
/* Non-zero tells rl_delete_text and rl_insert_text to not add to
|
||||
the undo list. */
|
||||
int _rl_doing_an_undo = 0;
|
||||
|
||||
/* How many unclosed undo groups we currently have. */
|
||||
int _rl_undo_group_level = 0;
|
||||
|
||||
/* The current undo list for THE_LINE. */
|
||||
UNDO_LIST *rl_undo_list = (UNDO_LIST *)NULL;
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Undo, and Undoing */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Remember how to undo something. Concatenate some undos if that
|
||||
seems right. */
|
||||
void
|
||||
rl_add_undo (what, start, end, text)
|
||||
enum undo_code what;
|
||||
int start, end;
|
||||
char *text;
|
||||
{
|
||||
UNDO_LIST *temp = (UNDO_LIST *)xmalloc (sizeof (UNDO_LIST));
|
||||
temp->what = what;
|
||||
temp->start = start;
|
||||
temp->end = end;
|
||||
temp->text = text;
|
||||
temp->next = rl_undo_list;
|
||||
rl_undo_list = temp;
|
||||
}
|
||||
|
||||
/* Free the existing undo list. */
|
||||
void
|
||||
free_undo_list ()
|
||||
{
|
||||
while (rl_undo_list)
|
||||
{
|
||||
UNDO_LIST *release = rl_undo_list;
|
||||
rl_undo_list = rl_undo_list->next;
|
||||
|
||||
if (release->what == UNDO_DELETE)
|
||||
free (release->text);
|
||||
|
||||
free (release);
|
||||
}
|
||||
rl_undo_list = (UNDO_LIST *)NULL;
|
||||
}
|
||||
|
||||
/* Undo the next thing in the list. Return 0 if there
|
||||
is nothing to undo, or non-zero if there was. */
|
||||
int
|
||||
rl_do_undo ()
|
||||
{
|
||||
UNDO_LIST *release;
|
||||
int waiting_for_begin = 0;
|
||||
int start, end;
|
||||
|
||||
#define TRANS(i) ((i) == -1 ? rl_point : ((i) == -2 ? rl_end : (i)))
|
||||
|
||||
do
|
||||
{
|
||||
if (!rl_undo_list)
|
||||
return (0);
|
||||
|
||||
_rl_doing_an_undo = 1;
|
||||
|
||||
/* To better support vi-mode, a start or end value of -1 means
|
||||
rl_point, and a value of -2 means rl_end. */
|
||||
if (rl_undo_list->what == UNDO_DELETE || rl_undo_list->what == UNDO_INSERT)
|
||||
{
|
||||
start = TRANS (rl_undo_list->start);
|
||||
end = TRANS (rl_undo_list->end);
|
||||
}
|
||||
|
||||
switch (rl_undo_list->what)
|
||||
{
|
||||
/* Undoing deletes means inserting some text. */
|
||||
case UNDO_DELETE:
|
||||
rl_point = start;
|
||||
rl_insert_text (rl_undo_list->text);
|
||||
free (rl_undo_list->text);
|
||||
break;
|
||||
|
||||
/* Undoing inserts means deleting some text. */
|
||||
case UNDO_INSERT:
|
||||
rl_delete_text (start, end);
|
||||
rl_point = start;
|
||||
break;
|
||||
|
||||
/* Undoing an END means undoing everything 'til we get to a BEGIN. */
|
||||
case UNDO_END:
|
||||
waiting_for_begin++;
|
||||
break;
|
||||
|
||||
/* Undoing a BEGIN means that we are done with this group. */
|
||||
case UNDO_BEGIN:
|
||||
if (waiting_for_begin)
|
||||
waiting_for_begin--;
|
||||
else
|
||||
ding ();
|
||||
break;
|
||||
}
|
||||
|
||||
_rl_doing_an_undo = 0;
|
||||
|
||||
release = rl_undo_list;
|
||||
rl_undo_list = rl_undo_list->next;
|
||||
free (release);
|
||||
}
|
||||
while (waiting_for_begin);
|
||||
|
||||
return (1);
|
||||
}
|
||||
#undef TRANS
|
||||
|
||||
int
|
||||
_rl_fix_last_undo_of_type (type, start, end)
|
||||
int type, start, end;
|
||||
{
|
||||
UNDO_LIST *rl;
|
||||
|
||||
for (rl = rl_undo_list; rl; rl = rl->next)
|
||||
{
|
||||
if (rl->what == type)
|
||||
{
|
||||
rl->start = start;
|
||||
rl->end = end;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Begin a group. Subsequent undos are undone as an atomic operation. */
|
||||
int
|
||||
rl_begin_undo_group ()
|
||||
{
|
||||
rl_add_undo (UNDO_BEGIN, 0, 0, 0);
|
||||
_rl_undo_group_level++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* End an undo group started with rl_begin_undo_group (). */
|
||||
int
|
||||
rl_end_undo_group ()
|
||||
{
|
||||
rl_add_undo (UNDO_END, 0, 0, 0);
|
||||
_rl_undo_group_level--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Save an undo entry for the text from START to END. */
|
||||
int
|
||||
rl_modifying (start, end)
|
||||
int start, end;
|
||||
{
|
||||
if (start > end)
|
||||
{
|
||||
SWAP (start, end);
|
||||
}
|
||||
|
||||
if (start != end)
|
||||
{
|
||||
char *temp = rl_copy_text (start, end);
|
||||
rl_begin_undo_group ();
|
||||
rl_add_undo (UNDO_DELETE, start, end, temp);
|
||||
rl_add_undo (UNDO_INSERT, start, end, (char *)NULL);
|
||||
rl_end_undo_group ();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Revert the current line to its previous state. */
|
||||
int
|
||||
rl_revert_line (count, key)
|
||||
int count, key;
|
||||
{
|
||||
if (!rl_undo_list)
|
||||
ding ();
|
||||
else
|
||||
{
|
||||
while (rl_undo_list)
|
||||
rl_do_undo ();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Do some undoing of things that were done. */
|
||||
int
|
||||
rl_undo_command (count, key)
|
||||
int count, key;
|
||||
{
|
||||
if (count < 0)
|
||||
return 0; /* Nothing to do. */
|
||||
|
||||
while (count)
|
||||
{
|
||||
if (rl_do_undo ())
|
||||
count--;
|
||||
else
|
||||
{
|
||||
ding ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
315
lib/readline/util.c
Normal file
315
lib/readline/util.c
Normal file
@@ -0,0 +1,315 @@
|
||||
/* util.c -- readline utility functions */
|
||||
|
||||
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library 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.
|
||||
|
||||
The GNU Readline Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#define READLINE_LIBRARY
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <setjmp.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h> /* for _POSIX_VERSION */
|
||||
#endif /* HAVE_UNISTD_H */
|
||||
|
||||
#if defined (HAVE_STDLIB_H)
|
||||
# include <stdlib.h>
|
||||
#else
|
||||
# include "ansi_stdlib.h"
|
||||
#endif /* HAVE_STDLIB_H */
|
||||
|
||||
/* System-specific feature definitions and include files. */
|
||||
#include "rldefs.h"
|
||||
|
||||
#if defined (TIOCSTAT_IN_SYS_IOCTL)
|
||||
# include <sys/ioctl.h>
|
||||
#endif /* TIOCSTAT_IN_SYS_IOCTL */
|
||||
|
||||
/* Some standard library routines. */
|
||||
#include "readline.h"
|
||||
|
||||
#define SWAP(s, e) do { int t; t = s; s = e; e = t; } while (0)
|
||||
|
||||
/* Pseudo-globals imported from readline.c */
|
||||
extern int readline_echoing_p;
|
||||
extern jmp_buf readline_top_level;
|
||||
extern int rl_line_buffer_len;
|
||||
extern Function *rl_last_func;
|
||||
|
||||
extern int _rl_defining_kbd_macro;
|
||||
extern char *_rl_executing_macro;
|
||||
|
||||
/* Pseudo-global functions imported from other library files. */
|
||||
extern void _rl_pop_executing_macro ();
|
||||
extern void _rl_set_the_line ();
|
||||
extern void _rl_init_argument ();
|
||||
|
||||
extern char *xmalloc (), *xrealloc ();
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Utility Functions */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Return 0 if C is not a member of the class of characters that belong
|
||||
in words, or 1 if it is. */
|
||||
|
||||
int _rl_allow_pathname_alphabetic_chars = 0;
|
||||
static char *pathname_alphabetic_chars = "/-_=~.#$";
|
||||
|
||||
int
|
||||
alphabetic (c)
|
||||
int c;
|
||||
{
|
||||
if (ALPHABETIC (c))
|
||||
return (1);
|
||||
|
||||
return (_rl_allow_pathname_alphabetic_chars &&
|
||||
strchr (pathname_alphabetic_chars, c) != NULL);
|
||||
}
|
||||
|
||||
/* How to abort things. */
|
||||
int
|
||||
_rl_abort_internal ()
|
||||
{
|
||||
ding ();
|
||||
rl_clear_message ();
|
||||
_rl_init_argument ();
|
||||
rl_pending_input = 0;
|
||||
|
||||
_rl_defining_kbd_macro = 0;
|
||||
while (_rl_executing_macro)
|
||||
_rl_pop_executing_macro ();
|
||||
|
||||
rl_last_func = (Function *)NULL;
|
||||
longjmp (readline_top_level, 1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rl_abort (count, key)
|
||||
int count, key;
|
||||
{
|
||||
return (_rl_abort_internal ());
|
||||
}
|
||||
|
||||
int
|
||||
rl_tty_status (count, key)
|
||||
int count, key;
|
||||
{
|
||||
#if defined (TIOCSTAT)
|
||||
ioctl (1, TIOCSTAT, (char *)0);
|
||||
rl_refresh_line ();
|
||||
#else
|
||||
ding ();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return a copy of the string between FROM and TO.
|
||||
FROM is inclusive, TO is not. */
|
||||
char *
|
||||
rl_copy_text (from, to)
|
||||
int from, to;
|
||||
{
|
||||
register int length;
|
||||
char *copy;
|
||||
|
||||
/* Fix it if the caller is confused. */
|
||||
if (from > to)
|
||||
SWAP (from, to);
|
||||
|
||||
length = to - from;
|
||||
copy = xmalloc (1 + length);
|
||||
strncpy (copy, rl_line_buffer + from, length);
|
||||
copy[length] = '\0';
|
||||
return (copy);
|
||||
}
|
||||
|
||||
/* Increase the size of RL_LINE_BUFFER until it has enough space to hold
|
||||
LEN characters. */
|
||||
void
|
||||
rl_extend_line_buffer (len)
|
||||
int len;
|
||||
{
|
||||
while (len >= rl_line_buffer_len)
|
||||
{
|
||||
rl_line_buffer_len += DEFAULT_BUFFER_SIZE;
|
||||
rl_line_buffer = xrealloc (rl_line_buffer, rl_line_buffer_len);
|
||||
}
|
||||
|
||||
_rl_set_the_line ();
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* String Utility Functions */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Determine if s2 occurs in s1. If so, return a pointer to the
|
||||
match in s1. The compare is case insensitive. */
|
||||
char *
|
||||
_rl_strindex (s1, s2)
|
||||
register char *s1, *s2;
|
||||
{
|
||||
register int i, l, len;
|
||||
|
||||
for (i = 0, l = strlen (s2), len = strlen (s1); (len - i) >= l; i++)
|
||||
if (_rl_strnicmp (s1 + i, s2, l) == 0)
|
||||
return (s1 + i);
|
||||
return ((char *)NULL);
|
||||
}
|
||||
|
||||
#if !defined (HAVE_STRCASECMP)
|
||||
/* Compare at most COUNT characters from string1 to string2. Case
|
||||
doesn't matter. */
|
||||
int
|
||||
_rl_strnicmp (string1, string2, count)
|
||||
char *string1, *string2;
|
||||
int count;
|
||||
{
|
||||
register char ch1, ch2;
|
||||
|
||||
while (count)
|
||||
{
|
||||
ch1 = *string1++;
|
||||
ch2 = *string2++;
|
||||
if (_rl_to_upper(ch1) == _rl_to_upper(ch2))
|
||||
count--;
|
||||
else
|
||||
break;
|
||||
}
|
||||
return (count);
|
||||
}
|
||||
|
||||
/* strcmp (), but caseless. */
|
||||
int
|
||||
_rl_stricmp (string1, string2)
|
||||
char *string1, *string2;
|
||||
{
|
||||
register char ch1, ch2;
|
||||
|
||||
while (*string1 && *string2)
|
||||
{
|
||||
ch1 = *string1++;
|
||||
ch2 = *string2++;
|
||||
if (_rl_to_upper(ch1) != _rl_to_upper(ch2))
|
||||
return (1);
|
||||
}
|
||||
return (*string1 - *string2);
|
||||
}
|
||||
#endif /* !HAVE_STRCASECMP */
|
||||
|
||||
/* Stupid comparison routine for qsort () ing strings. */
|
||||
int
|
||||
_rl_qsort_string_compare (s1, s2)
|
||||
char **s1, **s2;
|
||||
{
|
||||
#if defined (HAVE_STRCOLL)
|
||||
return (strcoll (*s1, *s2));
|
||||
#else
|
||||
int result;
|
||||
|
||||
result = **s1 - **s2;
|
||||
if (result == 0)
|
||||
result = strcmp (*s1, *s2);
|
||||
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined (SHELL)
|
||||
#ifdef savestring
|
||||
#undef savestring
|
||||
#endif
|
||||
/* Backwards compatibility, now that savestring has been removed from
|
||||
all `public' readline header files. */
|
||||
char *
|
||||
savestring (s)
|
||||
char *s;
|
||||
{
|
||||
return ((char *)strcpy (xmalloc (1 + (int)strlen (s)), (s)));
|
||||
}
|
||||
#endif /* !SHELL */
|
||||
|
||||
/* Function equivalents for the macros defined in chartypes.h. */
|
||||
#undef _rl_uppercase_p
|
||||
int
|
||||
_rl_uppercase_p (c)
|
||||
int c;
|
||||
{
|
||||
return (isupper (c));
|
||||
}
|
||||
|
||||
#undef _rl_lowercase_p
|
||||
int
|
||||
_rl_lowercase_p (c)
|
||||
int c;
|
||||
{
|
||||
return (islower (c));
|
||||
}
|
||||
|
||||
#undef _rl_pure_alphabetic
|
||||
int
|
||||
_rl_pure_alphabetic (c)
|
||||
int c;
|
||||
{
|
||||
return (isupper (c) || islower (c));
|
||||
}
|
||||
|
||||
#undef _rl_digit_p
|
||||
int
|
||||
_rl_digit_p (c)
|
||||
int c;
|
||||
{
|
||||
return (isdigit (c));
|
||||
}
|
||||
|
||||
#undef _rl_to_lower
|
||||
int
|
||||
_rl_to_lower (c)
|
||||
int c;
|
||||
{
|
||||
return (isupper (c) ? tolower (c) : c);
|
||||
}
|
||||
|
||||
#undef _rl_to_upper
|
||||
int
|
||||
_rl_to_upper (c)
|
||||
int c;
|
||||
{
|
||||
return (islower (c) ? toupper (c) : c);
|
||||
}
|
||||
|
||||
#undef _rl_digit_value
|
||||
int
|
||||
_rl_digit_value (c)
|
||||
int c;
|
||||
{
|
||||
return (isdigit (c) ? c - '0' : c);
|
||||
}
|
||||
@@ -65,13 +65,13 @@ KEYMAP_ENTRY_ARRAY vi_movement_keymap = {
|
||||
{ ISFUNC, (Function *)0x0 }, /* Control-\ */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Control-] */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Control-^ */
|
||||
{ ISFUNC, rl_undo_command }, /* Control-_ */
|
||||
{ ISFUNC, rl_vi_undo }, /* Control-_ */
|
||||
|
||||
/* The start of printing characters. */
|
||||
{ ISFUNC, rl_forward }, /* SPACE */
|
||||
{ ISFUNC, (Function *)0x0 }, /* ! */
|
||||
{ ISFUNC, (Function *)0x0 }, /* " */
|
||||
{ ISFUNC, rl_vi_comment }, /* # */
|
||||
{ ISFUNC, rl_insert_comment }, /* # */
|
||||
{ ISFUNC, rl_end_of_line }, /* $ */
|
||||
{ ISFUNC, rl_vi_match }, /* % */
|
||||
{ ISFUNC, rl_vi_tilde_expand }, /* & */
|
||||
@@ -140,7 +140,7 @@ KEYMAP_ENTRY_ARRAY vi_movement_keymap = {
|
||||
{ ISFUNC, (Function *)0x0 }, /* ] */
|
||||
{ ISFUNC, rl_vi_first_print }, /* ^ */
|
||||
{ ISFUNC, rl_vi_yank_arg }, /* _ */
|
||||
{ ISFUNC, (Function *)0x0 }, /* ` */
|
||||
{ ISFUNC, rl_vi_goto_mark }, /* ` */
|
||||
|
||||
/* Lowercase alphabet. */
|
||||
{ ISFUNC, rl_vi_append_mode }, /* a */
|
||||
@@ -155,7 +155,7 @@ KEYMAP_ENTRY_ARRAY vi_movement_keymap = {
|
||||
{ ISFUNC, rl_get_next_history }, /* j */
|
||||
{ ISFUNC, rl_get_previous_history }, /* k */
|
||||
{ ISFUNC, rl_forward }, /* l */
|
||||
{ ISFUNC, (Function *)0x0 }, /* m */
|
||||
{ ISFUNC, rl_vi_set_mark }, /* m */
|
||||
{ ISFUNC, rl_vi_search_again }, /* n */
|
||||
{ ISFUNC, (Function *)0x0 }, /* o */
|
||||
{ ISFUNC, rl_vi_put }, /* p */
|
||||
@@ -163,7 +163,7 @@ KEYMAP_ENTRY_ARRAY vi_movement_keymap = {
|
||||
{ ISFUNC, rl_vi_change_char }, /* r */
|
||||
{ ISFUNC, rl_vi_subst }, /* s */
|
||||
{ ISFUNC, rl_vi_char_search }, /* t */
|
||||
{ ISFUNC, rl_undo_command }, /* u */
|
||||
{ ISFUNC, rl_vi_undo }, /* u */
|
||||
{ ISFUNC, (Function *)0x0 }, /* v */
|
||||
{ ISFUNC, rl_vi_next_word }, /* w */
|
||||
{ ISFUNC, rl_vi_delete }, /* x */
|
||||
@@ -345,7 +345,7 @@ KEYMAP_ENTRY_ARRAY vi_insertion_keymap = {
|
||||
{ ISFUNC, rl_insert }, /* Control-\ */
|
||||
{ ISFUNC, rl_insert }, /* Control-] */
|
||||
{ ISFUNC, rl_insert }, /* Control-^ */
|
||||
{ ISFUNC, rl_undo_command }, /* Control-_ */
|
||||
{ ISFUNC, rl_vi_undo }, /* Control-_ */
|
||||
|
||||
/* The start of printing characters. */
|
||||
{ ISFUNC, rl_insert }, /* SPACE */
|
||||
@@ -630,7 +630,7 @@ KEYMAP_ENTRY_ARRAY vi_escape_keymap = {
|
||||
{ ISFUNC, (Function *)0x0 }, /* Control-\ */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Control-] */
|
||||
{ ISFUNC, (Function *)0x0 }, /* Control-^ */
|
||||
{ ISFUNC, rl_undo_command }, /* Control-_ */
|
||||
{ ISFUNC, rl_vi_undo }, /* Control-_ */
|
||||
|
||||
/* The start of printing characters. */
|
||||
{ ISFUNC, (Function *)0x0 }, /* SPACE */
|
||||
|
||||
@@ -31,6 +31,10 @@
|
||||
|
||||
#if defined (VI_MODE)
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#if defined (HAVE_STDLIB_H)
|
||||
@@ -50,12 +54,12 @@
|
||||
#include "readline.h"
|
||||
#include "history.h"
|
||||
|
||||
#ifndef digit_p
|
||||
#define digit_p(c) ((c) >= '0' && (c) <= '9')
|
||||
#ifndef _rl_digit_p
|
||||
#define _rl_digit_p(c) ((c) >= '0' && (c) <= '9')
|
||||
#endif
|
||||
|
||||
#ifndef digit_value
|
||||
#define digit_value(c) ((c) - '0')
|
||||
#ifndef _rl_digit_value
|
||||
#define _rl_digit_value(c) ((c) - '0')
|
||||
#endif
|
||||
|
||||
#ifndef member
|
||||
@@ -63,22 +67,14 @@
|
||||
#endif
|
||||
|
||||
#ifndef isident
|
||||
#define isident(c) ((pure_alphabetic (c) || digit_p (c) || c == '_'))
|
||||
#define isident(c) ((_rl_pure_alphabetic (c) || _rl_digit_p (c) || c == '_'))
|
||||
#endif
|
||||
|
||||
#ifndef exchange
|
||||
#define exchange(x, y) do {int temp = x; x = y; y = temp;} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef VI_COMMENT_BEGIN_DEFAULT
|
||||
#define VI_COMMENT_BEGIN_DEFAULT "#"
|
||||
#endif
|
||||
|
||||
#if defined (STATIC_MALLOC)
|
||||
static char *xmalloc (), *xrealloc ();
|
||||
#else
|
||||
extern char *xmalloc (), *xrealloc ();
|
||||
#endif /* STATIC_MALLOC */
|
||||
|
||||
/* Variables imported from readline.c */
|
||||
extern int rl_point, rl_end, rl_mark, rl_done;
|
||||
@@ -89,47 +85,63 @@ extern char *rl_prompt;
|
||||
extern char *rl_line_buffer;
|
||||
extern int rl_arg_sign;
|
||||
|
||||
extern int _rl_doing_an_undo;
|
||||
extern int _rl_undo_group_level;
|
||||
|
||||
extern void _rl_dispatch ();
|
||||
extern int _rl_char_search_internal ();
|
||||
|
||||
extern void rl_extend_line_buffer ();
|
||||
extern int rl_vi_check ();
|
||||
|
||||
/* Non-zero means enter insertion mode. */
|
||||
static int _rl_vi_doing_insert = 0;
|
||||
static int _rl_vi_doing_insert;
|
||||
|
||||
/* String inserted into the line by rl_vi_comment (). */
|
||||
char *rl_vi_comment_begin = (char *)NULL;
|
||||
|
||||
/* *** 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;
|
||||
static Keymap vi_replace_map;
|
||||
|
||||
/* The number of characters inserted in the last replace operation. */
|
||||
static int vi_replace_count = 0;
|
||||
static int vi_replace_count;
|
||||
|
||||
/* If non-zero, we have text inserted after a c[motion] command that put
|
||||
us implicitly into insert mode. Some people want this text to be
|
||||
attached to the command so that it is `redoable' with `.'. */
|
||||
static int vi_continued_command = 0;
|
||||
static int vi_continued_command;
|
||||
static char *vi_insert_buffer;
|
||||
static int vi_insert_buffer_size;
|
||||
|
||||
static int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
|
||||
static int _rl_vi_last_repeat = 1;
|
||||
static int _rl_vi_last_arg_sign = 1;
|
||||
static int _rl_vi_last_motion = 0;
|
||||
static int _rl_vi_last_search_char = 0;
|
||||
static int _rl_vi_last_replacement = 0;
|
||||
static int _rl_vi_last_motion;
|
||||
static int _rl_vi_last_search_char;
|
||||
static int _rl_vi_last_replacement;
|
||||
|
||||
static int vi_redoing = 0;
|
||||
static int _rl_vi_last_key_before_insert;
|
||||
|
||||
static int vi_redoing;
|
||||
|
||||
/* Text modification commands. These are the `redoable' commands. */
|
||||
static char *vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~";
|
||||
|
||||
/* Arrays for the saved marks. */
|
||||
static int vi_mark_chars[27];
|
||||
|
||||
static int rl_digit_loop1 ();
|
||||
|
||||
void
|
||||
_rl_vi_initialize_line ()
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < sizeof (vi_mark_chars) / sizeof (int); i++)
|
||||
vi_mark_chars[i] = -1;
|
||||
}
|
||||
|
||||
void
|
||||
_rl_vi_reset_last ()
|
||||
{
|
||||
@@ -150,15 +162,26 @@ _rl_vi_set_last (key, repeat, sign)
|
||||
|
||||
/* Is the command C a VI mode text modification command? */
|
||||
int
|
||||
rl_vi_textmod_command (c)
|
||||
_rl_vi_textmod_command (c)
|
||||
int c;
|
||||
{
|
||||
return (member (c, vi_textmod));
|
||||
}
|
||||
|
||||
static void
|
||||
_rl_vi_stuff_insert (count)
|
||||
int count;
|
||||
{
|
||||
rl_begin_undo_group ();
|
||||
while (count--)
|
||||
rl_insert_text (vi_insert_buffer);
|
||||
rl_end_undo_group ();
|
||||
}
|
||||
|
||||
/* Bound to `.'. Called from command mode, so we know that we have to
|
||||
redo a text modification command. The default for _rl_vi_last_command
|
||||
puts you back into insert mode. */
|
||||
int
|
||||
rl_vi_redo (count, c)
|
||||
int count, c;
|
||||
{
|
||||
@@ -169,13 +192,32 @@ rl_vi_redo (count, c)
|
||||
}
|
||||
|
||||
vi_redoing = 1;
|
||||
_rl_dispatch (_rl_vi_last_command, _rl_keymap);
|
||||
/* If we're redoing an insert with `i', stuff in the inserted text
|
||||
and do not go into insertion mode. */
|
||||
if (_rl_vi_last_command == 'i' && vi_insert_buffer && *vi_insert_buffer)
|
||||
{
|
||||
_rl_vi_stuff_insert (count);
|
||||
/* And back up point over the last character inserted. */
|
||||
if (rl_point > 0)
|
||||
rl_point--;
|
||||
}
|
||||
else
|
||||
_rl_dispatch (_rl_vi_last_command, _rl_keymap);
|
||||
vi_redoing = 0;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* A placeholder for further expansion. */
|
||||
int
|
||||
rl_vi_undo (count, key)
|
||||
int count, key;
|
||||
{
|
||||
return (rl_undo_command (count, key));
|
||||
}
|
||||
|
||||
/* Yank the nth arg from the previous line into this line at point. */
|
||||
int
|
||||
rl_vi_yank_arg (count, key)
|
||||
int count, key;
|
||||
{
|
||||
@@ -191,10 +233,11 @@ rl_vi_yank_arg (count, key)
|
||||
|
||||
/* With an argument, move back that many history lines, else move to the
|
||||
beginning of history. */
|
||||
int
|
||||
rl_vi_fetch_history (count, c)
|
||||
int count, c;
|
||||
{
|
||||
int current = where_history ();
|
||||
int wanted;
|
||||
|
||||
/* Giving an argument of n means we want the nth command in the history
|
||||
file. The command number is interpreted the same way that the bash
|
||||
@@ -203,11 +246,11 @@ rl_vi_fetch_history (count, c)
|
||||
output of `history'. */
|
||||
if (rl_explicit_arg)
|
||||
{
|
||||
int wanted = history_base + current - count;
|
||||
wanted = history_base + where_history () - count;
|
||||
if (wanted <= 0)
|
||||
rl_beginning_of_history (0, 0);
|
||||
else
|
||||
rl_get_previous_history (wanted);
|
||||
rl_get_previous_history (wanted, c);
|
||||
}
|
||||
else
|
||||
rl_beginning_of_history (count, 0);
|
||||
@@ -215,6 +258,7 @@ rl_vi_fetch_history (count, c)
|
||||
}
|
||||
|
||||
/* Search again for the last thing searched for. */
|
||||
int
|
||||
rl_vi_search_again (count, key)
|
||||
int count, key;
|
||||
{
|
||||
@@ -232,6 +276,7 @@ rl_vi_search_again (count, key)
|
||||
}
|
||||
|
||||
/* Do a vi style search. */
|
||||
int
|
||||
rl_vi_search (count, key)
|
||||
int count, key;
|
||||
{
|
||||
@@ -253,6 +298,7 @@ rl_vi_search (count, key)
|
||||
}
|
||||
|
||||
/* Completion, from vi's point of view. */
|
||||
int
|
||||
rl_vi_complete (ignore, key)
|
||||
int ignore, key;
|
||||
{
|
||||
@@ -281,6 +327,7 @@ rl_vi_complete (ignore, key)
|
||||
}
|
||||
|
||||
/* Tilde expansion for vi mode. */
|
||||
int
|
||||
rl_vi_tilde_expand (ignore, key)
|
||||
int ignore, key;
|
||||
{
|
||||
@@ -291,6 +338,7 @@ rl_vi_tilde_expand (ignore, key)
|
||||
}
|
||||
|
||||
/* Previous word in vi mode. */
|
||||
int
|
||||
rl_vi_prev_word (count, key)
|
||||
int count, key;
|
||||
{
|
||||
@@ -303,7 +351,7 @@ rl_vi_prev_word (count, key)
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (uppercase_p (key))
|
||||
if (_rl_uppercase_p (key))
|
||||
rl_vi_bWord (count);
|
||||
else
|
||||
rl_vi_bword (count);
|
||||
@@ -312,6 +360,7 @@ rl_vi_prev_word (count, key)
|
||||
}
|
||||
|
||||
/* Next word in vi mode. */
|
||||
int
|
||||
rl_vi_next_word (count, key)
|
||||
int count, key;
|
||||
{
|
||||
@@ -324,7 +373,7 @@ rl_vi_next_word (count, key)
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (uppercase_p (key))
|
||||
if (_rl_uppercase_p (key))
|
||||
rl_vi_fWord (count);
|
||||
else
|
||||
rl_vi_fword (count);
|
||||
@@ -332,6 +381,7 @@ rl_vi_next_word (count, key)
|
||||
}
|
||||
|
||||
/* Move to the end of the ?next? word. */
|
||||
int
|
||||
rl_vi_end_word (count, key)
|
||||
int count, key;
|
||||
{
|
||||
@@ -341,7 +391,7 @@ rl_vi_end_word (count, key)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (uppercase_p (key))
|
||||
if (_rl_uppercase_p (key))
|
||||
rl_vi_eWord (count);
|
||||
else
|
||||
rl_vi_eword (count);
|
||||
@@ -349,6 +399,7 @@ rl_vi_end_word (count, key)
|
||||
}
|
||||
|
||||
/* Move forward a word the way that 'W' does. */
|
||||
int
|
||||
rl_vi_fWord (count)
|
||||
int count;
|
||||
{
|
||||
@@ -365,6 +416,7 @@ rl_vi_fWord (count)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rl_vi_bWord (count)
|
||||
int count;
|
||||
{
|
||||
@@ -388,6 +440,7 @@ rl_vi_bWord (count)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rl_vi_eWord (count)
|
||||
int count;
|
||||
{
|
||||
@@ -417,6 +470,7 @@ rl_vi_eWord (count)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rl_vi_fword (count)
|
||||
int count;
|
||||
{
|
||||
@@ -442,6 +496,7 @@ rl_vi_fword (count)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rl_vi_bword (count)
|
||||
int count;
|
||||
{
|
||||
@@ -480,6 +535,7 @@ rl_vi_bword (count)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rl_vi_eword (count)
|
||||
int count;
|
||||
{
|
||||
@@ -504,6 +560,7 @@ rl_vi_eword (count)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rl_vi_insert_beg (count, key)
|
||||
int count, key;
|
||||
{
|
||||
@@ -512,6 +569,7 @@ rl_vi_insert_beg (count, key)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rl_vi_append_mode (count, key)
|
||||
int count, key;
|
||||
{
|
||||
@@ -521,6 +579,7 @@ rl_vi_append_mode (count, key)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rl_vi_append_eol (count, key)
|
||||
int count, key;
|
||||
{
|
||||
@@ -530,6 +589,7 @@ rl_vi_append_eol (count, key)
|
||||
}
|
||||
|
||||
/* What to do in the case of C-d. */
|
||||
int
|
||||
rl_vi_eof_maybe (count, c)
|
||||
int count, c;
|
||||
{
|
||||
@@ -540,13 +600,33 @@ rl_vi_eof_maybe (count, c)
|
||||
|
||||
/* Switching from one mode to the other really just involves
|
||||
switching keymaps. */
|
||||
int
|
||||
rl_vi_insertion_mode (count, key)
|
||||
int count, key;
|
||||
{
|
||||
_rl_keymap = vi_insertion_keymap;
|
||||
_rl_vi_last_key_before_insert = key;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
_rl_vi_save_insert (up)
|
||||
UNDO_LIST *up;
|
||||
{
|
||||
int len, start, end;
|
||||
|
||||
start = up->start;
|
||||
end = up->end;
|
||||
len = end - start + 1;
|
||||
if (len >= vi_insert_buffer_size)
|
||||
{
|
||||
vi_insert_buffer_size += (len + 32) - (len % 32);
|
||||
vi_insert_buffer = xrealloc (vi_insert_buffer, vi_insert_buffer_size);
|
||||
}
|
||||
strncpy (vi_insert_buffer, rl_line_buffer + start, len - 1);
|
||||
vi_insert_buffer[len-1] = '\0';
|
||||
}
|
||||
|
||||
void
|
||||
_rl_vi_done_inserting ()
|
||||
{
|
||||
@@ -555,38 +635,49 @@ _rl_vi_done_inserting ()
|
||||
rl_end_undo_group ();
|
||||
/* Now, the text between rl_undo_list->next->start and
|
||||
rl_undo_list->next->end is what was inserted while in insert
|
||||
mode. */
|
||||
mode. It gets copied to VI_INSERT_BUFFER because it depends
|
||||
on absolute indices into the line which may change (though they
|
||||
probably will not). */
|
||||
_rl_vi_doing_insert = 0;
|
||||
_rl_vi_save_insert (rl_undo_list->next);
|
||||
vi_continued_command = 1;
|
||||
}
|
||||
else
|
||||
vi_continued_command = 0;
|
||||
{
|
||||
if (_rl_vi_last_key_before_insert == 'i' && rl_undo_list)
|
||||
_rl_vi_save_insert (rl_undo_list);
|
||||
/* XXX - Other keys probably need to be checked. */
|
||||
else if (_rl_vi_last_key_before_insert == 'C')
|
||||
rl_end_undo_group ();
|
||||
while (_rl_undo_group_level > 0)
|
||||
rl_end_undo_group ();
|
||||
vi_continued_command = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
rl_vi_movement_mode (count, key)
|
||||
int count, key;
|
||||
{
|
||||
if (rl_point > 0)
|
||||
rl_backward (1);
|
||||
|
||||
#if 0
|
||||
_rl_vi_reset_last ();
|
||||
#endif
|
||||
rl_backward (1, key);
|
||||
|
||||
_rl_keymap = vi_movement_keymap;
|
||||
_rl_vi_done_inserting ();
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rl_vi_arg_digit (count, c)
|
||||
int count, c;
|
||||
{
|
||||
if (c == '0' && rl_numeric_arg == 1 && !rl_explicit_arg)
|
||||
return (rl_beg_of_line ());
|
||||
return (rl_beg_of_line (1, c));
|
||||
else
|
||||
return (rl_digit_argument (count, c));
|
||||
}
|
||||
|
||||
int
|
||||
rl_vi_change_case (count, ignore)
|
||||
int count, ignore;
|
||||
{
|
||||
@@ -598,14 +689,14 @@ rl_vi_change_case (count, ignore)
|
||||
|
||||
while (count-- && rl_point < rl_end)
|
||||
{
|
||||
if (uppercase_p (rl_line_buffer[rl_point]))
|
||||
c = to_lower (rl_line_buffer[rl_point]);
|
||||
else if (lowercase_p (rl_line_buffer[rl_point]))
|
||||
c = to_upper (rl_line_buffer[rl_point]);
|
||||
if (_rl_uppercase_p (rl_line_buffer[rl_point]))
|
||||
c = _rl_to_lower (rl_line_buffer[rl_point]);
|
||||
else if (_rl_lowercase_p (rl_line_buffer[rl_point]))
|
||||
c = _rl_to_upper (rl_line_buffer[rl_point]);
|
||||
else
|
||||
{
|
||||
/* Just skip over characters neither upper nor lower case. */
|
||||
rl_forward (1);
|
||||
rl_forward (1, c);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -619,22 +710,24 @@ rl_vi_change_case (count, ignore)
|
||||
rl_vi_check ();
|
||||
}
|
||||
else
|
||||
rl_forward (1);
|
||||
rl_forward (1, c);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rl_vi_put (count, key)
|
||||
int count, key;
|
||||
{
|
||||
if (!uppercase_p (key) && (rl_point + 1 <= rl_end))
|
||||
if (!_rl_uppercase_p (key) && (rl_point + 1 <= rl_end))
|
||||
rl_point++;
|
||||
|
||||
rl_yank ();
|
||||
rl_backward (1);
|
||||
rl_backward (1, key);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rl_vi_check ()
|
||||
{
|
||||
if (rl_point && rl_point == rl_end)
|
||||
@@ -642,11 +735,12 @@ rl_vi_check ()
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rl_vi_column (count, key)
|
||||
int count, key;
|
||||
{
|
||||
if (count > rl_end)
|
||||
rl_end_of_line ();
|
||||
rl_end_of_line (1, key);
|
||||
else
|
||||
rl_point = count - 1;
|
||||
return (0);
|
||||
@@ -665,10 +759,10 @@ rl_vi_domove (key, nextkey)
|
||||
|
||||
if (!member (c, vi_motion))
|
||||
{
|
||||
if (digit_p (c))
|
||||
if (_rl_digit_p (c))
|
||||
{
|
||||
save = rl_numeric_arg;
|
||||
rl_numeric_arg = digit_value (c);
|
||||
rl_numeric_arg = _rl_digit_value (c);
|
||||
rl_digit_loop1 ();
|
||||
rl_numeric_arg *= save;
|
||||
c = rl_read_key (); /* real command */
|
||||
@@ -677,7 +771,7 @@ rl_vi_domove (key, nextkey)
|
||||
else if (key == c && (key == 'd' || key == 'y' || key == 'c'))
|
||||
{
|
||||
rl_mark = rl_end;
|
||||
rl_beg_of_line ();
|
||||
rl_beg_of_line (1, c);
|
||||
_rl_vi_last_motion = c;
|
||||
return (0);
|
||||
}
|
||||
@@ -708,13 +802,13 @@ rl_vi_domove (key, nextkey)
|
||||
/* rl_vi_f[wW]ord () leaves the cursor on the first character of the next
|
||||
word. If we are not at the end of the line, and we are on a
|
||||
non-whitespace character, move back one (presumably to whitespace). */
|
||||
if ((to_upper (c) == 'W') && rl_point < rl_end && rl_point > rl_mark &&
|
||||
if ((_rl_to_upper (c) == 'W') && rl_point < rl_end && rl_point > rl_mark &&
|
||||
!whitespace (rl_line_buffer[rl_point]))
|
||||
rl_point--;
|
||||
|
||||
/* If cw or cW, back up to the end of a word, so the behaviour of ce
|
||||
or cE is the actual result. Brute-force, no subtlety. */
|
||||
if (key == 'c' && rl_point >= rl_mark && (to_upper (c) == 'W'))
|
||||
if (key == 'c' && rl_point >= rl_mark && (_rl_to_upper (c) == 'W'))
|
||||
{
|
||||
/* Don't move farther back than where we started. */
|
||||
while (rl_point > rl_mark && whitespace (rl_line_buffer[rl_point]))
|
||||
@@ -760,12 +854,12 @@ rl_digit_loop1 ()
|
||||
}
|
||||
|
||||
c = UNMETA (c);
|
||||
if (digit_p (c))
|
||||
if (_rl_digit_p (c))
|
||||
{
|
||||
if (rl_explicit_arg)
|
||||
rl_numeric_arg = (rl_numeric_arg * 10) + digit_value (c);
|
||||
rl_numeric_arg = (rl_numeric_arg * 10) + _rl_digit_value (c);
|
||||
else
|
||||
rl_numeric_arg = digit_value (c);
|
||||
rl_numeric_arg = _rl_digit_value (c);
|
||||
rl_explicit_arg = 1;
|
||||
}
|
||||
else
|
||||
@@ -778,12 +872,13 @@ rl_digit_loop1 ()
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rl_vi_delete_to (count, key)
|
||||
int count, key;
|
||||
{
|
||||
int c;
|
||||
|
||||
if (uppercase_p (key))
|
||||
if (_rl_uppercase_p (key))
|
||||
rl_stuff_char ('$');
|
||||
else if (vi_redoing)
|
||||
rl_stuff_char (_rl_vi_last_motion);
|
||||
@@ -803,12 +898,13 @@ rl_vi_delete_to (count, key)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rl_vi_change_to (count, key)
|
||||
int count, key;
|
||||
{
|
||||
int c, start_pos;
|
||||
|
||||
if (uppercase_p (key))
|
||||
if (_rl_uppercase_p (key))
|
||||
rl_stuff_char ('$');
|
||||
else if (vi_redoing)
|
||||
rl_stuff_char (_rl_vi_last_motion);
|
||||
@@ -828,25 +924,41 @@ rl_vi_change_to (count, key)
|
||||
rl_mark++;
|
||||
|
||||
/* The cursor never moves with c[wW]. */
|
||||
if ((to_upper (c) == 'W') && rl_point < start_pos)
|
||||
if ((_rl_to_upper (c) == 'W') && rl_point < start_pos)
|
||||
rl_point = start_pos;
|
||||
|
||||
rl_kill_text (rl_point, rl_mark);
|
||||
|
||||
rl_begin_undo_group ();
|
||||
_rl_vi_doing_insert = 1;
|
||||
_rl_vi_set_last (key, count, rl_arg_sign);
|
||||
rl_vi_insertion_mode (1, key);
|
||||
if (vi_redoing)
|
||||
{
|
||||
if (vi_insert_buffer && *vi_insert_buffer)
|
||||
rl_begin_undo_group ();
|
||||
rl_delete_text (rl_point, rl_mark);
|
||||
if (vi_insert_buffer && *vi_insert_buffer)
|
||||
{
|
||||
rl_insert_text (vi_insert_buffer);
|
||||
rl_end_undo_group ();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rl_begin_undo_group (); /* to make the `u' command work */
|
||||
rl_kill_text (rl_point, rl_mark);
|
||||
/* `C' does not save the text inserted for undoing or redoing. */
|
||||
if (_rl_uppercase_p (key) == 0)
|
||||
_rl_vi_doing_insert = 1;
|
||||
_rl_vi_set_last (key, count, rl_arg_sign);
|
||||
rl_vi_insertion_mode (1, key);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rl_vi_yank_to (count, key)
|
||||
int count, key;
|
||||
{
|
||||
int c, save = rl_point;
|
||||
|
||||
if (uppercase_p (key))
|
||||
if (_rl_uppercase_p (key))
|
||||
rl_stuff_char ('$');
|
||||
|
||||
if (rl_vi_domove (key, &c))
|
||||
@@ -869,6 +981,7 @@ rl_vi_yank_to (count, key)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rl_vi_delete (count, key)
|
||||
int count, key;
|
||||
{
|
||||
@@ -888,57 +1001,36 @@ rl_vi_delete (count, key)
|
||||
rl_kill_text (rl_point, end);
|
||||
|
||||
if (rl_point > 0 && rl_point == rl_end)
|
||||
rl_backward (1);
|
||||
rl_backward (1, key);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Turn the current line into a comment in shell history.
|
||||
A K*rn shell style function. */
|
||||
rl_vi_comment (count, key)
|
||||
int
|
||||
rl_vi_back_to_indent (count, key)
|
||||
int count, key;
|
||||
{
|
||||
rl_beg_of_line ();
|
||||
|
||||
if (rl_vi_comment_begin != (char *)NULL)
|
||||
rl_insert_text (rl_vi_comment_begin);
|
||||
else
|
||||
rl_insert_text (VI_COMMENT_BEGIN_DEFAULT); /* Default. */
|
||||
|
||||
rl_redisplay ();
|
||||
rl_newline (1, '\n');
|
||||
return (0);
|
||||
}
|
||||
|
||||
rl_vi_first_print (count, key)
|
||||
int count, key;
|
||||
{
|
||||
return (rl_back_to_indent ());
|
||||
}
|
||||
|
||||
rl_back_to_indent (ignore1, ignore2)
|
||||
int ignore1, ignore2;
|
||||
{
|
||||
rl_beg_of_line ();
|
||||
rl_beg_of_line (1, key);
|
||||
while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
|
||||
rl_point++;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
int
|
||||
rl_vi_first_print (count, key)
|
||||
int count, key;
|
||||
{
|
||||
return (rl_vi_back_to_indent (1, key));
|
||||
}
|
||||
|
||||
int
|
||||
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);
|
||||
dir = key == ';' ? orig_dir : -orig_dir;
|
||||
else
|
||||
{
|
||||
if (vi_redoing)
|
||||
@@ -966,71 +1058,11 @@ rl_vi_char_search (count, key)
|
||||
}
|
||||
}
|
||||
|
||||
pos = rl_point;
|
||||
|
||||
while (count--)
|
||||
{
|
||||
if (dir < 0)
|
||||
{
|
||||
if (pos == 0)
|
||||
{
|
||||
ding ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
pos--;
|
||||
do
|
||||
{
|
||||
if (rl_line_buffer[pos] == target)
|
||||
{
|
||||
if (dir == BTO)
|
||||
rl_point = pos + 1;
|
||||
else
|
||||
rl_point = pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (pos--);
|
||||
|
||||
if (pos < 0)
|
||||
{
|
||||
ding ();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ /* dir > 0 */
|
||||
if (pos >= rl_end)
|
||||
{
|
||||
ding ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
pos++;
|
||||
do
|
||||
{
|
||||
if (rl_line_buffer[pos] == target)
|
||||
{
|
||||
if (dir == FTO)
|
||||
rl_point = pos - 1;
|
||||
else
|
||||
rl_point = pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (++pos < rl_end);
|
||||
|
||||
if (pos >= (rl_end - 1))
|
||||
{
|
||||
ding ();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
return (_rl_char_search_internal (count, dir, target));
|
||||
}
|
||||
|
||||
/* Match brackets */
|
||||
int
|
||||
rl_vi_match (ignore, key)
|
||||
int ignore, key;
|
||||
{
|
||||
@@ -1041,7 +1073,7 @@ rl_vi_match (ignore, key)
|
||||
{
|
||||
while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0 &&
|
||||
rl_point < rl_end - 1)
|
||||
rl_forward (1);
|
||||
rl_forward (1, key);
|
||||
|
||||
if (brack <= 0)
|
||||
{
|
||||
@@ -1111,6 +1143,7 @@ rl_vi_bracktype (c)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
rl_vi_change_char (count, key)
|
||||
int count, key;
|
||||
{
|
||||
@@ -1131,22 +1164,23 @@ rl_vi_change_char (count, key)
|
||||
rl_delete (1, c);
|
||||
rl_insert (1, c);
|
||||
if (count == 0)
|
||||
rl_backward (1);
|
||||
rl_backward (1, c);
|
||||
|
||||
rl_end_undo_group ();
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rl_vi_subst (count, key)
|
||||
int count, key;
|
||||
{
|
||||
rl_begin_undo_group ();
|
||||
|
||||
if (uppercase_p (key))
|
||||
if (_rl_uppercase_p (key))
|
||||
{
|
||||
rl_beg_of_line ();
|
||||
rl_kill_line (1);
|
||||
rl_beg_of_line (1, key);
|
||||
rl_kill_line (1, key);
|
||||
}
|
||||
else
|
||||
rl_delete_text (rl_point, rl_point+count);
|
||||
@@ -1155,13 +1189,26 @@ rl_vi_subst (count, key)
|
||||
|
||||
_rl_vi_set_last (key, count, rl_arg_sign);
|
||||
|
||||
rl_begin_undo_group ();
|
||||
_rl_vi_doing_insert = 1;
|
||||
rl_vi_insertion_mode (1, key);
|
||||
if (vi_redoing)
|
||||
{
|
||||
int o = _rl_doing_an_undo;
|
||||
|
||||
_rl_doing_an_undo = 1;
|
||||
if (vi_insert_buffer && *vi_insert_buffer)
|
||||
rl_insert_text (vi_insert_buffer);
|
||||
_rl_doing_an_undo = o;
|
||||
}
|
||||
else
|
||||
{
|
||||
rl_begin_undo_group ();
|
||||
_rl_vi_doing_insert = 1;
|
||||
rl_vi_insertion_mode (1, key);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rl_vi_overstrike (count, key)
|
||||
int count, key;
|
||||
{
|
||||
@@ -1191,8 +1238,9 @@ rl_vi_overstrike (count, key)
|
||||
return (0);
|
||||
}
|
||||
|
||||
rl_vi_overstrike_delete (count)
|
||||
int count;
|
||||
int
|
||||
rl_vi_overstrike_delete (count, key)
|
||||
int count, key;
|
||||
{
|
||||
int i, s;
|
||||
|
||||
@@ -1209,7 +1257,7 @@ rl_vi_overstrike_delete (count)
|
||||
vi_replace_count--;
|
||||
|
||||
if (rl_point == s)
|
||||
rl_backward (1);
|
||||
rl_backward (1, key);
|
||||
}
|
||||
|
||||
if (vi_replace_count == 0 && _rl_vi_doing_insert)
|
||||
@@ -1221,6 +1269,7 @@ rl_vi_overstrike_delete (count)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rl_vi_replace (count, key)
|
||||
int count, key;
|
||||
{
|
||||
@@ -1256,6 +1305,7 @@ rl_vi_replace (count, key)
|
||||
/* 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 ;. */
|
||||
int
|
||||
rl_vi_possible_completions()
|
||||
{
|
||||
int save_pos = rl_point;
|
||||
@@ -1279,51 +1329,50 @@ rl_vi_possible_completions()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (STATIC_MALLOC)
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* xmalloc and xrealloc () */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
static void memory_error_and_abort ();
|
||||
|
||||
static char *
|
||||
xmalloc (bytes)
|
||||
int bytes;
|
||||
/* Functions to save and restore marks. */
|
||||
int
|
||||
rl_vi_set_mark (count, key)
|
||||
int count, key;
|
||||
{
|
||||
char *temp = (char *)malloc (bytes);
|
||||
int ch;
|
||||
|
||||
if (!temp)
|
||||
memory_error_and_abort ();
|
||||
return (temp);
|
||||
ch = rl_read_key ();
|
||||
if (_rl_lowercase_p (ch) == 0)
|
||||
{
|
||||
ding ();
|
||||
return -1;
|
||||
}
|
||||
ch -= 'a';
|
||||
vi_mark_chars[ch] = rl_point;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *
|
||||
xrealloc (pointer, bytes)
|
||||
char *pointer;
|
||||
int bytes;
|
||||
int
|
||||
rl_vi_goto_mark (count, key)
|
||||
int count, key;
|
||||
{
|
||||
char *temp;
|
||||
int ch;
|
||||
|
||||
if (!pointer)
|
||||
temp = (char *)xmalloc (bytes);
|
||||
else
|
||||
temp = (char *)realloc (pointer, bytes);
|
||||
ch = rl_read_key ();
|
||||
if (ch == '`')
|
||||
{
|
||||
rl_point = rl_mark;
|
||||
return 0;
|
||||
}
|
||||
else if (_rl_lowercase_p (ch) == 0)
|
||||
{
|
||||
ding ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!temp)
|
||||
memory_error_and_abort ();
|
||||
|
||||
return (temp);
|
||||
ch -= 'a';
|
||||
if (vi_mark_chars[ch] == -1)
|
||||
{
|
||||
ding ();
|
||||
return -1;
|
||||
}
|
||||
rl_point = vi_mark_chars[ch];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
memory_error_and_abort ()
|
||||
{
|
||||
fprintf (stderr, "readline: Out of virtual memory!\n");
|
||||
abort ();
|
||||
}
|
||||
#endif /* STATIC_MALLOC */
|
||||
|
||||
#endif /* VI_MODE */
|
||||
|
||||
@@ -19,8 +19,10 @@
|
||||
along with Readline; see the file COPYING. If not, write to the Free
|
||||
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#if defined (ALREADY_HAVE_XMALLOC)
|
||||
#else
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined (HAVE_STDLIB_H)
|
||||
@@ -44,9 +46,10 @@ char *
|
||||
xmalloc (bytes)
|
||||
int bytes;
|
||||
{
|
||||
char *temp = (char *)malloc (bytes);
|
||||
char *temp;
|
||||
|
||||
if (!temp)
|
||||
temp = (char *)malloc (bytes);
|
||||
if (temp == 0)
|
||||
memory_error_and_abort ("xmalloc");
|
||||
return (temp);
|
||||
}
|
||||
@@ -58,12 +61,9 @@ xrealloc (pointer, bytes)
|
||||
{
|
||||
char *temp;
|
||||
|
||||
if (!pointer)
|
||||
temp = (char *)malloc (bytes);
|
||||
else
|
||||
temp = (char *)realloc (pointer, bytes);
|
||||
temp = pointer ? (char *)realloc (pointer, bytes) : (char *)malloc (bytes);
|
||||
|
||||
if (!temp)
|
||||
if (temp == 0)
|
||||
memory_error_and_abort ("xrealloc");
|
||||
return (temp);
|
||||
}
|
||||
@@ -72,7 +72,16 @@ static void
|
||||
memory_error_and_abort (fname)
|
||||
char *fname;
|
||||
{
|
||||
fprintf (stderr, "%s: Out of virtual memory!\n", fname);
|
||||
abort ();
|
||||
fprintf (stderr, "%s: out of virtual memory\n", fname);
|
||||
exit (2);
|
||||
}
|
||||
|
||||
/* Use this as the function to call when adding unwind protects so we
|
||||
don't need to know what free() returns. */
|
||||
void
|
||||
xfree (string)
|
||||
char *string;
|
||||
{
|
||||
if (string)
|
||||
free (string);
|
||||
}
|
||||
#endif /* !ALREADY_HAVE_XMALLOC */
|
||||
|
||||
Reference in New Issue
Block a user