summaryrefslogtreecommitdiff
path: root/gnu/usr.bin/texinfo/info
diff options
context:
space:
mode:
authorMarc Espie <espie@cvs.openbsd.org>2002-06-10 13:51:05 +0000
committerMarc Espie <espie@cvs.openbsd.org>2002-06-10 13:51:05 +0000
commite1bc7714b7945713f4c443c444b4abf17b1d7877 (patch)
treee7485506af2dcb5e2e4d5f71f01a3a652049aafc /gnu/usr.bin/texinfo/info
parent0766fc34a2525ed5b1d084ea33b198382d10e7d5 (diff)
brain-dead cvs conflict merge
Diffstat (limited to 'gnu/usr.bin/texinfo/info')
-rw-r--r--gnu/usr.bin/texinfo/info/Makefile.am32
-rw-r--r--gnu/usr.bin/texinfo/info/Makefile.in583
-rw-r--r--gnu/usr.bin/texinfo/info/NEWS200
-rw-r--r--gnu/usr.bin/texinfo/info/clib.c112
-rw-r--r--gnu/usr.bin/texinfo/info/clib.h42
-rw-r--r--gnu/usr.bin/texinfo/info/diffs19
-rw-r--r--gnu/usr.bin/texinfo/info/display.c47
-rw-r--r--gnu/usr.bin/texinfo/info/dribble5
-rw-r--r--gnu/usr.bin/texinfo/info/echo-area.c30
-rw-r--r--gnu/usr.bin/texinfo/info/echo_area.c1508
-rw-r--r--gnu/usr.bin/texinfo/info/echo_area.h63
-rw-r--r--gnu/usr.bin/texinfo/info/filesys.c46
-rw-r--r--gnu/usr.bin/texinfo/info/general.h94
-rw-r--r--gnu/usr.bin/texinfo/info/indices.c6
-rw-r--r--gnu/usr.bin/texinfo/info/info-stnd.texi1365
-rw-r--r--gnu/usr.bin/texinfo/info/info.1229
-rw-r--r--gnu/usr.bin/texinfo/info/info.c142
-rw-r--r--gnu/usr.bin/texinfo/info/info.h25
-rw-r--r--gnu/usr.bin/texinfo/info/info.texi916
-rw-r--r--gnu/usr.bin/texinfo/info/infodoc.c615
-rw-r--r--gnu/usr.bin/texinfo/info/infomap.c1110
-rw-r--r--gnu/usr.bin/texinfo/info/m-x.c43
-rw-r--r--gnu/usr.bin/texinfo/info/makedoc.c130
-rw-r--r--gnu/usr.bin/texinfo/info/man.c33
-rw-r--r--gnu/usr.bin/texinfo/info/session.c295
-rw-r--r--gnu/usr.bin/texinfo/info/termdep.h11
-rw-r--r--gnu/usr.bin/texinfo/info/terminal.c56
-rw-r--r--gnu/usr.bin/texinfo/info/userdoc.texi1270
-rw-r--r--gnu/usr.bin/texinfo/info/variables.c44
-rw-r--r--gnu/usr.bin/texinfo/info/window.c121
-rw-r--r--gnu/usr.bin/texinfo/info/xmalloc.c80
31 files changed, 8536 insertions, 736 deletions
diff --git a/gnu/usr.bin/texinfo/info/Makefile.am b/gnu/usr.bin/texinfo/info/Makefile.am
index 7e9c77b81f5..9d5d989089a 100644
--- a/gnu/usr.bin/texinfo/info/Makefile.am
+++ b/gnu/usr.bin/texinfo/info/Makefile.am
@@ -1,13 +1,21 @@
-## Makefile.am for texinfo/info.
-## $Id: Makefile.am,v 1.3 2000/02/09 02:18:39 espie Exp $
-## Run automake in .. to produce Makefile.in from this.
+# $Id: Makefile.am,v 1.4 2002/06/10 13:51:03 espie Exp $
+# Makefile.am for texinfo/info.
+# Run automake in .. to produce Makefile.in from this.
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
noinst_PROGRAMS = makedoc
# Use `ginfo' for building to avoid confusion with the standard `info'
# target. Removes the `g' in the install rule before applying any
# user-specified name transformations.
-bin_PROGRAMS = ginfo
+bin_PROGRAMS = ginfo infokey
transform = s/ginfo/info/; @program_transform_name@
localedir = $(datadir)/locale
@@ -17,15 +25,20 @@ localedir = $(datadir)/locale
# we need to override it, so include them ourselves.
INCLUDES = -I. -I$(top_srcdir)/lib -I../intl -I.. -I$(srcdir)
DEFS = -DINFODIR=\"$(infodir)\" -DLOCALEDIR=\"$(localedir)\" @DEFS@
-LDADD = ../lib/libtxi.a @TERMLIBS@ @INTLLIBS@
+LDADD = ../lib/libtxi.a @TERMLIBS@ @LIBINTL@
EXTRA_DIST = README pcterm.c
+if TEXINFO_MAINT
# The files `doc.c' and `funs.h' are created by ./makedoc run over the source
# files which contain DECLARE_INFO_COMMAND. `funs.h' is a header file
# listing the functions found. `doc.c' is a structure containing pointers
# to those functions along with completable names and documentation strings.
-BUILT_SOURCES = doc.c funs.h
+BUILT_SOURCES = doc.c funs.h key.c
+else
+# don't make installers rebuild them.
+generated_sources = doc.c funs.h key.c
+endif
makedoc_SOURCES = makedoc.c
ginfo_SOURCES = dir.c display.c display.h doc.h dribble.c dribble.h \
@@ -35,14 +48,17 @@ ginfo_SOURCES = dir.c display.c display.h doc.h dribble.c dribble.h \
infomap.c infomap.h m-x.c man.c man.h nodemenu.c nodes.c nodes.h \
search.c search.h session.c session.h signals.c signals.h \
termdep.h terminal.c terminal.h tilde.c tilde.h \
- variables.c variables.h window.c window.h $(BUILT_SOURCES)
+ variables.c variables.h window.c window.h \
+ $(BUILT_SOURCES) $(generated_sources)
+infokey_SOURCES = infokey.c infokey.h key.c key.h
# Files with Info commands defined that makedoc should read.
cmd_sources = $(srcdir)/session.c $(srcdir)/echo-area.c $(srcdir)/infodoc.c \
$(srcdir)/m-x.c $(srcdir)/indices.c $(srcdir)/nodemenu.c \
$(srcdir)/footnotes.c $(srcdir)/variables.c
-$(BUILT_SOURCES): makedoc $(cmd_sources)
+# The $(EXEEXT) should be added by Automake, but isn't. Fine.
+$(BUILT_SOURCES): makedoc$(EXEEXT) $(cmd_sources)
# This is insufficient. We really need them not to be in the
# distribution in the first place, but it seems Automake does not
# currently allow that.
diff --git a/gnu/usr.bin/texinfo/info/Makefile.in b/gnu/usr.bin/texinfo/info/Makefile.in
index 9a0ce851d19..e89ea582a08 100644
--- a/gnu/usr.bin/texinfo/info/Makefile.in
+++ b/gnu/usr.bin/texinfo/info/Makefile.in
@@ -1,6 +1,8 @@
-# Makefile.in generated automatically by automake 1.4 from Makefile.am
+# Makefile.in generated by automake 1.6 from Makefile.am.
+# @configure_input@
-# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -10,7 +12,19 @@
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
-
+@SET_MAKE@
+
+# $Id: Makefile.in,v 1.8 2002/06/10 13:51:03 espie Exp $
+# Makefile.am for texinfo/info.
+# Run automake in .. to produce Makefile.in from this.
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
SHELL = @SHELL@
srcdir = @srcdir@
@@ -31,13 +45,9 @@ infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
-
-DESTDIR?=
-
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
-
top_builddir = ..
ACLOCAL = @ACLOCAL@
@@ -45,50 +55,69 @@ AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
INSTALL_SCRIPT = @INSTALL_SCRIPT@
-
+INSTALL_HEADER = $(INSTALL_DATA)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
-CATALOGS = @CATALOGS@
+host_alias = @host_alias@
+host_triplet = @host@
+
+EXEEXT = @EXEEXT@
+OBJEXT = @OBJEXT@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+transform = s/ginfo/info/; @program_transform_name@
+AMTAR = @AMTAR@
+AWK = @AWK@
+BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@
CATOBJEXT = @CATOBJEXT@
CC = @CC@
DATADIRNAME = @DATADIRNAME@
+DEPDIR = @DEPDIR@
GENCAT = @GENCAT@
-GMOFILES = @GMOFILES@
+GLIBC21 = @GLIBC21@
GMSGFMT = @GMSGFMT@
-GT_NO = @GT_NO@
-GT_YES = @GT_YES@
-INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
+HAVE_LIB = @HAVE_LIB@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
INSTOBJEXT = @INSTOBJEXT@
-INTLDEPS = @INTLDEPS@
+INTLBISON = @INTLBISON@
INTLLIBS = @INTLLIBS@
INTLOBJS = @INTLOBJS@
-MAKEINFO = @MAKEINFO@
+INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@
+LIB = @LIB@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LTLIB = @LTLIB@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
MKINSTALLDIRS = @MKINSTALLDIRS@
-MSGFMT = @MSGFMT@
PACKAGE = @PACKAGE@
-POFILES = @POFILES@
POSUB = @POSUB@
RANLIB = @RANLIB@
+STRIP = @STRIP@
TERMLIBS = @TERMLIBS@
USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
USE_NLS = @USE_NLS@
VERSION = @VERSION@
-l = @l@
+am__include = @am__include@
+am__quote = @am__quote@
+install_sh = @install_sh@
+
noinst_PROGRAMS = makedoc
# Use `ginfo' for building to avoid confusion with the standard `info'
# target. Removes the `g' in the install rule before applying any
# user-specified name transformations.
-bin_PROGRAMS = ginfo
-transform = s/ginfo/info/; @program_transform_name@
+bin_PROGRAMS = ginfo infokey
localedir = $(datadir)/locale
@@ -97,7 +126,7 @@ localedir = $(datadir)/locale
# we need to override it, so include them ourselves.
INCLUDES = -I. -I$(top_srcdir)/lib -I../intl -I.. -I$(srcdir)
DEFS = -DINFODIR=\"$(infodir)\" -DLOCALEDIR=\"$(localedir)\" @DEFS@
-LDADD = ../lib/libtxi.a @TERMLIBS@ @INTLLIBS@
+LDADD = ../lib/libtxi.a @TERMLIBS@ @LIBINTL@
EXTRA_DIST = README pcterm.c
@@ -105,354 +134,336 @@ EXTRA_DIST = README pcterm.c
# files which contain DECLARE_INFO_COMMAND. `funs.h' is a header file
# listing the functions found. `doc.c' is a structure containing pointers
# to those functions along with completable names and documentation strings.
-BUILT_SOURCES = doc.c funs.h
+@TEXINFO_MAINT_TRUE@BUILT_SOURCES = doc.c funs.h key.c
+# don't make installers rebuild them.
+@TEXINFO_MAINT_FALSE@generated_sources = doc.c funs.h key.c
makedoc_SOURCES = makedoc.c
-ginfo_SOURCES = dir.c display.c display.h doc.h dribble.c dribble.h echo-area.c echo-area.h filesys.c filesys.h footnotes.c footnotes.h gc.c gc.h indices.c indices.h info-utils.c info-utils.h info.c info.h infodoc.c infomap.c infomap.h m-x.c man.c man.h nodemenu.c nodes.c nodes.h search.c search.h session.c session.h signals.c signals.h termdep.h terminal.c terminal.h tilde.c tilde.h variables.c variables.h window.c window.h $(BUILT_SOURCES)
-
+ginfo_SOURCES = dir.c display.c display.h doc.h dribble.c dribble.h \
+ echo-area.c echo-area.h \
+ filesys.c filesys.h footnotes.c footnotes.h gc.c gc.h \
+ indices.c indices.h info-utils.c info-utils.h info.c info.h infodoc.c \
+ infomap.c infomap.h m-x.c man.c man.h nodemenu.c nodes.c nodes.h \
+ search.c search.h session.c session.h signals.c signals.h \
+ termdep.h terminal.c terminal.h tilde.c tilde.h \
+ variables.c variables.h window.c window.h \
+ $(BUILT_SOURCES) $(generated_sources)
+
+infokey_SOURCES = infokey.c infokey.h key.c key.h
# Files with Info commands defined that makedoc should read.
-cmd_sources = $(srcdir)/session.c $(srcdir)/echo-area.c $(srcdir)/infodoc.c $(srcdir)/m-x.c $(srcdir)/indices.c $(srcdir)/nodemenu.c $(srcdir)/footnotes.c $(srcdir)/variables.c
+cmd_sources = $(srcdir)/session.c $(srcdir)/echo-area.c $(srcdir)/infodoc.c \
+ $(srcdir)/m-x.c $(srcdir)/indices.c $(srcdir)/nodemenu.c \
+ $(srcdir)/footnotes.c $(srcdir)/variables.c
+subdir = info
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
-CONFIG_HEADER = ../config.h
-CONFIG_CLEAN_FILES =
-PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
-
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+bin_PROGRAMS = ginfo$(EXEEXT) infokey$(EXEEXT)
+noinst_PROGRAMS = makedoc$(EXEEXT)
+PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
+
+@TEXINFO_MAINT_TRUE@am__objects_1 = doc.$(OBJEXT) key.$(OBJEXT)
+@TEXINFO_MAINT_FALSE@am__objects_2 = doc.$(OBJEXT) key.$(OBJEXT)
+am_ginfo_OBJECTS = dir.$(OBJEXT) display.$(OBJEXT) dribble.$(OBJEXT) \
+ echo-area.$(OBJEXT) filesys.$(OBJEXT) footnotes.$(OBJEXT) \
+ gc.$(OBJEXT) indices.$(OBJEXT) info-utils.$(OBJEXT) \
+ info.$(OBJEXT) infodoc.$(OBJEXT) infomap.$(OBJEXT) \
+ m-x.$(OBJEXT) man.$(OBJEXT) nodemenu.$(OBJEXT) nodes.$(OBJEXT) \
+ search.$(OBJEXT) session.$(OBJEXT) signals.$(OBJEXT) \
+ terminal.$(OBJEXT) tilde.$(OBJEXT) variables.$(OBJEXT) \
+ window.$(OBJEXT) $(am__objects_1) $(am__objects_2)
+ginfo_OBJECTS = $(am_ginfo_OBJECTS)
+ginfo_LDADD = $(LDADD)
+ginfo_DEPENDENCIES = ../lib/libtxi.a
+ginfo_LDFLAGS =
+am_infokey_OBJECTS = infokey.$(OBJEXT) key.$(OBJEXT)
+infokey_OBJECTS = $(am_infokey_OBJECTS)
+infokey_LDADD = $(LDADD)
+infokey_DEPENDENCIES = ../lib/libtxi.a
+infokey_LDFLAGS =
+am_makedoc_OBJECTS = makedoc.$(OBJEXT)
+makedoc_OBJECTS = $(am_makedoc_OBJECTS)
+makedoc_LDADD = $(LDADD)
+makedoc_DEPENDENCIES = ../lib/libtxi.a
+makedoc_LDFLAGS =
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
-ginfo_OBJECTS = dir.o display.o dribble.o echo-area.o filesys.o \
-footnotes.o gc.o indices.o info-utils.o info.o infodoc.o infomap.o \
-m-x.o man.o nodemenu.o nodes.o search.o session.o signals.o terminal.o \
-tilde.o variables.o window.o doc.o
-ginfo_LDADD = $(LDADD)
-ginfo_DEPENDENCIES = ../lib/libtxi.a
-ginfo_LDFLAGS =
-makedoc_OBJECTS = makedoc.o
-makedoc_LDADD = $(LDADD)
-makedoc_DEPENDENCIES = ../lib/libtxi.a
-makedoc_LDFLAGS =
-CFLAGS = @CFLAGS@
-COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/dir.Po ./$(DEPDIR)/display.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/doc.Po ./$(DEPDIR)/dribble.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/echo-area.Po ./$(DEPDIR)/filesys.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/footnotes.Po ./$(DEPDIR)/gc.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/indices.Po ./$(DEPDIR)/info-utils.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/info.Po ./$(DEPDIR)/infodoc.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/infokey.Po ./$(DEPDIR)/infomap.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/key.Po ./$(DEPDIR)/m-x.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/makedoc.Po ./$(DEPDIR)/man.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/nodemenu.Po ./$(DEPDIR)/nodes.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/search.Po ./$(DEPDIR)/session.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/signals.Po ./$(DEPDIR)/terminal.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/tilde.Po ./$(DEPDIR)/variables.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/window.Po
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
-LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
-DIST_COMMON = README Makefile.am Makefile.in
-
-
-DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+CFLAGS = @CFLAGS@
+DIST_SOURCES = $(ginfo_SOURCES) $(infokey_SOURCES) $(makedoc_SOURCES)
+DIST_COMMON = README Makefile.am Makefile.in
+SOURCES = $(ginfo_SOURCES) $(infokey_SOURCES) $(makedoc_SOURCES)
-TAR = gtar
-GZIP_ENV = --best
-SOURCES = $(ginfo_SOURCES) $(makedoc_SOURCES)
-OBJECTS = $(ginfo_OBJECTS) $(makedoc_OBJECTS)
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-am
-all: all-redirect
.SUFFIXES:
-.SUFFIXES: .S .c .o .s
-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
- cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps info/Makefile
-
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
- cd $(top_builddir) \
- && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
-
-
-mostlyclean-binPROGRAMS:
-
-clean-binPROGRAMS:
- -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
-
-distclean-binPROGRAMS:
-
-maintainer-clean-binPROGRAMS:
-
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4)
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu info/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(bindir)
@list='$(bin_PROGRAMS)'; for p in $$list; do \
- if test -f $$p; then \
- echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
- $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ ; then \
+ p1=`echo "$$p1" | sed -e 's,^.*/,,'`; \
+ f=`echo $$p1|sed '$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f"; \
+ $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f; \
else :; fi; \
done
uninstall-binPROGRAMS:
@$(NORMAL_UNINSTALL)
- list='$(bin_PROGRAMS)'; for p in $$list; do \
- rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ f=`echo "$$f" | sed -e 's,^.*/,,'`; \
+ echo " rm -f $(DESTDIR)$(bindir)/$$f"; \
+ rm -f $(DESTDIR)$(bindir)/$$f; \
done
-mostlyclean-noinstPROGRAMS:
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
clean-noinstPROGRAMS:
-test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
-
-distclean-noinstPROGRAMS:
-
-maintainer-clean-noinstPROGRAMS:
-
-.c.o:
- $(COMPILE) -c $<
-
-.s.o:
- $(COMPILE) -c $<
-
-.S.o:
- $(COMPILE) -c $<
+ginfo$(EXEEXT): $(ginfo_OBJECTS) $(ginfo_DEPENDENCIES)
+ @rm -f ginfo$(EXEEXT)
+ $(LINK) $(ginfo_LDFLAGS) $(ginfo_OBJECTS) $(ginfo_LDADD) $(LIBS)
+infokey$(EXEEXT): $(infokey_OBJECTS) $(infokey_DEPENDENCIES)
+ @rm -f infokey$(EXEEXT)
+ $(LINK) $(infokey_LDFLAGS) $(infokey_OBJECTS) $(infokey_LDADD) $(LIBS)
+makedoc$(EXEEXT): $(makedoc_OBJECTS) $(makedoc_DEPENDENCIES)
+ @rm -f makedoc$(EXEEXT)
+ $(LINK) $(makedoc_LDFLAGS) $(makedoc_OBJECTS) $(makedoc_LDADD) $(LIBS)
mostlyclean-compile:
- -rm -f *.o core *.core
-
-clean-compile:
+ -rm -f *.$(OBJEXT) core *.core
distclean-compile:
-rm -f *.tab.c
-maintainer-clean-compile:
-
-ginfo: $(ginfo_OBJECTS) $(ginfo_DEPENDENCIES)
- @rm -f ginfo
- $(LINK) $(ginfo_LDFLAGS) $(ginfo_OBJECTS) $(ginfo_LDADD) $(LIBS)
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dir.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/display.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/doc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dribble.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/echo-area.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filesys.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/footnotes.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indices.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/info-utils.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/info.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/infodoc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/infokey.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/infomap.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/key.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m-x.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/makedoc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/man.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nodemenu.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nodes.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/search.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/session.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signals.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/terminal.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tilde.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/variables.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/window.Po@am__quote@
+
+distclean-depend:
+ -rm -rf ./$(DEPDIR)
-makedoc: $(makedoc_OBJECTS) $(makedoc_DEPENDENCIES)
- @rm -f makedoc
- $(LINK) $(makedoc_LDFLAGS) $(makedoc_OBJECTS) $(makedoc_LDADD) $(LIBS)
+.c.o:
+@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(COMPILE) -c `test -f $< || echo '$(srcdir)/'`$<
+
+.c.obj:
+@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(COMPILE) -c `cygpath -w $<`
+CCDEPMODE = @CCDEPMODE@
+install-info-am:
+uninstall-info-am:
+
+ETAGS = etags
+ETAGSFLAGS =
tags: TAGS
-ID: $(HEADERS) $(SOURCES) $(LISP)
- list='$(SOURCES) $(HEADERS)'; \
- unique=`for i in $$list; do echo $$i; done | \
- awk ' { files[$$0] = 1; } \
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
- here=`pwd` && cd $(srcdir) \
- && mkid -f$$here/ID $$unique $(LISP)
+ mkid -fID $$unique
-TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
- list='$(SOURCES) $(HEADERS)'; \
- unique=`for i in $$list; do echo $$i; done | \
- awk ' { files[$$0] = 1; } \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
- test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
- || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
-
-mostlyclean-tags:
+ test -z "$(ETAGS_ARGS)$$tags$$unique" \
+ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique
-clean-tags:
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
- -rm -f TAGS ID
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-maintainer-clean-tags:
-
-distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
-
-subdir = info
+top_distdir = ..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@for file in $(DISTFILES); do \
- d=$(srcdir); \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkinstalldirs) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
if test -d $$d/$$file; then \
- cp -pr $$d/$$file $(distdir)/$$file; \
+ cp -pR $$d/$$file $(distdir)$$dir \
+ || exit 1; \
else \
test -f $(distdir)/$$file \
- || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
- || cp -p $$d/$$file $(distdir)/$$file || :; \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
fi; \
done
-dir.o: dir.c info.h ../lib/system.h ../config.h ../lib/getopt.h \
- filesys.h display.h info-utils.h nodes.h window.h infomap.h \
- search.h terminal.h session.h dribble.h echo-area.h doc.h \
- footnotes.h gc.h tilde.h
-display.o: display.c info.h ../lib/system.h ../config.h ../lib/getopt.h \
- filesys.h display.h info-utils.h nodes.h window.h infomap.h \
- search.h terminal.h session.h dribble.h echo-area.h doc.h \
- footnotes.h gc.h
-doc.o: doc.c doc.h info.h ../lib/system.h ../config.h ../lib/getopt.h \
- filesys.h display.h info-utils.h nodes.h window.h infomap.h \
- search.h terminal.h session.h dribble.h echo-area.h footnotes.h \
- gc.h funs.h
-dribble.o: dribble.c info.h ../lib/system.h ../config.h ../lib/getopt.h \
- filesys.h display.h info-utils.h nodes.h window.h infomap.h \
- search.h terminal.h session.h dribble.h echo-area.h doc.h \
- footnotes.h gc.h
-echo-area.o: echo-area.c info.h ../lib/system.h ../config.h \
- ../lib/getopt.h filesys.h display.h info-utils.h nodes.h \
- window.h infomap.h search.h terminal.h session.h dribble.h \
- echo-area.h doc.h footnotes.h gc.h
-filesys.o: filesys.c info.h ../lib/system.h ../config.h ../lib/getopt.h \
- filesys.h display.h info-utils.h nodes.h window.h infomap.h \
- search.h terminal.h session.h dribble.h echo-area.h doc.h \
- footnotes.h gc.h tilde.h
-footnotes.o: footnotes.c info.h ../lib/system.h ../config.h \
- ../lib/getopt.h filesys.h display.h info-utils.h nodes.h \
- window.h infomap.h search.h terminal.h session.h dribble.h \
- echo-area.h doc.h footnotes.h gc.h
-gc.o: gc.c info.h ../lib/system.h ../config.h ../lib/getopt.h filesys.h \
- display.h info-utils.h nodes.h window.h infomap.h search.h \
- terminal.h session.h dribble.h echo-area.h doc.h footnotes.h \
- gc.h
-indices.o: indices.c info.h ../lib/system.h ../config.h ../lib/getopt.h \
- filesys.h display.h info-utils.h nodes.h window.h infomap.h \
- search.h terminal.h session.h dribble.h echo-area.h doc.h \
- footnotes.h gc.h indices.h
-info-utils.o: info-utils.c info.h ../lib/system.h ../config.h \
- ../lib/getopt.h filesys.h display.h info-utils.h nodes.h \
- window.h infomap.h search.h terminal.h session.h dribble.h \
- echo-area.h doc.h footnotes.h gc.h man.h
-info.o: info.c info.h ../lib/system.h ../config.h ../lib/getopt.h \
- filesys.h display.h info-utils.h nodes.h window.h infomap.h \
- search.h terminal.h session.h dribble.h echo-area.h doc.h \
- footnotes.h gc.h indices.h man.h
-infodoc.o: infodoc.c info.h ../lib/system.h ../config.h ../lib/getopt.h \
- filesys.h display.h info-utils.h nodes.h window.h infomap.h \
- search.h terminal.h session.h dribble.h echo-area.h doc.h \
- footnotes.h gc.h
-infokey.o: infokey.c info.h ../lib/system.h ../config.h filesys.h doc.h \
- display.h info-utils.h nodes.h window.h infomap.h search.h \
- terminal.h session.h dribble.h echo-area.h footnotes.h gc.h \
- infokey.h key.h ../lib/getopt.h
-infomap.o: infomap.c info.h ../lib/system.h ../config.h ../lib/getopt.h \
- filesys.h display.h info-utils.h nodes.h window.h infomap.h \
- search.h terminal.h session.h dribble.h echo-area.h doc.h \
- footnotes.h gc.h funs.h
-key.o: key.c key.h funs.h
-m-x.o: m-x.c info.h ../lib/system.h ../config.h ../lib/getopt.h \
- filesys.h display.h info-utils.h nodes.h window.h infomap.h \
- search.h terminal.h session.h dribble.h echo-area.h doc.h \
- footnotes.h gc.h
-makedoc.o: makedoc.c info.h ../lib/system.h ../config.h ../lib/getopt.h \
- filesys.h display.h info-utils.h nodes.h window.h infomap.h \
- search.h terminal.h session.h dribble.h echo-area.h doc.h \
- footnotes.h gc.h
-man.o: man.c info.h ../lib/system.h ../config.h ../lib/getopt.h \
- filesys.h display.h info-utils.h nodes.h window.h infomap.h \
- search.h terminal.h session.h dribble.h echo-area.h doc.h \
- footnotes.h gc.h signals.h tilde.h man.h
-nodemenu.o: nodemenu.c info.h ../lib/system.h ../config.h \
- ../lib/getopt.h filesys.h display.h info-utils.h nodes.h \
- window.h infomap.h search.h terminal.h session.h dribble.h \
- echo-area.h doc.h footnotes.h gc.h
-nodes.o: nodes.c info.h ../lib/system.h ../config.h ../lib/getopt.h \
- filesys.h display.h info-utils.h nodes.h window.h infomap.h \
- search.h terminal.h session.h dribble.h echo-area.h doc.h \
- footnotes.h gc.h man.h
-search.o: search.c info.h ../lib/system.h ../config.h ../lib/getopt.h \
- filesys.h display.h info-utils.h nodes.h window.h infomap.h \
- search.h terminal.h session.h dribble.h echo-area.h doc.h \
- footnotes.h gc.h
-session.o: session.c info.h ../lib/system.h ../config.h ../lib/getopt.h \
- filesys.h display.h info-utils.h nodes.h window.h infomap.h \
- search.h terminal.h session.h dribble.h echo-area.h doc.h \
- footnotes.h gc.h man.h
-signals.o: signals.c info.h ../lib/system.h ../config.h ../lib/getopt.h \
- filesys.h display.h info-utils.h nodes.h window.h infomap.h \
- search.h terminal.h session.h dribble.h echo-area.h doc.h \
- footnotes.h gc.h signals.h
-terminal.o: terminal.c info.h ../lib/system.h ../config.h \
- ../lib/getopt.h filesys.h display.h info-utils.h nodes.h \
- window.h infomap.h search.h terminal.h session.h dribble.h \
- echo-area.h doc.h footnotes.h gc.h termdep.h
-tilde.o: tilde.c info.h ../lib/system.h ../config.h ../lib/getopt.h \
- filesys.h display.h info-utils.h nodes.h window.h infomap.h \
- search.h terminal.h session.h dribble.h echo-area.h doc.h \
- footnotes.h gc.h
-variables.o: variables.c info.h ../lib/system.h ../config.h \
- ../lib/getopt.h filesys.h display.h info-utils.h nodes.h \
- window.h infomap.h search.h terminal.h session.h dribble.h \
- echo-area.h doc.h footnotes.h gc.h variables.h
-window.o: window.c info.h ../lib/system.h ../config.h ../lib/getopt.h \
- filesys.h display.h info-utils.h nodes.h window.h infomap.h \
- search.h terminal.h session.h dribble.h echo-area.h doc.h \
- footnotes.h gc.h
-
-info-am:
-info: info-am
-dvi-am:
-dvi: dvi-am
check-am: all-am
check: check-am
-installcheck-am:
-installcheck: installcheck-am
-install-exec-am: install-binPROGRAMS
-install-exec: install-exec-am
+all-am: Makefile $(PROGRAMS)
-install-data-am:
-install-data: install-data-am
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
-install-am: all-am
- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
install: install-am
-uninstall-am: uninstall-binPROGRAMS
+install-exec: install-exec-am
+install-data: install-data-am
uninstall: uninstall-am
-all-am: Makefile $(PROGRAMS)
-all-redirect: all-am
-install-strip:
- $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
-installdirs:
- $(mkinstalldirs) $(DESTDIR)$(bindir)
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
- -rm -f Makefile $(CONFIG_CLEAN_FILES)
- -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+ -rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
-mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-noinstPROGRAMS \
- mostlyclean-compile mostlyclean-tags \
- mostlyclean-generic
+clean: clean-am
-mostlyclean: mostlyclean-am
+clean-am: clean-binPROGRAMS clean-generic clean-noinstPROGRAMS \
+ mostlyclean-am
-clean-am: clean-binPROGRAMS clean-noinstPROGRAMS clean-compile \
- clean-tags clean-generic mostlyclean-am
+distclean: distclean-am
-clean: clean-am
+distclean-am: clean-am distclean-compile distclean-depend \
+ distclean-generic distclean-tags
-distclean-am: distclean-binPROGRAMS distclean-noinstPROGRAMS \
- distclean-compile distclean-tags distclean-generic \
- clean-am
+dvi: dvi-am
-distclean: distclean-am
+dvi-am:
-maintainer-clean-am: maintainer-clean-binPROGRAMS \
- maintainer-clean-noinstPROGRAMS \
- maintainer-clean-compile maintainer-clean-tags \
- maintainer-clean-generic distclean-am
- @echo "This command is intended for maintainers to use;"
- @echo "it deletes files that may require special tools to rebuild."
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-binPROGRAMS
+
+install-man:
+
+installcheck-am:
maintainer-clean: maintainer-clean-am
-.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \
-maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \
-mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \
-clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \
-mostlyclean-compile distclean-compile clean-compile \
-maintainer-clean-compile tags mostlyclean-tags distclean-tags \
-clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \
-check-am installcheck-am installcheck install-exec-am install-exec \
-install-data-am install-data install-am install uninstall-am uninstall \
-all-redirect all-am all installdirs mostlyclean-generic \
-distclean-generic clean-generic maintainer-clean-generic clean \
-mostlyclean distclean maintainer-clean
-
-
-$(BUILT_SOURCES): makedoc $(cmd_sources)
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+uninstall-am: uninstall-binPROGRAMS uninstall-info-am
+
+.PHONY: GTAGS all all-am check check-am clean clean-binPROGRAMS \
+ clean-generic clean-noinstPROGRAMS distclean distclean-compile \
+ distclean-depend distclean-generic distclean-tags distdir dvi \
+ dvi-am info info-am install install-am install-binPROGRAMS \
+ install-data install-data-am install-exec install-exec-am \
+ install-info-am install-man install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic tags uninstall uninstall-am \
+ uninstall-binPROGRAMS uninstall-info-am
+
+
+# The $(EXEEXT) should be added by Automake, but isn't. Fine.
+$(BUILT_SOURCES): makedoc$(EXEEXT) $(cmd_sources)
# This is insufficient. We really need them not to be in the
# distribution in the first place, but it seems Automake does not
# currently allow that.
rm -f $(BUILT_SOURCES)
./makedoc $(cmd_sources)
-
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
diff --git a/gnu/usr.bin/texinfo/info/NEWS b/gnu/usr.bin/texinfo/info/NEWS
new file mode 100644
index 00000000000..b13fb1531b5
--- /dev/null
+++ b/gnu/usr.bin/texinfo/info/NEWS
@@ -0,0 +1,200 @@
+This release of Info is version 2.11. Please read the file README.
+
+Version 2.11, Sat Apr 1 09:15:21 1995
+
+Changes since 2.7 beta:
+
+Although the basic code remains the same, there are numerous nits
+fixed, including some display bugs, and a memory leak. Some changes
+that have taken place with larger impact include the way in which the
+(dir) node is built; I have added in support for "localdir"
+directories among other things. Info files may be stored in
+compressed formats, and in their own subdirectories; menu items which
+do not explicitly name the node to which they are attached have the
+menu item name looked up as an Info file if it is not found within the
+current document. This means that the menu item:
+
+* Info:: The Info documentation reader.
+
+in (dir) refers to the info node "(info)Top".
+
+Please see the ChangeLog and documentation for details on other
+changes.
+
+Version 2.7 beta, Wed Dec 30 02:02:38 1992
+Version 2.6 beta, Tue Dec 22 03:58:07 1992
+Version 2.5 beta, Tue Dec 8 14:50:35 1992
+Version 2.4 beta, Sat Nov 28 14:34:02 1992
+Version 2.3 beta, Fri Nov 27 01:04:13 1992
+Version 2.2 beta, Tue Nov 24 09:36:08 1992
+Version 2.1 beta, Tue Nov 17 23:29:36 1992
+
+Changes since 2.5 beta:
+
+Note that versions 2.6 and 2.7 Beta were only released to a select group.
+
+* "info-" removed from the front of M-x commands.
+
+* Automatic footnote display. When you enter a node which contains
+ footnotes, and the variable "automatic-footnotes" is "On", Info pops
+ up a window containing the footnotes. Likewise, when you leave that
+ node, the window containing the footnotes goes away.
+
+* Cleaner built in documentation, and documentation functions.
+
+ Use:
+ o `M-x describe-variable' to read a variable's documenation
+ o `M-x describe-key' to find out what a particular keystroke does.
+ o `M-x describe-function' to read a function's documentation.
+ o `M-x where-is' to find out what keys invoke a particular function.
+
+* Info can "tile" the displayed windows (via "M-x tile-windows"). If
+ the variable "automatic-tiling" is "On", then splitting a window or
+ deleting a window causes the remaining windows to be retiled.
+
+* You can save every keystroke you type in a "dribble file" by using the
+ `--dribble FILENAME' option. You can initially read keystrokes from an
+ alternate input stream with `--restore FILENAME', or by redirecting
+ input on the command line `info < old-dribble'.
+
+* New behaviour of menu items. If the label is the same as the
+ target node name, and the node couldn't be found in the current file,
+ treat the label as a file name. For example, a menu entry in "DIR"
+ might contain:
+
+ * Emacs:: Cool text-editor.
+
+ Info would not find the node "(dir)Emacs", so just plain "(emacs)"
+ would be tried.
+
+* New variable "ISO-Latin" allows you to use European machines with
+ 8-bit character sets.
+
+* Cleanups in echo area reading, and redisplay. Cleanups in handling the
+ window which shows possible completions.
+
+* Info can now read files that have been compressed. An array in filesys.c
+ maps extensions to programs that can decompress stdin, and write the results
+ to stdout. Currently, ".Z"/uncompress, ".z"/gunzip, and ".Y"/unyabba are
+ supported. The modeline for a compressed file shows "zz" in it.
+
+* There is a new variable "gc-compressed-files" which, if non-zero, says
+ it is okay to reclaim the file buffer space allocated to a file which
+ was compressed, if, and only if, that file's contents do not appear in
+ any history node.
+
+* New file `nodemenu.c' implements a few functions for manipulating
+ previously visited nodes. `C-x C-b' (list-visited-nodes) produces a
+ menu of the nodes that could be reached by info-history-node in some
+ window. `C-x b' (select-visited-node) is similar, but reads one of
+ the node names with completion.
+
+* Keystroke `M-r' (move_to_screen_line) allows the user to place the cursor at
+ the start of a specific screen line. Without a numeric argument, place the
+ cursor on the center line; with an arg, place the cursor on that line.
+
+* Interruptible display implemented. Basic display speedups and hacks.
+* The message "*** Tags Out of Date ***" now means what it says.
+* Index searching with `,' (info-index-next) has been improved.
+* When scrolling with C-v, C-M-v, or M-v, only "Page Only" scrolling
+ will happen.
+
+* Continous scrolling (along with `]' (info-global-next) and `['
+ (info-global-prev) works better. `]' and `[' accept numeric
+ arguments, moving that many nodes in that case.
+
+* `C-x w' (info-toggle-wrap) controls how lines wider than the width
+ of the screen are displayed. If a line is too long, a `$' is
+ displayed in the rightmost column of the window.
+
+* There are some new variables for controlling the behaviour of Info
+ interactively. The current list of variables is as follows:
+
+ Variable Name Default Value Description
+ ------------- ------------- -----------
+ `automatic-footnotes' On When "On", footnotes appear and
+ disappear automatically.
+
+ `automatic-tiling' Off When "On", creating of deleting a
+ window resizes other windows.
+
+ `visible-bell' Off If non-zero, try to use a visible bell.
+
+ `errors-ring-bell' On If non-zero, errors cause a ring.
+
+ `show-index-match' On If non-zero, the portion of the string
+ matched is highlighted by changing its
+ case.
+
+ `scroll-behaviour' Continuous One of "Continuous", "Next Only", or
+ "Page Only". "Page Only" prevents you from
+ scrolling past the bottom or top of a node.
+ "Next Only" causes the Next or Prev node to
+ be selected when you scroll past the bottom
+ or top of a node. "Continous" moves
+ linearly through the files hierchichal
+ structure.
+
+ `scroll-step' 0 Controls how scrolling is done for you when
+ the cursor moves out of the current window.
+ Non-zero means it is the number of lines
+ you would like the screen to shift. A
+ value of 0 means to center the line
+ containing the cursor in the window.
+
+ `gc-compressed-files' Off If non-zero means it is okay to reclaim the
+ file buffer space allocated to a file which
+ was compressed, if, and only if, that
+ file's contents do not appear in the node
+ list of any window.
+
+ `ISO-Latin' Off Non-zero means that you are using an ISO
+ Latin character set. By default, standard
+ ASCII characters are assumed.
+________________________________________
+This release of Info is version 2.5 beta.
+
+Changes since 2.4 beta:
+
+* Index (i) and (,) commands fully implemented.
+* "configure" script now shipped with Info.
+* New function "set-variable" allows users to set various variables.
+* User-settable behaviour on end or beginning of node scrolling. This
+ supercedes the SPC and DEL changes in 2.3 beta.
+
+________________________________________
+This release of Info is version 2.4 beta.
+
+Changes since 2.3 beta:
+
+* info-last-node now means move to the last node of this info file.
+* info-history-node means move backwards through this window's node history.
+* info-first-node moves to the first node in the Info file. This node is
+ not necessarily "Top"!
+* SPC and DEL can select the Next or Prev node after printing an informative
+ message when pressed at the end/beg of a node.
+
+----------------------------------------
+This release of Info is version 2.3 beta.
+
+Changes since 2.2 beta:
+
+* M-x command lines if NAMED_COMMANDS is #defined. Variable in Makefile.
+* Screen height changes made quite robust.
+* Interactive function "set-screen-height" implements user height changes.
+* Scrolling on some terminals is faster now.
+* C-l with numeric arguement is fixed.
+
+----------------------------------------
+This release of Info is version 2.2 beta.
+
+Changes since 2.0:
+
+* C-g can now interrupt multi-file searches.
+* Incremental search is fully implemented.
+* Loading large tag tables is much faster now.
+* makedoc.c replaces shell script, speeding incremental builds.
+* Scrolling in redisplay is implemented.
+* Recursive uses of the echo area made more robust.
+* Garbage collection of unreferenced nodes.
+
diff --git a/gnu/usr.bin/texinfo/info/clib.c b/gnu/usr.bin/texinfo/info/clib.c
new file mode 100644
index 00000000000..67abc27d40d
--- /dev/null
+++ b/gnu/usr.bin/texinfo/info/clib.c
@@ -0,0 +1,112 @@
+/* clib.c: Functions which we normally expect to find in the C library.
+ $Id: clib.c,v 1.3 2002/06/10 13:51:03 espie Exp $
+
+ This file is part of GNU Info, a program for reading online documentation
+ stored in Info format.
+
+ Copyright (C) 1995 Free Software Foundation, Inc.
+
+ 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 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Written by Brian Fox (bfox@ai.mit.edu). */
+
+#include <stdio.h>
+
+#if defined (HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+
+#if defined (HAVE_STDLIB_H)
+#include <stdlib.h>
+#endif
+
+#if defined (HAVE_STRING_H)
+#include <string.h>
+#endif
+
+#include <sys/errno.h>
+
+extern void *xmalloc (), *xrealloc ();
+#include "general.h"
+
+#if !defined (errno)
+extern int errno;
+#endif
+
+#if !defined (HAVE_STRERROR)
+extern char *sys_errlist[];
+extern int sys_nerr;
+
+char *
+strerror (num)
+ int num;
+{
+ if (num >= sys_nerr)
+ return ("");
+ else
+ return (sys_errlist[num]);
+}
+#endif /* !HAVE_STRERROR */
+
+#if !defined (HAVE_STRCASECMP)
+/* This Unix doesn't have the strcasecmp () function. */
+int
+strcasecmp (string1, string2)
+ char *string1, *string2;
+{
+ char ch1, ch2;
+
+ for (;;)
+ {
+ ch1 = *string1++;
+ ch2 = *string2++;
+
+ if (!(ch1 | ch2))
+ return (0);
+
+ ch1 = info_toupper (ch1);
+ ch2 = info_toupper (ch2);
+
+ if (ch1 != ch2)
+ return (ch1 - ch2);
+ }
+}
+
+/* Compare at most COUNT characters from string1 to string2. Case
+ doesn't matter. */
+int
+strncasecmp (string1, string2, count)
+ char *string1, *string2;
+ int count;
+{
+ register char ch1, ch2;
+
+ while (count)
+ {
+ ch1 = *string1++;
+ ch2 = *string2++;
+
+ ch1 = info_toupper (ch1);
+ ch2 = info_toupper (ch2);
+
+ if (ch1 == ch2)
+ count--;
+ else
+ break;
+ }
+ return (count);
+}
+#endif /* !STRCASECMP */
+
diff --git a/gnu/usr.bin/texinfo/info/clib.h b/gnu/usr.bin/texinfo/info/clib.h
new file mode 100644
index 00000000000..c559fe51b60
--- /dev/null
+++ b/gnu/usr.bin/texinfo/info/clib.h
@@ -0,0 +1,42 @@
+/* clib.h: Declarations of functions which appear in clib.c (or libc.a). */
+
+/* This file is part of GNU Info, a program for reading online documentation
+ stored in Info format.
+
+ Copyright (C) 1995 Free Software Foundation, Inc.
+
+ 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 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Written by Brian Fox (bfox@ai.mit.edu). */
+
+#if !defined (_CLIB_H_)
+#define _CLIB_H_
+
+#if !defined (HAVE_STRDUP)
+extern char *strdup ();
+#endif
+
+#if !defined (HAVE_STRERROR)
+extern char *strerror ();
+#endif
+
+#if !defined (HAVE_STRCASECMP)
+extern int strcasecmp ();
+extern int strncasecmp ();
+#endif
+
+#endif /* !_CLIB_H_ */
+
+
diff --git a/gnu/usr.bin/texinfo/info/diffs b/gnu/usr.bin/texinfo/info/diffs
new file mode 100644
index 00000000000..ff866daa836
--- /dev/null
+++ b/gnu/usr.bin/texinfo/info/diffs
@@ -0,0 +1,19 @@
+*** indices.c.~1~ Tue Oct 26 16:36:35 1993
+--- indices.c Sat Nov 20 14:00:46 1993
+***************
+*** 253,259 ****
+ else
+ index_offset = -1;
+
+! old_offset == index_offset;
+
+ /* The "last" string searched for is this one. */
+ index_search = line;
+--- 253,259 ----
+ else
+ index_offset = -1;
+
+! old_offset = index_offset;
+
+ /* The "last" string searched for is this one. */
+ index_search = line;
diff --git a/gnu/usr.bin/texinfo/info/display.c b/gnu/usr.bin/texinfo/info/display.c
index a9ca5d65689..8a557f36371 100644
--- a/gnu/usr.bin/texinfo/info/display.c
+++ b/gnu/usr.bin/texinfo/info/display.c
@@ -1,5 +1,5 @@
/* display.c -- How to display Info windows.
- $Id: display.c,v 1.2 1999/01/11 16:38:06 espie Exp $
+ $Id: display.c,v 1.3 2002/06/10 13:51:03 espie Exp $
Copyright (C) 1993, 97 Free Software Foundation, Inc.
@@ -103,6 +103,8 @@ display_update_one_window (win)
char *printed_line; /* Buffer for a printed line. */
int pl_index = 0; /* Index into PRINTED_LINE. */
int line_index = 0; /* Number of lines done so far. */
+ int pl_ignore = 0; /* How many chars use zero width on screen. */
+ int allocated_win_width;
DISPLAY_LINE **display = the_display;
/* If display is inhibited, that counts as an interrupted display. */
@@ -123,7 +125,8 @@ display_update_one_window (win)
/* Print each line in the window into our local buffer, and then
check the contents of that buffer against the display. If they
differ, update the display. */
- printed_line = (char *)xmalloc (1 + win->width);
+ allocated_win_width = win->width + 1;
+ printed_line = (char *)xmalloc (allocated_win_width);
if (!win->node || !win->line_starts)
goto done_with_node_display;
@@ -147,7 +150,7 @@ display_update_one_window (win)
{
if (*nodetext == '\r' || *nodetext == '\n')
{
- replen = win->width - pl_index;
+ replen = win->width - pl_index + pl_ignore;
}
else
{
@@ -156,9 +159,26 @@ display_update_one_window (win)
}
}
+ /* Support ANSI escape sequences under -R. */
+ if (raw_escapes_p
+ && *nodetext == '\033'
+ && nodetext[1] == '['
+ && isdigit (nodetext[2]))
+ {
+ if (nodetext[3] == 'm')
+ pl_ignore += 4;
+ else if (isdigit (nodetext[3]) && nodetext[4] == 'm')
+ pl_ignore += 5;
+ }
+ while (pl_index + 2 >= allocated_win_width - 1)
+ {
+ allocated_win_width *= 2;
+ printed_line = (char *)xrealloc (printed_line, allocated_win_width);
+ }
+
/* If this character can be printed without passing the width of
the line, then stuff it into the line. */
- if (replen + pl_index < win->width)
+ if (replen + pl_index < win->width + pl_ignore)
{
/* Optimize if possible. */
if (replen == 1)
@@ -189,7 +209,7 @@ display_update_one_window (win)
the next line. Remember the offset of the last character
printed out of REP so that we can carry the character over
to the next line. */
- for (i = 0; pl_index < (win->width - 1);)
+ for (i = 0; pl_index < (win->width + pl_ignore - 1);)
printed_line[pl_index++] = rep[i++];
rep_carried_over = rep + i;
@@ -214,7 +234,9 @@ display_update_one_window (win)
/* If the screen line is inversed, then we have to clear
the line from the screen first. Why, I don't know. */
- if (entry->inverse)
+ if (entry->inverse
+ /* Need to erase the line if it has escape sequences. */
+ || (raw_escapes_p && strchr (entry->text, '\033') != 0))
{
terminal_goto_xy (0, line_index + win->first_row);
terminal_clear_to_eol ();
@@ -242,13 +264,21 @@ display_update_one_window (win)
/* If the printed text didn't extend all the way to the edge
of the window, and text was appearing between here and the
edge of the window, clear from here to the end of the line. */
- if ((pl_index < win->width && pl_index < entry->textlen) ||
- (entry->inverse))
+ if ((pl_index < win->width + pl_ignore
+ && pl_index < entry->textlen)
+ || (entry->inverse))
terminal_clear_to_eol ();
fflush (stdout);
/* Update the display text buffer. */
+ if (strlen (printed_line) > screenwidth)
+ /* printed_line[] can include more than screenwidth
+ characters if we are under -R and there are escape
+ sequences in it. However, entry->text was
+ allocated (in display_initialize_display) for
+ screenwidth characters only. */
+ entry->text = xrealloc (entry->text, strlen (printed_line)+1);
strcpy (entry->text + i, printed_line + i);
entry->textlen = pl_index;
@@ -274,6 +304,7 @@ display_update_one_window (win)
/* Reset PL_INDEX to the start of the line. */
pl_index = 0;
+ pl_ignore = 0; /* this is computed per line */
/* If there are characters from REP left to print, stuff them
into the buffer now. */
diff --git a/gnu/usr.bin/texinfo/info/dribble b/gnu/usr.bin/texinfo/info/dribble
new file mode 100644
index 00000000000..99d3a844815
--- /dev/null
+++ b/gnu/usr.bin/texinfo/info/dribble
@@ -0,0 +1,5 @@
+mfoo
+em
+buffers
+
+ââ \ No newline at end of file
diff --git a/gnu/usr.bin/texinfo/info/echo-area.c b/gnu/usr.bin/texinfo/info/echo-area.c
index 96f0e356828..0faad8942dd 100644
--- a/gnu/usr.bin/texinfo/info/echo-area.c
+++ b/gnu/usr.bin/texinfo/info/echo-area.c
@@ -1,7 +1,7 @@
/* echo-area.c -- how to read a line in the echo area.
- $Id: echo-area.c,v 1.3 2000/02/09 02:18:39 espie Exp $
+ $Id: echo-area.c,v 1.4 2002/06/10 13:51:03 espie Exp $
- Copyright (C) 1993, 97, 98, 99 Free Software Foundation, Inc.
+ Copyright (C) 1993, 97, 98, 99, 2001 Free Software Foundation, Inc.
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
@@ -868,7 +868,10 @@ info_read_completing_internal (window, prompt, completions, force)
/* If no match, go back and try again. */
if (i == completions_found_index)
{
- inform_in_echo_area (_("Not complete"));
+ if (!completions_found_index)
+ inform_in_echo_area (_("No completions"));
+ else
+ inform_in_echo_area (_("Not complete"));
continue;
}
}
@@ -1258,7 +1261,26 @@ build_completions ()
maybe_free (LCD_reference.label);
LCD_reference.label = (char *)xmalloc (1 + shortest);
- strncpy (LCD_reference.label, completions_found[0]->label, shortest);
+ /* Since both the sorting done inside remove_completion_duplicates
+ and all the comparisons above are case-insensitive, it's
+ possible that the completion we are going to return is
+ identical to what the user typed but for the letter-case. This
+ is confusing, since the user could type FOOBAR<TAB> and get her
+ string change letter-case for no good reason. So try to find a
+ possible completion whose letter-case is identical, and if so,
+ use that. */
+ if (completions_found_index > 1)
+ {
+ int req_len = strlen (request);
+
+ for (i = 0; i < completions_found_index; i++)
+ if (strncmp (request, completions_found[i]->label, req_len) == 0)
+ break;
+ /* If none of the candidates match exactly, use the first one. */
+ if (i >= completions_found_index)
+ i = 0;
+ }
+ strncpy (LCD_reference.label, completions_found[i]->label, shortest);
LCD_reference.label[shortest] = '\0';
LCD_completion = &LCD_reference;
}
diff --git a/gnu/usr.bin/texinfo/info/echo_area.c b/gnu/usr.bin/texinfo/info/echo_area.c
new file mode 100644
index 00000000000..265e9880425
--- /dev/null
+++ b/gnu/usr.bin/texinfo/info/echo_area.c
@@ -0,0 +1,1508 @@
+/* echo_area.c -- How to read a line in the echo area. */
+
+/* This file is part of GNU Info, a program for reading online documentation
+ stored in Info format.
+
+ Copyright (C) 1993 Free Software Foundation, Inc.
+
+ 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 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Written by Brian Fox (bfox@ai.mit.edu). */
+
+#include "info.h"
+
+#if defined (FD_SET)
+# if defined (hpux)
+# define fd_set_cast(x) (int *)(x)
+# else
+# define fd_set_cast(x) (fd_set *)(x)
+# endif /* !hpux */
+#endif /* FD_SET */
+
+/* Non-zero means that C-g was used to quit reading input. */
+int info_aborted_echo_area = 0;
+
+/* Non-zero means that the echo area is being used to read input. */
+int echo_area_is_active = 0;
+
+/* The address of the last command executed in the echo area. */
+VFunction *ea_last_executed_command = (VFunction *)NULL;
+
+/* Non-zero means that the last command executed while reading input
+ killed some text. */
+int echo_area_last_command_was_kill = 0;
+
+/* Variables which hold on to the current state of the input line. */
+static char input_line[1 + EA_MAX_INPUT];
+static char *input_line_prompt;
+static int input_line_point;
+static int input_line_beg;
+static int input_line_end;
+static NODE input_line_node = {
+ (char *)NULL, (char *)NULL, (char *)NULL, input_line, EA_MAX_INPUT, 0
+};
+
+static void echo_area_initialize_node ();
+static void push_echo_area (), pop_echo_area ();
+static int echo_area_stack_depth (), echo_area_stack_contains_completions_p ();
+
+static void ea_kill_text ();
+
+/* Non-zero means we force the user to complete. */
+static int echo_area_must_complete_p = 0;
+static int completions_window_p ();
+
+/* If non-null, this is a window which was specifically created to display
+ possible completions output. We remember it so we can delete it when
+ appropriate. */
+static WINDOW *echo_area_completions_window = (WINDOW *)NULL;
+
+/* Variables which keep track of the window which was active prior to
+ entering the echo area. */
+static WINDOW *calling_window = (WINDOW *)NULL;
+static NODE *calling_window_node = (NODE *)NULL;
+static long calling_window_point = 0;
+static long calling_window_pagetop = 0;
+
+/* Remember the node and pertinent variables of the calling window. */
+static void
+remember_calling_window (window)
+ WINDOW *window;
+{
+ /* Only do this if the calling window is not the completions window, or,
+ if it is the completions window and there is no other window. */
+ if (!completions_window_p (window) ||
+ ((window == windows) && !(window->next)))
+ {
+ calling_window = window;
+ calling_window_node = window->node;
+ calling_window_point = window->point;
+ calling_window_pagetop = window->pagetop;
+ }
+}
+
+/* Restore the caller's window so that it shows the node that it was showing
+ on entry to info_read_xxx_echo_area (). */
+static void
+restore_calling_window ()
+{
+ register WINDOW *win, *compwin = (WINDOW *)NULL;
+
+ /* If the calling window is still visible, and it is the window that
+ we used for completions output, then restore the calling window. */
+ for (win = windows; win; win = win->next)
+ {
+ if (completions_window_p (win))
+ compwin = win;
+
+ if (win == calling_window && win == compwin)
+ {
+ window_set_node_of_window (calling_window, calling_window_node);
+ calling_window->point = calling_window_point;
+ calling_window->pagetop = calling_window_pagetop;
+ compwin = (WINDOW *)NULL;
+ break;
+ }
+ }
+
+ /* Delete the completions window if it is still present, it isn't the
+ last window on the screen, and there aren't any prior echo area reads
+ pending which created a completions window. */
+ if (compwin)
+ {
+ if ((compwin != windows || windows->next) &&
+ !echo_area_stack_contains_completions_p ())
+ {
+ WINDOW *next;
+ int pagetop, start, end, amount;
+
+ next = compwin->next;
+ if (next)
+ {
+ start = next->first_row;
+ end = start + next->height;
+ amount = - (compwin->height + 1);
+ pagetop = next->pagetop;
+ }
+
+ info_delete_window_internal (compwin);
+
+ /* This is not necessary because info_delete_window_internal ()
+ calls echo_area_inform_of_deleted_window (), which does the
+ right thing. */
+#if defined (UNNECESSARY)
+ echo_area_completions_window = (WINDOW *)NULL;
+#endif /* UNNECESSARY */
+
+ if (next)
+ {
+ display_scroll_display (start, end, amount);
+ next->pagetop = pagetop;
+ display_update_display (windows);
+ }
+ }
+ }
+}
+
+/* Set up a new input line with PROMPT. */
+static void
+initialize_input_line (prompt)
+ char *prompt;
+{
+ input_line_prompt = prompt;
+ if (prompt)
+ strcpy (input_line, prompt);
+ else
+ input_line[0] = '\0';
+
+ input_line_beg = input_line_end = input_line_point = strlen (prompt);
+}
+
+static char *
+echo_area_after_read ()
+{
+ char *return_value;
+
+ if (info_aborted_echo_area)
+ {
+ info_aborted_echo_area = 0;
+ return_value = (char *)NULL;
+ }
+ else
+ {
+ if (input_line_beg == input_line_end)
+ return_value = strdup ("");
+ else
+ {
+ int line_len = input_line_end - input_line_beg;
+ return_value = (char *) xmalloc (1 + line_len);
+ strncpy (return_value, &input_line[input_line_beg], line_len);
+ return_value[line_len] = '\0';
+ }
+ }
+ return (return_value);
+}
+
+/* Read a line of text in the echo area. Return a malloc ()'ed string,
+ or NULL if the user aborted out of this read. WINDOW is the currently
+ active window, so that we can restore it when we need to. PROMPT, if
+ non-null, is a prompt to print before reading the line. */
+char *
+info_read_in_echo_area (window, prompt)
+ WINDOW *window;
+ char *prompt;
+{
+ char *line;
+
+ /* If the echo area is already active, remember the current state. */
+ if (echo_area_is_active)
+ push_echo_area ();
+
+ /* Initialize our local variables. */
+ initialize_input_line (prompt);
+
+ /* Initialize the echo area for the first (but maybe not the last) time. */
+ echo_area_initialize_node ();
+
+ /* Save away the original node of this window, and the window itself,
+ so echo area commands can temporarily use this window. */
+ remember_calling_window (window);
+
+ /* Let the rest of Info know that the echo area is active. */
+ echo_area_is_active++;
+ active_window = the_echo_area;
+
+ /* Read characters in the echo area. */
+ info_read_and_dispatch ();
+
+ echo_area_is_active--;
+
+ /* Restore the original active window and show point in it. */
+ active_window = calling_window;
+ restore_calling_window ();
+ display_cursor_at_point (active_window);
+ fflush (stdout);
+
+ /* Get the value of the line. */
+ line = echo_area_after_read ();
+
+ /* If there is a previous loop waiting for us, restore it now. */
+ if (echo_area_is_active)
+ pop_echo_area ();
+
+ /* Return the results to the caller. */
+ return (line);
+}
+
+/* (re) Initialize the echo area node. */
+static void
+echo_area_initialize_node ()
+{
+ register int i;
+
+ for (i = input_line_end; i < sizeof (input_line); i++)
+ input_line[i] = ' ';
+
+ input_line[i - 1] = '\n';
+ window_set_node_of_window (the_echo_area, &input_line_node);
+ input_line[input_line_end] = '\n';
+}
+
+/* Prepare to read characters in the echo area. This can initialize the
+ echo area node, but its primary purpose is to side effect the input
+ line buffer contents. */
+void
+echo_area_prep_read ()
+{
+ if (the_echo_area->node != &input_line_node)
+ echo_area_initialize_node ();
+
+ the_echo_area->point = input_line_point;
+ input_line[input_line_end] = '\n';
+ display_update_one_window (the_echo_area);
+ display_cursor_at_point (active_window);
+}
+
+
+/* **************************************************************** */
+/* */
+/* Echo Area Movement Commands */
+/* */
+/* **************************************************************** */
+
+DECLARE_INFO_COMMAND (ea_forward, "Move forward a character")
+{
+ if (count < 0)
+ ea_backward (window, -count, key);
+ else
+ {
+ input_line_point += count;
+ if (input_line_point > input_line_end)
+ input_line_point = input_line_end;
+ }
+}
+
+DECLARE_INFO_COMMAND (ea_backward, "Move backward a character")
+{
+ if (count < 0)
+ ea_forward (window, -count, key);
+ else
+ {
+ input_line_point -= count;
+ if (input_line_point < input_line_beg)
+ input_line_point = input_line_beg;
+ }
+}
+
+DECLARE_INFO_COMMAND (ea_beg_of_line, "Move to the start of this line")
+{
+ input_line_point = input_line_beg;
+}
+
+DECLARE_INFO_COMMAND (ea_end_of_line, "Move to the end of this line")
+{
+ input_line_point = input_line_end;
+}
+
+#define alphabetic(c) (islower (c) || isupper (c) || isdigit (c))
+
+/* Move forward a word in the input line. */
+DECLARE_INFO_COMMAND (ea_forward_word, "Move forward a word")
+{
+ int c;
+
+ if (count < 0)
+ ea_backward_word (window, -count, key);
+ else
+ {
+ while (count--)
+ {
+ if (input_line_point == input_line_end)
+ return;
+
+ /* If we are not in a word, move forward until we are in one.
+ Then, move forward until we hit a non-alphabetic character. */
+ c = input_line[input_line_point];
+
+ if (!alphabetic (c))
+ {
+ while (++input_line_point < input_line_end)
+ {
+ c = input_line[input_line_point];
+ if (alphabetic (c))
+ break;
+ }
+ }
+
+ if (input_line_point == input_line_end)
+ return;
+
+ while (++input_line_point < input_line_end)
+ {
+ c = input_line[input_line_point];
+ if (!alphabetic (c))
+ break;
+ }
+ }
+ }
+}
+
+DECLARE_INFO_COMMAND (ea_backward_word, "Move backward a word")
+{
+ int c;
+
+ if (count < 0)
+ ea_forward_word (window, -count, key);
+ else
+ {
+ while (count--)
+ {
+ if (input_line_point == input_line_beg)
+ return;
+
+ /* Like ea_forward_word (), except that we look at the
+ characters just before point. */
+
+ c = input_line[input_line_point - 1];
+
+ if (!alphabetic (c))
+ {
+ while ((--input_line_point) != input_line_beg)
+ {
+ c = input_line[input_line_point - 1];
+ if (alphabetic (c))
+ break;
+ }
+ }
+
+ while (input_line_point != input_line_beg)
+ {
+ c = input_line[input_line_point - 1];
+ if (!alphabetic (c))
+ break;
+ else
+ --input_line_point;
+ }
+ }
+ }
+}
+
+DECLARE_INFO_COMMAND (ea_delete, "Delete the character under the cursor")
+{
+ register int i;
+
+ if (count < 0)
+ ea_rubout (window, -count, key);
+ else
+ {
+ if (input_line_point == input_line_end)
+ return;
+
+ if (info_explicit_arg || count > 1)
+ {
+ int orig_point;
+
+ orig_point = input_line_point;
+ ea_forward (window, count, key);
+ ea_kill_text (orig_point, input_line_point);
+ input_line_point = orig_point;
+ }
+ else
+ {
+ for (i = input_line_point; i < input_line_end; i++)
+ input_line[i] = input_line[i + 1];
+
+ input_line_end--;
+ }
+ }
+}
+
+DECLARE_INFO_COMMAND (ea_rubout, "Delete the character behind the cursor")
+{
+ if (count < 0)
+ ea_delete (window, -count, key);
+ else
+ {
+ int start;
+
+ if (input_line_point == input_line_beg)
+ return;
+
+ start = input_line_point;
+ ea_backward (window, count, key);
+
+ if (info_explicit_arg || count > 1)
+ ea_kill_text (start, input_line_point);
+ else
+ ea_delete (window, count, key);
+ }
+}
+
+DECLARE_INFO_COMMAND (ea_abort, "Cancel or quit operation")
+{
+ /* If any text, just discard it, and restore the calling window's node.
+ If no text, quit. */
+ if (input_line_end != input_line_beg)
+ {
+ terminal_ring_bell ();
+ input_line_end = input_line_point = input_line_beg;
+ if (calling_window->node != calling_window_node)
+ restore_calling_window ();
+ }
+ else
+ info_aborted_echo_area = 1;
+}
+
+DECLARE_INFO_COMMAND (ea_newline, "Accept (or force completion of) this line")
+{
+ /* Stub does nothing. Simply here to see if it has been executed. */
+}
+
+DECLARE_INFO_COMMAND (ea_quoted_insert, "Insert next character verbatim")
+{
+ unsigned char character;
+
+ character = info_get_another_input_char ();
+ ea_insert (window, count, character);
+}
+
+DECLARE_INFO_COMMAND (ea_insert, "Insert this character")
+{
+ register int i;
+
+ if ((input_line_end + 1) == EA_MAX_INPUT)
+ {
+ terminal_ring_bell ();
+ return;
+ }
+
+ for (i = input_line_end + 1; i != input_line_point; i--)
+ input_line[i] = input_line[i - 1];
+
+ input_line[input_line_point] = key;
+ input_line_point++;
+ input_line_end++;
+}
+
+DECLARE_INFO_COMMAND (ea_tab_insert, "Insert a TAB character")
+{
+ ea_insert (window, count, '\t');
+}
+
+/* Transpose the characters at point. If point is at the end of the line,
+ then transpose the characters before point. */
+DECLARE_INFO_COMMAND (ea_transpose_chars, "Transpose characters at point")
+{
+ /* Handle conditions that would make it impossible to transpose
+ characters. */
+ if (!count || !input_line_point || (input_line_end - input_line_beg) < 2)
+ return;
+
+ while (count)
+ {
+ int t;
+ if (input_line_point == input_line_end)
+ {
+ t = input_line[input_line_point - 1];
+
+ input_line[input_line_point - 1] = input_line[input_line_point - 2];
+ input_line[input_line_point - 2] = t;
+ }
+ else
+ {
+ t = input_line[input_line_point];
+
+ input_line[input_line_point] = input_line[input_line_point - 1];
+ input_line[input_line_point - 1] = t;
+
+ if (count < 0 && input_line_point != input_line_beg)
+ input_line_point--;
+ else
+ input_line_point++;
+ }
+
+ if (count < 0)
+ count++;
+ else
+ count--;
+ }
+}
+
+/* **************************************************************** */
+/* */
+/* Echo Area Killing and Yanking */
+/* */
+/* **************************************************************** */
+
+static char **kill_ring = (char **)NULL;
+static int kill_ring_index = 0; /* Number of kills appearing in KILL_RING. */
+static int kill_ring_slots = 0; /* Number of slots allocated to KILL_RING. */
+static int kill_ring_loc = 0; /* Location of current yank pointer. */
+
+/* The largest number of kills that we remember at one time. */
+static int max_retained_kills = 15;
+
+DECLARE_INFO_COMMAND (ea_yank, "Yank back the contents of the last kill")
+{
+ register int i;
+ register char *text;
+
+ if (!kill_ring_index)
+ {
+ inform_in_echo_area ("Kill ring is empty");
+ return;
+ }
+
+ text = kill_ring[kill_ring_loc];
+
+ for (i = 0; text[i]; i++)
+ ea_insert (window, 1, text[i]);
+}
+
+/* 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. */
+DECLARE_INFO_COMMAND (ea_yank_pop, "Yank back a previous kill")
+{
+ register int len;
+
+ if (((ea_last_executed_command != ea_yank) &&
+ (ea_last_executed_command != ea_yank_pop)) ||
+ (kill_ring_index == 0))
+ return;
+
+ len = strlen (kill_ring[kill_ring_loc]);
+
+ /* Delete the last yanked item from the line. */
+ {
+ register int i, counter;
+
+ counter = input_line_end - input_line_point;
+
+ for (i = input_line_point - len; counter; i++, counter--)
+ input_line[i] = input_line[i + len];
+
+ input_line_end -= len;
+ input_line_point -= len;
+ }
+
+ /* Get a previous kill, and yank that. */
+ kill_ring_loc--;
+ if (kill_ring_loc < 0)
+ kill_ring_loc = kill_ring_index - 1;
+
+ ea_yank (window, count, key);
+}
+
+/* Delete the text from point to end of line. */
+DECLARE_INFO_COMMAND (ea_kill_line, "Kill to the end of the line")
+{
+ if (count < 0)
+ {
+ ea_kill_text (input_line_point, input_line_beg);
+ input_line_point = input_line_beg;
+ }
+ else
+ ea_kill_text (input_line_point, input_line_end);
+}
+
+/* Delete the text from point to beg of line. */
+DECLARE_INFO_COMMAND (ea_backward_kill_line,
+ "Kill to the beginning of the line")
+{
+ if (count < 0)
+ ea_kill_text (input_line_point, input_line_end);
+ else
+ {
+ ea_kill_text (input_line_point, input_line_beg);
+ input_line_point = input_line_beg;
+ }
+}
+
+/* Delete from point to the end of the current word. */
+DECLARE_INFO_COMMAND (ea_kill_word, "Kill the word following the cursor")
+{
+ int orig_point = input_line_point;
+
+ if (count < 0)
+ ea_backward_kill_word (window, -count, key);
+ else
+ {
+ ea_forward_word (window, count, key);
+
+ if (input_line_point != orig_point)
+ ea_kill_text (orig_point, input_line_point);
+
+ input_line_point = orig_point;
+ }
+}
+
+/* Delete from point to the start of the current word. */
+DECLARE_INFO_COMMAND (ea_backward_kill_word,
+ "Kill the word preceding the cursor")
+{
+ int orig_point = input_line_point;
+
+ if (count < 0)
+ ea_kill_word (window, -count, key);
+ else
+ {
+ ea_backward_word (window, count, key);
+
+ if (input_line_point != orig_point)
+ ea_kill_text (orig_point, input_line_point);
+ }
+}
+
+/* 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 killed text is appended to the most recent kill,
+ otherwise it is prepended. If the last command was not a kill command,
+ then a new slot is made for this kill. */
+static void
+ea_kill_text (from, to)
+ int from, to;
+{
+ register int i, counter, distance;
+ int killing_backwards, slot;
+ char *killed_text;
+
+ killing_backwards = (from > to);
+
+ /* If killing backwards, reverse the values of FROM and TO. */
+ if (killing_backwards)
+ {
+ int temp = from;
+ from = to;
+ to = temp;
+ }
+
+ /* Remember the text that we are about to delete. */
+ distance = to - from;
+ killed_text = (char *)xmalloc (1 + distance);
+ strncpy (killed_text, &input_line[from], distance);
+ killed_text[distance] = '\0';
+
+ /* Actually delete the text from the line. */
+ counter = input_line_end - to;
+
+ for (i = from; counter; i++, counter--)
+ input_line[i] = input_line[i + distance];
+
+ input_line_end -= distance;
+
+ /* If the last command was a kill, append or prepend the killed text to
+ the last command's killed text. */
+ if (echo_area_last_command_was_kill)
+ {
+ char *old, *new;
+
+ slot = kill_ring_loc;
+ old = kill_ring[slot];
+ new = (char *)xmalloc (1 + strlen (old) + strlen (killed_text));
+
+ if (killing_backwards)
+ {
+ /* Prepend TEXT to current kill. */
+ strcpy (new, killed_text);
+ strcat (new, old);
+ }
+ else
+ {
+ /* Append TEXT to current kill. */
+ strcpy (new, old);
+ strcat (new, killed_text);
+ }
+
+ free (old);
+ free (killed_text);
+ kill_ring[slot] = new;
+ }
+ else
+ {
+ /* Try to store the kill in a new slot, unless that would cause there
+ to be too many remembered kills. */
+ slot = kill_ring_index;
+
+ if (slot == max_retained_kills)
+ slot = 0;
+
+ if (slot + 1 > kill_ring_slots)
+ kill_ring = (char **) xrealloc
+ (kill_ring,
+ (kill_ring_slots += max_retained_kills) * sizeof (char *));
+
+ if (slot != kill_ring_index)
+ free (kill_ring[slot]);
+ else
+ kill_ring_index++;
+
+ kill_ring[slot] = killed_text;
+
+ kill_ring_loc = slot;
+ }
+
+ /* Notice that the last command was a kill. */
+ echo_area_last_command_was_kill++;
+}
+
+/* **************************************************************** */
+/* */
+/* Echo Area Completion */
+/* */
+/* **************************************************************** */
+
+/* Pointer to an array of REFERENCE to complete over. */
+static REFERENCE **echo_area_completion_items = (REFERENCE **)NULL;
+
+/* Sorted array of REFERENCE * which is the possible completions found in
+ the variable echo_area_completion_items. If there is only one element,
+ it is the only possible completion. */
+static REFERENCE **completions_found = (REFERENCE **)NULL;
+static int completions_found_index = 0;
+static int completions_found_slots = 0;
+
+/* The lowest common denominator found while completing. */
+static REFERENCE *LCD_completion;
+
+/* Internal functions used by the user calls. */
+static void build_completions (), completions_must_be_rebuilt ();
+
+/* Variable which holds the output of completions. */
+static NODE *possible_completions_output_node = (NODE *)NULL;
+
+static char *compwin_name = "*Completions*";
+
+/* Return non-zero if WINDOW is a window used for completions output. */
+static int
+completions_window_p (window)
+ WINDOW *window;
+{
+ int result = 0;
+
+ if (internal_info_node_p (window->node) &&
+ (strcmp (window->node->nodename, compwin_name) == 0))
+ result = 1;
+
+ return (result);
+}
+
+/* Workhorse for completion readers. If FORCE is non-zero, the user cannot
+ exit unless the line read completes, or is empty. */
+char *
+info_read_completing_internal (window, prompt, completions, force)
+ WINDOW *window;
+ char *prompt;
+ REFERENCE **completions;
+ int force;
+{
+ char *line;
+
+ /* If the echo area is already active, remember the current state. */
+ if (echo_area_is_active)
+ push_echo_area ();
+
+ echo_area_must_complete_p = force;
+
+ /* Initialize our local variables. */
+ initialize_input_line (prompt);
+
+ /* Initialize the echo area for the first (but maybe not the last) time. */
+ echo_area_initialize_node ();
+
+ /* Save away the original node of this window, and the window itself,
+ so echo area commands can temporarily use this window. */
+ remember_calling_window (window);
+
+ /* Save away the list of items to complete over. */
+ echo_area_completion_items = completions;
+ completions_must_be_rebuilt ();
+
+ active_window = the_echo_area;
+ echo_area_is_active++;
+
+ /* Read characters in the echo area. */
+ while (1)
+ {
+ info_read_and_dispatch ();
+
+ line = echo_area_after_read ();
+
+ /* Force the completion to take place if the user hasn't accepted
+ a default or aborted, and if FORCE is active. */
+ if (force && line && *line && completions)
+ {
+ register int i;
+
+ build_completions ();
+
+ /* If there is only one completion, then make the line be that
+ completion. */
+ if (completions_found_index == 1)
+ {
+ free (line);
+ line = strdup (completions_found[0]->label);
+ break;
+ }
+
+ /* If one of the completions matches exactly, then that is okay, so
+ return the current line. */
+ for (i = 0; i < completions_found_index; i++)
+ if (strcasecmp (completions_found[i]->label, line) == 0)
+ {
+ free (line);
+ line = strdup (completions_found[i]->label);
+ break;
+ }
+
+ /* If no match, go back and try again. */
+ if (i == completions_found_index)
+ {
+ inform_in_echo_area ("Not complete");
+ continue;
+ }
+ }
+ break;
+ }
+ echo_area_is_active--;
+
+ /* Restore the original active window and show point in it. */
+ active_window = calling_window;
+ restore_calling_window ();
+ display_cursor_at_point (active_window);
+ fflush (stdout);
+
+ echo_area_completion_items = (REFERENCE **)NULL;
+ completions_must_be_rebuilt ();
+
+ /* If there is a previous loop waiting for us, restore it now. */
+ if (echo_area_is_active)
+ pop_echo_area ();
+
+ return (line);
+}
+
+/* Read a line in the echo area with completion over COMPLETIONS. */
+char *
+info_read_completing_in_echo_area (window, prompt, completions)
+ WINDOW *window;
+ char *prompt;
+ REFERENCE **completions;
+{
+ return (info_read_completing_internal (window, prompt, completions, 1));
+}
+
+/* Read a line in the echo area allowing completion over COMPLETIONS, but
+ not requiring it. */
+char *
+info_read_maybe_completing (window, prompt, completions)
+ WINDOW *window;
+ char *prompt;
+ REFERENCE **completions;
+{
+ return (info_read_completing_internal (window, prompt, completions, 0));
+}
+
+DECLARE_INFO_COMMAND (ea_possible_completions, "List possible completions")
+{
+ if (!echo_area_completion_items)
+ {
+ ea_insert (window, count, key);
+ return;
+ }
+
+ build_completions ();
+
+ if (!completions_found_index)
+ {
+ terminal_ring_bell ();
+ inform_in_echo_area ("No completions");
+ }
+ else if ((completions_found_index == 1) && (key != '?'))
+ {
+ inform_in_echo_area ("Sole completion");
+ }
+ else
+ {
+ register int i, l;
+ int limit, count, max_label = 0;
+
+ initialize_message_buffer ();
+ printf_to_message_buffer
+ ("There %s %d ", completions_found_index == 1 ? "is" : "are",
+ completions_found_index);
+ printf_to_message_buffer
+ ("completion%s:\n", completions_found_index == 1 ? "" : "s");
+
+ /* Find the maximum length of a label. */
+ for (i = 0; i < completions_found_index; i++)
+ {
+ int len = strlen (completions_found[i]->label);
+ if (len > max_label)
+ max_label = len;
+ }
+
+ max_label += 4;
+
+ /* Find out how many columns we should print in. */
+ limit = calling_window->width / max_label;
+ if (limit != 1 && (limit * max_label == calling_window->width))
+ limit--;
+
+ /* Avoid a possible floating exception. If max_label > width then
+ the limit will be 0 and a divide-by-zero fault will result. */
+ if (limit == 0)
+ limit = 1;
+
+ /* How many iterations of the printing loop? */
+ count = (completions_found_index + (limit - 1)) / limit;
+
+ /* Watch out for special case. If the number of completions is less
+ than LIMIT, then just do the inner printing loop. */
+ if (completions_found_index < limit)
+ count = 1;
+
+ /* Print the sorted items, up-and-down alphabetically. */
+ for (i = 0; i < count; i++)
+ {
+ register int j;
+
+ for (j = 0, l = i; j < limit; j++)
+ {
+ if (l >= completions_found_index)
+ break;
+ else
+ {
+ char *label;
+ int printed_length, k;
+
+ label = completions_found[l]->label;
+ printed_length = strlen (label);
+ printf_to_message_buffer ("%s", label);
+
+ if (j + 1 < limit)
+ {
+ for (k = 0; k < max_label - printed_length; k++)
+ printf_to_message_buffer (" ");
+ }
+ }
+ l += count;
+ }
+ printf_to_message_buffer ("\n");
+ }
+
+ /* Make a new node to hold onto possible completions. Don't destroy
+ dangling pointers. */
+ {
+ NODE *temp;
+
+ temp = message_buffer_to_node ();
+ add_gcable_pointer (temp->contents);
+ name_internal_node (temp, compwin_name);
+ possible_completions_output_node = temp;
+ }
+
+ /* Find a suitable window for displaying the completions output.
+ First choice is an existing window showing completions output.
+ If there is only one window, and it is large, make another
+ (smaller) window, and use that one. Otherwise, use the caller's
+ window. */
+ {
+ WINDOW *compwin;
+
+ compwin = get_internal_info_window (compwin_name);
+
+ if (!compwin)
+ {
+ /* If we can split the window to display most of the completion
+ items, then do so. */
+ if (calling_window->height > (count * 2))
+ {
+ int start, end, pagetop;
+
+ active_window = calling_window;
+
+ /* Perhaps we can scroll this window on redisplay. */
+ start = calling_window->first_row;
+ pagetop = calling_window->pagetop;
+
+ compwin =
+ window_make_window (possible_completions_output_node);
+ active_window = the_echo_area;
+ window_change_window_height
+ (compwin, -(compwin->height - (count + 2)));
+
+ window_adjust_pagetop (calling_window);
+ remember_calling_window (calling_window);
+
+#if defined (SPLIT_BEFORE_ACTIVE)
+ /* If the pagetop hasn't changed, scrolling the calling
+ window is a reasonable thing to do. */
+ if (pagetop == calling_window->pagetop)
+ {
+ end = start + calling_window->height;
+ display_scroll_display
+ (start, end, calling_window->prev->height + 1);
+ }
+#else /* !SPLIT_BEFORE_ACTIVE */
+ /* If the pagetop has changed, set the new pagetop here. */
+ if (pagetop != calling_window->pagetop)
+ {
+ int newtop = calling_window->pagetop;
+ calling_window->pagetop = pagetop;
+ set_window_pagetop (calling_window, newtop);
+ }
+#endif /* !SPLIT_BEFORE_ACTIVE */
+
+ echo_area_completions_window = compwin;
+ remember_window_and_node (compwin, compwin->node);
+ }
+ else
+ compwin = calling_window;
+ }
+
+ if (compwin->node != possible_completions_output_node)
+ {
+ window_set_node_of_window
+ (compwin, possible_completions_output_node);
+ remember_window_and_node (compwin, compwin->node);
+ }
+
+ display_update_display (windows);
+ }
+ }
+}
+
+DECLARE_INFO_COMMAND (ea_complete, "Insert completion")
+{
+ if (!echo_area_completion_items)
+ {
+ ea_insert (window, count, key);
+ return;
+ }
+
+ /* If KEY is SPC, and we are not forcing completion to take place, simply
+ insert the key. */
+ if (!echo_area_must_complete_p && key == SPC)
+ {
+ ea_insert (window, count, key);
+ return;
+ }
+
+ if (ea_last_executed_command == ea_complete)
+ {
+ /* If the keypress is a SPC character, and we have already tried
+ completing once, and there are several completions, then check
+ the batch of completions to see if any continue with a space.
+ If there are some, insert the space character and continue. */
+ if (key == SPC && completions_found_index > 1)
+ {
+ register int i, offset;
+
+ offset = input_line_end - input_line_beg;
+
+ for (i = 0; i < completions_found_index; i++)
+ if (completions_found[i]->label[offset] == ' ')
+ break;
+
+ if (completions_found[i])
+ ea_insert (window, 1, ' ');
+ else
+ {
+ ea_possible_completions (window, count, key);
+ return;
+ }
+ }
+ else
+ {
+ ea_possible_completions (window, count, key);
+ return;
+ }
+ }
+
+ input_line_point = input_line_end;
+ build_completions ();
+
+ if (!completions_found_index)
+ terminal_ring_bell ();
+ else if (LCD_completion->label[0] == '\0')
+ ea_possible_completions (window, count, key);
+ else
+ {
+ register int i;
+ input_line_point = input_line_end = input_line_beg;
+ for (i = 0; LCD_completion->label[i]; i++)
+ ea_insert (window, 1, LCD_completion->label[i]);
+ }
+}
+
+/* Utility REFERENCE used to store possible LCD. */
+static REFERENCE LCD_reference = { (char *)NULL, (char *)NULL, (char *)NULL };
+
+static void remove_completion_duplicates ();
+
+/* Variables which remember the state of the most recent call
+ to build_completions (). */
+static char *last_completion_request = (char *)NULL;
+static REFERENCE **last_completion_items = (REFERENCE **)NULL;
+
+/* How to tell the completion builder to reset internal state. */
+static void
+completions_must_be_rebuilt ()
+{
+ maybe_free (last_completion_request);
+ last_completion_request = (char *)NULL;
+ last_completion_items = (REFERENCE **)NULL;
+}
+
+/* Build a list of possible completions from echo_area_completion_items,
+ and the contents of input_line. */
+static void
+build_completions ()
+{
+ register int i, len;
+ register REFERENCE *entry;
+ char *request;
+ int informed_of_lengthy_job = 0;
+
+ /* If there are no items to complete over, exit immediately. */
+ if (!echo_area_completion_items)
+ {
+ completions_found_index = 0;
+ LCD_completion = (REFERENCE *)NULL;
+ return;
+ }
+
+ /* Check to see if this call to build completions is the same as the last
+ call to build completions. */
+ len = input_line_end - input_line_beg;
+ request = (char *)xmalloc (1 + len);
+ strncpy (request, &input_line[input_line_beg], len);
+ request[len] = '\0';
+
+ if (last_completion_request && last_completion_items &&
+ last_completion_items == echo_area_completion_items &&
+ (strcmp (last_completion_request, request) == 0))
+ {
+ free (request);
+ return;
+ }
+
+ maybe_free (last_completion_request);
+ last_completion_request = request;
+ last_completion_items = echo_area_completion_items;
+
+ /* Always start at the beginning of the list. */
+ completions_found_index = 0;
+ LCD_completion = (REFERENCE *)NULL;
+
+ for (i = 0; entry = echo_area_completion_items[i]; i++)
+ {
+ if (strncasecmp (request, entry->label, len) == 0)
+ add_pointer_to_array (entry, completions_found_index,
+ completions_found, completions_found_slots,
+ 20, REFERENCE *);
+
+ if (!informed_of_lengthy_job && completions_found_index > 100)
+ {
+ informed_of_lengthy_job = 1;
+ window_message_in_echo_area ("Building completions...");
+ }
+ }
+
+ if (!completions_found_index)
+ return;
+
+ /* Sort and prune duplicate entries from the completions array. */
+ remove_completion_duplicates ();
+
+ /* If there is only one completion, just return that. */
+ if (completions_found_index == 1)
+ {
+ LCD_completion = completions_found[0];
+ return;
+ }
+
+ /* Find the least common denominator. */
+ {
+ long shortest = 100000;
+
+ for (i = 1; i < completions_found_index; i++)
+ {
+ register int j;
+ int c1, c2;
+
+ for (j = 0;
+ (c1 = info_tolower (completions_found[i - 1]->label[j])) &&
+ (c2 = info_tolower (completions_found[i]->label[j]));
+ j++)
+ if (c1 != c2)
+ break;
+
+ if (shortest > j)
+ shortest = j;
+ }
+
+ maybe_free (LCD_reference.label);
+ LCD_reference.label = (char *)xmalloc (1 + shortest);
+ strncpy (LCD_reference.label, completions_found[0]->label, shortest);
+ LCD_reference.label[shortest] = '\0';
+ LCD_completion = &LCD_reference;
+ }
+
+ if (informed_of_lengthy_job)
+ echo_area_initialize_node ();
+}
+
+/* Function called by qsort. */
+static int
+compare_references (entry1, entry2)
+ REFERENCE **entry1, **entry2;
+{
+ return (strcasecmp ((*entry1)->label, (*entry2)->label));
+}
+
+/* Prune duplicate entries from COMPLETIONS_FOUND. */
+static void
+remove_completion_duplicates ()
+{
+ register int i, j;
+ REFERENCE **temp;
+ int newlen;
+
+ if (!completions_found_index)
+ return;
+
+ /* Sort the items. */
+ qsort (completions_found, completions_found_index, sizeof (REFERENCE *),
+ compare_references);
+
+ for (i = 0, newlen = 1; i < completions_found_index - 1; i++)
+ {
+ if (strcmp (completions_found[i]->label,
+ completions_found[i + 1]->label) == 0)
+ completions_found[i] = (REFERENCE *)NULL;
+ else
+ newlen++;
+ }
+
+ /* We have marked all the dead slots. It is faster to copy the live slots
+ twice than to prune the dead slots one by one. */
+ temp = (REFERENCE **)xmalloc ((1 + newlen) * sizeof (REFERENCE *));
+ for (i = 0, j = 0; i < completions_found_index; i++)
+ if (completions_found[i])
+ temp[j++] = completions_found[i];
+
+ for (i = 0; i < newlen; i++)
+ completions_found[i] = temp[i];
+
+ completions_found[i] = (REFERENCE *)NULL;
+ completions_found_index = newlen;
+ free (temp);
+}
+
+/* Scroll the "other" window. If there is a window showing completions, scroll
+ that one, otherwise scroll the window which was active on entering the read
+ function. */
+DECLARE_INFO_COMMAND (ea_scroll_completions_window, "Scroll the completions window")
+{
+ WINDOW *compwin;
+ int old_pagetop;
+
+ compwin = get_internal_info_window (compwin_name);
+
+ if (!compwin)
+ compwin = calling_window;
+
+ old_pagetop = compwin->pagetop;
+
+ /* Let info_scroll_forward () do the work, and print any messages that
+ need to be displayed. */
+ info_scroll_forward (compwin, count, key);
+}
+
+/* Function which gets called when an Info window is deleted while the
+ echo area is active. WINDOW is the window which has just been deleted. */
+void
+echo_area_inform_of_deleted_window (window)
+ WINDOW *window;
+{
+ /* If this is the calling_window, forget what we remembered about it. */
+ if (window == calling_window)
+ {
+ if (active_window != the_echo_area)
+ remember_calling_window (active_window);
+ else
+ remember_calling_window (windows);
+ }
+
+ /* If this window was the echo_area_completions_window, then notice that
+ the window has been deleted. */
+ if (window == echo_area_completions_window)
+ echo_area_completions_window = (WINDOW *)NULL;
+}
+
+/* **************************************************************** */
+/* */
+/* Pushing and Popping the Echo Area */
+/* */
+/* **************************************************************** */
+
+/* Push and Pop the echo area. */
+typedef struct {
+ char *line;
+ char *prompt;
+ REFERENCE **comp_items;
+ int point, beg, end;
+ int must_complete;
+ NODE node;
+ WINDOW *compwin;
+} PUSHED_EA;
+
+static PUSHED_EA **pushed_echo_areas = (PUSHED_EA **)NULL;
+static int pushed_echo_areas_index = 0;
+static int pushed_echo_areas_slots = 0;
+
+/* Pushing the echo_area has a side effect of zeroing the completion_items. */
+static void
+push_echo_area ()
+{
+ PUSHED_EA *pushed;
+
+ pushed = (PUSHED_EA *)xmalloc (sizeof (PUSHED_EA));
+ pushed->line = strdup (input_line);
+ pushed->prompt = input_line_prompt;
+ pushed->point = input_line_point;
+ pushed->beg = input_line_beg;
+ pushed->end = input_line_end;
+ pushed->node = input_line_node;
+ pushed->comp_items = echo_area_completion_items;
+ pushed->must_complete = echo_area_must_complete_p;
+ pushed->compwin = echo_area_completions_window;
+
+ add_pointer_to_array (pushed, pushed_echo_areas_index, pushed_echo_areas,
+ pushed_echo_areas_slots, 4, PUSHED_EA *);
+
+ echo_area_completion_items = (REFERENCE **)NULL;
+}
+
+static void
+pop_echo_area ()
+{
+ PUSHED_EA *popped;
+
+ popped = pushed_echo_areas[--pushed_echo_areas_index];
+
+ strcpy (input_line, popped->line);
+ free (popped->line);
+ input_line_prompt = popped->prompt;
+ input_line_point = popped->point;
+ input_line_beg = popped->beg;
+ input_line_end = popped->end;
+ input_line_node = popped->node;
+ echo_area_completion_items = popped->comp_items;
+ echo_area_must_complete_p = popped->must_complete;
+ echo_area_completions_window = popped->compwin;
+ completions_must_be_rebuilt ();
+
+ /* If the completion window no longer exists, forget about it. */
+ if (echo_area_completions_window)
+ {
+ register WINDOW *win;
+
+ for (win = windows; win; win = win->next)
+ if (echo_area_completions_window == win)
+ break;
+
+ /* If the window wasn't found, then it has already been deleted. */
+ if (!win)
+ echo_area_completions_window = (WINDOW *)NULL;
+ }
+
+ free (popped);
+}
+
+static int
+echo_area_stack_depth ()
+{
+ return (pushed_echo_areas_index);
+}
+
+/* Returns non-zero if any of the prior stacked calls to read in the echo
+ area produced a completions window. */
+static int
+echo_area_stack_contains_completions_p ()
+{
+ register int i;
+
+ for (i = 0; i < pushed_echo_areas_index; i++)
+ if (pushed_echo_areas[i]->compwin)
+ return (1);
+
+ return (0);
+}
+
+/* **************************************************************** */
+/* */
+/* Error Messages While Reading in Echo Area */
+/* */
+/* **************************************************************** */
+
+#if defined (HAVE_SYS_TIME_H)
+# include <sys/time.h>
+# define HAVE_STRUCT_TIMEVAL
+#endif /* HAVE_SYS_TIME_H */
+
+static void
+pause_or_input ()
+{
+#if defined (FD_SET)
+ struct timeval timer;
+ fd_set readfds;
+ int ready;
+
+ FD_ZERO (&readfds);
+ FD_SET (fileno (stdin), &readfds);
+ timer.tv_sec = 2;
+ timer.tv_usec = 750;
+ ready = select (1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer);
+#endif /* FD_SET */
+}
+
+/* Print MESSAGE right after the end of the current line, and wait
+ for input or 2.75 seconds, whichever comes first. Then flush the
+ informational message that was printed. */
+void
+inform_in_echo_area (message)
+ char *message;
+{
+ register int i;
+ char *text;
+
+ text = strdup (message);
+ for (i = 0; text[i] && text[i] != '\n'; i++);
+ text[i] = '\0';
+
+ echo_area_initialize_node ();
+ sprintf (&input_line[input_line_end], "%s[%s]\n",
+ echo_area_is_active ? " ": "", text);
+ free (text);
+ the_echo_area->point = input_line_point;
+ display_update_one_window (the_echo_area);
+ display_cursor_at_point (active_window);
+ fflush (stdout);
+ pause_or_input ();
+ echo_area_initialize_node ();
+}
diff --git a/gnu/usr.bin/texinfo/info/echo_area.h b/gnu/usr.bin/texinfo/info/echo_area.h
new file mode 100644
index 00000000000..09c2bc7e22e
--- /dev/null
+++ b/gnu/usr.bin/texinfo/info/echo_area.h
@@ -0,0 +1,63 @@
+/* echo_area.h -- Functions used in reading information from the echo area. */
+
+/* This file is part of GNU Info, a program for reading online documentation
+ stored in Info format.
+
+ Copyright (C) 1993 Free Software Foundation, Inc.
+
+ 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 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Written by Brian Fox (bfox@ai.mit.edu). */
+
+#if !defined (_ECHO_AREA_H_)
+#define _ECHO_AREA_H_
+
+#define EA_MAX_INPUT 256
+
+extern int echo_area_is_active, info_aborted_echo_area;
+
+/* Non-zero means that the last command executed while reading input
+ killed some text. */
+extern int echo_area_last_command_was_kill;
+
+extern void inform_in_echo_area (), echo_area_inform_of_deleted_window ();
+extern void echo_area_prep_read ();
+extern VFunction *ea_last_executed_command;
+
+/* Read a line of text in the echo area. Return a malloc ()'ed string,
+ or NULL if the user aborted out of this read. WINDOW is the currently
+ active window, so that we can restore it when we need to. PROMPT, if
+ non-null, is a prompt to print before reading the line. */
+extern char *info_read_in_echo_area ();
+
+/* Read a line in the echo area with completion over COMPLETIONS.
+ Takes arguments of WINDOW, PROMPT, and COMPLETIONS, a REFERENCE **. */
+char *info_read_completing_in_echo_area ();
+
+/* Read a line in the echo area allowing completion over COMPLETIONS, but
+ not requiring it. Takes arguments of WINDOW, PROMPT, and COMPLETIONS,
+ a REFERENCE **. */
+extern char *info_read_maybe_completing ();
+
+extern void ea_insert (), ea_quoted_insert ();
+extern void ea_beg_of_line (), ea_backward (), ea_delete (), ea_end_of_line ();
+extern void ea_forward (), ea_abort (), ea_rubout (), ea_complete ();
+extern void ea_newline (), ea_kill_line (), ea_transpose_chars ();
+extern void ea_yank (), ea_tab_insert (), ea_possible_completions ();
+extern void ea_backward_word (), ea_kill_word (), ea_forward_word ();
+extern void ea_yank_pop (), ea_backward_kill_word ();
+extern void ea_scroll_completions_window ();
+
+#endif /* _ECHO_AREA_H_ */
diff --git a/gnu/usr.bin/texinfo/info/filesys.c b/gnu/usr.bin/texinfo/info/filesys.c
index a2dde47fd51..5cf455f22b1 100644
--- a/gnu/usr.bin/texinfo/info/filesys.c
+++ b/gnu/usr.bin/texinfo/info/filesys.c
@@ -1,7 +1,7 @@
/* filesys.c -- filesystem specific functions.
- $Id: filesys.c,v 1.3 2000/02/09 02:18:39 espie Exp $
+ $Id: filesys.c,v 1.4 2002/06/10 13:51:03 espie Exp $
- Copyright (C) 1993, 97, 98 Free Software Foundation, Inc.
+ Copyright (C) 1993, 97, 98, 2000 Free Software Foundation, Inc.
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
@@ -163,6 +163,11 @@ info_file_in_path (filename, path)
char *temp_dirname;
int statable, dirname_index;
+ /* Reject ridiculous cases up front, to prevent infinite recursion
+ later on. E.g., someone might say "info '(.)foo'"... */
+ if (!*filename || STREQ (filename, ".") || STREQ (filename, ".."))
+ return NULL;
+
dirname_index = 0;
while ((temp_dirname = extract_colon_unit (path, &dirname_index)))
@@ -505,6 +510,7 @@ filesys_read_info_file (pathname, filesize, finfo, is_compressed)
want to waste storage. */
if (*filesize < st_size)
contents = (char *)xrealloc (contents, 1 + *filesize);
+ contents[*filesize] = '\0';
return (contents);
}
@@ -557,7 +563,7 @@ filesys_read_compressed (pathname, filesize, finfo)
/* Read chunks from this file until there are none left to read. */
if (stream)
{
- int offset, size;
+ long offset, size;
char *chunk;
offset = size = 0;
@@ -591,6 +597,7 @@ filesys_read_compressed (pathname, filesize, finfo)
{
*filesize = convert_eols (contents, offset);
contents = (char *)xrealloc (contents, 1 + *filesize);
+ contents[*filesize] = '\0';
}
}
else
@@ -689,25 +696,34 @@ filesys_error_string (filename, error_num)
}
-/* Check for FILENAME eq "dir" first, then all the compression
- suffixes. */
+/* Check for "dir" with all the possible info and compression suffixes,
+ in combination. */
int
is_dir_name (filename)
char *filename;
{
unsigned i;
- if (strcasecmp (filename, "dir") == 0)
- return 1;
-
- for (i = 0; compress_suffixes[i].suffix; i++)
+
+ for (i = 0; info_suffixes[i]; i++)
{
- char dir_compressed[50]; /* can be short */
- strcpy (dir_compressed, "dir");
- strcat (dir_compressed, compress_suffixes[i].suffix);
- if (strcasecmp (filename, dir_compressed) == 0)
+ unsigned c;
+ char trydir[50];
+ strcpy (trydir, "dir");
+ strcat (trydir, info_suffixes[i]);
+
+ if (strcasecmp (filename, trydir) == 0)
return 1;
- }
-
+
+ for (c = 0; compress_suffixes[c].suffix; c++)
+ {
+ char dir_compressed[50]; /* can be short */
+ strcpy (dir_compressed, trydir);
+ strcat (dir_compressed, compress_suffixes[c].suffix);
+ if (strcasecmp (filename, dir_compressed) == 0)
+ return 1;
+ }
+ }
+
return 0;
}
diff --git a/gnu/usr.bin/texinfo/info/general.h b/gnu/usr.bin/texinfo/info/general.h
new file mode 100644
index 00000000000..4b97dc8d8da
--- /dev/null
+++ b/gnu/usr.bin/texinfo/info/general.h
@@ -0,0 +1,94 @@
+/* general.h -- Some generally useful defines. */
+
+/* This file is part of GNU Info, a program for reading online documentation
+ stored in Info format.
+
+ Copyright (C) 1993 Free Software Foundation, Inc.
+
+ 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 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Written by Brian Fox (bfox@ai.mit.edu). */
+
+#if !defined (_GENERAL_H_)
+#define _GENERAL_H_
+
+extern void *xmalloc (), *xrealloc ();
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#if defined (HAVE_STRING_H)
+# include <string.h>
+#else
+# include <strings.h>
+#endif /* !HAVE_STRING_H */
+
+#include "clib.h"
+
+#define info_toupper(x) (islower (x) ? toupper (x) : x)
+#define info_tolower(x) (isupper (x) ? tolower (x) : x)
+
+#if !defined (whitespace)
+# define whitespace(c) ((c == ' ') || (c == '\t'))
+#endif /* !whitespace */
+
+#if !defined (whitespace_or_newline)
+# define whitespace_or_newline(c) (whitespace (c) || (c == '\n'))
+#endif /* !whitespace_or_newline */
+
+#if !defined (__FUNCTION_DEF)
+# define __FUNCTION_DEF
+typedef int Function ();
+typedef void VFunction ();
+typedef char *CFunction ();
+#endif /* _FUNCTION_DEF */
+
+/* Add POINTER to the list of pointers found in ARRAY. SLOTS is the number
+ of slots that have already been allocated. INDEX is the index into the
+ array where POINTER should be added. GROW is the number of slots to grow
+ ARRAY by, in the case that it needs growing. TYPE is a cast of the type
+ of object stored in ARRAY (e.g., NODE_ENTRY *. */
+#define add_pointer_to_array(pointer, idx, array, slots, grow, type) \
+ do { \
+ if (idx + 2 >= slots) \
+ array = (type *)(xrealloc (array, (slots += grow) * sizeof (type))); \
+ array[idx++] = (type)pointer; \
+ array[idx] = (type)NULL; \
+ } while (0)
+
+#define maybe_free(x) do { if (x) free (x); } while (0)
+
+#if !defined (zero_mem) && defined (HAVE_MEMSET)
+# define zero_mem(mem, length) memset (mem, 0, length)
+#endif /* !zero_mem && HAVE_MEMSET */
+
+#if !defined (zero_mem) && defined (HAVE_BZERO)
+# define zero_mem(mem, length) bzero (mem, length)
+#endif /* !zero_mem && HAVE_BZERO */
+
+#if !defined (zero_mem)
+# define zero_mem(mem, length) \
+ do { \
+ register int zi; \
+ register unsigned char *place; \
+ \
+ place = (unsigned char *)mem; \
+ for (zi = 0; zi < length; zi++) \
+ place[zi] = 0; \
+ } while (0)
+#endif /* !zero_mem */
+
+#endif /* !_GENERAL_H_ */
diff --git a/gnu/usr.bin/texinfo/info/indices.c b/gnu/usr.bin/texinfo/info/indices.c
index 21ad7bdf470..e292b859618 100644
--- a/gnu/usr.bin/texinfo/info/indices.c
+++ b/gnu/usr.bin/texinfo/info/indices.c
@@ -1,7 +1,7 @@
/* indices.c -- deal with an Info file index.
- $Id: indices.c,v 1.3 2000/02/09 02:18:39 espie Exp $
+ $Id: indices.c,v 1.4 2002/06/10 13:51:03 espie Exp $
- Copyright (C) 1993, 97, 98, 99 Free Software Foundation, Inc.
+ Copyright (C) 1993, 97, 98, 99, 2002 Free Software Foundation, Inc.
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
@@ -61,7 +61,7 @@ add_index_to_index_nodenames (array, node)
register int i, last;
INDEX_NAME_ASSOC *assoc;
- for (last = 0; array[last]; last++);
+ for (last = 0; array[last + 1]; last++);
assoc = (INDEX_NAME_ASSOC *)xmalloc (sizeof (INDEX_NAME_ASSOC));
assoc->name = xstrdup (node->nodename);
diff --git a/gnu/usr.bin/texinfo/info/info-stnd.texi b/gnu/usr.bin/texinfo/info/info-stnd.texi
new file mode 100644
index 00000000000..0ff5fd7fb28
--- /dev/null
+++ b/gnu/usr.bin/texinfo/info/info-stnd.texi
@@ -0,0 +1,1365 @@
+\input texinfo @c -*-texinfo-*-
+@comment %**start of header
+@setfilename info-stnd.info
+@settitle GNU Info
+@set InfoProgVer 2.11
+@paragraphindent none
+@footnotestyle end
+@synindex vr cp
+@synindex fn cp
+@synindex ky cp
+@comment %**end of header
+@comment $Id: info-stnd.texi,v 1.3 2002/06/10 13:51:03 espie Exp $
+
+@dircategory Texinfo documentation system
+@direntry
+* info program: (info-stnd). Standalone Info-reading program.
+@end direntry
+
+@ifinfo
+This file documents GNU Info, a program for viewing the on-line formatted
+versions of Texinfo files. This documentation is different from the
+documentation for the Info reader that is part of GNU Emacs. If you do
+not know how to use Info, but have a working Info reader, you should
+read that documentation first.
+
+Copyright @copyright{} 1992, 93, 96 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+
+@ignore
+Permission is granted to process this file through TeX and print the
+results, provided the printed document carries a copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+@end ignore
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided also that the
+sections entitled ``Copying'' and ``GNU General Public License'' are
+included exactly as in the original, and provided that the entire
+resulting derived work is distributed under the terms of a permission
+notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation
+approved by the Free Software Foundation.
+@end ifinfo
+
+@titlepage
+@title GNU Info User's Guide
+@subtitle For GNU Info version @value{InfoProgVer}
+@author Brian J. Fox (bfox@@ai.mit.edu)
+@page
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1992, 1993 Free Software Foundation
+
+Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided also that the
+sections entitled ``Copying'' and ``GNU General Public License'' are
+included exactly as in the original, and provided that the entire
+resulting derived work is distributed under the terms of a permission
+notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation
+approved by the Free Software Foundation.
+@end titlepage
+
+@ifinfo
+@node Top, What is Info, (dir), (dir)
+@top The GNU Info Program
+
+This file documents GNU Info, a program for viewing the on-line
+formatted versions of Texinfo files, version @value{InfoProgVer}. This
+documentation is different from the documentation for the Info reader
+that is part of GNU Emacs.
+@end ifinfo
+
+@menu
+* What is Info::
+* Options:: Options you can pass on the command line.
+* Cursor Commands:: Commands which move the cursor within a node.
+* Scrolling Commands:: Commands for moving the node around
+ in a window.
+* Node Commands:: Commands for selecting a new node.
+* Searching Commands:: Commands for searching an Info file.
+* Xref Commands:: Commands for selecting cross references.
+* Window Commands:: Commands which manipulate multiple windows.
+* Printing Nodes:: How to print out the contents of a node.
+* Miscellaneous Commands:: A few commands that defy categories.
+* Variables:: How to change the default behavior of Info.
+* GNU Info Global Index:: Global index containing keystrokes,
+ command names, variable names,
+ and general concepts.
+@end menu
+
+@node What is Info, Options, Top, Top
+@chapter What is Info?
+
+@iftex
+This file documents GNU Info, a program for viewing the on-line formatted
+versions of Texinfo files, version @value{InfoProgVer}.
+@end iftex
+
+@dfn{Info} is a program which is used to view Info files on an ASCII
+terminal. @dfn{Info files} are the result of processing Texinfo files
+with the program @code{makeinfo} or with one of the Emacs commands, such
+as @code{M-x texinfo-format-buffer}. Texinfo itself is a documentation
+system that uses a single source file to produce both on-line
+information and printed output. You can typeset and print the
+files that you read in Info.@refill
+
+@node Options, Cursor Commands, What is Info, Top
+@chapter Command Line Options
+@cindex command line options
+@cindex arguments, command line
+
+GNU Info accepts several options to control the initial node being
+viewed, and to specify which directories to search for Info files. Here
+is a template showing an invocation of GNU Info from the shell:
+
+@example
+info [--@var{option-name} @var{option-value}] @var{menu-item}@dots{}
+@end example
+
+The following @var{option-names} are available when invoking Info from
+the shell:
+
+@table @code
+@cindex directory path
+@item --directory @var{directory-path}
+@itemx -d @var{directory-path}
+Add @var{directory-path} to the list of directory paths searched when
+Info needs to find a file. You may issue @code{--directory} multiple
+times; once for each directory which contains Info files.
+Alternatively, you may specify a value for the environment variable
+@code{INFOPATH}; if @code{--directory} is not given, the value of
+@code{INFOPATH} is used. The value of @code{INFOPATH} is a colon
+separated list of directory names. If you do not supply @code{INFOPATH}
+or @code{--directory-path}, Info uses a default path.
+
+@item --file @var{filename}
+@itemx -f @var{filename}
+@cindex Info file, selecting
+Specify a particular Info file to visit. By default, Info visits
+the file @code{dir}; if you use this option, Info will start with
+@code{(@var{filename})Top} as the first file and node.
+
+@item --node @var{nodename}
+@itemx -n @var{nodename}
+@cindex node, selecting
+Specify a particular node to visit in the initial file that Info
+loads. This is especially useful in conjunction with
+@code{--file}@footnote{Of course, you can specify both the file and node
+in a @code{--node} command; but don't forget to escape the open and
+close parentheses from the shell as in: @code{info --node
+"(emacs)Buffers"}}. You may specify @code{--node} multiple times; for
+an interactive Info, each @var{nodename} is visited in its own window,
+for a non-interactive Info (such as when @code{--output} is given) each
+@var{nodename} is processed sequentially.
+
+@item --output @var{filename}
+@itemx -o @var{filename}
+@cindex file, outputting to
+@cindex outputting to a file
+Specify @var{filename} as the name of a file to which to direct output.
+Each node that Info visits will be output to @var{filename} instead of
+interactively viewed. A value of @code{-} for @var{filename} specifies
+the standard output.
+
+@item --subnodes
+@cindex @code{--subnodes}, command line option
+This option only has meaning when given in conjunction with
+@code{--output}. It means to recursively output the nodes appearing in
+the menus of each node being output. Menu items which resolve to
+external Info files are not output, and neither are menu items which are
+members of an index. Each node is only output once.
+
+@item --help
+@itemx -h
+Produces a relatively brief description of the available Info options.
+
+@item --version
+@cindex version information
+Prints the version information of Info and exits.
+
+@item @var{menu-item}
+@cindex menu, following
+Info treats its remaining arguments as the names of menu items. The
+first argument is a menu item in the initial node visited, while
+the second argument is a menu item in the first argument's node.
+You can easily move to the node of your choice by specifying the menu
+names which describe the path to that node. For example,
+
+@example
+info emacs buffers
+@end example
+
+@noindent
+first selects the menu item @samp{Emacs} in the node @samp{(dir)Top},
+and then selects the menu item @samp{Buffers} in the node
+@samp{(emacs)Top}.
+@end table
+
+@node Cursor Commands, Scrolling Commands, Options, Top
+@chapter Moving the Cursor
+@cindex cursor, moving
+
+Many people find that reading screens of text page by page is made
+easier when one is able to indicate particular pieces of text with some
+kind of pointing device. Since this is the case, GNU Info (both the
+Emacs and standalone versions) have several commands which allow you to
+move the cursor about the screen. The notation used in this manual to
+describe keystrokes is identical to the notation used within the Emacs
+manual, and the GNU Readline manual. @xref{Characters, , Character
+Conventions, emacs, the GNU Emacs Manual}, if you are unfamiliar with the
+notation.
+
+The following table lists the basic cursor movement commands in Info.
+Each entry consists of the key sequence you should type to execute the
+cursor movement, the @code{M-x}@footnote{@code{M-x} is also a command; it
+invokes @code{execute-extended-command}. @xref{M-x, , Executing an
+extended command, emacs, the GNU Emacs Manual}, for more detailed
+information.} command name (displayed in parentheses), and a short
+description of what the command does. All of the cursor motion commands
+can take an @dfn{numeric} argument (@pxref{Miscellaneous Commands,
+@code{universal-argument}}), to find out how to supply them. With a
+numeric argument, the motion commands are simply executed that
+many times; for example, a numeric argument of 4 given to
+@code{next-line} causes the cursor to move down 4 lines. With a
+negative numeric argument, the motion is reversed; an argument of -4
+given to the @code{next-line} command would cause the cursor to move
+@emph{up} 4 lines.
+
+@table @asis
+@item @code{C-n} (@code{next-line})
+@kindex C-n
+@findex next-line
+Move the cursor down to the next line.
+
+@item @code{C-p} (@code{prev-line})
+@kindex C-p
+@findex prev-line
+Move the cursor up to the previous line.
+
+@item @code{C-a} (@code{beginning-of-line})
+@kindex C-a, in Info windows
+@findex beginning-of-line
+Move the cursor to the start of the current line.
+
+@item @code{C-e} (@code{end-of-line})
+@kindex C-e, in Info windows
+@findex end-of-line
+Move the cursor to the end of the current line.
+
+@item @code{C-f} (@code{forward-char})
+@kindex C-f, in Info windows
+@findex forward-char
+Move the cursor forward a character.
+
+@item @code{C-b} (@code{backward-char})
+@kindex C-b, in Info windows
+@findex backward-char
+Move the cursor backward a character.
+
+@item @code{M-f} (@code{forward-word})
+@kindex M-f, in Info windows
+@findex forward-word
+Move the cursor forward a word.
+
+@item @code{M-b} (@code{backward-word})
+@kindex M-b, in Info windows
+@findex backward-word
+Move the cursor backward a word.
+
+@item @code{M-<} (@code{beginning-of-node})
+@itemx @code{b}
+@kindex b, in Info windows
+@kindex M-<
+@findex beginning-of-node
+Move the cursor to the start of the current node.
+
+@item @code{M->} (@code{end-of-node})
+@kindex M->
+@findex end-of-node
+Move the cursor to the end of the current node.
+
+@item @code{M-r} (@code{move-to-window-line})
+@kindex M-r
+@findex move-to-window-line
+Move the cursor to a specific line of the window. Without a numeric
+argument, @code{M-r} moves the cursor to the start of the line in the
+center of the window. With a numeric argument of @var{n}, @code{M-r}
+moves the cursor to the start of the @var{n}th line in the window.
+@end table
+
+@node Scrolling Commands, Node Commands, Cursor Commands, Top
+@chapter Moving Text Within a Window
+@cindex scrolling
+
+Sometimes you are looking at a screenful of text, and only part of the
+current paragraph you are reading is visible on the screen. The
+commands detailed in this section are used to shift which part of the
+current node is visible on the screen.
+
+@table @asis
+@item @code{SPC} (@code{scroll-forward})
+@itemx @code{C-v}
+@kindex SPC, in Info windows
+@kindex C-v
+@findex scroll-forward
+Shift the text in this window up. That is, show more of the node which
+is currently below the bottom of the window. With a numeric argument,
+show that many more lines at the bottom of the window; a numeric
+argument of 4 would shift all of the text in the window up 4 lines
+(discarding the top 4 lines), and show you four new lines at the bottom
+of the window. Without a numeric argument, @key{SPC} takes the bottom
+two lines of the window and places them at the top of the window,
+redisplaying almost a completely new screenful of lines.
+
+@item @code{DEL} (@code{scroll-backward})
+@itemx @code{M-v}
+@kindex DEL, in Info windows
+@kindex M-v
+@findex scroll-backward
+Shift the text in this window down. The inverse of
+@code{scroll-forward}.
+@end table
+
+@cindex scrolling through node structure
+The @code{scroll-forward} and @code{scroll-backward} commands can also
+move forward and backward through the node structure of the file. If
+you press @key{SPC} while viewing the end of a node, or @key{DEL} while
+viewing the beginning of a node, what happens is controlled by the
+variable @code{scroll-behavior}. @xref{Variables,
+@code{scroll-behavior}}, for more information.
+
+@table @asis
+@item @code{C-l} (@code{redraw-display})
+@kindex C-l
+@findex redraw-display
+Redraw the display from scratch, or shift the line containing the cursor
+to a specified location. With no numeric argument, @samp{C-l} clears
+the screen, and then redraws its entire contents. Given a numeric
+argument of @var{n}, the line containing the cursor is shifted so that
+it is on the @var{n}th line of the window.
+
+@item @code{C-x w} (@code{toggle-wrap})
+@kindex C-w
+@findex toggle-wrap
+Toggles the state of line wrapping in the current window. Normally,
+lines which are longer than the screen width @dfn{wrap}, i.e., they are
+continued on the next line. Lines which wrap have a @samp{\} appearing
+in the rightmost column of the screen. You can cause such lines to be
+terminated at the rightmost column by changing the state of line
+wrapping in the window with @code{C-x w}. When a line which needs more
+space than one screen width to display is displayed, a @samp{$} appears
+in the rightmost column of the screen, and the remainder of the line is
+invisible.
+@end table
+
+@node Node Commands, Searching Commands, Scrolling Commands, Top
+@chapter Selecting a New Node
+@cindex nodes, selection of
+
+This section details the numerous Info commands which select a new node
+to view in the current window.
+
+The most basic node commands are @samp{n}, @samp{p}, @samp{u}, and
+@samp{l}.
+
+When you are viewing a node, the top line of the node contains some Info
+@dfn{pointers} which describe where the next, previous, and up nodes
+are. Info uses this line to move about the node structure of the file
+when you use the following commands:
+
+@table @asis
+@item @code{n} (@code{next-node})
+@kindex n
+@findex next-node
+Select the `Next' node.
+
+@item @code{p} (@code{prev-node})
+@kindex p
+@findex prev-node
+Select the `Prev' node.
+
+@item @code{u} (@code{up-node})
+@kindex u
+@findex up-node
+Select the `Up' node.
+@end table
+
+You can easily select a node that you have already viewed in this window
+by using the @samp{l} command -- this name stands for "last", and
+actually moves through the list of already visited nodes for this
+window. @samp{l} with a negative numeric argument moves forward through
+the history of nodes for this window, so you can quickly step between
+two adjacent (in viewing history) nodes.
+
+@table @asis
+@item @code{l} (@code{history-node})
+@kindex l
+@findex history-node
+Select the most recently selected node in this window.
+@end table
+
+Two additional commands make it easy to select the most commonly
+selected nodes; they are @samp{t} and @samp{d}.
+
+@table @asis
+@item @code{t} (@code{top-node})
+@kindex t
+@findex top-node
+Select the node @samp{Top} in the current Info file.
+
+@item @code{d} (@code{dir-node})
+@kindex d
+@findex dir-node
+Select the directory node (i.e., the node @samp{(dir)}).
+@end table
+
+Here are some other commands which immediately result in the selection
+of a different node in the current window:
+
+@table @asis
+@item @code{<} (@code{first-node})
+@kindex <
+@findex first-node
+Selects the first node which appears in this file. This node is most
+often @samp{Top}, but it does not have to be.
+
+@item @code{>} (@code{last-node})
+@kindex >
+@findex last-node
+Select the last node which appears in this file.
+
+@item @code{]} (@code{global-next-node})
+@kindex ]
+@findex global-next-node
+Move forward or down through node structure. If the node that you are
+currently viewing has a @samp{Next} pointer, that node is selected.
+Otherwise, if this node has a menu, the first menu item is selected. If
+there is no @samp{Next} and no menu, the same process is tried with the
+@samp{Up} node of this node.
+
+@item @code{[} (@code{global-prev-node})
+@kindex [
+@findex global-prev-node
+Move backward or up through node structure. If the node that you are
+currently viewing has a @samp{Prev} pointer, that node is selected.
+Otherwise, if the node has an @samp{Up} pointer, that node is selected,
+and if it has a menu, the last item in the menu is selected.
+@end table
+
+You can get the same behavior as @code{global-next-node} and
+@code{global-prev-node} while simply scrolling through the file with
+@key{SPC} and @key{DEL}; @xref{Variables, @code{scroll-behavior}}, for
+more information.
+
+@table @asis
+@item @code{g} (@code{goto-node})
+@kindex g
+@findex goto-node
+Read the name of a node and select it. No completion is done while
+reading the node name, since the desired node may reside in a separate
+file. The node must be typed exactly as it appears in the Info file. A
+file name may be included as with any node specification, for example
+
+@example
+@code{g(emacs)Buffers}
+@end example
+
+finds the node @samp{Buffers} in the Info file @file{emacs}.
+
+@item @code{C-x k} (@code{kill-node})
+@kindex C-x k
+@findex kill-node
+Kill a node. The node name is prompted for in the echo area, with a
+default of the current node. @dfn{Killing} a node means that Info tries
+hard to forget about it, removing it from the list of history nodes kept
+for the window where that node is found. Another node is selected in
+the window which contained the killed node.
+
+@item @code{C-x C-f} (@code{view-file})
+@kindex C-x C-f
+@findex view-file
+Read the name of a file and selects the entire file. The command
+@example
+@code{C-x C-f @var{filename}}
+@end example
+is equivalent to typing
+@example
+@code{g(@var{filename})*}
+@end example
+
+@item @code{C-x C-b} (@code{list-visited-nodes})
+@kindex C-x C-b
+@findex list-visited-nodes
+Make a window containing a menu of all of the currently visited nodes.
+This window becomes the selected window, and you may use the standard
+Info commands within it.
+
+@item @code{C-x b} (@code{select-visited-node})
+@kindex C-x b
+@findex select-visited-node
+Select a node which has been previously visited in a visible window.
+This is similar to @samp{C-x C-b} followed by @samp{m}, but no window is
+created.
+@end table
+
+@node Searching Commands, Xref Commands, Node Commands, Top
+@chapter Searching an Info File
+@cindex searching
+
+GNU Info allows you to search for a sequence of characters throughout an
+entire Info file, search through the indices of an Info file, or find
+areas within an Info file which discuss a particular topic.
+
+@table @asis
+@item @code{s} (@code{search})
+@kindex s
+@findex search
+Read a string in the echo area and search for it.
+
+@item @code{C-s} (@code{isearch-forward})
+@kindex C-s
+@findex isearch-forward
+Interactively search forward through the Info file for a string as you
+type it.
+
+@item @code{C-r} (@code{isearch-backward})
+@kindex C-r
+@findex isearch-backward
+Interactively search backward through the Info file for a string as
+you type it.
+
+@item @code{i} (@code{index-search})
+@kindex i
+@findex index-search
+Look up a string in the indices for this Info file, and select a node
+where the found index entry points to.
+
+@item @code{,} (@code{next-index-match})
+@kindex ,
+@findex next-index-match
+Move to the node containing the next matching index item from the last
+@samp{i} command.
+@end table
+
+The most basic searching command is @samp{s} (@code{search}). The
+@samp{s} command prompts you for a string in the echo area, and then
+searches the remainder of the Info file for an occurrence of that string.
+If the string is found, the node containing it is selected, and the
+cursor is left positioned at the start of the found string. Subsequent
+@samp{s} commands show you the default search string within @samp{[} and
+@samp{]}; pressing @key{RET} instead of typing a new string will use the
+default search string.
+
+@dfn{Incremental searching} is similar to basic searching, but the
+string is looked up while you are typing it, instead of waiting until
+the entire search string has been specified.
+
+@node Xref Commands, Window Commands, Searching Commands, Top
+@chapter Selecting Cross References
+
+We have already discussed the @samp{Next}, @samp{Prev}, and @samp{Up}
+pointers which appear at the top of a node. In addition to these
+pointers, a node may contain other pointers which refer you to a
+different node, perhaps in another Info file. Such pointers are called
+@dfn{cross references}, or @dfn{xrefs} for short.
+
+@menu
+* Parts of an Xref:: What a cross reference is made of.
+* Selecting Xrefs:: Commands for selecting menu or note items.
+@end menu
+
+@node Parts of an Xref, Selecting Xrefs, , Xref Commands
+@section Parts of an Xref
+
+Cross references have two major parts: the first part is called the
+@dfn{label}; it is the name that you can use to refer to the cross
+reference, and the second is the @dfn{target}; it is the full name of
+the node that the cross reference points to.
+
+The target is separated from the label by a colon @samp{:}; first the
+label appears, and then the target. For example, in the sample menu
+cross reference below, the single colon separates the label from the
+target.
+
+@example
+* Foo Label: Foo Target. More information about Foo.
+@end example
+
+Note the @samp{.} which ends the name of the target. The @samp{.} is
+not part of the target; it serves only to let Info know where the target
+name ends.
+
+A shorthand way of specifying references allows two adjacent colons to
+stand for a target name which is the same as the label name:
+
+@example
+* Foo Commands:: Commands pertaining to Foo.
+@end example
+
+In the above example, the name of the target is the same as the name of
+the label, in this case @code{Foo Commands}.
+
+You will normally see two types of cross reference while viewing nodes:
+@dfn{menu} references, and @dfn{note} references. Menu references
+appear within a node's menu; they begin with a @samp{*} at the beginning
+of a line, and continue with a label, a target, and a comment which
+describes what the contents of the node pointed to contains.
+
+Note references appear within the body of the node text; they begin with
+@code{*Note}, and continue with a label and a target.
+
+Like @samp{Next}, @samp{Prev}, and @samp{Up} pointers, cross references
+can point to any valid node. They are used to refer you to a place
+where more detailed information can be found on a particular subject.
+Here is a cross reference which points to a node within the Texinfo
+documentation: @xref{xref, , Writing an Xref, texinfo, the Texinfo
+Manual}, for more information on creating your own texinfo cross
+references.
+
+@node Selecting Xrefs, , Parts of an Xref, Xref Commands
+@section Selecting Xrefs
+
+The following table lists the Info commands which operate on menu items.
+
+@table @asis
+@item @code{1} (@code{menu-digit})
+@itemx @code{2} @dots{} @code{9}
+@cindex 1 @dots{} 9, in Info windows
+@kindex 1 @dots{} 9, in Info windows
+@findex menu-digit
+Within an Info window, pressing a single digit, (such as @samp{1}),
+selects that menu item, and places its node in the current window.
+For convenience, there is one exception; pressing @samp{0} selects the
+@emph{last} item in the node's menu.
+
+@item @code{0} (@code{last-menu-item})
+@kindex 0, in Info windows
+@findex last-menu-item
+Select the last item in the current node's menu.
+
+@item @code{m} (@code{menu-item})
+@kindex m
+@findex menu-item
+Reads the name of a menu item in the echo area and selects its node.
+Completion is available while reading the menu label.
+
+@item @code{M-x find-menu}
+@findex find-menu
+Move the cursor to the start of this node's menu.
+@end table
+
+This table lists the Info commands which operate on note cross references.
+
+@table @asis
+@item @code{f} (@code{xref-item})
+@itemx @code{r}
+@kindex f
+@kindex r
+@findex xref-item
+Reads the name of a note cross reference in the echo area and selects
+its node. Completion is available while reading the cross reference
+label.
+@end table
+
+Finally, the next few commands operate on menu or note references alike:
+
+@table @asis
+@item @code{TAB} (@code{move-to-next-xref})
+@kindex TAB, in Info windows
+@findex move-to-next-xref
+Move the cursor to the start of the next nearest menu item or note
+reference in this node. You can then use @key{RET}
+(@code{select-reference-this-line}) to select the menu or note reference.
+
+@item @code{M-TAB} (@code{move-to-prev-xref})
+@kindex M-TAB, in Info windows
+@findex move-to-prev-xref
+Move the cursor the start of the nearest previous menu item or note
+reference in this node.
+
+@item @code{RET} (@code{select-reference-this-line})
+@kindex RET, in Info windows
+@findex select-reference-this-line
+Select the menu item or note reference appearing on this line.
+@end table
+
+@node Window Commands, Printing Nodes, Xref Commands, Top
+@chapter Manipulating Multiple Windows
+@cindex windows, manipulating
+
+A @dfn{window} is a place to show the text of a node. Windows have a
+view area where the text of the node is displayed, and an associated
+@dfn{mode line}, which briefly describes the node being viewed.
+
+GNU Info supports multiple windows appearing in a single screen; each
+window is separated from the next by its modeline. At any time, there
+is only one @dfn{active} window, that is, the window in which the cursor
+appears. There are commands available for creating windows, changing
+the size of windows, selecting which window is active, and for deleting
+windows.
+
+@menu
+* The Mode Line:: What appears in the mode line?
+* Basic Windows:: Manipulating windows in Info.
+* The Echo Area:: Used for displaying errors and reading input.
+@end menu
+
+@node The Mode Line, Basic Windows, , Window Commands
+@section The Mode Line
+
+A @dfn{mode line} is a line of inverse video which appears at the bottom
+of an Info window. It describes the contents of the window just above
+it; this information includes the name of the file and node appearing in
+that window, the number of screen lines it takes to display the node,
+and the percentage of text that is above the top of the window. It can
+also tell you if the indirect tags table for this Info file needs to be
+updated, and whether or not the Info file was compressed when stored on
+disk.
+
+Here is a sample mode line for a window containing an uncompressed file
+named @file{dir}, showing the node @samp{Top}.
+
+@example
+@group
+-----Info: (dir)Top, 40 lines --Top---------------------------------------
+ ^^ ^ ^^^ ^^
+ (file)Node #lines where
+@end group
+@end example
+
+When a node comes from a file which is compressed on disk, this is
+indicated in the mode line with two small @samp{z}'s. In addition, if
+the Info file containing the node has been split into subfiles, the name
+of the subfile containing the node appears in the modeline as well:
+
+@example
+--zz-Info: (emacs)Top, 291 lines --Top-- Subfile: emacs-1.Z---------------
+@end example
+
+When Info makes a node internally, such that there is no corresponding
+info file on disk, the name of the node is surrounded by asterisks
+(@samp{*}). The name itself tells you what the contents of the window
+are; the sample mode line below shows an internally constructed node
+showing possible completions:
+
+@example
+-----Info: *Completions*, 7 lines --All-----------------------------------
+@end example
+
+@node Basic Windows, The Echo Area, The Mode Line, Window Commands
+@section Window Commands
+
+It can be convenient to view more than one node at a time. To allow
+this, Info can display more than one @dfn{window}. Each window has its
+own mode line (@pxref{The Mode Line}) and history of nodes viewed in that
+window (@pxref{Node Commands, , @code{history-node}}).
+
+@table @asis
+@item @code{C-x o} (@code{next-window})
+@cindex windows, selecting
+@kindex C-x o
+@findex next-window
+Select the next window on the screen. Note that the echo area can only be
+selected if it is already in use, and you have left it temporarily.
+Normally, @samp{C-x o} simply moves the cursor into the next window on
+the screen, or if you are already within the last window, into the first
+window on the screen. Given a numeric argument, @samp{C-x o} moves over
+that many windows. A negative argument causes @samp{C-x o} to select
+the previous window on the screen.
+
+@item @code{M-x prev-window}
+@findex prev-window
+Select the previous window on the screen. This is identical to
+@samp{C-x o} with a negative argument.
+
+@item @code{C-x 2} (@code{split-window})
+@cindex windows, creating
+@kindex C-x 2
+@findex split-window
+Split the current window into two windows, both showing the same node.
+Each window is one half the size of the original window, and the cursor
+remains in the original window. The variable @code{automatic-tiling}
+can cause all of the windows on the screen to be resized for you
+automatically, please @pxref{Variables, , automatic-tiling} for more
+information.
+
+@item @code{C-x 0} (@code{delete-window})
+@cindex windows, deleting
+@kindex C-x 0
+@findex delete-window
+Delete the current window from the screen. If you have made too many
+windows and your screen appears cluttered, this is the way to get rid of
+some of them.
+
+@item @code{C-x 1} (@code{keep-one-window})
+@kindex C-x 1
+@findex keep-one-window
+Delete all of the windows excepting the current one.
+
+@item @code{ESC C-v} (@code{scroll-other-window})
+@kindex ESC C-v, in Info windows
+@findex scroll-other-window
+Scroll the other window, in the same fashion that @samp{C-v} might
+scroll the current window. Given a negative argument, scroll the
+"other" window backward.
+
+@item @code{C-x ^} (@code{grow-window})
+@kindex C-x ^
+@findex grow-window
+Grow (or shrink) the current window. Given a numeric argument, grow
+the current window that many lines; with a negative numeric argument,
+shrink the window instead.
+
+@item @code{C-x t} (@code{tile-windows})
+@cindex tiling
+@kindex C-x t
+@findex tile-windows
+Divide the available screen space among all of the visible windows.
+Each window is given an equal portion of the screen in which to display
+its contents. The variable @code{automatic-tiling} can cause
+@code{tile-windows} to be called when a window is created or deleted.
+@xref{Variables, , @code{automatic-tiling}}.
+@end table
+
+@node The Echo Area, , Basic Windows, Window Commands
+@section The Echo Area
+@cindex echo area
+
+The @dfn{echo area} is a one line window which appears at the bottom of
+the screen. It is used to display informative or error messages, and to
+read lines of input from you when that is necessary. Almost all of the
+commands available in the echo area are identical to their Emacs
+counterparts, so please refer to that documentation for greater depth of
+discussion on the concepts of editing a line of text. The following
+table briefly lists the commands that are available while input is being
+read in the echo area:
+
+@table @asis
+@item @code{C-f} (@code{echo-area-forward})
+@kindex C-f, in the echo area
+@findex echo-area-forward
+Move forward a character.
+
+@item @code{C-b} (@code{echo-area-backward})
+@kindex C-b, in the echo area
+@findex echo-area-backward
+Move backward a character.
+
+@item @code{C-a} (@code{echo-area-beg-of-line})
+@kindex C-a, in the echo area
+@findex echo-area-beg-of-line
+Move to the start of the input line.
+
+@item @code{C-e} (@code{echo-area-end-of-line})
+@kindex C-e, in the echo area
+@findex echo-area-end-of-line
+Move to the end of the input line.
+
+@item @code{M-f} (@code{echo-area-forward-word})
+@kindex M-f, in the echo area
+@findex echo-area-forward-word
+Move forward a word.
+
+@item @code{M-b} (@code{echo-area-backward-word})
+@kindex M-b, in the echo area
+@findex echo-area-backward-word
+Move backward a word.
+
+@item @code{C-d} (@code{echo-area-delete})
+@kindex C-d, in the echo area
+@findex echo-area-delete
+Delete the character under the cursor.
+
+@item @code{DEL} (@code{echo-area-rubout})
+@kindex DEL, in the echo area
+@findex echo-area-rubout
+Delete the character behind the cursor.
+
+@item @code{C-g} (@code{echo-area-abort})
+@kindex C-g, in the echo area
+@findex echo-area-abort
+Cancel or quit the current operation. If completion is being read,
+@samp{C-g} discards the text of the input line which does not match any
+completion. If the input line is empty, @samp{C-g} aborts the calling
+function.
+
+@item @code{RET} (@code{echo-area-newline})
+@kindex RET, in the echo area
+@findex echo-area-newline
+Accept (or forces completion of) the current input line.
+
+@item @code{C-q} (@code{echo-area-quoted-insert})
+@kindex C-q, in the echo area
+@findex echo-area-quoted-insert
+Insert the next character verbatim. This is how you can insert control
+characters into a search string, for example.
+
+@item @var{printing character} (@code{echo-area-insert})
+@kindex printing characters, in the echo area
+@findex echo-area-insert
+Insert the character.
+
+@item @code{M-TAB} (@code{echo-area-tab-insert})
+@kindex M-TAB, in the echo area
+@findex echo-area-tab-insert
+Insert a TAB character.
+
+@item @code{C-t} (@code{echo-area-transpose-chars})
+@kindex C-t, in the echo area
+@findex echo-area-transpose-chars
+Transpose the characters at the cursor.
+@end table
+
+The next group of commands deal with @dfn{killing}, and @dfn{yanking}
+text. For an in depth discussion of killing and yanking,
+@pxref{Killing, , Killing and Deleting, emacs, the GNU Emacs Manual}
+
+@table @asis
+@item @code{M-d} (@code{echo-area-kill-word})
+@kindex M-d, in the echo area
+@findex echo-area-kill-word
+Kill the word following the cursor.
+
+@item @code{M-DEL} (@code{echo-area-backward-kill-word})
+@kindex M-DEL, in the echo area
+@findex echo-area-backward-kill-word
+Kill the word preceding the cursor.
+
+@item @code{C-k} (@code{echo-area-kill-line})
+@kindex C-k, in the echo area
+@findex echo-area-kill-line
+Kill the text from the cursor to the end of the line.
+
+@item @code{C-x DEL} (@code{echo-area-backward-kill-line})
+@kindex C-x DEL, in the echo area
+@findex echo-area-backward-kill-line
+Kill the text from the cursor to the beginning of the line.
+
+@item @code{C-y} (@code{echo-area-yank})
+@kindex C-y, in the echo area
+@findex echo-area-yank
+Yank back the contents of the last kill.
+
+@item @code{M-y} (@code{echo-area-yank-pop})
+@kindex M-y, in the echo area
+@findex echo-area-yank-pop
+Yank back a previous kill, removing the last yanked text first.
+@end table
+
+Sometimes when reading input in the echo area, the command that needed
+input will only accept one of a list of several choices. The choices
+represent the @dfn{possible completions}, and you must respond with one
+of them. Since there are a limited number of responses you can make,
+Info allows you to abbreviate what you type, only typing as much of the
+response as is necessary to uniquely identify it. In addition, you can
+request Info to fill in as much of the response as is possible; this
+is called @dfn{completion}.
+
+The following commands are available when completing in the echo area:
+
+@table @asis
+@item @code{TAB} (@code{echo-area-complete})
+@itemx @code{SPC}
+@kindex TAB, in the echo area
+@kindex SPC, in the echo area
+@findex echo-area-complete
+Insert as much of a completion as is possible.
+
+@item @code{?} (@code{echo-area-possible-completions})
+@kindex ?, in the echo area
+@findex echo-area-possible-completions
+Display a window containing a list of the possible completions of what
+you have typed so far. For example, if the available choices are:
+
+@example
+@group
+bar
+foliate
+food
+forget
+@end group
+@end example
+
+@noindent
+and you have typed an @samp{f}, followed by @samp{?}, the possible
+completions would contain:
+
+@example
+@group
+foliate
+food
+forget
+@end group
+@end example
+
+@noindent
+i.e., all of the choices which begin with @samp{f}. Pressing @key{SPC}
+or @key{TAB} would result in @samp{fo} appearing in the echo area, since
+all of the choices which begin with @samp{f} continue with @samp{o}.
+Now, typing @samp{l} followed by @samp{TAB} results in @samp{foliate}
+appearing in the echo area, since that is the only choice which begins
+with @samp{fol}.
+
+@item @code{ESC C-v} (@code{echo-area-scroll-completions-window})
+@kindex ESC C-v, in the echo area
+@findex echo-area-scroll-completions-window
+Scroll the completions window, if that is visible, or the "other"
+window if not.
+@end table
+
+@node Printing Nodes, Miscellaneous Commands, Window Commands, Top
+@chapter Printing Out Nodes
+@cindex printing
+
+You may wish to print out the contents of a node as a quick reference
+document for later use. Info provides you with a command for doing
+this. In general, we recommend that you use @TeX{} to format the
+document and print sections of it, by running @code{tex} on the Texinfo
+source file.
+
+@table @asis
+@item @code{M-x print-node}
+@findex print-node
+@cindex INFO_PRINT_COMMAND, environment variable
+Pipe the contents of the current node through the command in the
+environment variable @code{INFO_PRINT_COMMAND}. If the variable does not
+exist, the node is simply piped to @code{lpr}.
+@end table
+
+@node Miscellaneous Commands, Variables, Printing Nodes, Top
+@chapter Miscellaneous Commands
+
+GNU Info contains several commands which self-document GNU Info:
+
+@table @asis
+@item @code{M-x describe-command}
+@cindex functions, describing
+@cindex commands, describing
+@findex describe-command
+Read the name of an Info command in the echo area and then display a
+brief description of what that command does.
+
+@item @code{M-x describe-key}
+@cindex keys, describing
+@findex describe-key
+Read a key sequence in the echo area, and then display the name and
+documentation of the Info command that the key sequence invokes.
+
+@item @code{M-x describe-variable}
+Read the name of a variable in the echo area and then display a brief
+description of what the variable affects.
+
+@item @code{M-x where-is}
+@findex where-is
+Read the name of an Info command in the echo area, and then display
+a key sequence which can be typed in order to invoke that command.
+
+@item @code{C-h} (@code{get-help-window})
+@itemx @code{?}
+@kindex C-h
+@kindex ?, in Info windows
+@findex get-help-window
+Create (or Move into) the window displaying @code{*Help*}, and place
+a node containing a quick reference card into it. This window displays
+the most concise information about GNU Info available.
+
+@item @code{h} (@code{get-info-help-node})
+@kindex h
+@findex get-info-help-node
+Try hard to visit the node @code{(info)Help}. The Info file
+@file{info.texi} distributed with GNU Info contains this node. Of
+course, the file must first be processed with @code{makeinfo}, and then
+placed into the location of your Info directory.
+@end table
+
+Here are the commands for creating a numeric argument:
+
+@table @asis
+@item @code{C-u} (@code{universal-argument})
+@cindex numeric arguments
+@kindex C-u
+@findex universal-argument
+Start (or multiply by 4) the current numeric argument. @samp{C-u} is
+a good way to give a small numeric argument to cursor movement or
+scrolling commands; @samp{C-u C-v} scrolls the screen 4 lines, while
+@samp{C-u C-u C-n} moves the cursor down 16 lines.
+
+@item @code{M-1} (@code{add-digit-to-numeric-arg})
+@itemx @code{M-2} @dots{} @code{M-9}
+@kindex M-1 @dots{} M-9
+@findex add-digit-to-numeric-arg
+Add the digit value of the invoking key to the current numeric
+argument. Once Info is reading a numeric argument, you may just type
+the digits of the argument, without the Meta prefix. For example, you
+might give @samp{C-l} a numeric argument of 32 by typing:
+
+@example
+@kbd{C-u 3 2 C-l}
+@end example
+
+@noindent
+or
+
+@example
+@kbd{M-3 2 C-l}
+@end example
+@end table
+
+@samp{C-g} is used to abort the reading of a multi-character key
+sequence, to cancel lengthy operations (such as multi-file searches) and
+to cancel reading input in the echo area.
+
+@table @asis
+@item @code{C-g} (@code{abort-key})
+@cindex cancelling typeahead
+@cindex cancelling the current operation
+@kindex C-g, in Info windows
+@findex abort-key
+Cancel current operation.
+@end table
+
+The @samp{q} command of Info simply quits running Info.
+
+@table @asis
+@item @code{q} (@code{quit})
+@cindex quitting
+@kindex q
+@findex quit
+Exit GNU Info.
+@end table
+
+If the operating system tells GNU Info that the screen is 60 lines tall,
+and it is actually only 40 lines tall, here is a way to tell Info that
+the operating system is correct.
+
+@table @asis
+@item @code{M-x set-screen-height}
+@findex set-screen-height
+@cindex screen, changing the height of
+Read a height value in the echo area and set the height of the
+displayed screen to that value.
+@end table
+
+Finally, Info provides a convenient way to display footnotes which might
+be associated with the current node that you are viewing:
+
+@table @asis
+@item @code{ESC C-f} (@code{show-footnotes})
+@kindex ESC C-f
+@findex show-footnotes
+@cindex footnotes, displaying
+Show the footnotes (if any) associated with the current node in another
+window. You can have Info automatically display the footnotes
+associated with a node when the node is selected by setting the variable
+@code{automatic-footnotes}. @xref{Variables, , @code{automatic-footnotes}}.
+@end table
+
+@node Variables, GNU Info Global Index, Miscellaneous Commands, Top
+@chapter Manipulating Variables
+
+GNU Info contains several @dfn{variables} whose values are looked at by
+various Info commands. You can change the values of these variables,
+and thus change the behavior of Info to more closely match your
+environment and Info file reading manner.
+
+@table @asis
+@item @code{M-x set-variable}
+@cindex variables, setting
+@findex set-variable
+Read the name of a variable, and the value for it, in the echo area and
+then set the variable to that value. Completion is available when
+reading the variable name; often, completion is available when reading
+the value to give to the variable, but that depends on the variable
+itself. If a variable does @emph{not} supply multiple choices to
+complete over, it expects a numeric value.
+
+@item @code{M-x describe-variable}
+@cindex variables, describing
+@findex describe-variable
+Read the name of a variable in the echo area and then display a brief
+description of what the variable affects.
+@end table
+
+Here is a list of the variables that you can set in Info.
+
+@table @code
+@item automatic-footnotes
+@vindex automatic-footnotes
+When set to @code{On}, footnotes appear and disappear automatically.
+This variable is @code{On} by default. When a node is selected, a
+window containing the footnotes which appear in that node is created,
+and the footnotes are displayed within the new window. The window that
+Info creates to contain the footnotes is called @samp{*Footnotes*}. If
+a node is selected which contains no footnotes, and a @samp{*Footnotes*}
+window is on the screen, the @samp{*Footnotes*} window is deleted.
+Footnote windows created in this fashion are not automatically tiled so
+that they can use as little of the display as is possible.
+
+@item automatic-tiling
+@vindex automatic-tiling
+When set to @code{On}, creating or deleting a window resizes other
+windows. This variable is @code{Off} by default. Normally, typing
+@samp{C-x 2} divides the current window into two equal parts. When
+@code{automatic-tiling} is set to @code{On}, all of the windows are
+resized automatically, keeping an equal number of lines visible in each
+window. There are exceptions to the automatic tiling; specifically, the
+windows @samp{*Completions*} and @samp{*Footnotes*} are @emph{not}
+resized through automatic tiling; they remain their original size.
+
+@item visible-bell
+@vindex visible-bell
+When set to @code{On}, GNU Info attempts to flash the screen instead of
+ringing the bell. This variable is @code{Off} by default. Of course,
+Info can only flash the screen if the terminal allows it; in the case
+that the terminal does not allow it, the setting of this variable has no
+effect. However, you can make Info perform quietly by setting the
+@code{errors-ring-bell} variable to @code{Off}.
+
+@item errors-ring-bell
+@vindex errors-ring-bell
+When set to @code{On}, errors cause the bell to ring. The default
+setting of this variable is @code{On}.
+
+@item gc-compressed-files
+@vindex gc-compressed-files
+When set to @code{On}, Info garbage collects files which had to be
+uncompressed. The default value of this variable is @code{Off}.
+Whenever a node is visited in Info, the Info file containing that node
+is read into core, and Info reads information about the tags and nodes
+contained in that file. Once the tags information is read by Info, it
+is never forgotten. However, the actual text of the nodes does not need
+to remain in core unless a particular Info window needs it. For
+non-compressed files, the text of the nodes does not remain in core when
+it is no longer in use. But de-compressing a file can be a time
+consuming operation, and so Info tries hard not to do it twice.
+@code{gc-compressed-files} tells Info it is okay to garbage collect the
+text of the nodes of a file which was compressed on disk.
+
+@item show-index-match
+@vindex show-index-match
+When set to @code{On}, the portion of the matched search string is
+highlighted in the message which explains where the matched search
+string was found. The default value of this variable is @code{On}.
+When Info displays the location where an index match was found,
+(@pxref{Searching Commands, , @code{next-index-match}}), the portion of the
+string that you had typed is highlighted by displaying it in the inverse
+case from its surrounding characters.
+
+@item scroll-behavior
+@vindex scroll-behavior
+Control what happens when forward scrolling is requested at the end of
+a node, or when backward scrolling is requested at the beginning of a
+node. The default value for this variable is @code{Continuous}. There
+are three possible values for this variable:
+
+@table @code
+@item Continuous
+Try to get the first item in this node's menu, or failing that, the
+@samp{Next} node, or failing that, the @samp{Next} of the @samp{Up}.
+This behavior is identical to using the @samp{]}
+(@code{global-next-node}) and @samp{[} (@code{global-prev-node})
+commands.
+
+@item Next Only
+Only try to get the @samp{Next} node.
+
+@item Page Only
+Simply give up, changing nothing. If @code{scroll-behavior} is
+@code{Page Only}, no scrolling command can change the node that is being
+viewed.
+@end table
+
+@item scroll-step
+@vindex scroll-step
+The number of lines to scroll when the cursor moves out of the window.
+Scrolling happens automatically if the cursor has moved out of the
+visible portion of the node text when it is time to display. Usually
+the scrolling is done so as to put the cursor on the center line of the
+current window. However, if the variable @code{scroll-step} has a
+nonzero value, Info attempts to scroll the node text by that many lines;
+if that is enough to bring the cursor back into the window, that is what
+is done. The default value of this variable is 0, thus placing the
+cursor (and the text it is attached to) in the center of the window.
+Setting this variable to 1 causes a kind of "smooth scrolling" which
+some people prefer.
+
+@item ISO-Latin
+@cindex ISO Latin characters
+@vindex ISO-Latin
+When set to @code{On}, Info accepts and displays ISO Latin characters.
+By default, Info assumes an ASCII character set. @code{ISO-Latin} tells
+Info that it is running in an environment where the European standard
+character set is in use, and allows you to input such characters to
+Info, as well as display them.
+@end table
+
+
+
+@c the following is incomplete
+@ignore
+@c node Info for Sys Admins
+@c chapter Info for System Administrators
+
+This text describes some common ways of setting up an Info hierarchy
+from scratch, and details the various options that are available when
+installing Info. This text is designed for the person who is installing
+GNU Info on the system; although users may find the information present
+in this section interesting, none of it is vital to understanding how to
+use GNU Info.
+
+@menu
+* Setting the INFOPATH:: Where are my Info files kept?
+* Editing the DIR node:: What goes in `DIR', and why?
+* Storing Info files:: Alternate formats allow flexibility in setups.
+* Using `localdir':: Building DIR on the fly.
+* Example setups:: Some common ways to organize Info files.
+@end menu
+
+@c node Setting the INFOPATH
+@c section Setting the INFOPATH
+
+Where are my Info files kept?
+
+@c node Editing the DIR node
+@c section Editing the DIR node
+
+What goes in `DIR', and why?
+
+@c node Storing Info files
+@c section Storing Info files
+
+Alternate formats allow flexibility in setups.
+
+@c node Using `localdir'
+@c section Using `localdir'
+
+Building DIR on the fly.
+
+@c node Example setups
+@c section Example setups
+
+Some common ways to organize Info files.
+@end ignore
+
+@node GNU Info Global Index, , Variables, Top
+@appendix Global Index
+
+@printindex cp
+
+@contents
+@bye
diff --git a/gnu/usr.bin/texinfo/info/info.1 b/gnu/usr.bin/texinfo/info/info.1
new file mode 100644
index 00000000000..f95687303d2
--- /dev/null
+++ b/gnu/usr.bin/texinfo/info/info.1
@@ -0,0 +1,229 @@
+.TH info 1 "7th December 1990"
+.SH NAME
+info \- GNU's hypertext system
+.SH SYNOPSIS
+.B info
+[
+.B \-\-option-name option-value
+]
+.B \menu-item...
+.SH COPYRIGHT
+.if n Copyright (C) 1989, 1993 Free Software Foundation, Inc.
+.if t Copyright \(co 1989, 1993 Free Software Foundation, Inc.
+.SH DESCRIPTION
+.LP
+The GNU project has a hypertext system called
+.I Info
+which allows the same source file to be either printed as a
+paper manual, or viewed using
+.B info.
+It is possible to use the
+.B info
+program from inside Emacs, or to use the stand-alone version described here.
+This manual page gives a brief summary of its capabilities.
+
+.SH OPTIONS
+.TP
+.B \-\-directory directory-path
+Add
+.B directory-path
+to the list of directory paths searched when
+.B info
+needs to find a file. You may issue
+.B \-\-directory
+multiple times.
+Alternatively, you may specify a value for the environment variable
+.B INFOPATH;
+if
+.B \-\-directory
+is not given, the value of
+.B INFOPATH
+is used. The value of
+.B INFOPATH
+is a colon separated list of directory names. If you do not supply either
+.B INFOPATH
+or
+.B \-\-directory-path,
+.B info
+uses a default path.
+.TP
+.B \-f filename
+Specify a particular
+.B info
+file to visit. By default,
+.B info
+visits
+the file
+.B dir;
+if you use this option,
+.B info
+will start with
+.B (FILENAME)Top
+as the first file and node.
+.TP
+.B \-n nodename
+Specify a particular node to visit in the initial file that
+.B info
+loads. This is especially useful in conjunction with
+.B \-\-file.
+You may specify
+.B \-\-node
+multiple times.
+.TP
+.B -o file
+Direct output to
+.B file
+instead of starting an interactive
+.B info
+session.
+.TP
+.B \-h
+Produce a relatively brief description of the available
+.B info
+options.
+.TP
+.B \-\-version
+Print the version information of
+.B info
+and exit.
+.TP
+.B menu-item
+.B info
+treats its remaining arguments as the names of menu items.
+The first argument is a menu item in the initial node visited,
+while the second argument is a menu item in the first argument's
+node. You can easily move to the node of your choice by
+specifying the menu names which describe the path to that node.
+For example,
+
+.B info emacs buffers
+
+first selects the menu item
+.B emacs
+in the node
+.B (dir)Top,
+and then selects the menu item
+.B buffers
+in the node
+.B (emacs)Top.
+.SH COMMANDS
+When in
+.B info
+the following commands are available:
+.TP
+.B h
+Invoke the Info tutorial.
+.TP
+.B ?
+Get a short summary of
+.B info
+commands.
+.TP
+.B h
+Select the
+.B info
+node from the main directory; this is much more complete than just
+using
+.B ?.
+.TP
+.B Ctrl-g
+Abort whatever you are doing.
+.TP
+.B Ctrl-l
+Redraw the screen.
+.PP
+Selecting other nodes:
+.TP
+.B n
+Move to the "next" node of this node.
+.TP
+.B p
+Move to the "previous" node of this node.
+.TP
+.B u
+Move to this node's "up" node.
+.TP
+.B m
+Pick a menu item specified by name. Picking a menu item causes another
+node to be selected. You do not need to type a complete nodename; if
+you type a few letters and then a space or tab
+.B info
+will will try to fill in the rest of the nodename. If you ask for further
+completion without typing any more characters you'll be given a list
+of possibilities; you can also get the list with
+.B ?.
+If you type a few characters and then hit return
+.B info
+will try to do a completion, and if it is ambigous use the first possibility.
+.TP
+.B f
+Follow a cross reference. You are asked for the name of the reference,
+using command completion as for
+.B m.
+.TP
+.B l
+Move to the last node you were at.
+.PP
+Moving within a node:
+.TP
+.B Space
+Scroll forward a page.
+.TP
+.B DEL
+Scroll backward a page.
+.TP
+.B b
+Go to the beginning of this node.
+.PP
+Advanced commands:
+.TP
+.B q
+Quit
+.B info.
+.TP
+.B 1
+Pick first item in node's menu.
+.TP
+.B 2 \-\- 5
+Pick second ... fifth item in node's menu.
+.TP
+.B g
+Move to node specified by name. You may include a filename as well,
+as
+.B (FILENAME)NODENAME.
+.TP
+.B s
+Search through this
+.B info
+file for a specified string, and select the node in which
+the next occurrence is found.
+.TP
+.B M-x print-node
+Pipe the contents of the current node through the command in the
+environment variable
+.B INFO_PRINT_COMMAND.
+If the variable does not exist, the node is simply piped to
+.B lpr.
+.SH ENVIRONMENT
+.TP
+.B INFOPATH
+A colon-separated list of directories to search for
+.B info
+files. Used if
+.B \-\-directory
+is not given.
+.TP
+.B INFO_PRINT_COMMAND
+The command used for printing.
+.SH SEE ALSO
+.BR emacs (1)
+.SH AUTHOR
+.RS
+Brian Fox, Free Software Foundation
+.br
+bfox@ai.mit.edu
+.SH MANUAL AUTHOR
+.RS
+Robert Lupton; updated by Robert J. Chassell.
+.br
+rhl@astro.princeton.edu; bob@gnu.ai.mit.edu
diff --git a/gnu/usr.bin/texinfo/info/info.c b/gnu/usr.bin/texinfo/info/info.c
index d7d0046f178..175f945ad85 100644
--- a/gnu/usr.bin/texinfo/info/info.c
+++ b/gnu/usr.bin/texinfo/info/info.c
@@ -1,7 +1,8 @@
/* info.c -- Display nodes of Info files in multiple windows.
- $Id: info.c,v 1.5 2000/02/09 02:18:39 espie Exp $
+ $Id: info.c,v 1.6 2002/06/10 13:51:03 espie Exp $
- Copyright (C) 1993, 96, 97, 98, 99 Free Software Foundation, Inc.
+ Copyright (C) 1993, 96, 97, 98, 99, 2000, 01, 02
+ Free Software Foundation, Inc.
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
@@ -76,6 +77,9 @@ int dump_subnodes = 0;
/* Non-zero means make default keybindings be loosely modeled on vi(1). */
int vi_keys_p = 0;
+/* Non-zero means don't remove ANSI escape sequences from man pages. */
+int raw_escapes_p = 0;
+
#ifdef __MSDOS__
/* Non-zero indicates that screen output should be made 'speech-friendly'.
Since on MSDOS the usual behavior is to write directly to the video
@@ -95,29 +99,30 @@ int speech_friendly = 0;
static struct option long_options[] = {
{ "apropos", 1, 0, APROPOS_OPTION },
{ "directory", 1, 0, 'd' },
- { "node", 1, 0, 'n' },
+ { "dribble", 1, 0, DRIBBLE_OPTION },
{ "file", 1, 0, 'f' },
- { "subnodes", 0, &dump_subnodes, 1 },
+ { "help", 0, &print_help_p, 1 },
+ { "index-search", 1, 0, IDXSRCH_OPTION },
+ { "node", 1, 0, 'n' },
{ "output", 1, 0, 'o' },
+ { "raw-escapes", 0, &raw_escapes_p, 1 },
+ { "restore", 1, 0, RESTORE_OPTION },
{ "show-options", 0, 0, 'O' },
+ { "subnodes", 0, &dump_subnodes, 1 },
{ "usage", 0, 0, 'O' },
- { "vi-keys", 0, &vi_keys_p, 1 },
- { "help", 0, &print_help_p, 1 },
{ "version", 0, &print_version_p, 1 },
- { "dribble", 1, 0, DRIBBLE_OPTION },
- { "restore", 1, 0, RESTORE_OPTION },
+ { "vi-keys", 0, &vi_keys_p, 1 },
#ifdef __MSDOS__
{ "speech-friendly", 0, &speech_friendly, 1 },
#endif
- { "index-search", 1, 0, IDXSRCH_OPTION },
{NULL, 0, NULL, 0}
};
/* String describing the shorthand versions of the long options found above. */
#ifdef __MSDOS__
-static char *short_options = "d:n:f:o:Osb";
+static char *short_options = "d:n:f:o:ORsb";
#else
-static char *short_options = "d:n:f:o:Os";
+static char *short_options = "d:n:f:o:ORs";
#endif
/* When non-zero, the Info window system has been initialized. */
@@ -126,6 +131,7 @@ int info_windows_initialized_p = 0;
/* Some "forward" declarations. */
static void info_short_help (), remember_info_program_name ();
static void init_messages ();
+extern void add_file_directory_to_path ();
/* **************************************************************** */
@@ -206,6 +212,12 @@ main (argc, argv)
goto_invocation_p = 1;
break;
+ /* User has specified that she wants the escape sequences
+ in man pages to be passed thru unaltered. */
+ case 'R':
+ raw_escapes_p = 1;
+ break;
+
/* User is specifying that she wishes to dump the subnodes of
the node that she is dumping. */
case 's':
@@ -213,7 +225,7 @@ main (argc, argv)
break;
#ifdef __MSDOS__
- /* User specifies that she wants speech-friendly output. */
+ /* User wants speech-friendly output. */
case 'b':
speech_friendly = 1;
break;
@@ -268,7 +280,7 @@ main (argc, argv)
There is NO warranty. You may redistribute this software\n\
under the terms of the GNU General Public License.\n\
For more information about these matters, see the files named COPYING.\n"),
- "1999");
+ "2002");
xexit (0);
}
@@ -313,25 +325,7 @@ For more information about these matters, see the files named COPYING.\n"),
/* If the user specified a particular filename, add the path of that
file to the contents of INFOPATH. */
if (user_filename)
- {
- char *directory_name = xstrdup (user_filename);
- char *temp = filename_non_directory (directory_name);
-
- if (temp != directory_name)
- {
- if (HAVE_DRIVE (directory_name) && temp == directory_name + 2)
- {
- /* The directory of "d:foo" is stored as "d:.", to avoid
- mixing it with "d:/" when a slash is appended. */
- *temp = '.';
- temp += 2;
- }
- temp[-1] = 0;
- info_add_path (directory_name, INFOPATH_PREPEND);
- }
-
- free (directory_name);
- }
+ add_file_directory_to_path (user_filename);
/* If the user wants to search every known index for a given string,
do that now, and report the results. */
@@ -382,13 +376,14 @@ For more information about these matters, see the files named COPYING.\n"),
char *errstr, *errarg1, *errarg2;
NODE *new_initial_node = info_follow_menus (initial_node, argv + optind,
&errstr, &errarg1, &errarg2);
+
if (new_initial_node && new_initial_node != initial_node)
initial_node = new_initial_node;
/* If the user specified that this node should be output, then do that
now. Otherwise, start the Info session with this node. Or act
accordingly if the initial node was not found. */
- if (user_output_filename)
+ if (user_output_filename && !goto_invocation_p)
{
if (!errstr)
dump_node_to_file (initial_node, user_output_filename,
@@ -447,7 +442,13 @@ For more information about these matters, see the files named COPYING.\n"),
free (program);
}
- info_read_and_dispatch ();
+ if (user_output_filename)
+ {
+ dump_node_to_file (windows->node, user_output_filename,
+ dump_subnodes);
+ }
+ else
+ info_read_and_dispatch ();
/* On program exit, leave the cursor at the bottom of the
window, and restore the terminal IO. */
@@ -474,6 +475,29 @@ For more information about these matters, see the files named COPYING.\n"),
}
}
+void
+add_file_directory_to_path (filename)
+ char *filename;
+{
+ char *directory_name = xstrdup (filename);
+ char *temp = filename_non_directory (directory_name);
+
+ if (temp != directory_name)
+ {
+ if (HAVE_DRIVE (directory_name) && temp == directory_name + 2)
+ {
+ /* The directory of "d:foo" is stored as "d:.", to avoid
+ mixing it with "d:/" when a slash is appended. */
+ *temp = '.';
+ temp += 2;
+ }
+ temp[-1] = 0;
+ info_add_path (directory_name, INFOPATH_PREPEND);
+ }
+
+ free (directory_name);
+}
+
/* Error handling. */
@@ -527,25 +551,34 @@ info_error (format, arg1, arg2)
static void
info_short_help ()
{
+#ifdef __MSDOS__
+ static const char speech_friendly_string[] = N_("\
+ -b, --speech-friendly be friendly to speech synthesizers.\n");
+#else
+ static const char speech_friendly_string[] = "";
+#endif
+
+
printf (_("\
Usage: %s [OPTION]... [MENU-ITEM...]\n\
\n\
Read documentation in Info format.\n\
\n\
Options:\n\
- --apropos=SUBJECT look up SUBJECT in all indices of all manuals.\n\
- --directory=DIR add DIR to INFOPATH.\n\
- --dribble=FILENAME remember user keystrokes in FILENAME.\n\
- --file=FILENAME specify Info file to visit.\n\
- --help display this help and exit.\n\
- --index-search=STRING go to node pointed by index entry STRING.\n\
- --node=NODENAME specify nodes in first visited Info file.\n\
- --output=FILENAME output selected nodes to FILENAME.\n\
- --restore=FILENAME read initial keystrokes from FILENAME.\n\
- --show-options, --usage go to command-line options node.\n\
- --subnodes recursively output menu items.\n%s\
- --vi-keys use vi-like and less-like key bindings.\n\
- --version display version information and exit.\n\
+ --apropos=STRING look up STRING in all indices of all manuals.\n\
+ -d, --directory=DIR add DIR to INFOPATH.\n\
+ --dribble=FILENAME remember user keystrokes in FILENAME.\n\
+ -f, --file=FILENAME specify Info file to visit.\n\
+ -h, --help display this help and exit.\n\
+ --index-search=STRING go to node pointed by index entry STRING.\n\
+ -n, --node=NODENAME specify nodes in first visited Info file.\n\
+ -o, --output=FILENAME output selected nodes to FILENAME.\n\
+ -R, --raw-escapes don't remove ANSI escapes from man pages.\n\
+ --restore=FILENAME read initial keystrokes from FILENAME.\n\
+ -O, --show-options, --usage go to command-line options node.\n%s\
+ --subnodes recursively output menu items.\n\
+ --vi-keys use vi-like and less-like key bindings.\n\
+ --version display version information and exit.\n\
\n\
The first non-option argument, if present, is the menu entry to start from;\n\
it is searched for in all `dir' files along INFOPATH.\n\
@@ -559,18 +592,13 @@ Examples:\n\
info emacs buffers start at buffers node within emacs manual\n\
info --show-options emacs start at node with emacs' command line options\n\
info -f ./foo.info show file ./foo.info, not searching dir\n\
-\n\
+"),
+ program_name, speech_friendly_string);
+
+ puts (_("\n\
Email bug reports to bug-texinfo@gnu.org,\n\
general questions and discussion to help-texinfo@gnu.org.\n\
-"),
- program_name,
-#ifdef __MSDOS__
-"\
- --speech-friendly be friendly to speech synthesizers.\n"
-#else
-""
-#endif
- );
+Texinfo home page: http://www.gnu.org/software/texinfo/"));
xexit (0);
}
diff --git a/gnu/usr.bin/texinfo/info/info.h b/gnu/usr.bin/texinfo/info/info.h
index 2e8cae21cbd..deb57e704ff 100644
--- a/gnu/usr.bin/texinfo/info/info.h
+++ b/gnu/usr.bin/texinfo/info/info.h
@@ -1,7 +1,7 @@
/* info.h -- Header file which includes all of the other headers.
- $Id: info.h,v 1.3 2000/02/09 02:18:40 espie Exp $
+ $Id: info.h,v 1.4 2002/06/10 13:51:03 espie Exp $
- Copyright (C) 1993, 97, 98, 99 Free Software Foundation, Inc.
+ Copyright (C) 1993, 97, 98, 99, 2001 Free Software Foundation, Inc.
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
@@ -25,6 +25,7 @@
/* We always want these, so why clutter up the compile command? */
#define HANDLE_MAN_PAGES
#define NAMED_FUNCTIONS
+#define INFOKEY
/* System dependencies. */
#include "system.h"
@@ -34,12 +35,11 @@ typedef int Function ();
typedef void VFunction ();
typedef char *CFunction ();
-
#include "filesys.h"
+#include "doc.h"
#include "display.h"
#include "session.h"
#include "echo-area.h"
-#include "doc.h"
#include "footnotes.h"
#include "gc.h"
@@ -119,14 +119,14 @@ extern int info_error_rings_bell_p;
/* Non-zero means default keybindings are loosely modeled on vi(1). */
extern int vi_keys_p;
+/* Non-zero means don't remove ANSI escape sequences from man pages. */
+extern int raw_escapes_p;
+
/* Print FORMAT with ARG1 and ARG2. If the window system was initialized,
then the message is printed in the echo area. Otherwise, a message is
output to stderr. */
extern void info_error ();
-/* The version numbers of Info. */
-extern int info_major_version, info_minor_version;
-
/* Error message defines. */
extern char *msg_cant_find_node;
extern char *msg_cant_file_node;
@@ -146,13 +146,14 @@ extern char *msg_win_too_small;
extern char *msg_cant_make_help;
-/* Found in info-utils.c. */
-extern char *filename_non_directory ();
+extern char *filename_non_directory (); /* Found in info-utils.c. */
-#if !defined (BUILDING_LIBRARY)
-/* Found in session.c */
-extern int info_windows_initialized_p;
+#if defined(INFOKEY)
+extern void set_variable_to_value (); /* Found in variables.c. */
+#endif /* INFOKEY */
+#if !defined (BUILDING_LIBRARY)
+extern int info_windows_initialized_p; /* Found in session.c */
/* Found in window.c. */
extern void message_in_echo_area (), unmessage_in_echo_area ();
#endif /* !BUILDING_LIBRARY */
diff --git a/gnu/usr.bin/texinfo/info/info.texi b/gnu/usr.bin/texinfo/info/info.texi
new file mode 100644
index 00000000000..43ea852e4cc
--- /dev/null
+++ b/gnu/usr.bin/texinfo/info/info.texi
@@ -0,0 +1,916 @@
+\input texinfo @c -*-texinfo-*-
+@comment %**start of header
+@setfilename info.info
+@settitle Info 1.0
+@comment %**end of header
+@comment $Id: info.texi,v 1.3 2002/06/10 13:51:03 espie Exp $
+
+@dircategory Texinfo documentation system
+@direntry
+* Info: (info). Documentation browsing system.
+@end direntry
+
+@ifinfo
+This file describes how to use Info,
+the on-line, menu-driven GNU documentation system.
+
+Copyright (C) 1989, 92, 96 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+@ignore
+Permission is granted to process this file through TeX and print the
+results, provided the printed document carries copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+
+@end ignore
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the entire
+resulting derived work is distributed under the terms of a permission
+notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation approved
+by the Free Software Foundation.
+@end ifinfo
+
+@titlepage
+@sp 11
+@center @titlefont{Info}
+@sp 2
+@center The
+@sp 2
+@center On-line, Menu-driven
+@sp 2
+@center GNU Documentation System
+
+@page
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1989, 1992, 1993 Free Software Foundation, Inc.
+@sp 2
+
+Published by the Free Software Foundation @*
+59 Temple Place - Suite 330 @*
+Boston, MA 02111-1307, USA.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the entire
+resulting derived work is distributed under the terms of a permission
+notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation approved
+by the Free Software Foundation.
+@end titlepage
+
+@ifinfo
+@node Top, Getting Started, (dir), (dir)
+@top Info: An Introduction
+
+Info is a program for reading documentation, which you are using now.
+
+To learn how to use Info, type the command @kbd{h}. It brings you
+to a programmed instruction sequence.
+
+@c Need to make sure that `Info-help' goes to the right node,
+@c which is the first node of the first chapter. (It should.)
+@c (Info-find-node "info"
+@c (if (< (window-height) 23)
+@c "Help-Small-Screen"
+@c "Help")))
+
+To learn advanced Info commands, type @kbd{n} twice. This brings you to
+@cite{Info for Experts}, skipping over the `Getting Started' chapter.
+@end ifinfo
+
+@menu
+* Getting Started:: Getting started using an Info reader.
+* Advanced Info:: Advanced commands within Info.
+* Create an Info File:: How to make your own Info file.
+* The Standalone Info Program: (info-stnd.info).
+@end menu
+
+@node Getting Started, Advanced Info, Top, Top
+@comment node-name, next, previous, up
+@chapter Getting Started
+
+This first part of the Info manual describes how to get around inside
+of Info. The second part of the manual describes various advanced
+Info commands, and how to write an Info as distinct from a Texinfo
+file. The third part is about how to generate Info files from
+Texinfo files.
+
+@iftex
+This manual is primarily designed for use on a computer, so that you can
+try Info commands while reading about them. Reading it on paper is less
+effective, since you must take it on faith that the commands described
+really do what the manual says. By all means go through this manual now
+that you have it; but please try going through the on-line version as
+well.
+
+There are two ways of looking at the online version of this manual:
+
+@enumerate
+@item
+Type @code{info} at your shell's command line. This approach uses a
+small stand-alone program designed just to read Info files.
+
+@item
+Type @code{emacs} at the command line; then type @kbd{C-h i} (Control
+@kbd{h}, followed by @kbd{i}). This approach uses the Info mode of the
+Emacs program, an editor with many other capabilities.
+@end enumerate
+
+In either case, then type @kbd{mInfo} (just the letters), followed by
+@key{RET}---the ``Return'' or ``Enter'' key. At this point, you should
+be ready to follow the instructions in this manual as you read them on
+the screen.
+@c FIXME! (pesch@cygnus.com, 14 dec 1992)
+@c Is it worth worrying about what-if the beginner goes to somebody
+@c else's Emacs session, which already has an Info running in the middle
+@c of something---in which case these simple instructions won't work?
+@end iftex
+
+@menu
+* Help-Small-Screen:: Starting Info on a Small Screen
+* Help:: How to use Info
+* Help-P:: Returning to the Previous node
+* Help-^L:: The Space, Rubout, B and ^L commands.
+* Help-M:: Menus
+* Help-Adv:: Some advanced Info commands
+* Help-Q:: Quitting Info
+@end menu
+
+@node Help-Small-Screen, Help, , Getting Started
+@comment node-name, next, previous, up
+@section Starting Info on a Small Screen
+
+@iftex
+(In Info, you only see this section if your terminal has a small
+number of lines; most readers pass by it without seeing it.)
+@end iftex
+
+Since your terminal has an unusually small number of lines on its
+screen, it is necessary to give you special advice at the beginning.
+
+If you see the text @samp{--All----} at near the bottom right corner
+of the screen, it means the entire text you are looking at fits on the
+screen. If you see @samp{--Top----} instead, it means that there is
+more text below that does not fit. To move forward through the text
+and see another screen full, press the Space bar, @key{SPC}. To move
+back up, press the key labeled @samp{Backspace} or @key{Delete}.
+
+@ifinfo
+Here are 40 lines of junk, so you can try Spaces and Deletes and
+see what they do. At the end are instructions of what you should do
+next.
+
+This is line 17 @*
+This is line 18 @*
+This is line 19 @*
+This is line 20 @*
+This is line 21 @*
+This is line 22 @*
+This is line 23 @*
+This is line 24 @*
+This is line 25 @*
+This is line 26 @*
+This is line 27 @*
+This is line 28 @*
+This is line 29 @*
+This is line 30 @*
+This is line 31 @*
+This is line 32 @*
+This is line 33 @*
+This is line 34 @*
+This is line 35 @*
+This is line 36 @*
+This is line 37 @*
+This is line 38 @*
+This is line 39 @*
+This is line 40 @*
+This is line 41 @*
+This is line 42 @*
+This is line 43 @*
+This is line 44 @*
+This is line 45 @*
+This is line 46 @*
+This is line 47 @*
+This is line 48 @*
+This is line 49 @*
+This is line 50 @*
+This is line 51 @*
+This is line 52 @*
+This is line 53 @*
+This is line 54 @*
+This is line 55 @*
+This is line 56 @*
+
+If you have managed to get here, go back to the beginning with
+Delete, and come back here again, then you understand Space and
+Delete. So now type an @kbd{n} ---just one character; don't type
+the quotes and don't type the Return key afterward--- to
+get to the normal start of the course.
+@end ifinfo
+
+@node Help, Help-P, Help-Small-Screen, Getting Started
+@comment node-name, next, previous, up
+@section How to use Info
+
+You are talking to the program Info, for reading documentation.
+
+ Right now you are looking at one @dfn{Node} of Information.
+A node contains text describing a specific topic at a specific
+level of detail. This node's topic is ``how to use Info''.
+
+ The top line of a node is its @dfn{header}. This node's header (look at
+it now) says that it is the node named @samp{Help} in the file
+@file{info}. It says that the @samp{Next} node after this one is the node
+called @samp{Help-P}. An advanced Info command lets you go to any node
+whose name you know.
+
+ Besides a @samp{Next}, a node can have a @samp{Previous} or an @samp{Up}.
+This node has a @samp{Previous} but no @samp{Up}, as you can see.
+
+ Now it is time to move on to the @samp{Next} node, named @samp{Help-P}.
+
+>> Type @samp{n} to move there. Type just one character;
+ do not type the quotes and do not type a @key{RET} afterward.
+
+@samp{>>} in the margin means it is really time to try a command.
+
+@node Help-P, Help-^L, Help, Getting Started
+@comment node-name, next, previous, up
+@section Returning to the Previous node
+
+This node is called @samp{Help-P}. The @samp{Previous} node, as you see,
+is @samp{Help}, which is the one you just came from using the @kbd{n}
+command. Another @kbd{n} command now would take you to the next
+node, @samp{Help-^L}.
+
+>> But do not do that yet. First, try the @kbd{p} command, which takes
+ you to the @samp{Previous} node. When you get there, you can do an
+ @kbd{n} again to return here.
+
+ This all probably seems insultingly simple so far, but @emph{do not} be
+led into skimming. Things will get more complicated soon. Also,
+do not try a new command until you are told it is time to. Otherwise,
+you may make Info skip past an important warning that was coming up.
+
+>> Now do an @kbd{n} to get to the node @samp{Help-^L} and learn more.
+
+@node Help-^L, Help-M, Help-P, Getting Started
+@comment node-name, next, previous, up
+@section The Space, Delete, B and ^L commands.
+
+ This node's header tells you that you are now at node @samp{Help-^L}, and
+that @kbd{p} would get you back to @samp{Help-P}. The node's title is
+underlined; it says what the node is about (most nodes have titles).
+
+ This is a big node and it does not all fit on your display screen.
+You can tell that there is more that is not visible because you
+can see the string @samp{--Top-----} rather than @samp{--All----} near
+the bottom right corner of the screen.
+
+ The Space, Delete and @kbd{B} commands exist to allow you to ``move
+around'' in a node that does not all fit on the screen at once.
+Space moves forward, to show what was below the bottom of the screen.
+Delete moves backward, to show what was above the top of the screen
+(there is not anything above the top until you have typed some spaces).
+
+>> Now try typing a Space (afterward, type a Delete to return here).
+
+ When you type the space, the two lines that were at the bottom of
+the screen appear at the top, followed by more lines. Delete takes
+the two lines from the top and moves them to the bottom,
+@emph{usually}, but if there are not a full screen's worth of lines
+above them they may not make it all the way to the bottom.
+
+ If you type Space when there is no more to see, it rings the
+bell and otherwise does nothing. The same goes for Delete when
+the header of the node is visible.
+
+ If your screen is ever garbaged, you can tell Info to print it out
+again by typing @kbd{C-l} (@kbd{Control-L}, that is---hold down ``Control'' and
+type an @key{L} or @kbd{l}).
+
+>> Type @kbd{C-l} now.
+
+ To move back to the beginning of the node you are on, you can type
+a lot of Deletes. You can also type simply @kbd{b} for beginning.
+>> Try that now. (We have put in enough verbiage to push this past
+the first screenful, but screens are so big nowadays that perhaps it
+isn't enough. You may need to shrink your Emacs or Info window.)
+Then come back, with Spaces.
+
+ If your screen is very tall, all of this node might fit at once.
+In that case, "b" won't do anything. Sorry; what can we do?
+
+ You have just learned a considerable number of commands. If you
+want to use one but have trouble remembering which, you should type
+a @key{?} which prints out a brief list of commands. When you are
+finished looking at the list, make it go away by typing a @key{SPC}.
+
+>> Type a @key{?} now. After it finishes, type a @key{SPC}.
+
+ (If you are using the standalone Info reader, type `l' to return here.)
+
+ From now on, you will encounter large nodes without warning, and
+will be expected to know how to use Space and Delete to move
+around in them without being told. Since not all terminals have
+the same size screen, it would be impossible to warn you anyway.
+
+>> Now type @kbd{n} to see the description of the @kbd{m} command.
+
+@node Help-M, Help-Adv, Help-^L, Getting Started
+@comment node-name, next, previous, up
+@section Menus
+
+Menus and the @kbd{m} command
+
+ With only the @kbd{n} and @kbd{p} commands for moving between nodes, nodes
+are restricted to a linear sequence. Menus allow a branching
+structure. A menu is a list of other nodes you can move to. It is
+actually just part of the text of the node formatted specially so that
+Info can interpret it. The beginning of a menu is always identified
+by a line which starts with @samp{* Menu:}. A node contains a menu if and
+only if it has a line in it which starts that way. The only menu you
+can use at any moment is the one in the node you are in. To use a
+menu in any other node, you must move to that node first.
+
+ After the start of the menu, each line that starts with a @samp{*}
+identifies one subtopic. The line usually contains a brief name
+for the subtopic (followed by a @samp{:}), the name of the node that talks
+about that subtopic, and optionally some further description of the
+subtopic. Lines in the menu that do not start with a @samp{*} have no
+special meaning---they are only for the human reader's benefit and do
+not define additional subtopics. Here is an example:
+
+@example
+* Foo: FOO's Node This tells about FOO
+@end example
+
+The subtopic name is Foo, and the node describing it is @samp{FOO's Node}.
+The rest of the line is just for the reader's Information.
+[[ But this line is not a real menu item, simply because there is
+no line above it which starts with @samp{* Menu:}.]]
+
+ When you use a menu to go to another node (in a way that will be
+described soon), what you specify is the subtopic name, the first
+thing in the menu line. Info uses it to find the menu line, extracts
+the node name from it, and goes to that node. The reason that there
+is both a subtopic name and a node name is that the node name must be
+meaningful to the computer and may therefore have to be ugly looking.
+The subtopic name can be chosen just to be convenient for the user to
+specify. Often the node name is convenient for the user to specify
+and so both it and the subtopic name are the same. There is an
+abbreviation for this:
+
+@example
+* Foo:: This tells about FOO
+@end example
+
+@noindent
+This means that the subtopic name and node name are the same; they are
+both @samp{Foo}.
+
+>> Now use Spaces to find the menu in this node, then come back to
+ the front with a @kbd{b} and some Spaces. As you see, a menu is
+ actually visible in its node. If you cannot find a menu in a node
+ by looking at it, then the node does not have a menu and the
+ @kbd{m} command is not available.
+
+ The command to go to one of the subnodes is @kbd{m}---but @emph{do
+not do it yet!} Before you use @kbd{m}, you must understand the
+difference between commands and arguments. So far, you have learned
+several commands that do not need arguments. When you type one, Info
+processes it and is instantly ready for another command. The @kbd{m}
+command is different: it is incomplete without the @dfn{name of the
+subtopic}. Once you have typed @kbd{m}, Info tries to read the
+subtopic name.
+
+ Now look for the line containing many dashes near the bottom of the
+screen. There is one more line beneath that one, but usually it is
+blank. If it is empty, Info is ready for a command, such as @kbd{n}
+or @kbd{b} or Space or @kbd{m}. If that line contains text ending
+in a colon, it mean Info is trying to read the @dfn{argument} to a
+command. At such times, commands do not work, because Info tries to
+use them as the argument. You must either type the argument and
+finish the command you started, or type @kbd{Control-g} to cancel the
+command. When you have done one of those things, the line becomes
+blank again.
+
+ The command to go to a subnode via a menu is @kbd{m}. After you type
+the @kbd{m}, the line at the bottom of the screen says @samp{Menu item: }.
+You must then type the name of the subtopic you want, and end it with
+a @key{RET}.
+
+ You can abbreviate the subtopic name. If the abbreviation is not
+unique, the first matching subtopic is chosen. Some menus put
+the shortest possible abbreviation for each subtopic name in capital
+letters, so you can see how much you need to type. It does not
+matter whether you use upper case or lower case when you type the
+subtopic. You should not put any spaces at the end, or inside of the
+item name, except for one space where a space appears in the item in
+the menu.
+
+ You can also use the @dfn{completion} feature to help enter the subtopic
+name. If you type the Tab key after entering part of a name, it will
+magically fill in more of the name---as much as follows uniquely from
+what you have entered.
+
+ If you move the cursor to one of the menu subtopic lines, then you do
+not need to type the argument: you just type a Return, and it stands for
+the subtopic of the line you are on.
+
+Here is a menu to give you a chance to practice.
+
+* Menu: The menu starts here.
+
+This menu gives you three ways of going to one place, Help-FOO.
+
+* Foo: Help-FOO. A node you can visit for fun.@*
+* Bar: Help-FOO. Strange! two ways to get to the same place.@*
+* Help-FOO:: And yet another!@*
+
+
+>> Now type just an @kbd{m} and see what happens:
+
+ Now you are ``inside'' an @kbd{m} command. Commands cannot be used
+now; the next thing you will type must be the name of a subtopic.
+
+ You can change your mind about doing the @kbd{m} by typing Control-g.
+
+>> Try that now; notice the bottom line clear.
+
+>> Then type another @kbd{m}.
+
+>> Now type @samp{BAR} item name. Do not type Return yet.
+
+ While you are typing the item name, you can use the Delete key to
+cancel one character at a time if you make a mistake.
+
+>> Type one to cancel the @samp{R}. You could type another @samp{R} to
+ replace it. You do not have to, since @samp{BA} is a valid abbreviation.
+
+>> Now you are ready to go. Type a @key{RET}.
+
+ After visiting Help-FOO, you should return here.
+
+>> Type @kbd{n} to see more commands.
+
+@c If a menu appears at the end of this node, remove it.
+@c It is an accident of the menu updating command.
+
+Here is another way to get to Help-FOO, a menu. You can ignore this
+if you want, or else try it (but then please come back to here).
+
+@menu
+* Help-FOO::
+@end menu
+
+@node Help-FOO, , , Help-M
+@comment node-name, next, previous, up
+@subsection The @kbd{u} command
+
+ Congratulations! This is the node @samp{Help-FOO}. Unlike the other
+nodes you have seen, this one has an @samp{Up}: @samp{Help-M}, the node you
+just came from via the @kbd{m} command. This is the usual
+convention---the nodes you reach from a menu have @samp{Up} nodes that lead
+back to the menu. Menus move Down in the tree, and @samp{Up} moves Up.
+@samp{Previous}, on the other hand, is usually used to ``stay on the same
+level but go backwards''
+
+ You can go back to the node @samp{Help-M} by typing the command
+@kbd{u} for ``Up''. That puts you at the @emph{front} of the
+node---to get back to where you were reading you have to type
+some @key{SPC}s.
+
+>> Now type @kbd{u} to move back up to @samp{Help-M}.
+
+@node Help-Adv, Help-Q, Help-M, Getting Started
+@comment node-name, next, previous, up
+@section Some advanced Info commands
+
+ The course is almost over, so please stick with it to the end.
+
+ If you have been moving around to different nodes and wish to
+retrace your steps, the @kbd{l} command (@kbd{l} for @dfn{last}) will
+do that, one node-step at a time. As you move from node to node, Info
+records the nodes where you have been in a special history list. The
+@kbd{l} command revisits nodes in the history list; each successive
+@kbd{l} command moves one step back through the history.
+
+ If you have been following directions, ad @kbd{l} command now will get
+you back to @samp{Help-M}. Another @kbd{l} command would undo the
+@kbd{u} and get you back to @samp{Help-FOO}. Another @kbd{l} would undo
+the @kbd{m} and get you back to @samp{Help-M}.
+
+>> Try typing three @kbd{l}'s, pausing in between to see what each
+ @kbd{l} does.
+
+Then follow directions again and you will end up back here.
+
+ Note the difference between @kbd{l} and @kbd{p}: @kbd{l} moves to
+where @emph{you} last were, whereas @kbd{p} always moves to the node
+which the header says is the @samp{Previous} node (from this node, to
+@samp{Help-M}).
+
+ The @samp{d} command gets you instantly to the Directory node.
+This node, which is the first one you saw when you entered Info,
+has a menu which leads (directly, or indirectly through other menus),
+to all the nodes that exist.
+
+>> Try doing a @samp{d}, then do an @kbd{l} to return here (yes,
+ @emph{do} return).
+
+ Sometimes, in Info documentation, you will see a cross reference.
+Cross references look like this: @xref{Help-Cross, Cross}. That is a
+real, live cross reference which is named @samp{Cross} and points at
+the node named @samp{Help-Cross}.
+
+ If you wish to follow a cross reference, you must use the @samp{f}
+command. The @samp{f} must be followed by the cross reference name
+(in this case, @samp{Cross}). While you enter the name, you can use the
+Delete key to edit your input. If you change your mind about following
+any reference, you can use @kbd{Control-g} to cancel the command.
+
+ Completion is available in the @samp{f} command; you can complete among
+all the cross reference names in the current node by typing a Tab.
+
+>> Type @samp{f}, followed by @samp{Cross}, and a @key{RET}.
+
+ To get a list of all the cross references in the current node, you can
+type @kbd{?} after an @samp{f}. The @samp{f} continues to await a
+cross reference name even after printing the list, so if you don't
+actually want to follow a reference, you should type a @kbd{Control-g}
+to cancel the @samp{f}.
+
+>> Type "f?" to get a list of the cross references in this node. Then
+ type a @kbd{Control-g} and see how the @samp{f} gives up.
+
+>> Now type @kbd{n} to see the last node of the course.
+
+@c If a menu appears at the end of this node, remove it.
+@c It is an accident of the menu updating command.
+
+@node Help-Cross, , , Help-Adv
+@comment node-name, next, previous, up
+@unnumberedsubsec The node reached by the cross reference in Info
+
+ This is the node reached by the cross reference named @samp{Cross}.
+
+ While this node is specifically intended to be reached by a cross
+reference, most cross references lead to nodes that ``belong''
+someplace else far away in the structure of Info. So you cannot expect
+the footnote to have a @samp{Next}, @samp{Previous} or @samp{Up} pointing back to
+where you came from. In general, the @kbd{l} (el) command is the only
+way to get back there.
+
+>> Type @kbd{l} to return to the node where the cross reference was.
+
+@node Help-Q, , Help-Adv, Getting Started
+@comment node-name, next, previous, up
+@section Quitting Info
+
+ To get out of Info, back to what you were doing before, type @kbd{q}
+for @dfn{Quit}.
+
+ This is the end of the course on using Info. There are some other
+commands that are meant for experienced users; they are useful, and you
+can find them by looking in the directory node for documentation on
+Info. Finding them will be a good exercise in using Info in the usual
+manner.
+
+>> Type @samp{d} to go to the Info directory node; then type
+ @samp{mInfo} and Return, to get to the node about Info and
+ see what other help is available.
+
+@node Advanced Info, Create an Info File, Getting Started, Top
+@comment node-name, next, previous, up
+@chapter Info for Experts
+
+This chapter describes various advanced Info commands, and how to write
+an Info as distinct from a Texinfo file. (However, in most cases, writing a
+Texinfo file is better, since you can use it @emph{both} to generate an
+Info file and to make a printed manual. @xref{Top,, Overview of
+Texinfo, texinfo, Texinfo: The GNU Documentation Format}.)
+
+@menu
+* Expert:: Advanced Info commands: g, s, e, and 1 - 5.
+* Add:: Describes how to add new nodes to the hierarchy.
+ Also tells what nodes look like.
+* Menus:: How to add to or create menus in Info nodes.
+* Cross-refs:: How to add cross-references to Info nodes.
+* Tags:: How to make tag tables for Info files.
+* Checking:: Checking an Info File
+* Emacs Info Variables:: Variables modifying the behavior of Emacs Info.
+@end menu
+
+@node Expert, Add, , Advanced Info
+@comment node-name, next, previous, up
+@section Advanced Info Commands
+
+@kbd{g}, @kbd{s}, @kbd{1}, -- @kbd{9}, and @kbd{e}
+
+If you know a node's name, you can go there by typing @kbd{g}, the
+name, and @key{RET}. Thus, @kbd{gTop@key{RET}} would go to the node
+called @samp{Top} in this file (its directory node).
+@kbd{gExpert@key{RET}} would come back here.
+
+Unlike @kbd{m}, @kbd{g} does not allow the use of abbreviations.
+
+To go to a node in another file, you can include the filename in the
+node name by putting it at the front, in parentheses. Thus,
+@kbd{g(dir)Top@key{RET}} would go to the Info Directory node, which is
+node @samp{Top} in the file @file{dir}.
+
+The node name @samp{*} specifies the whole file. So you can look at
+all of the current file by typing @kbd{g*@key{RET}} or all of any
+other file with @kbd{g(FILENAME)@key{RET}}.
+
+The @kbd{s} command allows you to search a whole file for a string.
+It switches to the next node if and when that is necessary. You
+type @kbd{s} followed by the string to search for, terminated by
+@key{RET}. To search for the same string again, just @kbd{s} followed
+by @key{RET} will do. The file's nodes are scanned in the order
+they are in in the file, which has no necessary relationship to the
+order that they may be in in the tree structure of menus and @samp{next} pointers.
+But normally the two orders are not very different. In any case,
+you can always do a @kbd{b} to find out what node you have reached, if
+the header is not visible (this can happen, because @kbd{s} puts your
+cursor at the occurrence of the string, not at the beginning of the
+node).
+
+If you grudge the system each character of type-in it requires, you
+might like to use the commands @kbd{1}, @kbd{2}, @kbd{3}, @kbd{4}, ...
+@kbd{9}. They are short for the @kbd{m} command together with an
+argument. @kbd{1} goes through the first item in the current node's
+menu; @kbd{2} goes through the second item, etc.
+
+If you display supports multiple fonts, and you are using Emacs' Info
+mode to read Info files, the @samp{*} for the fifth menu item is
+underlines, and so is the @samp{*} for the ninth item; these underlines
+make it easy to see at a glance which number to use for an item.
+
+On ordinary terminals, you won't have underlining. If you need to
+actually count items, it is better to use @kbd{m} instead, and specify
+the name.
+
+The Info command @kbd{e} changes from Info mode to an ordinary
+Emacs editing mode, so that you can edit the text of the current node.
+Type @kbd{C-c C-c} to switch back to Info. The @kbd{e} command is allowed
+only if the variable @code{Info-enable-edit} is non-@code{nil}.
+
+@node Add, Menus, Expert, Advanced Info
+@comment node-name, next, previous, up
+@section Adding a new node to Info
+
+To add a new topic to the list in the Info directory, you must:
+@enumerate
+@item
+Create some nodes, in some file, to document that topic.
+@item
+Put that topic in the menu in the directory. @xref{Menus, Menu}.
+@end enumerate
+
+Usually, the way to create the nodes is with Texinfo @pxref{Top,, Overview of
+Texinfo, texinfo, Texinfo: The GNU Documentation Format}); this has the
+advantage that you can also make a printed manual from them. However,
+if hyou want to edit an Info file, here is how.
+
+ The new node can live in an existing documentation file, or in a new
+one. It must have a @key{^_} character before it (invisible to the
+user; this node has one but you cannot see it), and it ends with either
+a @key{^_}, a @key{^L}, or the end of file. Note: If you put in a
+@key{^L} to end a new node, be sure that there is a @key{^_} after it
+to start the next one, since @key{^L} cannot @emph{start} a node.
+Also, a nicer way to make a node boundary be a page boundary as well
+is to put a @key{^L} @emph{right after} the @key{^_}.
+
+ The @key{^_} starting a node must be followed by a newline or a
+@key{^L} newline, after which comes the node's header line. The
+header line must give the node's name (by which Info finds it),
+and state the names of the @samp{Next}, @samp{Previous}, and @samp{Up} nodes (if
+there are any). As you can see, this node's @samp{Up} node is the node
+@samp{Top}, which points at all the documentation for Info. The @samp{Next}
+node is @samp{Menus}.
+
+ The keywords @dfn{Node}, @dfn{Previous}, @dfn{Up}, and @dfn{Next},
+may appear in any order, anywhere in the header line, but the
+recommended order is the one in this sentence. Each keyword must be
+followed by a colon, spaces and tabs, and then the appropriate name.
+The name may be terminated with a tab, a comma, or a newline. A space
+does not end it; node names may contain spaces. The case of letters
+in the names is insignificant.
+
+ A node name has two forms. A node in the current file is named by
+what appears after the @samp{Node: } in that node's first line. For
+example, this node's name is @samp{Add}. A node in another file is
+named by @samp{(@var{filename})@var{node-within-file}}, as in
+@samp{(info)Add} for this node. If the file name starts with ``./'',
+then it is relative to the current directory; otherwise, it is relative
+starting from the standard Info file directory of your site.
+The name @samp{(@var{filename})Top} can be abbreviated to just
+@samp{(@var{filename})}. By convention, the name @samp{Top} is used for
+the ``highest'' node in any single file---the node whose @samp{Up} points
+out of the file. The Directory node is @file{(dir)}. The @samp{Top} node
+of a document file listed in the Directory should have an @samp{Up:
+(dir)} in it.
+
+ The node name @kbd{*} is special: it refers to the entire file.
+Thus, @kbd{g*} shows you the whole current file. The use of the
+node @kbd{*} is to make it possible to make old-fashioned,
+unstructured files into nodes of the tree.
+
+ The @samp{Node:} name, in which a node states its own name, must not
+contain a filename, since Info when searching for a node does not
+expect one to be there. The @samp{Next}, @samp{Previous} and @samp{Up} names may
+contain them. In this node, since the @samp{Up} node is in the same file,
+it was not necessary to use one.
+
+ Note that the nodes in this file have a file name in the header
+line. The file names are ignored by Info, but they serve as comments
+to help identify the node for the user.
+
+@node Menus, Cross-refs, Add, Advanced Info
+@comment node-name, next, previous, up
+@section How to Create Menus
+
+ Any node in the Info hierarchy may have a @dfn{menu}---a list of subnodes.
+The @kbd{m} command searches the current node's menu for the topic which it
+reads from the terminal.
+
+ A menu begins with a line starting with @samp{* Menu:}. The rest of the
+line is a comment. After the starting line, every line that begins
+with a @samp{* } lists a single topic. The name of the topic--the
+argument that the user must give to the @kbd{m} command to select this
+topic---comes right after the star and space, and is followed by a
+colon, spaces and tabs, and the name of the node which discusses that
+topic. The node name, like node names following @samp{Next}, @samp{Previous}
+and @samp{Up}, may be terminated with a tab, comma, or newline; it may also
+be terminated with a period.
+
+ If the node name and topic name are the same, then rather than
+giving the name twice, the abbreviation @samp{* NAME::} may be used
+(and should be used, whenever possible, as it reduces the visual
+clutter in the menu).
+
+ It is considerate to choose the topic names so that they differ
+from each other very near the beginning---this allows the user to type
+short abbreviations. In a long menu, it is a good idea to capitalize
+the beginning of each item name which is the minimum acceptable
+abbreviation for it (a long menu is more than 5 or so entries).
+
+ The nodes listed in a node's menu are called its ``subnodes'', and
+it is their ``superior''. They should each have an @samp{Up:} pointing at
+the superior. It is often useful to arrange all or most of the
+subnodes in a sequence of @samp{Next} and @samp{Previous} pointers so that someone who
+wants to see them all need not keep revisiting the Menu.
+
+ The Info Directory is simply the menu of the node @samp{(dir)Top}---that
+is, node @samp{Top} in file @file{.../info/dir}. You can put new entries
+in that menu just like any other menu. The Info Directory is @emph{not} the
+same as the file directory called @file{info}. It happens that many of
+Info's files live on that file directory, but they do not have to; and
+files on that directory are not automatically listed in the Info
+Directory node.
+
+ Also, although the Info node graph is claimed to be a ``hierarchy'',
+in fact it can be @emph{any} directed graph. Shared structures and
+pointer cycles are perfectly possible, and can be used if they are
+appropriate to the meaning to be expressed. There is no need for all
+the nodes in a file to form a connected structure. In fact, this file
+has two connected components. You are in one of them, which is under
+the node @samp{Top}; the other contains the node @samp{Help} which the
+@kbd{h} command goes to. In fact, since there is no garbage
+collector, nothing terrible happens if a substructure is not pointed
+to, but such a substructure is rather useless since nobody can
+ever find out that it exists.
+
+@node Cross-refs, Tags, Menus, Advanced Info
+@comment node-name, next, previous, up
+@section Creating Cross References
+
+ A cross reference can be placed anywhere in the text, unlike a menu
+item which must go at the front of a line. A cross reference looks
+like a menu item except that it has @samp{*note} instead of @kbd{*}.
+It @emph{cannot} be terminated by a @samp{)}, because @samp{)}'s are
+so often part of node names. If you wish to enclose a cross reference
+in parentheses, terminate it with a period first. Here are two
+examples of cross references pointers:
+
+@example
+*Note details: commands. (See *note 3: Full Proof.)
+@end example
+
+They are just examples. The places they ``lead to'' do not really exist!
+
+@node Tags, Checking, Cross-refs, Advanced Info
+@comment node-name, next, previous, up
+@section Tag Tables for Info Files
+
+ You can speed up the access to nodes of a large Info file by giving
+it a tag table. Unlike the tag table for a program, the tag table for
+an Info file lives inside the file itself and is used
+automatically whenever Info reads in the file.
+
+ To make a tag table, go to a node in the file using Emacs Info mode and type
+@kbd{M-x Info-tagify}. Then you must use @kbd{C-x C-s} to save the
+file.
+
+ Once the Info file has a tag table, you must make certain it is up
+to date. If, as a result of deletion of text, any node moves back
+more than a thousand characters in the file from the position
+recorded in the tag table, Info will no longer be able to find that
+node. To update the tag table, use the @code{Info-tagify} command again.
+
+ An Info file tag table appears at the end of the file and looks like
+this:
+
+@example
+^_
+Tag Table:
+File: info, Node: Cross-refs^?21419
+File: info, Node: Tags^?22145
+^_
+End Tag Table
+@end example
+
+@noindent
+Note that it contains one line per node, and this line contains
+the beginning of the node's header (ending just after the node name),
+a Delete character, and the character position in the file of the
+beginning of the node.
+
+@node Checking, Emacs Info Variables, Tags, Advanced Info
+@comment node-name, next, previous, up
+@section Checking an Info File
+
+ When creating an Info file, it is easy to forget the name of a node
+when you are making a pointer to it from another node. If you put in
+the wrong name for a node, this is not detected until someone
+tries to go through the pointer using Info. Verification of the Info
+file is an automatic process which checks all pointers to nodes and
+reports any pointers which are invalid. Every @samp{Next}, @samp{Previous}, and
+@samp{Up} is checked, as is every menu item and every cross reference. In
+addition, any @samp{Next} which does not have a @samp{Previous} pointing back is
+reported. Only pointers within the file are checked, because checking
+pointers to other files would be terribly slow. But those are usually
+few.
+
+ To check an Info file, do @kbd{M-x Info-validate} while looking at
+any node of the file with Emacs Info mode.
+
+@node Emacs Info Variables, , Checking, Advanced Info
+@section Emacs Info-mode Variables
+
+The following variables may modify the behaviour of Info-mode in Emacs;
+you may wish to set one or several of these variables interactively, or
+in your @file{~/.emacs} init file. @xref{Examining, Examining and Setting
+Variables, Examining and Setting Variables, emacs, The GNU Emacs
+Manual}.
+
+@vtable @code
+@item Info-enable-edit
+Set to @code{nil}, disables the @samp{e} (@code{Info-edit}) command. A
+non-@code{nil} value enables it. @xref{Add, Edit}.
+
+@item Info-enable-active-nodes
+When set to a non-@code{nil} value, allows Info to execute Lisp code
+associated with nodes. The Lisp code is executed when the node is
+selected.
+
+@item Info-directory-list
+The list of directories to search for Info files. Each element is a
+string (directory name) or @code{nil} (try default directory).
+
+@item Info-directory
+The standard directory for Info documentation files. Only used when the
+function @code{Info-directory} is called.
+@end vtable
+
+@node Create an Info File, , Advanced Info, Top
+@comment node-name, next, previous, up
+@chapter Creating an Info File from a Makeinfo file
+
+@code{makeinfo} is a utility that converts a Texinfo file into an Info
+file; @code{texinfo-format-region} and @code{texinfo-format-buffer} are
+GNU Emacs functions that do the same.
+
+@xref{Create an Info File, , Creating an Info File, texinfo, the Texinfo
+Manual}, to learn how to create an Info file from a Texinfo file.
+
+@xref{Top,, Overview of Texinfo, texinfo, Texinfo: The GNU Documentation
+Format}, to learn how to write a Texinfo file.
+
+@bye
diff --git a/gnu/usr.bin/texinfo/info/infodoc.c b/gnu/usr.bin/texinfo/info/infodoc.c
index f3e15738d86..8d0c42dad4c 100644
--- a/gnu/usr.bin/texinfo/info/infodoc.c
+++ b/gnu/usr.bin/texinfo/info/infodoc.c
@@ -1,7 +1,7 @@
/* infodoc.c -- Functions which build documentation nodes.
- $Id: infodoc.c,v 1.3 2000/02/09 02:18:40 espie Exp $
+ $Id: infodoc.c,v 1.4 2002/06/10 13:51:03 espie Exp $
- Copyright (C) 1993, 97, 98, 99 Free Software Foundation, Inc.
+ Copyright (C) 1993, 97, 98, 99, 2001, 02 Free Software Foundation, Inc.
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
@@ -20,17 +20,12 @@
Written by Brian Fox (bfox@ai.mit.edu). */
#include "info.h"
+#include "funs.h"
/* HELP_NODE_GETS_REGENERATED is always defined now that keys may get
rebound, or other changes in the help text may occur. */
#define HELP_NODE_GETS_REGENERATED 1
-/* **************************************************************** */
-/* */
-/* Info Help Windows */
-/* */
-/* **************************************************************** */
-
/* The name of the node used in the help window. */
static char *info_help_nodename = "*Info Help*";
@@ -40,26 +35,71 @@ static NODE *internal_info_help_node = (NODE *)NULL;
/* A pointer to the contents of the help node. */
static char *internal_info_help_node_contents = (char *)NULL;
-/* The static text which appears in the internal info help node. */
+/* The (more or less) static text which appears in the internal info
+ help node. The actual key bindings are inserted. Keep the
+ underlines (****, etc.) in the same N_ call as the text lines they
+ refer to, so translations can make the number of *'s or -'s match. */
+#if defined(INFOKEY)
+
+static char *info_internal_help_text[] = {
+ N_("Basic Commands in Info Windows\n\
+******************************\n"),
+ "\n",
+ N_("\\%-10[quit-help] Quit this help.\n"),
+ N_("\\%-10[quit] Quit Info altogether.\n"),
+ N_("\\%-10[get-info-help-node] Invoke the Info tutorial.\n"),
+ "\n",
+ N_("Selecting other nodes:\n\
+----------------------\n"),
+ N_("\\%-10[next-node] Move to the \"next\" node of this node.\n"),
+ N_("\\%-10[prev-node] Move to the \"previous\" node of this node.\n"),
+ N_("\\%-10[up-node] Move \"up\" from this node.\n"),
+ N_("\\%-10[menu-item] Pick menu item specified by name.\n\
+ Picking a menu item causes another node to be selected.\n"),
+ N_("\\%-10[xref-item] Follow a cross reference. Reads name of reference.\n"),
+ N_("\\%-10[history-node] Move to the last node seen in this window.\n"),
+ N_("\\%-10[move-to-next-xref] Skip to next hypertext link within this node.\n"),
+ N_("\\%-10[move-to-prev-xref] Skip to previous hypertext link within this node.\n"),
+ N_("\\%-10[select-reference-this-line] Follow the hypertext link under cursor.\n"),
+ N_("\\%-10[dir-node] Move to the `directory' node. Equivalent to `\\[goto-node] (DIR)'.\n"),
+ N_("\\%-10[top-node] Move to the Top node. Equivalent to `\\[goto-node] Top'.\n"),
+ "\n",
+ N_("Moving within a node:\n\
+---------------------\n"),
+ N_("\\%-10[scroll-forward] Scroll forward a page.\n"),
+ N_("\\%-10[scroll-backward] Scroll backward a page.\n"),
+ N_("\\%-10[beginning-of-node] Go to the beginning of this node.\n"),
+ N_("\\%-10[end-of-node] Go to the end of this node.\n"),
+ N_("\\%-10[scroll-forward] Scroll forward 1 line.\n"),
+ N_("\\%-10[scroll-backward] Scroll backward 1 line.\n"),
+ "\n",
+ N_("Other commands:\n\
+---------------\n"),
+ N_("\\%-10[menu-digit] Pick first ... ninth item in node's menu.\n"),
+ N_("\\%-10[last-menu-item] Pick last item in node's menu.\n"),
+ N_("\\%-10[index-search] Search for a specified string in the index entries of this Info\n\
+ file, and select the node referenced by the first entry found.\n"),
+ N_("\\%-10[goto-node] Move to node specified by name.\n\
+ You may include a filename as well, as in (FILENAME)NODENAME.\n"),
+ N_("\\%-10[search] Search forward for a specified string\n\
+ and select the node in which the next occurrence is found.\n"),
+ N_("\\%-10[search-backward] Search backward for a specified string\n\
+ and select the node in which the previous occurrence is found.\n"),
+ NULL
+};
+
+#else /* !INFOKEY */
+
static char *info_internal_help_text[] = {
- N_("Basic Commands in Info Windows\n"),
- N_("******************************\n"),
+ N_("Basic Commands in Info Windows\n\
+******************************\n"),
"\n",
N_(" %-10s Quit this help.\n"),
N_(" %-10s Quit Info altogether.\n"),
N_(" %-10s Invoke the Info tutorial.\n"),
"\n",
- N_("Moving within a node:\n"),
- N_("---------------------\n"),
- N_(" %-10s Scroll forward a page.\n"),
- N_(" %-10s Scroll backward a page.\n"),
- N_(" %-10s Go to the beginning of this node.\n"),
- N_(" %-10s Go to the end of this node.\n"),
- N_(" %-10s Scroll forward 1 line.\n"),
- N_(" %-10s Scroll backward 1 line.\n"),
- "\n",
- N_("Selecting other nodes:\n"),
- N_("----------------------\n"),
+ N_("Selecting other nodes:\n\
+----------------------\n",
N_(" %-10s Move to the `next' node of this node.\n"),
N_(" %-10s Move to the `previous' node of this node.\n"),
N_(" %-10s Move `up' from this node.\n"),
@@ -72,17 +112,26 @@ static char *info_internal_help_text[] = {
N_(" %-10s Move to the `directory' node. Equivalent to `g (DIR)'.\n"),
N_(" %-10s Move to the Top node. Equivalent to `g Top'.\n"),
"\n",
- N_("Other commands:\n"),
- N_("---------------\n"),
+ N_("Moving within a node:\n\
+---------------------\n"),
+ N_(" %-10s Scroll forward a page.\n"),
+ N_(" %-10s Scroll backward a page.\n"),
+ N_(" %-10s Go to the beginning of this node.\n"),
+ N_(" %-10s Go to the end of this node.\n"),
+ N_(" %-10s Scroll forward 1 line.\n"),
+ N_(" %-10s Scroll backward 1 line.\n"),
+ "\n",
+ N_("Other commands:\n\
+---------------\n"),
N_(" %-10s Pick first ... ninth item in node's menu.\n"),
N_(" %-10s Pick last item in node's menu.\n"),
N_(" %-10s Search for a specified string in the index entries of this Info\n"),
N_(" file, and select the node referenced by the first entry found.\n"),
N_(" %-10s Move to node specified by name.\n"),
N_(" You may include a filename as well, as in (FILENAME)NODENAME.\n"),
- N_(" %-10s Search forward through this Info file for a specified string,\n"),
+ N_(" %-10s Search forward for a specified string,\n"),
N_(" and select the node in which the next occurrence is found.\n"),
- N_(" %-10s Search backward in this Info file for a specified string,\n"),
+ N_(" %-10s Search backward for a specified string\n"),
N_(" and select the node in which the next occurrence is found.\n"),
NULL
};
@@ -133,7 +182,9 @@ static char *info_help_keys_text[][2] = {
NULL
};
-static char *where_is (), *where_is_internal ();
+#endif /* !INFOKEY */
+
+static char *where_is_internal ();
void
dump_map_to_message_buffer (prefix, map)
@@ -141,20 +192,18 @@ dump_map_to_message_buffer (prefix, map)
Keymap map;
{
register int i;
+ unsigned prefix_len = strlen (prefix);
+ char *new_prefix = (char *)xmalloc (prefix_len + 2);
+
+ strncpy (new_prefix, prefix, prefix_len);
+ new_prefix[prefix_len + 1] = '\0';
for (i = 0; i < 256; i++)
{
+ new_prefix[prefix_len] = i;
if (map[i].type == ISKMAP)
{
- char *new_prefix, *keyname;
-
- keyname = pretty_keyname (i);
- new_prefix = (char *)
- xmalloc (3 + strlen (prefix) + strlen (keyname));
- sprintf (new_prefix, "%s%s%s ", prefix, *prefix ? " " : "", keyname);
-
dump_map_to_message_buffer (new_prefix, (Keymap)map[i].function);
- free (new_prefix);
}
else if (map[i].function)
{
@@ -176,14 +225,13 @@ dump_map_to_message_buffer (prefix, map)
if (last - 1 != i)
{
- printf_to_message_buffer
- ("%s%s .. ", prefix, pretty_keyname (i));
- printf_to_message_buffer
- ("%s%s\t", prefix, pretty_keyname (last - 1));
+ printf_to_message_buffer ("%s .. ", pretty_keyseq (new_prefix));
+ new_prefix[prefix_len] = last - 1;
+ printf_to_message_buffer ("%s\t", pretty_keyseq (new_prefix));
i = last - 1;
}
else
- printf_to_message_buffer ("%s%s\t", prefix, pretty_keyname (i));
+ printf_to_message_buffer ("%s\t", pretty_keyseq (new_prefix));
#if defined (NAMED_FUNCTIONS)
/* Print the name of the function, and some padding before the
@@ -210,6 +258,7 @@ dump_map_to_message_buffer (prefix, map)
printf_to_message_buffer ("%s\n", doc);
}
}
+ free (new_prefix);
}
/* How to create internal_info_help_node. HELP_IS_ONLY_WINDOW_P says
@@ -225,6 +274,7 @@ create_internal_info_help_node (help_is_only_window_p)
register int i;
NODE *node;
char *contents = NULL;
+ char *exec_keys;
#ifndef HELP_NODE_GETS_REGENERATED
if (internal_info_help_node_contents)
@@ -239,6 +289,10 @@ create_internal_info_help_node (help_is_only_window_p)
for (i = 0; info_internal_help_text[i]; i++)
{
+#ifdef INFOKEY
+ printf_to_message_buffer (replace_in_documentation (
+ _(info_internal_help_text[i]), help_is_only_window_p));
+#else
/* Don't translate blank lines, gettext outputs the po file
header in that case. We want a blank line. */
char *msg = *(info_internal_help_text[i])
@@ -252,6 +306,7 @@ create_internal_info_help_node (help_is_only_window_p)
key = "l";
printf_to_message_buffer (msg, key);
+#endif /* !INFOKEY */
}
printf_to_message_buffer ("---------------------\n\n");
@@ -265,35 +320,46 @@ create_internal_info_help_node (help_is_only_window_p)
dump_map_to_message_buffer ("", echo_area_keymap);
#if defined (NAMED_FUNCTIONS)
- /* Get a list of the M-x commands which have no keystroke equivs. */
+ /* Get a list of commands which have no keystroke equivs. */
+ exec_keys = where_is (info_keymap, InfoCmd(info_execute_command));
+ if (exec_keys)
+ exec_keys = xstrdup (exec_keys);
for (i = 0; function_doc_array[i].func; i++)
{
- VFunction *func = function_doc_array[i].func;
+ InfoCommand *cmd = DocInfoCmd(&function_doc_array[i]);
- if ((!where_is_internal (info_keymap, func)) &&
- (!where_is_internal (echo_area_keymap, func)))
+ if (InfoFunction(cmd) != info_do_lowercase_version
+ && !where_is_internal (info_keymap, cmd)
+ && !where_is_internal (echo_area_keymap, cmd))
{
if (!printed_one_mx)
{
printf_to_message_buffer ("---------------------\n\n");
- printf_to_message_buffer
- (_("The following commands can only be invoked via M-x:\n\n"));
+ if (exec_keys && exec_keys[0])
+ printf_to_message_buffer
+ (_("The following commands can only be invoked via %s:\n\n"), exec_keys);
+ else
+ printf_to_message_buffer
+ (_("The following commands cannot be invoked at all:\n\n"));
printed_one_mx = 1;
}
printf_to_message_buffer
- ("M-x %s\n %s\n",
+ ("%s %s\n %s\n",
+ exec_keys,
function_doc_array[i].func_name,
replace_in_documentation (strlen (function_doc_array[i].doc)
- == 0
- ? function_doc_array[i].doc
- : _(function_doc_array[i].doc)));
+ ? _(function_doc_array[i].doc)
+ : "")
+ );
}
}
if (printed_one_mx)
printf_to_message_buffer ("\n");
+
+ maybe_free (exec_keys);
#endif /* NAMED_FUNCTIONS */
printf_to_message_buffer
@@ -492,39 +558,56 @@ DECLARE_INFO_COMMAND (info_get_info_help_node, _("Visit Info node `(info)Help'")
/* Return the documentation associated with the Info command FUNCTION. */
char *
-function_documentation (function)
- VFunction *function;
+function_documentation (cmd)
+ InfoCommand *cmd;
{
+ char *doc;
+
+#if defined (INFOKEY)
+
+ doc = cmd->doc;
+
+#else /* !INFOKEY */
+
register int i;
for (i = 0; function_doc_array[i].func; i++)
- if (function == function_doc_array[i].func)
+ if (InfoFunction(cmd) == function_doc_array[i].func)
break;
- return replace_in_documentation ((strlen (function_doc_array[i].doc) == 0)
- ? function_doc_array[i].doc
- : _(function_doc_array[i].doc));
+ doc = function_doc_array[i].func ? function_doc_array[i].doc : "";
+
+#endif /* !INFOKEY */
+
+ return replace_in_documentation ((strlen (doc) == 0) ? doc : _(doc));
}
#if defined (NAMED_FUNCTIONS)
/* Return the user-visible name of the function associated with the
Info command FUNCTION. */
char *
-function_name (function)
-
- VFunction *function;
+function_name (cmd)
+ InfoCommand *cmd;
{
+#if defined (INFOKEY)
+
+ return cmd->func_name;
+
+#else /* !INFOKEY */
+
register int i;
for (i = 0; function_doc_array[i].func; i++)
- if (function == function_doc_array[i].func)
+ if (InfoFunction(cmd) == function_doc_array[i].func)
break;
return (function_doc_array[i].func_name);
+
+#endif /* !INFOKEY */
}
-/* Return a pointer to the function named NAME. */
-VFunction *
+/* Return a pointer to the info command for function NAME. */
+InfoCommand *
named_function (name)
char *name;
{
@@ -534,7 +617,7 @@ named_function (name)
if (strcmp (function_doc_array[i].func_name, name) == 0)
break;
- return (function_doc_array[i].func);
+ return (DocInfoCmd(&function_doc_array[i]));
}
#endif /* NAMED_FUNCTIONS */
@@ -544,7 +627,7 @@ key_documentation (key, map)
char key;
Keymap map;
{
- VFunction *function = map[key].function;
+ InfoCommand *function = map[key].function;
if (function)
return (function_documentation (function));
@@ -554,21 +637,21 @@ key_documentation (key, map)
DECLARE_INFO_COMMAND (describe_key, _("Print documentation for KEY"))
{
- char keyname[50];
- int keyname_index = 0;
+ char keys[50];
unsigned char keystroke;
- char *rep;
+ char *k = keys;
Keymap map;
- keyname[0] = 0;
+ *k = '\0';
map = window->keymap;
for (;;)
{
- message_in_echo_area (_("Describe key: %s"), keyname);
+ message_in_echo_area (_("Describe key: %s"), pretty_keyseq (keys));
keystroke = info_get_input_char ();
unmessage_in_echo_area ();
+#if !defined (INFOKEY)
if (Meta_p (keystroke))
{
if (map[ESC].type != ISKMAP)
@@ -578,32 +661,53 @@ DECLARE_INFO_COMMAND (describe_key, _("Print documentation for KEY"))
return;
}
- strcpy (keyname + keyname_index, "ESC ");
- keyname_index = strlen (keyname);
+ *k++ = '\e';
keystroke = UnMeta (keystroke);
map = (Keymap)map[ESC].function;
}
+#endif /* !INFOKEY */
- /* Add the printed representation of KEYSTROKE to our keyname. */
- rep = pretty_keyname (keystroke);
- strcpy (keyname + keyname_index, rep);
- keyname_index = strlen (keyname);
+ /* Add the KEYSTROKE to our list. */
+ *k++ = keystroke;
+ *k = '\0';
- if (map[keystroke].function == (VFunction *)NULL)
+ if (map[keystroke].function == (InfoCommand *)NULL)
{
- message_in_echo_area (_("%s is undefined."), keyname);
+ message_in_echo_area (_("%s is undefined."), pretty_keyseq (keys));
return;
}
else if (map[keystroke].type == ISKMAP)
{
map = (Keymap)map[keystroke].function;
- strcat (keyname, " ");
- keyname_index = strlen (keyname);
continue;
}
else
{
- char *message, *fundoc, *funname = "";
+ char *keyname, *message, *fundoc, *funname = "";
+
+#if defined (INFOKEY)
+ /* If the key is bound to do-lowercase-version, but its
+ lower-case variant is undefined, say that this key is
+ also undefined. This is especially important for unbound
+ edit keys that emit an escape sequence: it's terribly
+ confusing to see a message "Home (do-lowercase-version)"
+ or some such when Home is unbound. */
+ if (InfoFunction(map[keystroke].function) == info_do_lowercase_version)
+ {
+ unsigned char lowerkey = Meta_p(keystroke)
+ ? Meta (tolower (UnMeta (keystroke)))
+ : tolower (keystroke);
+
+ if (map[lowerkey].function == (InfoCommand *)NULL)
+ {
+ message_in_echo_area (_("%s is undefined."),
+ pretty_keyseq (keys));
+ return;
+ }
+ }
+#endif
+
+ keyname = pretty_keyseq (keys);
#if defined (NAMED_FUNCTIONS)
funname = function_name (map[keystroke].function);
@@ -627,13 +731,12 @@ DECLARE_INFO_COMMAND (describe_key, _("Print documentation for KEY"))
}
}
-/* How to get the pretty printable name of a character. */
-static char rep_buffer[30];
-
+/* Return the pretty printable name of a single character. */
char *
pretty_keyname (key)
unsigned char key;
{
+ static char rep_buffer[30];
char *rep;
if (Meta_p (key))
@@ -642,7 +745,11 @@ pretty_keyname (key)
rep = pretty_keyname (UnMeta (key));
+#if defined (INFOKEY)
+ sprintf (temp, "M-%s", rep);
+#else /* !INFOKEY */
sprintf (temp, "ESC %s", rep);
+#endif /* !INFOKEY */
strcpy (rep_buffer, temp);
rep = rep_buffer;
}
@@ -675,57 +782,269 @@ pretty_keyname (key)
return (rep);
}
+/* Return the pretty printable string which represents KEYSEQ. */
+
+static void pretty_keyseq_internal ();
+
+char *
+pretty_keyseq (keyseq)
+ char *keyseq;
+{
+ static char keyseq_rep[200];
+
+ keyseq_rep[0] = '\0';
+ if (*keyseq)
+ pretty_keyseq_internal (keyseq, keyseq_rep);
+ return (keyseq_rep);
+}
+
+static void
+pretty_keyseq_internal (keyseq, rep)
+ char *keyseq, *rep;
+{
+ if (term_kP && strncmp(keyseq, term_kP, strlen(term_kP)) == 0)
+ {
+ strcpy(rep, "PgUp");
+ keyseq += strlen(term_kP);
+ }
+ else if (term_kN && strncmp(keyseq, term_kN, strlen(term_kN)) == 0)
+ {
+ strcpy(rep, "PgDn");
+ keyseq += strlen(term_kN);
+ }
+#if defined(INFOKEY)
+ else if (term_kh && strncmp(keyseq, term_kh, strlen(term_kh)) == 0)
+ {
+ strcpy(rep, "Home");
+ keyseq += strlen(term_kh);
+ }
+ else if (term_ke && strncmp(keyseq, term_ke, strlen(term_ke)) == 0)
+ {
+ strcpy(rep, "End");
+ keyseq += strlen(term_ke);
+ }
+ else if (term_ki && strncmp(keyseq, term_ki, strlen(term_ki)) == 0)
+ {
+ strcpy(rep, "INS");
+ keyseq += strlen(term_ki);
+ }
+ else if (term_kx && strncmp(keyseq, term_kx, strlen(term_kx)) == 0)
+ {
+ strcpy(rep, "DEL");
+ keyseq += strlen(term_kx);
+ }
+#endif /* INFOKEY */
+ else if (term_ku && strncmp(keyseq, term_ku, strlen(term_ku)) == 0)
+ {
+ strcpy(rep, "Up");
+ keyseq += strlen(term_ku);
+ }
+ else if (term_kd && strncmp(keyseq, term_kd, strlen(term_kd)) == 0)
+ {
+ strcpy(rep, "Down");
+ keyseq += strlen(term_kd);
+ }
+ else if (term_kl && strncmp(keyseq, term_kl, strlen(term_kl)) == 0)
+ {
+ strcpy(rep, "Left");
+ keyseq += strlen(term_kl);
+ }
+ else if (term_kr && strncmp(keyseq, term_kr, strlen(term_kr)) == 0)
+ {
+ strcpy(rep, "Right");
+ keyseq += strlen(term_kr);
+ }
+ else
+ {
+ strcpy (rep, pretty_keyname (keyseq[0]));
+ keyseq++;
+ }
+ if (*keyseq)
+ {
+ strcat (rep, " ");
+ pretty_keyseq_internal (keyseq, rep + strlen(rep));
+ }
+}
+
+/* Return a pointer to the last character in s that is found in f. */
+static char *
+strrpbrk (s, f)
+ const char *s, *f;
+{
+ register const char *e = s + strlen(s);
+ register const char *t;
+
+ while (e-- != s)
+ {
+ for (t = f; *t; t++)
+ if (*e == *t)
+ return (char *)e;
+ }
+ return NULL;
+}
+
/* Replace the names of functions with the key that invokes them. */
char *
-replace_in_documentation (string)
+replace_in_documentation (string, help_is_only_window_p)
char *string;
+ int help_is_only_window_p;
{
+ unsigned reslen = strlen (string);
register int i, start, next;
static char *result = (char *)NULL;
maybe_free (result);
- result = (char *)xmalloc (1 + strlen (string));
+ result = (char *)xmalloc (1 + reslen);
i = next = start = 0;
/* Skip to the beginning of a replaceable function. */
for (i = start; string[i]; i++)
{
- /* Is this the start of a replaceable function name? */
- if (string[i] == '\\' && string[i + 1] == '[')
- {
- char *fun_name, *rep;
- VFunction *function;
-
- /* Copy in the old text. */
- strncpy (result + next, string + start, i - start);
- next += (i - start);
- start = i + 2;
-
- /* Move to the end of the function name. */
- for (i = start; string[i] && (string[i] != ']'); i++);
-
- fun_name = (char *)xmalloc (1 + i - start);
- strncpy (fun_name, string + start, i - start);
- fun_name[i - start] = '\0';
-
- /* Find a key which invokes this function in the info_keymap. */
- function = named_function (fun_name);
+ int j = i + 1;
- /* If the internal documentation string fails, there is a
- serious problem with the associated command's documentation.
- We croak so that it can be fixed immediately. */
- if (!function)
- abort ();
-
- rep = where_is (info_keymap, function);
- strcpy (result + next, rep);
- next = strlen (result);
-
- start = i;
- if (string[i])
- start++;
- }
+ /* Is this the start of a replaceable function name? */
+ if (string[i] == '\\')
+ {
+ char *fmt = NULL;
+ unsigned min = 0;
+ unsigned max = 0;
+
+ if(string[j] == '%')
+ {
+ if (string[++j] == '-')
+ j++;
+ if (isdigit(string[j]))
+ {
+ min = atoi(string + j);
+ while (isdigit(string[j]))
+ j++;
+ if (string[j] == '.' && isdigit(string[j + 1]))
+ {
+ j += 1;
+ max = atoi(string + j);
+ while (isdigit(string[j]))
+ j++;
+ }
+ fmt = (char *)xmalloc (j - i + 2);
+ strncpy (fmt, string + i + 1, j - i);
+ fmt[j - i - 1] = 's';
+ fmt[j - i] = '\0';
+ }
+ else
+ j = i + 1;
+ }
+ if (string[j] == '[')
+ {
+ unsigned arg = 0;
+ char *argstr = NULL;
+ char *rep_name, *fun_name, *rep;
+ InfoCommand *command;
+ char *repstr = NULL;
+ unsigned replen;
+
+ /* Copy in the old text. */
+ strncpy (result + next, string + start, i - start);
+ next += (i - start);
+ start = j + 1;
+
+ /* Look for an optional numeric arg. */
+ i = start;
+ if (isdigit(string[i])
+ || (string[i] == '-' && isdigit(string[i + 1])) )
+ {
+ arg = atoi(string + i);
+ if (string[i] == '-')
+ i++;
+ while (isdigit(string[i]))
+ i++;
+ }
+ start = i;
+
+ /* Move to the end of the function name. */
+ for (i = start; string[i] && (string[i] != ']'); i++);
+
+ rep_name = (char *)xmalloc (1 + i - start);
+ strncpy (rep_name, string + start, i - start);
+ rep_name[i - start] = '\0';
+
+ /* If we have only one window (because the window size was too
+ small to split it), we have to quit help by going back one
+ noew in the history list, not deleting the window. */
+ if (strcmp (rep_name, "quit-help") == 0)
+ fun_name = help_is_only_window_p ? "history-node"
+ : "delete-window";
+ else
+ fun_name = rep_name;
+
+ /* Find a key which invokes this function in the info_keymap. */
+ command = named_function (fun_name);
+
+ free (rep_name);
+
+ /* If the internal documentation string fails, there is a
+ serious problem with the associated command's documentation.
+ We croak so that it can be fixed immediately. */
+ if (!command)
+ abort ();
+
+ if (arg)
+ {
+ char *argrep, *p;
+
+ argrep = where_is (info_keymap, InfoCmd(info_add_digit_to_numeric_arg));
+ p = argrep ? strrpbrk (argrep, "0123456789-") : NULL;
+ if (p)
+ {
+ argstr = (char *)xmalloc (p - argrep + 21);
+ strncpy (argstr, argrep, p - argrep);
+ sprintf (argstr + (p - argrep), "%d", arg);
+ }
+ else
+ command = NULL;
+ }
+ rep = command ? where_is (info_keymap, command) : NULL;
+ if (!rep)
+ rep = "N/A";
+ replen = (argstr ? strlen (argstr) + 1 : 0) + strlen (rep);
+ repstr = (char *)xmalloc (replen);
+ repstr[0] = '\0';
+ if (argstr)
+ {
+ strcat(repstr, argstr);
+ strcat(repstr, " ");
+ free (argstr);
+ }
+ strcat(repstr, rep);
+
+ if (fmt)
+ {
+ if (replen > max)
+ replen = max;
+ if (replen < min)
+ replen = min;
+ }
+ if (next + replen > reslen)
+ {
+ reslen = next + replen + 1;
+ result = (char *)xrealloc (result, reslen + 1);
+ }
+
+ if (fmt)
+ sprintf (result + next, fmt, repstr);
+ else
+ strcpy (result + next, repstr);
+
+ next = strlen (result);
+ free (repstr);
+
+ start = i;
+ if (string[i])
+ start++;
+ }
+
+ maybe_free (fmt);
+ }
}
strcpy (result + next, string + start);
return (result);
@@ -737,10 +1056,10 @@ static char *where_is_rep = (char *)NULL;
static int where_is_rep_index = 0;
static int where_is_rep_size = 0;
-static char *
-where_is (map, function)
+char *
+where_is (map, cmd)
Keymap map;
- VFunction *function;
+ InfoCommand *cmd;
{
char *rep;
@@ -748,35 +1067,53 @@ where_is (map, function)
where_is_rep = (char *)xmalloc (where_is_rep_size = 100);
where_is_rep_index = 0;
- rep = where_is_internal (map, function);
+ rep = where_is_internal (map, cmd);
- /* If it couldn't be found, return "M-x Foo". */
+ /* If it couldn't be found, return "M-x Foo" (or equivalent). */
if (!rep)
{
char *name;
- name = function_name (function);
+ name = function_name (cmd);
+ if (!name)
+ return NULL; /* no such function */
+
+ rep = where_is_internal (map, InfoCmd(info_execute_command));
+ if (!rep)
+ return ""; /* function exists but can't be got to by user */
- if (name)
- sprintf (where_is_rep, "M-x %s", name);
+ sprintf (where_is_rep, "%s %s", rep, name);
rep = where_is_rep;
}
return (rep);
}
-/* Return the printed rep of FUNCTION as found in MAP, or NULL. */
+/* Return the printed rep of the keystrokes that invoke FUNCTION,
+ as found in MAP, or NULL. */
static char *
-where_is_internal (map, function)
+where_is_internal (map, cmd)
Keymap map;
- VFunction *function;
+ InfoCommand *cmd;
{
+#if defined(INFOKEY)
+
+ register FUNCTION_KEYSEQ *k;
+
+ for (k = cmd->keys; k; k = k->next)
+ if (k->map == map)
+ return pretty_keyseq (k->keyseq);
+
+ return NULL;
+
+#else /* !INFOKEY */
+
register int i;
/* If the function is directly invokable in MAP, return the representation
of that keystroke. */
for (i = 0; i < 256; i++)
- if ((map[i].type == ISFUNC) && map[i].function == function)
+ if ((map[i].type == ISFUNC) && map[i].function == cmd)
{
sprintf (where_is_rep + where_is_rep_index, "%s", pretty_keyname (i));
return (where_is_rep);
@@ -794,7 +1131,7 @@ where_is_internal (map, function)
pretty_keyname (i));
where_is_rep_index = strlen (where_is_rep);
- rep = where_is_internal ((Keymap)map[i].function, function);
+ rep = where_is_internal ((Keymap)map[i].function, cmd);
if (rep)
return (where_is_rep);
@@ -804,6 +1141,8 @@ where_is_internal (map, function)
}
return NULL;
+
+#endif /* INFOKEY */
}
extern char *read_function_name ();
@@ -823,23 +1162,23 @@ DECLARE_INFO_COMMAND (info_where_is,
if (*command_name)
{
- VFunction *function;
+ InfoCommand *command;
- function = named_function (command_name);
+ command = named_function (command_name);
- if (function)
+ if (command)
{
char *location;
- location = where_is (active_window->keymap, function);
+ location = where_is (active_window->keymap, command);
- if (!location)
+ if (!location || !location[0])
{
info_error (_("`%s' is not on any keys"), command_name);
}
else
{
- if (strncmp (location, "M-x ", 4) == 0)
+ if (strstr (location, function_name (command)))
window_message_in_echo_area
(_("%s can only be invoked via %s."), command_name, location);
else
diff --git a/gnu/usr.bin/texinfo/info/infomap.c b/gnu/usr.bin/texinfo/info/infomap.c
index 47e388e190d..9ae2c2d40f1 100644
--- a/gnu/usr.bin/texinfo/info/infomap.c
+++ b/gnu/usr.bin/texinfo/info/infomap.c
@@ -1,7 +1,7 @@
-/* infomap.c -- Keymaps for Info.
- $Id: infomap.c,v 1.3 2000/02/09 02:18:40 espie Exp $
+/* infomap.c -- keymaps for Info.
+ $Id: infomap.c,v 1.4 2002/06/10 13:51:03 espie Exp $
- Copyright (C) 1993, 97, 98, 99 Free Software Foundation, Inc.
+ Copyright (C) 1993, 97, 98, 99, 2001, 02 Free Software Foundation, Inc.
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
@@ -24,12 +24,17 @@
#include "funs.h"
#include "terminal.h"
+#if defined(INFOKEY)
+#include "infokey.h"
+#include "variables.h"
+#endif /* INFOKEY */
+
/* Return a new keymap which has all the uppercase letters mapped to run
the function info_do_lowercase_version (). */
Keymap
keymap_make_keymap ()
{
- register int i;
+ int i;
Keymap keymap;
keymap = (Keymap)xmalloc (256 * sizeof (KEYMAP_ENTRY));
@@ -37,13 +42,17 @@ keymap_make_keymap ()
for (i = 0; i < 256; i++)
{
keymap[i].type = ISFUNC;
- keymap[i].function = (VFunction *)NULL;
+ keymap[i].function = (InfoCommand *)NULL;
}
for (i = 'A'; i < ('Z' + 1); i++)
{
keymap[i].type = ISFUNC;
- keymap[i].function = info_do_lowercase_version;
+#if defined(INFOKEY)
+ keymap[Meta(i)].type = ISFUNC;
+ keymap[Meta(i)].function =
+#endif /* INFOKEY */
+ keymap[i].function = InfoCmd(info_do_lowercase_version);
}
return (keymap);
@@ -54,7 +63,7 @@ Keymap
keymap_copy_keymap (map)
Keymap map;
{
- register int i;
+ int i;
Keymap keymap;
keymap = keymap_make_keymap ();
@@ -72,7 +81,7 @@ void
keymap_discard_keymap (map)
Keymap (map);
{
- register int i;
+ int i;
if (!map)
return;
@@ -99,9 +108,9 @@ keymap_bind_keyseq (map, keyseq, keyentry)
const unsigned char *keyseq;
KEYMAP_ENTRY *keyentry;
{
- register Keymap m = map;
- register const unsigned char *s = keyseq;
- register int c;
+ Keymap m = map;
+ const unsigned char *s = keyseq;
+ int c;
if (s == NULL || *s == '\0') return 0;
@@ -110,14 +119,18 @@ keymap_bind_keyseq (map, keyseq, keyentry)
switch (m[c].type)
{
case ISFUNC:
- if (!(m[c].function == NULL ||
- (m != map && m[c].function == info_do_lowercase_version)))
+ if (!(m[c].function == NULL || (
+#if !defined(INFOKEY)
+ m != map &&
+#endif /* !INFOKEY */
+ m[c].function == InfoCmd(info_do_lowercase_version))
+ ))
return 0;
if (*s != '\0')
{
m[c].type = ISKMAP;
- m[c].function = (VFunction *)keymap_make_keymap ();
+ m[c].function = (InfoCommand *)keymap_make_keymap ();
}
break;
@@ -132,6 +145,20 @@ keymap_bind_keyseq (map, keyseq, keyentry)
}
else
{
+#if defined(INFOKEY)
+ FUNCTION_KEYSEQ *k;
+
+ for (k = keyentry->function->keys; k && k->map != map; k = k->next)
+ ;
+ if (!k)
+ {
+ FUNCTION_KEYSEQ *ks = (FUNCTION_KEYSEQ *)xmalloc (sizeof(FUNCTION_KEYSEQ));
+ ks->next = keyentry->function->keys;
+ ks->map = map;
+ ks->keyseq = xstrdup (keyseq);
+ keyentry->function->keys = ks;
+ }
+#endif /* INFOKEY */
m[c] = *keyentry;
}
}
@@ -144,6 +171,8 @@ keymap_bind_keyseq (map, keyseq, keyentry)
Keymap info_keymap = NULL;
Keymap echo_area_keymap = NULL;
+#if !defined(INFOKEY)
+
static void
initialize_emacs_like_keymaps ()
{
@@ -157,9 +186,9 @@ initialize_emacs_like_keymaps ()
}
info_keymap[ESC].type = ISKMAP;
- info_keymap[ESC].function = (VFunction *)keymap_make_keymap ();
+ info_keymap[ESC].function = (InfoCommand *)keymap_make_keymap ();
info_keymap[Control ('x')].type = ISKMAP;
- info_keymap[Control ('x')].function = (VFunction *)keymap_make_keymap ();
+ info_keymap[Control ('x')].function = (InfoCommand *)keymap_make_keymap ();
/* Bind the echo area insert routines. Let's make all characters
insertable by default, regardless of which character set we might
@@ -168,10 +197,10 @@ initialize_emacs_like_keymaps ()
echo_area_keymap[i].function = ea_insert;
echo_area_keymap[ESC].type = ISKMAP;
- echo_area_keymap[ESC].function = (VFunction *) keymap_make_keymap ();
+ echo_area_keymap[ESC].function = (InfoCommand *) keymap_make_keymap ();
echo_area_keymap[Control ('x')].type = ISKMAP;
echo_area_keymap[Control ('x')].function
- = (VFunction *) keymap_make_keymap ();
+ = (InfoCommand *) keymap_make_keymap ();
/* Bind numeric arg functions for both echo area and info window maps. */
for (i = '0'; i < '9' + 1; i++)
@@ -253,6 +282,9 @@ initialize_emacs_like_keymaps ()
keymap_bind_keyseq (map, term_kl, &map[Control ('b')]); /* left */
keymap_bind_keyseq (map, "\033OD", &map[Control ('b')]);
keymap_bind_keyseq (map, "\033[D", &map[Control ('b')]);
+ keymap_bind_keyseq (map, term_kD, &map[DEL]); /* delete */
+ keymap_bind_keyseq (map, term_kh, &map[Control ('a')]); /* home */
+ keymap_bind_keyseq (map, term_ke, &map[Control ('e')]); /* end */
map = (Keymap)echo_area_keymap[ESC].function;
keymap_bind_keyseq (map, term_kl, &map['b']); /* left */
@@ -261,6 +293,10 @@ initialize_emacs_like_keymaps ()
keymap_bind_keyseq (map, term_kr, &map['f']); /* right */
keymap_bind_keyseq (map, "\033OB", &map['f']);
keymap_bind_keyseq (map, "\033[B", &map['f']);
+ keymap_bind_keyseq (map, term_kD, &map[DEL]); /* delete */
+
+ map = (Keymap)echo_area_keymap[Control ('x')].function;
+ keymap_bind_keyseq (map, term_kD, &map[DEL]); /* delete */
/* Bind commands for Info window keymaps. */
map = info_keymap;
@@ -280,7 +316,7 @@ initialize_emacs_like_keymaps ()
map[Control ('r')].function = isearch_backward;
map[Control ('s')].function = isearch_forward;
map[Control ('u')].function = info_universal_argument;
- map[Control ('v')].function = info_scroll_forward;
+ map[Control ('v')].function = info_scroll_forward_page_only;
map[','].function = info_next_index_match;
map['/'].function = info_search;
@@ -327,7 +363,7 @@ initialize_emacs_like_keymaps ()
map['b'].function = info_backward_word;
map['f'].function = info_forward_word;
map['r'].function = info_move_to_window_line;
- map['v'].function = info_scroll_backward;
+ map['v'].function = info_scroll_backward_page_only;
#if defined (NAMED_FUNCTIONS)
map['x'].function = info_execute_command;
#endif /* NAMED_FUNCTIONS */
@@ -368,6 +404,9 @@ initialize_emacs_like_keymaps ()
keymap_bind_keyseq (map, term_kl, &map[Control ('b')]); /* left */
keymap_bind_keyseq (map, "\033OD", &map[Control ('b')]);
keymap_bind_keyseq (map, "\033[D", &map[Control ('b')]);
+ keymap_bind_keyseq (map, term_kh, &map['b']); /* home */
+ keymap_bind_keyseq (map, term_ke, &map['e']); /* end */
+ keymap_bind_keyseq (map, term_kD, &map[DEL]); /* delete */
map = (Keymap)info_keymap[ESC].function;
keymap_bind_keyseq (map, term_kl, &map['b']); /* left */
@@ -378,6 +417,7 @@ initialize_emacs_like_keymaps ()
keymap_bind_keyseq (map, "\033[B", &map['f']);
keymap_bind_keyseq (map, term_kN, &map[Control ('v')]); /* pagedown */
keymap_bind_keyseq (map, term_kP, &map[DEL]); /* pageup */
+ keymap_bind_keyseq (map, term_kD, &map[DEL]); /* delete */
/* The alternative to this definition of a `main map' key in the
`ESC map' section, is something like:
@@ -389,7 +429,7 @@ initialize_emacs_like_keymaps ()
static void
initialize_vi_like_keymaps ()
{
- register int i;
+ int i;
Keymap map;
if (!info_keymap)
@@ -399,19 +439,19 @@ initialize_vi_like_keymaps ()
}
info_keymap[ESC].type = ISKMAP;
- info_keymap[ESC].function = (VFunction *)keymap_make_keymap ();
+ info_keymap[ESC].function = (InfoCommand *)keymap_make_keymap ();
info_keymap[Control ('x')].type = ISKMAP;
- info_keymap[Control ('x')].function = (VFunction *)keymap_make_keymap ();
+ info_keymap[Control ('x')].function = (InfoCommand *)keymap_make_keymap ();
/* Bind the echo area insert routines. */
for (i = 0; i < 256; i++)
echo_area_keymap[i].function = ea_insert;
echo_area_keymap[ESC].type = ISKMAP;
- echo_area_keymap[ESC].function = (VFunction *)keymap_make_keymap ();
+ echo_area_keymap[ESC].function = (InfoCommand *)keymap_make_keymap ();
echo_area_keymap[Control ('x')].type = ISKMAP;
echo_area_keymap[Control ('x')].function =
- (VFunction *)keymap_make_keymap ();
+ (InfoCommand *)keymap_make_keymap ();
/* Bind numeric arg functions for both echo area and info window maps. */
for (i = '0'; i < '9' + 1; i++)
@@ -497,6 +537,9 @@ initialize_vi_like_keymaps ()
keymap_bind_keyseq (map, term_kl, &map[Control ('b')]); /* left */
keymap_bind_keyseq (map, "\033OD", &map[Control ('b')]);
keymap_bind_keyseq (map, "\033[D", &map[Control ('b')]);
+ keymap_bind_keyseq (map, term_kh, &map[Control ('a')]); /* home */
+ keymap_bind_keyseq (map, term_ke, &map[Control ('e')]); /* end */
+ keymap_bind_keyseq (map, term_kD, &map[DEL]); /* delete */
map = (Keymap)echo_area_keymap[ESC].function;
keymap_bind_keyseq (map, term_kl, &map['b']); /* left */
@@ -505,6 +548,10 @@ initialize_vi_like_keymaps ()
keymap_bind_keyseq (map, term_kr, &map['f']); /* right */
keymap_bind_keyseq (map, "\033OB", &map['f']);
keymap_bind_keyseq (map, "\033[B", &map['f']);
+ keymap_bind_keyseq (map, term_kD, &map[DEL]); /* delete */
+
+ map = (Keymap)echo_area_keymap[Control ('x')].function;
+ keymap_bind_keyseq (map, term_kD, &map[DEL]);
/* Bind commands for Info window keymaps. */
map = info_keymap;
@@ -513,10 +560,10 @@ initialize_vi_like_keymaps ()
map[RET].function = info_down_line;
map[SPC].function = info_scroll_forward;
map[Control ('a')].function = info_beginning_of_line;
- map[Control ('b')].function = info_scroll_backward;
+ map[Control ('b')].function = info_scroll_backward_page_only;
map[Control ('d')].function = info_scroll_half_screen_down;
map[Control ('e')].function = info_down_line;
- map[Control ('f')].function = info_scroll_forward;
+ map[Control ('f')].function = info_scroll_forward_page_only;
map[Control ('g')].function = info_abort_key;
map[Control ('k')].function = info_up_line;
map[Control ('l')].function = info_redraw_display;
@@ -525,7 +572,7 @@ initialize_vi_like_keymaps ()
map[Control ('r')].function = info_redraw_display;
map[Control ('s')].function = isearch_forward;
map[Control ('u')].function = info_scroll_half_screen_up;
- map[Control ('v')].function = info_scroll_forward;
+ map[Control ('v')].function = info_scroll_forward_page_only;
map[Control ('y')].function = info_up_line;
map[','].function = info_next_index_match;
map['/'].function = info_search;
@@ -545,8 +592,8 @@ initialize_vi_like_keymaps ()
map['d'].function = info_scroll_half_screen_down;
map['e'].function = info_down_line;
map['E'].function = info_view_file;
- map['f'].function = info_scroll_forward;
- map['F'].function = info_scroll_forward;
+ map['f'].function = info_scroll_forward_page_only;
+ map['F'].function = info_scroll_forward_page_only;
map['g'].function = info_first_node;
map['G'].function = info_last_node;
map['h'].function = info_get_help_window;
@@ -569,11 +616,12 @@ initialize_vi_like_keymaps ()
map['S'].function = info_search_case_sensitively;
map['t'].function = info_top_node;
map['u'].function = info_scroll_half_screen_up;
- map['w'].function = info_scroll_backward_set_window;
+ map['w'].function = info_scroll_backward_page_only_set_window;
map['y'].function = info_up_line;
- map['z'].function = info_scroll_forward_set_window;
+ map['z'].function = info_scroll_forward_page_only_set_window;
map['Z'].function = NULL; /* unbind, so it works to bind "ZZ" below */
map[DEL].function = info_scroll_backward;
+ keymap_bind_keyseq (map, term_kD, &map[DEL]);
keymap_bind_keyseq (map, ":q", &map['q']);
keymap_bind_keyseq (map, ":Q", &map['q']);
keymap_bind_keyseq (map, "ZZ", &map['q']);
@@ -583,7 +631,7 @@ initialize_vi_like_keymaps ()
map[Control ('f')].function = info_show_footnotes;
map[Control ('g')].function = info_abort_key;
map[TAB].function = info_move_to_prev_xref;
- map[SPC].function = info_scroll_forward;
+ map[SPC].function = info_scroll_forward_page_only;
map[Control ('v')].function = info_scroll_other_window;
map['<'].function = info_beginning_of_node;
map['>'].function = info_end_of_node;
@@ -601,7 +649,7 @@ initialize_vi_like_keymaps ()
map['r'].function = isearch_backward;
map['s'].function = isearch_forward;
map['t'].function = info_top_node;
- map['v'].function = info_scroll_backward;
+ map['v'].function = info_scroll_backward_page_only;
#if defined (NAMED_FUNCTIONS)
map['x'].function = info_execute_command;
#endif /* NAMED_FUNCTIONS */
@@ -652,6 +700,8 @@ initialize_vi_like_keymaps ()
keymap_bind_keyseq (map, term_kl, &map[Control ('b')]); /* left */
keymap_bind_keyseq (map, "\033OD", &map[Control ('b')]);
keymap_bind_keyseq (map, "\033[D", &map[Control ('b')]);
+ keymap_bind_keyseq (map, term_kh, &map['b']); /* home */
+ keymap_bind_keyseq (map, term_ke, &map['e']); /* end */
map = (Keymap)info_keymap[ESC].function;
keymap_bind_keyseq (map, term_kl, &map['b']); /* left */
@@ -662,6 +712,7 @@ initialize_vi_like_keymaps ()
keymap_bind_keyseq (map, "\033[B", &map['f']);
keymap_bind_keyseq (map, term_kN, &map[Control ('v')]); /* pagedown */
keymap_bind_keyseq (map, term_kP, &map[DEL]); /* pageup */
+ keymap_bind_keyseq (map, term_kD, &map[DEL]); /* delete */
/* The alternative to this definition of a `main map' key in the
`ESC map' section, is something like:
@@ -679,3 +730,994 @@ initialize_info_keymaps ()
initialize_emacs_like_keymaps ();
}
+#else /* defined(INFOKEY) */
+
+/* Make sure that we don't have too many command codes defined. */
+
+#if A_NCOMMANDS > A_MAX_COMMAND + 1
+#error "too many commands defined"
+#endif
+
+/* Initialize the keymaps from the .info keymap file. */
+
+#define NUL '\0'
+
+static unsigned char default_emacs_like_info_keys[] =
+{
+ 0, /* suppress-default-keybindings flag */
+ TAB, NUL, A_info_move_to_next_xref,
+ LFD, NUL, A_info_select_reference_this_line,
+ RET, NUL, A_info_select_reference_this_line,
+ SPC, NUL, A_info_scroll_forward,
+ CONTROL('a'), NUL, A_info_beginning_of_line,
+ CONTROL('b'), NUL, A_info_backward_char,
+ CONTROL('e'), NUL, A_info_end_of_line,
+ CONTROL('f'), NUL, A_info_forward_char,
+ CONTROL('g'), NUL, A_info_abort_key,
+ CONTROL('h'), NUL, A_info_get_help_window,
+ CONTROL('l'), NUL, A_info_redraw_display,
+ CONTROL('n'), NUL, A_info_next_line,
+ CONTROL('p'), NUL, A_info_prev_line,
+ CONTROL('r'), NUL, A_isearch_backward,
+ CONTROL('s'), NUL, A_isearch_forward,
+ CONTROL('u'), NUL, A_info_universal_argument,
+ CONTROL('v'), NUL, A_info_scroll_forward_page_only,
+ ',', NUL, A_info_next_index_match,
+ '/', NUL, A_info_search,
+ '0', NUL, A_info_last_menu_item,
+ '1', NUL, A_info_menu_digit,
+ '2', NUL, A_info_menu_digit,
+ '3', NUL, A_info_menu_digit,
+ '4', NUL, A_info_menu_digit,
+ '5', NUL, A_info_menu_digit,
+ '6', NUL, A_info_menu_digit,
+ '7', NUL, A_info_menu_digit,
+ '8', NUL, A_info_menu_digit,
+ '9', NUL, A_info_menu_digit,
+ '<', NUL, A_info_first_node,
+ '>', NUL, A_info_last_node,
+ '?', NUL, A_info_get_help_window,
+ '[', NUL, A_info_global_prev_node,
+ ']', NUL, A_info_global_next_node,
+ 'b', NUL, A_info_beginning_of_node,
+ 'd', NUL, A_info_dir_node,
+ 'e', NUL, A_info_end_of_node,
+ 'f', NUL, A_info_xref_item,
+ 'g', NUL, A_info_goto_node,
+ 'G', NUL, A_info_menu_sequence,
+ 'h', NUL, A_info_get_info_help_node,
+ 'i', NUL, A_info_index_search,
+ 'l', NUL, A_info_history_node,
+ 'm', NUL, A_info_menu_item,
+ 'n', NUL, A_info_next_node,
+ 'O', NUL, A_info_goto_invocation_node,
+ 'p', NUL, A_info_prev_node,
+ 'q', NUL, A_info_quit,
+ 'r', NUL, A_info_xref_item,
+ 's', NUL, A_info_search,
+ 'S', NUL, A_info_search_case_sensitively,
+ 't', NUL, A_info_top_node,
+ 'u', NUL, A_info_up_node,
+ DEL, NUL, A_info_scroll_backward,
+ ESC, '0', NUL, A_info_add_digit_to_numeric_arg,
+ ESC, '1', NUL, A_info_add_digit_to_numeric_arg,
+ ESC, '2', NUL, A_info_add_digit_to_numeric_arg,
+ ESC, '3', NUL, A_info_add_digit_to_numeric_arg,
+ ESC, '4', NUL, A_info_add_digit_to_numeric_arg,
+ ESC, '5', NUL, A_info_add_digit_to_numeric_arg,
+ ESC, '6', NUL, A_info_add_digit_to_numeric_arg,
+ ESC, '7', NUL, A_info_add_digit_to_numeric_arg,
+ ESC, '8', NUL, A_info_add_digit_to_numeric_arg,
+ ESC, '9', NUL, A_info_add_digit_to_numeric_arg,
+ ESC, '-', NUL, A_info_add_digit_to_numeric_arg,
+ ESC, CONTROL('f'), NUL, A_info_show_footnotes,
+ ESC, CONTROL('g'), NUL, A_info_abort_key,
+ ESC, TAB, NUL, A_info_move_to_prev_xref,
+ ESC, CONTROL('v'), NUL, A_info_scroll_other_window,
+ ESC, '<', NUL, A_info_beginning_of_node,
+ ESC, '>', NUL, A_info_end_of_node,
+ ESC, 'b', NUL, A_info_backward_word,
+ ESC, 'f', NUL, A_info_forward_word,
+ ESC, 'r', NUL, A_info_move_to_window_line,
+ ESC, 'v', NUL, A_info_scroll_backward_page_only,
+ Meta('0'), NUL, A_info_add_digit_to_numeric_arg,
+ Meta('1'), NUL, A_info_add_digit_to_numeric_arg,
+ Meta('2'), NUL, A_info_add_digit_to_numeric_arg,
+ Meta('3'), NUL, A_info_add_digit_to_numeric_arg,
+ Meta('4'), NUL, A_info_add_digit_to_numeric_arg,
+ Meta('5'), NUL, A_info_add_digit_to_numeric_arg,
+ Meta('6'), NUL, A_info_add_digit_to_numeric_arg,
+ Meta('7'), NUL, A_info_add_digit_to_numeric_arg,
+ Meta('8'), NUL, A_info_add_digit_to_numeric_arg,
+ Meta('9'), NUL, A_info_add_digit_to_numeric_arg,
+ Meta('-'), NUL, A_info_add_digit_to_numeric_arg,
+ Meta(CONTROL('f')), NUL, A_info_show_footnotes,
+ Meta(CONTROL('g')), NUL, A_info_abort_key,
+ Meta(TAB), NUL, A_info_move_to_prev_xref,
+ Meta(CONTROL('v')), NUL, A_info_scroll_other_window,
+ Meta('<'), NUL, A_info_beginning_of_node,
+ Meta('>'), NUL, A_info_end_of_node,
+ Meta('b'), NUL, A_info_backward_word,
+ Meta('f'), NUL, A_info_forward_word,
+ Meta('r'), NUL, A_info_move_to_window_line,
+ Meta('v'), NUL, A_info_scroll_backward_page_only,
+#if defined (NAMED_FUNCTIONS)
+ ESC, 'x', NUL, A_info_execute_command,
+ Meta('x'), NUL, A_info_execute_command,
+#endif /* NAMED_FUNCTIONS */
+
+ CONTROL('x'), CONTROL('b'), NUL, A_list_visited_nodes,
+ CONTROL('x'), CONTROL('c'), NUL, A_info_quit,
+ CONTROL('x'), CONTROL('f'), NUL, A_info_view_file,
+ CONTROL('x'), CONTROL('g'), NUL, A_info_abort_key,
+ CONTROL('x'), CONTROL('v'), NUL, A_info_view_file,
+ CONTROL('x'), '0', NUL, A_info_delete_window,
+ CONTROL('x'), '1', NUL, A_info_keep_one_window,
+ CONTROL('x'), '2', NUL, A_info_split_window,
+ CONTROL('x'), '^', NUL, A_info_grow_window,
+ CONTROL('x'), 'b', NUL, A_select_visited_node,
+ CONTROL('x'), 'k', NUL, A_info_kill_node,
+ CONTROL('x'), 'n', NUL, A_info_search_next,
+ CONTROL('x'), 'N', NUL, A_info_search_previous,
+ CONTROL('x'), 'o', NUL, A_info_next_window,
+ CONTROL('x'), 't', NUL, A_info_tile_windows,
+ CONTROL('x'), 'w', NUL, A_info_toggle_wrap,
+
+/* Arrow key bindings for info keymaps. It seems that some
+ terminals do not match their termcap entries, so it's best to just
+ define everything with both of the usual prefixes. */
+
+ SK_ESCAPE, SK_PAGE_UP, NUL, A_info_scroll_backward_page_only,
+ SK_ESCAPE, SK_PAGE_DOWN, NUL, A_info_scroll_forward_page_only,
+ SK_ESCAPE, SK_UP_ARROW, NUL, A_info_prev_line,
+ '\033', 'O', 'A', NUL, A_info_prev_line,
+ '\033', '[', 'A', NUL, A_info_prev_line,
+ SK_ESCAPE, SK_DOWN_ARROW, NUL, A_info_next_line,
+ '\033', 'O', 'B', NUL, A_info_next_line,
+ '\033', '[', 'B', NUL, A_info_next_line,
+ SK_ESCAPE, SK_RIGHT_ARROW, NUL, A_info_forward_char,
+ '\033', 'O', 'C', NUL, A_info_forward_char,
+ '\033', '[', 'C', NUL, A_info_forward_char,
+ SK_ESCAPE, SK_LEFT_ARROW, NUL, A_info_backward_char,
+ '\033', 'O', 'D', NUL, A_info_backward_char,
+ '\033', '[', 'D', NUL, A_info_backward_char,
+ SK_ESCAPE, SK_HOME, NUL, A_info_beginning_of_node,
+ SK_ESCAPE, SK_END, NUL, A_info_end_of_node,
+ SK_ESCAPE, SK_DELETE, NUL, A_info_scroll_backward,
+
+ ESC, SK_ESCAPE, SK_PAGE_UP, NUL, A_info_scroll_other_window_backward,
+ ESC, SK_ESCAPE, SK_PAGE_DOWN, NUL, A_info_scroll_other_window,
+ ESC, SK_ESCAPE, SK_UP_ARROW, NUL, A_info_prev_line,
+ ESC, '\033', 'O', 'A', NUL, A_info_prev_line,
+ ESC, '\033', '[', 'A', NUL, A_info_prev_line,
+ ESC, SK_ESCAPE, SK_DOWN_ARROW, NUL, A_info_next_line,
+ ESC, '\033', 'O', 'B', NUL, A_info_next_line,
+ ESC, '\033', '[', 'B', NUL, A_info_next_line,
+ ESC, SK_ESCAPE, SK_RIGHT_ARROW, NUL, A_info_forward_word,
+ ESC, '\033', 'O', 'C', NUL, A_info_forward_word,
+ ESC, '\033', '[', 'C', NUL, A_info_forward_word,
+ ESC, SK_ESCAPE, SK_LEFT_ARROW, NUL, A_info_backward_word,
+ ESC, '\033', 'O', 'D', NUL, A_info_backward_word,
+ ESC, '\033', '[', 'D', NUL, A_info_backward_word,
+};
+
+static unsigned char default_emacs_like_ea_keys[] =
+{
+ 0, /* suppress-default-keybindings flag */
+ ESC, '0', NUL, A_info_add_digit_to_numeric_arg,
+ ESC, '1', NUL, A_info_add_digit_to_numeric_arg,
+ ESC, '2', NUL, A_info_add_digit_to_numeric_arg,
+ ESC, '3', NUL, A_info_add_digit_to_numeric_arg,
+ ESC, '4', NUL, A_info_add_digit_to_numeric_arg,
+ ESC, '5', NUL, A_info_add_digit_to_numeric_arg,
+ ESC, '6', NUL, A_info_add_digit_to_numeric_arg,
+ ESC, '7', NUL, A_info_add_digit_to_numeric_arg,
+ ESC, '8', NUL, A_info_add_digit_to_numeric_arg,
+ ESC, '9', NUL, A_info_add_digit_to_numeric_arg,
+ ESC, '-', NUL, A_info_add_digit_to_numeric_arg,
+ Meta('0'), NUL, A_info_add_digit_to_numeric_arg,
+ Meta('1'), NUL, A_info_add_digit_to_numeric_arg,
+ Meta('2'), NUL, A_info_add_digit_to_numeric_arg,
+ Meta('3'), NUL, A_info_add_digit_to_numeric_arg,
+ Meta('4'), NUL, A_info_add_digit_to_numeric_arg,
+ Meta('5'), NUL, A_info_add_digit_to_numeric_arg,
+ Meta('6'), NUL, A_info_add_digit_to_numeric_arg,
+ Meta('7'), NUL, A_info_add_digit_to_numeric_arg,
+ Meta('8'), NUL, A_info_add_digit_to_numeric_arg,
+ Meta('9'), NUL, A_info_add_digit_to_numeric_arg,
+ Meta('-'), NUL, A_info_add_digit_to_numeric_arg,
+ ESC, CONTROL('g'), NUL, A_ea_abort,
+ ESC, CONTROL('v'), NUL, A_ea_scroll_completions_window,
+ ESC, 'b', NUL, A_ea_backward_word,
+ ESC, 'd', NUL, A_ea_kill_word,
+ ESC, 'f', NUL, A_ea_forward_word,
+ ESC, 'y', NUL, A_ea_yank_pop,
+ ESC, '?', NUL, A_ea_possible_completions,
+ ESC, TAB, NUL, A_ea_tab_insert,
+ ESC, DEL, NUL, A_ea_backward_kill_word,
+ Meta(CONTROL('g')), NUL, A_ea_abort,
+ Meta(CONTROL('v')), NUL, A_ea_scroll_completions_window,
+ Meta('b'), NUL, A_ea_backward_word,
+ Meta('d'), NUL, A_ea_kill_word,
+ Meta('f'), NUL, A_ea_forward_word,
+ Meta('y'), NUL, A_ea_yank_pop,
+ Meta('?'), NUL, A_ea_possible_completions,
+ Meta(TAB), NUL, A_ea_tab_insert,
+ Meta(DEL), NUL, A_ea_backward_kill_word,
+ CONTROL('a'), NUL, A_ea_beg_of_line,
+ CONTROL('b'), NUL, A_ea_backward,
+ CONTROL('d'), NUL, A_ea_delete,
+ CONTROL('e'), NUL, A_ea_end_of_line,
+ CONTROL('f'), NUL, A_ea_forward,
+ CONTROL('g'), NUL, A_ea_abort,
+ CONTROL('h'), NUL, A_ea_rubout,
+/* CONTROL('k') */
+ SK_ESCAPE, SK_LITERAL, NUL, A_ea_kill_line,
+ CONTROL('l'), NUL, A_info_redraw_display,
+ CONTROL('q'), NUL, A_ea_quoted_insert,
+ CONTROL('t'), NUL, A_ea_transpose_chars,
+ CONTROL('u'), NUL, A_info_universal_argument,
+ CONTROL('y'), NUL, A_ea_yank,
+ LFD, NUL, A_ea_newline,
+ RET, NUL, A_ea_newline,
+ SPC, NUL, A_ea_complete,
+ TAB, NUL, A_ea_complete,
+ '?', NUL, A_ea_possible_completions,
+#ifdef __MSDOS__
+ /* PC users will lynch me if I don't give them their usual DEL
+ effect... */
+ DEL, NUL, A_ea_delete,
+#else
+ DEL, NUL, A_ea_rubout,
+#endif
+#if defined (NAMED_FUNCTIONS)
+ /* ESC, 'x', NUL, A_info_execute_command, */
+ /* Meta('x'), NUL, A_info_execute_command, */
+#endif /* NAMED_FUNCTIONS */
+ CONTROL('x'), 'o', NUL, A_info_next_window,
+ CONTROL('x'), DEL, NUL, A_ea_backward_kill_line,
+
+/* Arrow key bindings for echo area keymaps. It seems that some
+ terminals do not match their termcap entries, so it's best to just
+ define everything with both of the usual prefixes. */
+
+ SK_ESCAPE, SK_RIGHT_ARROW, NUL, A_ea_forward,
+ '\033', 'O', 'C', NUL, A_ea_forward,
+ '\033', '[', 'C', NUL, A_ea_forward,
+ SK_ESCAPE, SK_LEFT_ARROW, NUL, A_ea_backward,
+ '\033', 'O', 'D', NUL, A_ea_backward,
+ '\033', '[', 'D', NUL, A_ea_backward,
+ ESC, SK_ESCAPE, SK_RIGHT_ARROW, NUL, A_ea_forward_word,
+ ESC, '\033', 'O', 'C', NUL, A_ea_forward_word,
+ ESC, '\033', '[', 'C', NUL, A_ea_forward_word,
+ ESC, SK_ESCAPE, SK_LEFT_ARROW, NUL, A_ea_backward_word,
+ ESC, '\033', 'O', 'D', NUL, A_ea_backward_word,
+ ESC, '\033', '[', 'D', NUL, A_ea_backward_word,
+#ifdef __MSDOS__
+ SK_ESCAPE, SK_DELETE, NUL, A_ea_delete,
+#else
+ SK_ESCAPE, SK_DELETE, NUL, A_ea_rubout,
+#endif
+ SK_ESCAPE, SK_HOME, NUL, A_ea_beg_of_line,
+ SK_ESCAPE, SK_END, NUL, A_ea_end_of_line,
+ ESC, SK_ESCAPE, SK_DELETE, NUL, A_ea_backward_kill_word,
+ CONTROL('x'), SK_ESCAPE, SK_DELETE, NUL,A_ea_backward_kill_line,
+};
+
+static unsigned char default_vi_like_info_keys[] =
+{
+ 0, /* suppress-default-keybindings flag */
+ '0', NUL, A_info_add_digit_to_numeric_arg,
+ '1', NUL, A_info_add_digit_to_numeric_arg,
+ '2', NUL, A_info_add_digit_to_numeric_arg,
+ '3', NUL, A_info_add_digit_to_numeric_arg,
+ '4', NUL, A_info_add_digit_to_numeric_arg,
+ '5', NUL, A_info_add_digit_to_numeric_arg,
+ '6', NUL, A_info_add_digit_to_numeric_arg,
+ '7', NUL, A_info_add_digit_to_numeric_arg,
+ '8', NUL, A_info_add_digit_to_numeric_arg,
+ '9', NUL, A_info_add_digit_to_numeric_arg,
+ '-', NUL, A_info_add_digit_to_numeric_arg,
+ TAB, NUL, A_info_move_to_next_xref,
+ LFD, NUL, A_info_down_line,
+ RET, NUL, A_info_down_line,
+ SPC, NUL, A_info_scroll_forward,
+ CONTROL('a'), NUL, A_info_beginning_of_line,
+ CONTROL('b'), NUL, A_info_scroll_backward_page_only,
+ CONTROL('d'), NUL, A_info_scroll_half_screen_down,
+ CONTROL('e'), NUL, A_info_down_line,
+ CONTROL('f'), NUL, A_info_scroll_forward_page_only,
+ CONTROL('g'), NUL, A_info_abort_key,
+ CONTROL('k'), NUL, A_info_up_line,
+ CONTROL('l'), NUL, A_info_redraw_display,
+ CONTROL('n'), NUL, A_info_down_line,
+ CONTROL('p'), NUL, A_info_up_line,
+ CONTROL('r'), NUL, A_info_redraw_display,
+ CONTROL('s'), NUL, A_isearch_forward,
+ CONTROL('u'), NUL, A_info_scroll_half_screen_up,
+ CONTROL('v'), NUL, A_info_scroll_forward_page_only,
+ CONTROL('y'), NUL, A_info_up_line,
+ ',', NUL, A_info_next_index_match,
+ '/', NUL, A_info_search,
+ ESC, '0', NUL, A_info_last_menu_item,
+ ESC, '1', NUL, A_info_menu_digit,
+ ESC, '2', NUL, A_info_menu_digit,
+ ESC, '3', NUL, A_info_menu_digit,
+ ESC, '4', NUL, A_info_menu_digit,
+ ESC, '5', NUL, A_info_menu_digit,
+ ESC, '6', NUL, A_info_menu_digit,
+ ESC, '7', NUL, A_info_menu_digit,
+ ESC, '8', NUL, A_info_menu_digit,
+ ESC, '9', NUL, A_info_menu_digit,
+ Meta('0'), NUL, A_info_last_menu_item,
+ Meta('1'), NUL, A_info_menu_digit,
+ Meta('2'), NUL, A_info_menu_digit,
+ Meta('3'), NUL, A_info_menu_digit,
+ Meta('4'), NUL, A_info_menu_digit,
+ Meta('5'), NUL, A_info_menu_digit,
+ Meta('6'), NUL, A_info_menu_digit,
+ Meta('7'), NUL, A_info_menu_digit,
+ Meta('8'), NUL, A_info_menu_digit,
+ Meta('9'), NUL, A_info_menu_digit,
+ '<', NUL, A_info_first_node,
+ '>', NUL, A_info_last_node,
+ '?', NUL, A_info_search_backward,
+ '[', NUL, A_info_global_prev_node,
+ ']', NUL, A_info_global_next_node,
+ '\'', NUL, A_info_history_node,
+ 'b', NUL, A_info_scroll_backward,
+ 'd', NUL, A_info_scroll_half_screen_down,
+ 'e', NUL, A_info_down_line,
+ 'E', NUL, A_info_view_file,
+ ':', 'e', NUL, A_info_view_file,
+ 'f', NUL, A_info_scroll_forward_page_only,
+ 'F', NUL, A_info_scroll_forward_page_only,
+ 'g', NUL, A_info_first_node,
+ 'G', NUL, A_info_last_node,
+ 'h', NUL, A_info_get_help_window,
+ 'H', NUL, A_info_get_help_window,
+ 'i', NUL, A_info_index_search,
+ 'I', NUL, A_info_goto_invocation_node,
+ 'j', NUL, A_info_down_line,
+ 'k', NUL, A_info_up_line,
+ 'l', NUL, A_info_history_node,
+ 'm', NUL, A_info_menu_item,
+ 'n', NUL, A_info_search_next,
+ 'N', NUL, A_info_search_previous,
+ 'O', NUL, A_info_goto_invocation_node,
+ 'p', NUL, A_info_prev_node,
+ 'q', NUL, A_info_quit,
+ 'Q', NUL, A_info_quit,
+ ':', 'q', NUL, A_info_quit,
+ ':', 'Q', NUL, A_info_quit,
+ 'Z', 'Z', NUL, A_info_quit,
+ 'r', NUL, A_info_redraw_display,
+ 'R', NUL, A_info_redraw_display,
+ 's', NUL, A_info_search,
+ 'S', NUL, A_info_search_case_sensitively,
+ 't', NUL, A_info_top_node,
+ 'u', NUL, A_info_scroll_half_screen_up,
+ 'w', NUL, A_info_scroll_backward_page_only_set_window,
+ 'y', NUL, A_info_up_line,
+ 'z', NUL, A_info_scroll_forward_page_only_set_window,
+ DEL, NUL, A_info_scroll_backward,
+ ESC, CONTROL('f'), NUL, A_info_show_footnotes,
+ ESC, CONTROL('g'), NUL, A_info_abort_key,
+ ESC, TAB, NUL, A_info_move_to_prev_xref,
+ ESC, SPC, NUL, A_info_scroll_forward_page_only,
+ ESC, CONTROL('v'), NUL, A_info_scroll_other_window,
+ ESC, '<', NUL, A_info_beginning_of_node,
+ ESC, '>', NUL, A_info_end_of_node,
+ ESC, '/', NUL, A_info_search,
+ ESC, '?', NUL, A_info_search_backward,
+ ESC, 'b', NUL, A_info_beginning_of_node,
+ ESC, 'd', NUL, A_info_dir_node,
+ ESC, 'e', NUL, A_info_end_of_node,
+ ESC, 'f', NUL, A_info_xref_item,
+ ESC, 'g', NUL, A_info_select_reference_this_line,
+ ESC, 'h', NUL, A_info_get_info_help_node,
+ ESC, 'm', NUL, A_info_menu_item,
+ ESC, 'n', NUL, A_info_search,
+ ESC, 'N', NUL, A_info_search_backward,
+ ESC, 'r', NUL, A_isearch_backward,
+ ESC, 's', NUL, A_isearch_forward,
+ ESC, 't', NUL, A_info_top_node,
+ ESC, 'v', NUL, A_info_scroll_backward_page_only,
+#if defined (NAMED_FUNCTIONS)
+ ESC, 'x', NUL, A_info_execute_command,
+ Meta('x'), NUL, A_info_execute_command,
+#endif /* NAMED_FUNCTIONS */
+ ESC, DEL, NUL, A_info_scroll_other_window_backward,
+ CONTROL('x'), CONTROL('b'), NUL, A_list_visited_nodes,
+ CONTROL('x'), CONTROL('c'), NUL, A_info_quit,
+ CONTROL('x'), CONTROL('f'), NUL, A_info_view_file,
+ CONTROL('x'), CONTROL('g'), NUL, A_info_abort_key,
+ CONTROL('x'), CONTROL('v'), NUL, A_info_view_file,
+ CONTROL('x'), LFD, NUL, A_info_select_reference_this_line,
+ CONTROL('x'), RET, NUL, A_info_select_reference_this_line,
+ CONTROL('x'), '0', NUL, A_info_delete_window,
+ CONTROL('x'), '1', NUL, A_info_keep_one_window,
+ CONTROL('x'), '2', NUL, A_info_split_window,
+ CONTROL('x'), '^', NUL, A_info_grow_window,
+ CONTROL('x'), 'b', NUL, A_select_visited_node,
+ CONTROL('x'), 'g', NUL, A_info_goto_node,
+ CONTROL('x'), 'i', NUL, A_info_index_search,
+ CONTROL('x'), 'I', NUL, A_info_goto_invocation_node,
+ CONTROL('x'), 'k', NUL, A_info_kill_node,
+ CONTROL('x'), 'n', NUL, A_info_next_node,
+ CONTROL('x'), 'o', NUL, A_info_next_window,
+ CONTROL('x'), 'O', NUL, A_info_goto_invocation_node,
+ CONTROL('x'), 'p', NUL, A_info_prev_node,
+ CONTROL('x'), 'r', NUL, A_info_xref_item,
+ CONTROL('x'), 't', NUL, A_info_tile_windows,
+ CONTROL('x'), 'u', NUL, A_info_up_node,
+ CONTROL('x'), 'w', NUL, A_info_toggle_wrap,
+ CONTROL('x'), ',', NUL, A_info_next_index_match,
+
+/* Arrow key bindings for info keymaps. It seems that some
+ terminals do not match their termcap entries, so it's best to just
+ define everything with both of the usual prefixes. */
+
+ SK_ESCAPE, SK_PAGE_UP, NUL, A_info_scroll_backward_page_only,
+ SK_ESCAPE, SK_PAGE_DOWN, NUL, A_info_scroll_forward_page_only,
+ SK_ESCAPE, SK_UP_ARROW, NUL, A_info_up_line,
+ '\033', 'O', 'A', NUL, A_info_up_line,
+ '\033', '[', 'A', NUL, A_info_up_line,
+ SK_ESCAPE, SK_DOWN_ARROW, NUL, A_info_down_line,
+ '\033', 'O', 'B', NUL, A_info_down_line,
+ '\033', '[', 'B', NUL, A_info_down_line,
+ SK_ESCAPE, SK_RIGHT_ARROW, NUL, A_info_scroll_forward_page_only,
+ '\033', 'O', 'C', NUL, A_info_scroll_forward_page_only,
+ '\033', '[', 'C', NUL, A_info_scroll_forward_page_only,
+ SK_ESCAPE, SK_LEFT_ARROW, NUL, A_info_scroll_backward_page_only,
+ '\033', 'O', 'D', NUL, A_info_scroll_backward_page_only,
+ '\033', '[', 'D', NUL, A_info_scroll_backward_page_only,
+ SK_ESCAPE, SK_HOME, NUL, A_info_beginning_of_node,
+ SK_ESCAPE, SK_END, NUL, A_info_end_of_node,
+ ESC, SK_ESCAPE, SK_PAGE_DOWN, NUL, A_info_scroll_other_window,
+ ESC, SK_ESCAPE, SK_PAGE_UP, NUL, A_info_scroll_other_window_backward,
+ ESC, SK_ESCAPE, SK_DELETE, NUL, A_info_scroll_other_window_backward,
+ ESC, SK_ESCAPE, SK_UP_ARROW, NUL, A_info_prev_node,
+ ESC, '\033', 'O', 'A', NUL, A_info_prev_node,
+ ESC, '\033', '[', 'A', NUL, A_info_prev_node,
+ ESC, SK_ESCAPE, SK_DOWN_ARROW, NUL, A_info_next_node,
+ ESC, '\033', 'O', 'B', NUL, A_info_next_node,
+ ESC, '\033', '[', 'B', NUL, A_info_next_node,
+ ESC, SK_ESCAPE, SK_RIGHT_ARROW, NUL, A_info_xref_item,
+ ESC, '\033', 'O', 'C', NUL, A_info_xref_item,
+ ESC, '\033', '[', 'C', NUL, A_info_xref_item,
+ ESC, SK_ESCAPE, SK_LEFT_ARROW, NUL, A_info_beginning_of_node,
+ ESC, '\033', 'O', 'D', NUL, A_info_beginning_of_node,
+ ESC, '\033', '[', 'D', NUL, A_info_beginning_of_node,
+ CONTROL('x'), SK_ESCAPE, SK_DELETE, NUL,A_ea_backward_kill_line,
+};
+
+static unsigned char default_vi_like_ea_keys[] =
+{
+ 0, /* suppress-default-keybindings flag */
+ ESC, '1', NUL, A_info_add_digit_to_numeric_arg,
+ ESC, '2', NUL, A_info_add_digit_to_numeric_arg,
+ ESC, '3', NUL, A_info_add_digit_to_numeric_arg,
+ ESC, '4', NUL, A_info_add_digit_to_numeric_arg,
+ ESC, '5', NUL, A_info_add_digit_to_numeric_arg,
+ ESC, '6', NUL, A_info_add_digit_to_numeric_arg,
+ ESC, '7', NUL, A_info_add_digit_to_numeric_arg,
+ ESC, '8', NUL, A_info_add_digit_to_numeric_arg,
+ ESC, '9', NUL, A_info_add_digit_to_numeric_arg,
+ ESC, '-', NUL, A_info_add_digit_to_numeric_arg,
+ Meta('1'), NUL, A_info_add_digit_to_numeric_arg,
+ Meta('2'), NUL, A_info_add_digit_to_numeric_arg,
+ Meta('3'), NUL, A_info_add_digit_to_numeric_arg,
+ Meta('4'), NUL, A_info_add_digit_to_numeric_arg,
+ Meta('5'), NUL, A_info_add_digit_to_numeric_arg,
+ Meta('6'), NUL, A_info_add_digit_to_numeric_arg,
+ Meta('7'), NUL, A_info_add_digit_to_numeric_arg,
+ Meta('8'), NUL, A_info_add_digit_to_numeric_arg,
+ Meta('9'), NUL, A_info_add_digit_to_numeric_arg,
+ Meta('-'), NUL, A_info_add_digit_to_numeric_arg,
+ ESC, CONTROL('g'), NUL, A_ea_abort,
+ ESC, CONTROL('h'), NUL, A_ea_backward_kill_word,
+ ESC, CONTROL('v'), NUL, A_ea_scroll_completions_window,
+ ESC, '0', NUL, A_ea_beg_of_line,
+ ESC, '$', NUL, A_ea_end_of_line,
+ ESC, 'b', NUL, A_ea_backward_word,
+ ESC, 'd', NUL, A_ea_kill_word,
+ ESC, 'f', NUL, A_ea_forward_word,
+ ESC, 'h', NUL, A_ea_forward,
+ ESC, 'l', NUL, A_ea_backward,
+ ESC, 'w', NUL, A_ea_forward_word,
+ ESC, 'x', NUL, A_ea_delete,
+ ESC, 'X', NUL, A_ea_kill_word,
+ ESC, 'y', NUL, A_ea_yank_pop,
+ ESC, '?', NUL, A_ea_possible_completions,
+ ESC, TAB, NUL, A_ea_tab_insert,
+ ESC, DEL, NUL, A_ea_kill_word,
+ Meta(CONTROL('g')), NUL, A_ea_abort,
+ Meta(CONTROL('h')), NUL, A_ea_backward_kill_word,
+ Meta(CONTROL('v')), NUL, A_ea_scroll_completions_window,
+ Meta('0'), NUL, A_ea_beg_of_line,
+ Meta('$'), NUL, A_ea_end_of_line,
+ Meta('b'), NUL, A_ea_backward_word,
+ Meta('d'), NUL, A_ea_kill_word,
+ Meta('f'), NUL, A_ea_forward_word,
+ Meta('h'), NUL, A_ea_forward,
+ Meta('l'), NUL, A_ea_backward,
+ Meta('w'), NUL, A_ea_forward_word,
+ Meta('x'), NUL, A_ea_delete,
+ Meta('X'), NUL, A_ea_kill_word,
+ Meta('y'), NUL, A_ea_yank_pop,
+ Meta('?'), NUL, A_ea_possible_completions,
+ Meta(TAB), NUL, A_ea_tab_insert,
+ Meta(DEL), NUL, A_ea_kill_word,
+ CONTROL('a'), NUL, A_ea_beg_of_line,
+ CONTROL('b'), NUL, A_ea_backward,
+ CONTROL('d'), NUL, A_ea_delete,
+ CONTROL('e'), NUL, A_ea_end_of_line,
+ CONTROL('f'), NUL, A_ea_forward,
+ CONTROL('g'), NUL, A_ea_abort,
+ CONTROL('h'), NUL, A_ea_rubout,
+/* CONTROL('k') */
+ SK_ESCAPE, SK_LITERAL, NUL, A_ea_kill_line,
+ CONTROL('l'), NUL, A_info_redraw_display,
+ CONTROL('q'), NUL, A_ea_quoted_insert,
+ CONTROL('t'), NUL, A_ea_transpose_chars,
+ CONTROL('u'), NUL, A_ea_abort,
+ CONTROL('v'), NUL, A_ea_quoted_insert,
+ CONTROL('y'), NUL, A_ea_yank,
+ LFD, NUL, A_ea_newline,
+ RET, NUL, A_ea_newline,
+ SPC, NUL, A_ea_complete,
+ TAB, NUL, A_ea_complete,
+ '?', NUL, A_ea_possible_completions,
+#ifdef __MSDOS__
+ /* PC users will lynch me if I don't give them their usual DEL
+ effect... */
+ DEL, NUL, A_ea_delete,
+#else
+ DEL, NUL, A_ea_rubout,
+#endif
+ CONTROL('x'), 'o', NUL, A_info_next_window,
+ CONTROL('x'), DEL, NUL, A_ea_backward_kill_line,
+
+ /* Arrow key bindings for echo area keymaps. It seems that some
+ terminals do not match their termcap entries, so it's best to just
+ define everything with both of the usual prefixes. */
+
+ SK_ESCAPE, SK_RIGHT_ARROW, NUL, A_ea_forward,
+ '\033', 'O', 'C', NUL, A_ea_forward,
+ '\033', '[', 'C', NUL, A_ea_forward,
+ SK_ESCAPE, SK_LEFT_ARROW, NUL, A_ea_backward,
+ '\033', 'O', 'D', NUL, A_ea_backward,
+ '\033', '[', 'D', NUL, A_ea_backward,
+ SK_ESCAPE, SK_HOME, NUL, A_ea_beg_of_line,
+ SK_ESCAPE, SK_END, NUL, A_ea_end_of_line,
+#ifdef __MSDOS__
+ SK_ESCAPE, SK_DELETE, NUL, A_ea_delete,
+#else
+ SK_DELETE, SK_DELETE, NUL, A_ea_rubout,
+#endif
+ ESC, SK_ESCAPE, SK_RIGHT_ARROW, NUL, A_ea_forward_word,
+ ESC, '\033', 'O', 'C', NUL, A_ea_forward_word,
+ ESC, '\033', '[', 'C', NUL, A_ea_forward_word,
+ ESC, SK_ESCAPE, SK_LEFT_ARROW, NUL, A_ea_backward_word,
+ ESC, '\033', 'O', 'D', NUL, A_ea_backward_word,
+ ESC, '\033', '[', 'D', NUL, A_ea_backward_word,
+ ESC, SK_ESCAPE, SK_DELETE, NUL, A_ea_kill_word,
+ CONTROL('x'), SK_ESCAPE, SK_DELETE, NUL,A_ea_backward_kill_line,
+};
+
+static unsigned char *user_info_keys;
+static unsigned int user_info_keys_len;
+static unsigned char *user_ea_keys;
+static unsigned int user_ea_keys_len;
+static unsigned char *user_vars;
+static unsigned int user_vars_len;
+
+/*
+ * Return the size of a file, or 0 if the size can't be determined.
+ */
+static unsigned long
+filesize(f)
+ int f;
+{
+ long pos = lseek(f, 0L, SEEK_CUR);
+ long sz = -1L;
+ if (pos != -1L)
+ {
+ sz = lseek(f, 0L, SEEK_END);
+ lseek(f, pos, SEEK_SET);
+ }
+ return sz == -1L ? 0L : sz;
+}
+
+/* Get an integer from a infokey file.
+ Integers are stored as two bytes, low order first, in radix INFOKEY_RADIX.
+ */
+static int
+getint(sp)
+ unsigned char **sp;
+{
+ int n;
+
+ if ( !((*sp)[0] < INFOKEY_RADIX && (*sp)[1] < INFOKEY_RADIX) )
+ return -1;
+ n = (*sp)[0] + (*sp)[1] * INFOKEY_RADIX;
+ *sp += 2;
+ return n;
+}
+
+
+/* Fetch the contents of the standard infokey file "$HOME/.info". Return
+ true if ok, false if not. */
+static int
+fetch_user_maps()
+{
+ char *filename = NULL;
+ char *homedir;
+ int f;
+ unsigned char *buf;
+ unsigned long len;
+ long nread;
+ unsigned char *p;
+ int n;
+
+ /* Find and open file. */
+ if ((filename = getenv("INFOKEY")) != NULL)
+ filename = xstrdup(filename);
+ else if ((homedir = getenv("HOME")) != NULL)
+ {
+ filename = xmalloc(strlen(homedir) + 2 + strlen(INFOKEY_FILE));
+ strcpy(filename, homedir);
+ strcat(filename, "/");
+ strcat(filename, INFOKEY_FILE);
+ }
+#ifdef __MSDOS__
+ /* Poor baby, she doesn't have a HOME... */
+ else
+ filename = xstrdup(INFOKEY_FILE); /* try current directory */
+#endif
+ if (filename == NULL || (f = open(filename, O_RDONLY)) == (-1))
+ {
+ if (filename)
+ {
+ info_error(filesys_error_string(filename, errno));
+ free(filename);
+ }
+ return 0;
+ }
+ SET_BINARY (f);
+
+ /* Ensure that the file is a reasonable size. */
+ len = filesize(f);
+ if (len < INFOKEY_NMAGIC + 2 || len > 100 * 1024)
+ {
+ /* Bad file (a valid file must have at least 9 chars, and
+ more than 100 KB is a problem). */
+ if (len < INFOKEY_NMAGIC + 2)
+ info_error(_("Ignoring invalid infokey file `%s' - too small"),
+ filename);
+ else
+ info_error(_("Ignoring invalid infokey file `%s' - too big"),
+ filename);
+ close(f);
+ free(filename);
+ return 0;
+ }
+
+ /* Read the file into a buffer. */
+ buf = (unsigned char *)xmalloc((int)len);
+ nread = read(f, buf, (unsigned int) len);
+ close(f);
+ if (nread != len)
+ {
+ info_error(_("Error reading infokey file `%s' - short read"), filename);
+ free(buf);
+ free(filename);
+ return 0;
+ }
+
+ /* Check the header, trailer, and version of the file to increase
+ our confidence that the contents are valid. */
+ if ( buf[0] != INFOKEY_MAGIC_S0
+ || buf[1] != INFOKEY_MAGIC_S1
+ || buf[2] != INFOKEY_MAGIC_S2
+ || buf[3] != INFOKEY_MAGIC_S3
+ || buf[len - 4] != INFOKEY_MAGIC_E0
+ || buf[len - 3] != INFOKEY_MAGIC_E1
+ || buf[len - 2] != INFOKEY_MAGIC_E2
+ || buf[len - 1] != INFOKEY_MAGIC_E3
+ )
+ {
+ info_error(_("Invalid infokey file `%s' (bad magic numbers) -- run infokey to update it"), filename);
+ free(filename);
+ return 0;
+ }
+ if (len < INFOKEY_NMAGIC + strlen(VERSION) + 1 || strcmp(VERSION, buf + 4) != 0)
+ {
+ info_error(_("Your infokey file `%s' is out of date -- run infokey to update it"), filename);
+ free(filename);
+ return 0;
+ }
+
+ /* Extract the pieces. */
+ for (p = buf + 4 + strlen(VERSION) + 1; p - buf < len - 4; p += n)
+ {
+ int s = *p++;
+
+ n = getint(&p);
+ if (n < 0 || n > len - 4 - (p - buf))
+ {
+ info_error(_("Invalid infokey file `%s' (bad section length) -- run infokey to update it"), filename);
+ free(filename);
+ return 0;
+ }
+
+ switch (s)
+ {
+ case INFOKEY_SECTION_INFO:
+ user_info_keys = p;
+ user_info_keys_len = n;
+ break;
+ case INFOKEY_SECTION_EA:
+ user_ea_keys = p;
+ user_ea_keys_len = n;
+ break;
+ case INFOKEY_SECTION_VAR:
+ user_vars = p;
+ user_vars_len = n;
+ break;
+ default:
+ info_error(_("Invalid infokey file `%s' (bad section code) -- run infokey to update it"), filename);
+ free(filename);
+ return 0;
+ }
+ }
+
+ free(filename);
+ return 1;
+}
+
+/* Decode special key sequences from the infokey file. Return zero
+ if the key sequence includes special keys which the terminal
+ doesn't define.
+ */
+static int
+decode_keys(src, slen, dst, dlen)
+ unsigned char *src;
+ unsigned int slen;
+ unsigned char *dst;
+ unsigned int dlen;
+{
+ unsigned char *s = src;
+ unsigned char *d = dst;
+
+#define To_dst(c) do { if (d - dst < dlen) *d++ = (c); } while (0)
+
+ while (s - src < slen)
+ {
+ unsigned char c = ISMETA(*s) ? UNMETA(*s) : *s;
+
+ if (c == SK_ESCAPE)
+ {
+ unsigned char *t;
+ static char lit[] = { SK_ESCAPE, NUL };
+
+ switch (s + 1 - src < slen ? s[1] : '\0')
+ {
+ case SK_RIGHT_ARROW: t = term_kr; break;
+ case SK_LEFT_ARROW: t = term_kl; break;
+ case SK_UP_ARROW: t = term_ku; break;
+ case SK_DOWN_ARROW: t = term_kd; break;
+ case SK_PAGE_UP: t = term_kP; break;
+ case SK_PAGE_DOWN: t = term_kN; break;
+ case SK_HOME: t = term_kh; break;
+ case SK_END: t = term_ke; break;
+ case SK_DELETE: t = term_kx; break;
+ case SK_INSERT: t = term_ki; break;
+ case SK_LITERAL:
+ default: t = lit; break;
+ }
+ if (t == NULL)
+ return 0;
+ while (*t)
+ To_dst(ISMETA(*s) ? Meta(*t++) : *t++);
+ s += 2;
+ }
+ else
+ {
+ if (ISMETA(*s))
+ To_dst(Meta(*s++));
+ else
+ To_dst(*s++);
+ }
+ }
+
+ To_dst('\0');
+
+ return 1;
+
+#undef To_dst
+
+}
+
+/* Convert an infokey file section to keymap bindings. Return false if
+ the default bindings are to be suppressed. */
+static int
+section_to_keymaps(map, table, len)
+ Keymap map;
+ unsigned char *table;
+ unsigned int len;
+{
+ int stop;
+ unsigned char *p;
+ unsigned char *seq;
+ unsigned int seqlen;
+ KEYMAP_ENTRY ke;
+ enum { getseq, gotseq, getaction } state = getseq;
+
+ stop = len > 0 ? table[0] : 0;
+
+ for (p = table + 1; p - table < len; p++)
+ {
+ switch (state)
+ {
+ case getseq:
+ if (*p)
+ {
+ seq = p;
+ state = gotseq;
+ }
+ break;
+
+ case gotseq:
+ if (!*p)
+ {
+ seqlen = p - seq;
+ state = getaction;
+ }
+ break;
+
+ case getaction:
+ {
+ unsigned int action = *p;
+ unsigned char keyseq[256];
+ KEYMAP_ENTRY ke;
+
+ state = getseq;
+ /* If decode_keys returns zero, it
+ means that seq includes keys which
+ the terminal doesn't support, like
+ PageDown. In that case, don't bind
+ the key sequence. */
+ if (decode_keys(seq, seqlen, keyseq,
+ sizeof keyseq))
+ {
+ keyseq[sizeof keyseq - 1] = '\0';
+ ke.type = ISFUNC;
+ ke.function =
+ action < A_NCOMMANDS
+ ? &function_doc_array[action]
+ : NULL;
+ keymap_bind_keyseq(map, keyseq, &ke);
+ }
+ }
+ break;
+ }
+ }
+ if (state != getseq)
+ info_error(_("Bad data in infokey file -- some key bindings ignored"));
+ return !stop;
+}
+
+/* Convert an infokey file section to variable settings.
+ */
+static void
+section_to_vars(table, len)
+ unsigned char *table;
+ unsigned int len;
+{
+ enum { getvar, gotvar, getval, gotval } state = getvar;
+ unsigned char *var = NULL;
+ unsigned char *val = NULL;
+ unsigned char *p;
+
+ for (p = table; p - table < len; p++)
+ {
+ switch (state)
+ {
+ case getvar:
+ if (*p)
+ {
+ var = p;
+ state = gotvar;
+ }
+ break;
+
+ case gotvar:
+ if (!*p)
+ state = getval;
+ break;
+
+ case getval:
+ if (*p)
+ {
+ val = p;
+ state = gotval;
+ }
+ break;
+
+ case gotval:
+ if (!*p)
+ {
+ set_variable_to_value(var, val);
+ state = getvar;
+ }
+ break;
+ }
+ }
+ if (state != getvar)
+ info_error(_("Bad data in infokey file -- some var settings ignored"));
+}
+
+void
+initialize_info_keymaps ()
+{
+ int i;
+ int suppress_info_default_bindings = 0;
+ int suppress_ea_default_bindings = 0;
+ Keymap map;
+
+ if (!info_keymap)
+ {
+ info_keymap = keymap_make_keymap ();
+ echo_area_keymap = keymap_make_keymap ();
+ }
+
+ /* Bind the echo area insert routines. */
+ for (i = 0; i < 256; i++)
+ if (isprint (i))
+ echo_area_keymap[i].function = InfoCmd(ea_insert);
+
+ /* Get user-defined keys and variables. */
+ if (fetch_user_maps())
+ {
+ if (user_info_keys_len && user_info_keys[0])
+ suppress_info_default_bindings = 1;
+ if (user_ea_keys_len && user_ea_keys[0])
+ suppress_ea_default_bindings = 1;
+ }
+
+ /* Apply the default bindings, unless the user says to suppress
+ them. */
+ if (vi_keys_p)
+ {
+ if (!suppress_info_default_bindings)
+ section_to_keymaps(info_keymap, default_vi_like_info_keys,
+ sizeof(default_vi_like_info_keys));
+ if (!suppress_ea_default_bindings)
+ section_to_keymaps(echo_area_keymap, default_vi_like_ea_keys,
+ sizeof(default_vi_like_ea_keys));
+ }
+ else
+ {
+ if (!suppress_info_default_bindings)
+ section_to_keymaps(info_keymap, default_emacs_like_info_keys,
+ sizeof(default_emacs_like_info_keys));
+ if (!suppress_ea_default_bindings)
+ section_to_keymaps(echo_area_keymap, default_emacs_like_ea_keys,
+ sizeof(default_emacs_like_ea_keys));
+ }
+
+ /* If the user specified custom bindings, apply them on top of the
+ default ones. */
+ if (user_info_keys_len)
+ section_to_keymaps(info_keymap, user_info_keys, user_info_keys_len);
+
+ if (user_ea_keys_len)
+ section_to_keymaps(echo_area_keymap, user_ea_keys, user_ea_keys_len);
+
+ if (user_vars_len)
+ section_to_vars(user_vars, user_vars_len);
+}
+
+#endif /* defined(INFOKEY) */
diff --git a/gnu/usr.bin/texinfo/info/m-x.c b/gnu/usr.bin/texinfo/info/m-x.c
index bf4dc2ffcce..4fa90d48e0c 100644
--- a/gnu/usr.bin/texinfo/info/m-x.c
+++ b/gnu/usr.bin/texinfo/info/m-x.c
@@ -1,7 +1,7 @@
/* m-x.c -- Meta-x minibuffer reader.
- $Id: m-x.c,v 1.3 2000/02/09 02:18:40 espie Exp $
+ $Id: m-x.c,v 1.4 2002/06/10 13:51:03 espie Exp $
- Copyright (C) 1993, 97, 98 Free Software Foundation, Inc.
+ Copyright (C) 1993, 97, 98, 2001 Free Software Foundation, Inc.
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
@@ -20,6 +20,7 @@
Written by Brian Fox (bfox@ai.mit.edu). */
#include "info.h"
+#include "funs.h"
/* **************************************************************** */
/* */
@@ -81,13 +82,13 @@ DECLARE_INFO_COMMAND (describe_command,
/* Describe the function named in "LINE". */
if (*line)
{
- VFunction *fun = named_function (line);
+ InfoCommand *cmd = named_function (line);
- if (!fun)
+ if (!cmd)
return;
window_message_in_echo_area ("%s: %s.",
- line, function_documentation (fun));
+ line, function_documentation (cmd));
}
free (line);
}
@@ -96,18 +97,24 @@ DECLARE_INFO_COMMAND (info_execute_command,
_("Read a command name in the echo area and execute it"))
{
char *line;
+ char *keys;
+ char *prompt;
- /* Ask the completer to read a reference for us. */
- if (info_explicit_arg || count != 1)
- {
- char *prompt;
+ prompt = (char *)xmalloc (20);
- prompt = (char *)xmalloc (20);
- sprintf (prompt, "%d M-x ", count);
- line = read_function_name (prompt, window);
- }
+ keys = where_is (info_keymap, InfoCmd(info_execute_command));
+ /* If the where_is () function thinks that this command doesn't exist,
+ there's something very wrong! */
+ if (!keys)
+ abort();
+
+ if (info_explicit_arg || count != 1)
+ sprintf (prompt, "%d %s ", count, keys);
else
- line = read_function_name ("M-x ", window);
+ sprintf (prompt, "%s ", keys);
+
+ /* Ask the completer to read a reference for us. */
+ line = read_function_name (prompt, window);
/* User aborted? */
if (!line)
@@ -125,7 +132,7 @@ DECLARE_INFO_COMMAND (info_execute_command,
/* User wants to execute a named command. Do it. */
{
- VFunction *function;
+ InfoCommand *command;
if ((active_window != the_echo_area) &&
(strncmp (line, "echo-area-", 10) == 0))
@@ -135,13 +142,13 @@ DECLARE_INFO_COMMAND (info_execute_command,
return;
}
- function = named_function (line);
+ command = named_function (line);
free (line);
- if (!function)
+ if (!command)
return;
- (*function) (active_window, count, 0);
+ (*InfoFunction(command)) (active_window, count, 0);
}
}
diff --git a/gnu/usr.bin/texinfo/info/makedoc.c b/gnu/usr.bin/texinfo/info/makedoc.c
index 2a0b27a5236..919ea090480 100644
--- a/gnu/usr.bin/texinfo/info/makedoc.c
+++ b/gnu/usr.bin/texinfo/info/makedoc.c
@@ -1,7 +1,7 @@
/* makedoc.c -- make doc.c and funs.h from input files.
- $Id: makedoc.c,v 1.3 2000/02/09 02:18:40 espie Exp $
+ $Id: makedoc.c,v 1.4 2002/06/10 13:51:03 espie Exp $
- Copyright (C) 1993, 97, 98, 99 Free Software Foundation, Inc.
+ Copyright (C) 1993, 97, 98, 99, 2001 Free Software Foundation, Inc.
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
@@ -25,6 +25,7 @@
declared with DECLARE_INFO_COMMAND. */
#include "info.h"
+#include "infokey.h"
static void fatal_file_error ();
@@ -33,6 +34,7 @@ static char *funs_filename = "funs.h";
/* Name of the documentation to function pointer file. */
static char *doc_filename = "doc.c";
+static char *key_filename = "key.c";
static char *doc_header[] = {
"/* doc.c -- Generated structure containing function names and doc strings.",
@@ -50,7 +52,7 @@ static char *doc_header_1[] = {
#endif /* NAMED_FUNCTIONS */
" and a string which documents its purpose. */",
"",
- "#include \"doc.h\"",
+ "#include \"info.h\"",
"#include \"funs.h\"",
"",
"FUNCTION_DOC function_doc_array[] = {",
@@ -58,6 +60,28 @@ static char *doc_header_1[] = {
(char *)NULL
};
+static char *key_header[] = {
+ "/* key.c -- Generated array containing function names.",
+ "",
+ " This file was automatically made from various source files with the",
+ " command \"%s\". DO NOT EDIT THIS FILE, only \"%s.c\".",
+ "",
+ (char *)NULL
+};
+
+static char *key_header_1[] = {
+ " An entry in the array FUNCTION_KEY_ARRAY is made for each command",
+ " found in the above files; each entry consists of",
+ " a string which is the user-visible name of the function. */",
+ "",
+ "#include \"key.h\"",
+ "#include \"funs.h\"",
+ "",
+ "FUNCTION_KEY function_key_array[] = {",
+ "",
+ (char *)NULL
+};
+
/* How to remember the locations of the functions found so that Emacs
can use the information in a tag table. */
typedef struct {
@@ -83,6 +107,8 @@ int emacs_tags_slots = 0;
static void process_one_file ();
static void maybe_dump_tags ();
static FILE *must_fopen ();
+static void init_func_key ();
+static unsigned int next_func_key ();
int
main (argc, argv)
@@ -92,6 +118,7 @@ main (argc, argv)
register int i;
int tags_only = 0;
FILE *funs_stream, *doc_stream;
+ FILE *key_stream;
#if STRIP_DOT_EXE
{
@@ -113,10 +140,12 @@ main (argc, argv)
{
funs_filename = NULL_DEVICE;
doc_filename = NULL_DEVICE;
+ key_filename = NULL_DEVICE;
}
funs_stream = must_fopen (funs_filename, "w");
doc_stream = must_fopen (doc_filename, "w");
+ key_stream = must_fopen (key_filename, "w");
fprintf (funs_stream,
"/* %s -- Generated declarations for Info commands. */\n",
@@ -131,14 +160,29 @@ main (argc, argv)
fprintf (doc_stream,
_(" Source files groveled to make this file include:\n\n"));
+ for (i = 0; key_header[i]; i++)
+ {
+ fprintf (key_stream, key_header[i], argv[0], argv[0]);
+ fprintf (key_stream, "\n");
+ }
+ fprintf (key_stream,
+ _(" Source files groveled to make this file include:\n\n"));
+
for (i = 1; i < argc; i++)
- fprintf (doc_stream, "\t%s\n", argv[i]);
+ {
+ fprintf (doc_stream, "\t%s\n", argv[i]);
+ fprintf (key_stream, "\t%s\n", argv[i]);
+ }
fprintf (doc_stream, "\n");
-
for (i = 0; doc_header_1[i]; i++)
fprintf (doc_stream, "%s\n", doc_header_1[i]);
+ fprintf (key_stream, "\n");
+ for (i = 0; key_header_1[i]; i++)
+ fprintf (key_stream, "%s\n", key_header_1[i]);
+
+ init_func_key(0);
for (i = 1; i < argc; i++)
{
@@ -149,17 +193,39 @@ main (argc, argv)
continue;
fprintf (doc_stream, "/* Commands found in \"%s\". */\n", curfile);
+ fprintf (key_stream, "/* Commands found in \"%s\". */\n", curfile);
fprintf (funs_stream, "\n/* Functions declared in \"%s\". */\n",
curfile);
- process_one_file (curfile, doc_stream, funs_stream);
+ process_one_file (curfile, doc_stream, key_stream, funs_stream);
}
+#if defined (INFOKEY)
+
+#if defined (NAMED_FUNCTIONS)
+ fprintf (doc_stream,
+ " { (VFunction *)NULL, (char *)NULL, (FUNCTION_KEYSEQ *)NULL, (char *)NULL }\n};\n");
+#else /* !NAMED_FUNCTIONS */
+ fprintf (doc_stream, " { (VFunction *)NULL, (FUNCTION_KEYSEQ *)NULL, (char *)NULL }\n};\n");
+#endif /* !NAMED_FUNCTIONS */
+
+#else /* !INFOKEY */
+
+#if defined (NAMED_FUNCTIONS)
fprintf (doc_stream,
" { (VFunction *)NULL, (char *)NULL, (char *)NULL }\n};\n");
+#else /* !NAMED_FUNCTIONS */
+ fprintf (doc_stream, " { (VFunction *)NULL, (char *)NULL }\n};\n");
+#endif /* !NAMED_FUNCTIONS */
+
+#endif /* !INFOKEY */
+
+ fprintf (key_stream, " (char *)0\n};\n");
+ fprintf (funs_stream, "\n#define A_NCOMMANDS %u\n", next_func_key());
fclose (funs_stream);
fclose (doc_stream);
+ fclose (key_stream);
if (tags_only)
maybe_dump_tags (stdout);
@@ -250,11 +316,13 @@ add_tag_to_block (block, name, line, char_offset)
/* Read the file represented by FILENAME into core, and search it for Info
function declarations. Output the declarations in various forms to the
- DOC_STREAM and FUNS_STREAM. */
+ DOC_STREAM, KEY_STREAM, and FUNS_STREAM. */
static void
-process_one_file (filename, doc_stream, funs_stream)
+process_one_file (filename, doc_stream, key_stream, funs_stream)
char *filename;
- FILE *doc_stream, *funs_stream;
+ FILE *doc_stream;
+ FILE *key_stream;
+ FILE *funs_stream;
{
int descriptor, decl_len;
char *buffer, *decl_str;
@@ -292,9 +360,9 @@ process_one_file (filename, doc_stream, funs_stream)
int line_number = 0;
char *func, *doc;
-#if defined (NAMED_FUNCTIONS)
+#if defined (INFOKEY) || defined (NAMED_FUNCTIONS)
char *func_name;
-#endif /* NAMED_FUNCTIONS */
+#endif /* INFOKEY || NAMED_FUNCTIONS */
for (; offset < (file_size - decl_len); offset++)
{
@@ -359,7 +427,7 @@ process_one_file (filename, doc_stream, funs_stream)
add_tag_to_block (block, tag_name, line_number, point);
}
-#if defined (NAMED_FUNCTIONS)
+#if defined (INFOKEY) || defined (NAMED_FUNCTIONS)
/* Generate the user-visible function name from the function's name. */
{
register int i;
@@ -388,7 +456,7 @@ process_one_file (filename, doc_stream, funs_stream)
if (func_name[i] == '_')
func_name[i] = '-';
}
-#endif /* NAMED_FUNCTIONS */
+#endif /* INFOKEY || NAMED_FUNCTIONS */
/* Find doc string. */
point = offset + 1;
@@ -433,13 +501,33 @@ process_one_file (filename, doc_stream, funs_stream)
strncpy (doc, buffer + point, offset - point);
doc[offset - point] = '\0';
+#if defined (INFOKEY)
+
+#if defined (NAMED_FUNCTIONS)
+ fprintf (doc_stream, " { %s, \"%s\", (FUNCTION_KEYSEQ *)0, %s },\n", func, func_name, doc);
+#else /* !NAMED_FUNCTIONS */
+ fprintf (doc_stream, " { %s, (FUNCTION_KEYSEQ *)0, %s },\n", func, doc);
+#endif /* !NAMED_FUNCTIONS */
+
+ fprintf (key_stream, " { \"%s\", A_%s },\n", func_name, func);
+
+#else /* !INFOKEY */
+
#if defined (NAMED_FUNCTIONS)
fprintf (doc_stream, " { %s, \"%s\", %s },\n", func, func_name, doc);
- free (func_name);
#else /* !NAMED_FUNCTIONS */
fprintf (doc_stream, " { %s, %s },\n", func, doc);
#endif /* !NAMED_FUNCTIONS */
+#endif /* !INFOKEY */
+
+#if defined (INFOKEY) || defined (NAMED_FUNCTIONS)
+ free (func_name);
+#endif /* INFOKEY || NAMED_FUNCTIONS */
+
+#if defined (INFOKEY)
+ fprintf (funs_stream, "#define A_%s %u\n", func, next_func_key());
+#endif /* INFOKEY */
fprintf (funs_stream, "extern void %s ();\n", func);
free (func);
free (doc);
@@ -479,3 +567,17 @@ must_fopen (filename, mode)
return (stream);
}
+static unsigned int func_key;
+
+static void
+init_func_key(val)
+ unsigned int val;
+{
+ func_key = val;
+}
+
+static unsigned int
+next_func_key()
+{
+ return func_key++;
+}
diff --git a/gnu/usr.bin/texinfo/info/man.c b/gnu/usr.bin/texinfo/info/man.c
index f0ff1032f12..db92d09499b 100644
--- a/gnu/usr.bin/texinfo/info/man.c
+++ b/gnu/usr.bin/texinfo/info/man.c
@@ -1,7 +1,7 @@
/* man.c: How to read and format man files.
- $Id: man.c,v 1.3 2000/02/09 02:18:40 espie Exp $
+ $Id: man.c,v 1.4 2002/06/10 13:51:03 espie Exp $
- Copyright (C) 1995, 97, 98, 99 Free Software Foundation, Inc.
+ Copyright (C) 1995, 97, 98, 99, 2000 Free Software Foundation, Inc.
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
@@ -397,11 +397,36 @@ clean_manpage (manpage)
newline_count--;
}
- if (manpage[i] == '\b' || manpage[i] == '\f')
+ /* A malformed man page could have a \b as its first character,
+ in which case decrementing j by 2 will cause us to write into
+ newpage[-1], smashing the hidden info stored there by malloc. */
+ if (manpage[i] == '\b' || manpage[i] == '\f' && j > 0)
j -= 2;
+ else if (!raw_escapes_p)
+ {
+ /* Remove the ANSI escape sequences for color, boldface,
+ underlining, and italics, generated by some versions of
+ Groff. */
+ if (manpage[i] == '\033' && manpage[i + 1] == '['
+ && isdigit (manpage[i + 2]))
+ {
+ if (isdigit (manpage[i + 3]) && manpage[i + 4] == 'm')
+ {
+ i += 4;
+ j--;
+ }
+ else if (manpage[i + 3] == 'm')
+ {
+ i += 3;
+ j--;
+ }
+ /* Else do nothing: it's some unknown escape sequence,
+ so let's leave it alone. */
+ }
+ }
}
- newpage[j++] = '\0';
+ newpage[j++] = 0;
strcpy (manpage, newpage);
free (newpage);
diff --git a/gnu/usr.bin/texinfo/info/session.c b/gnu/usr.bin/texinfo/info/session.c
index 0eb60a80576..43b8e22ce5f 100644
--- a/gnu/usr.bin/texinfo/info/session.c
+++ b/gnu/usr.bin/texinfo/info/session.c
@@ -1,7 +1,8 @@
/* session.c -- user windowing interface to Info.
- $Id: session.c,v 1.4 2000/02/09 02:18:40 espie Exp $
+ $Id: session.c,v 1.5 2002/06/10 13:51:03 espie Exp $
- Copyright (C) 1993, 96, 97, 98, 99 Free Software Foundation, Inc.
+ Copyright (C) 1993, 96, 97, 98, 99, 2000, 01, 02
+ Free Software Foundation, Inc.
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
@@ -1139,19 +1140,26 @@ DECLARE_INFO_COMMAND (info_global_prev_node,
}
}
-/* Show the next screen of WINDOW's node. */
-DECLARE_INFO_COMMAND (info_scroll_forward, _("Scroll forward in this window"))
+static void _scroll_forward();
+static void _scroll_backward();
+
+static void
+_scroll_forward(window, count, key, behaviour)
+ WINDOW *window;
+ int count;
+ unsigned char key;
+ int behaviour;
{
if (count < 0)
- info_scroll_backward (window, -count, key);
+ _scroll_backward (window, -count, key, behaviour);
else
{
int desired_top;
/* Without an explicit numeric argument, scroll the bottom two
lines to the top of this window, Or, if at bottom of window,
- and the user wishes to scroll through nodes get the "Next" node
- for this window. */
+ and the chosen behaviour is to scroll through nodes get the
+ "Next" node for this window. */
if (default_window_size > 0)
desired_top = window->pagetop + default_window_size;
else if (!info_explicit_arg && count == 1)
@@ -1159,16 +1167,9 @@ DECLARE_INFO_COMMAND (info_scroll_forward, _("Scroll forward in this window"))
desired_top = window->pagetop + (window->height - 2);
/* If there are no more lines to scroll here, error, or get
- another node, depending on INFO_SCROLL_BEHAVIOUR. */
+ another node, depending on BEHAVIOUR. */
if (desired_top > window->line_count)
{
- int behaviour = info_scroll_behaviour;
-
- /* Here is a hack. If the key being used is not SPC, do the
- PageOnly behaviour. */
- if (key != SPC && key != DEL)
- behaviour = IS_PageOnly;
-
forward_move_node_structure (window, behaviour);
return;
}
@@ -1186,28 +1187,22 @@ DECLARE_INFO_COMMAND (info_scroll_forward, _("Scroll forward in this window"))
}
}
-/* Like info_scroll_forward, but sets default_window_size as a side
- effect. */
-DECLARE_INFO_COMMAND (info_scroll_forward_set_window,
- _("Scroll forward in this window and set default window size"))
-{
- if (info_explicit_arg)
- default_window_size = count;
- info_scroll_forward (window, count, key);
-}
-
-/* Show the previous screen of WINDOW's node. */
-DECLARE_INFO_COMMAND (info_scroll_backward, _("Scroll backward in this window"))
+static void
+_scroll_backward(window, count, key, behaviour)
+ WINDOW *window;
+ int count;
+ unsigned char key;
+ int behaviour;
{
if (count < 0)
- info_scroll_forward (window, -count, key);
+ _scroll_forward (window, -count, key, behaviour);
else
{
int desired_top;
/* Without an explicit numeric argument, scroll the top two lines
- to the bottom of this window, or move to the previous, or Up'th
- node. */
+ to the bottom of this window, or, depending on the selected
+ behaviour, move to the previous, or Up'th node. */
if (default_window_size > 0)
desired_top = window->pagetop - default_window_size;
else if (!info_explicit_arg && count == 1)
@@ -1216,14 +1211,6 @@ DECLARE_INFO_COMMAND (info_scroll_backward, _("Scroll backward in this window"))
if ((desired_top < 0) && (window->pagetop == 0))
{
- int behaviour = info_scroll_behaviour;
-
- /* Same kind of hack as in info_scroll_forward. If the key
- used to invoke this command is not DEL, do only the PageOnly
- behaviour. */
- if (key != DEL && key != SPC)
- behaviour = IS_PageOnly;
-
backward_move_node_structure (window, behaviour);
return;
}
@@ -1238,6 +1225,44 @@ DECLARE_INFO_COMMAND (info_scroll_backward, _("Scroll backward in this window"))
}
}
+/* Show the next screen of WINDOW's node. */
+DECLARE_INFO_COMMAND (info_scroll_forward, _("Scroll forward in this window"))
+{
+ _scroll_forward (window, count, key, info_scroll_behaviour);
+}
+
+/* Like info_scroll_forward, but sets default_window_size as a side
+ effect. */
+DECLARE_INFO_COMMAND (info_scroll_forward_set_window,
+ _("Scroll forward in this window and set default window size"))
+{
+ if (info_explicit_arg)
+ default_window_size = count;
+ _scroll_forward (window, count, key, info_scroll_behaviour);
+}
+
+/* Show the next screen of WINDOW's node but never advance to next node. */
+DECLARE_INFO_COMMAND (info_scroll_forward_page_only, _("Scroll forward in this window staying within node"))
+{
+ _scroll_forward (window, count, key, IS_PageOnly);
+}
+
+/* Like info_scroll_forward_page_only, but sets default_window_size as a side
+ effect. */
+DECLARE_INFO_COMMAND (info_scroll_forward_page_only_set_window,
+ _("Scroll forward in this window staying within node and set default window size"))
+{
+ if (info_explicit_arg)
+ default_window_size = count;
+ _scroll_forward (window, count, key, IS_PageOnly);
+}
+
+/* Show the previous screen of WINDOW's node. */
+DECLARE_INFO_COMMAND (info_scroll_backward, _("Scroll backward in this window"))
+{
+ _scroll_backward (window, count, key, info_scroll_behaviour);
+}
+
/* Like info_scroll_backward, but sets default_window_size as a side
effect. */
DECLARE_INFO_COMMAND (info_scroll_backward_set_window,
@@ -1245,7 +1270,24 @@ DECLARE_INFO_COMMAND (info_scroll_backward_set_window,
{
if (info_explicit_arg)
default_window_size = count;
- info_scroll_backward (window, count, key);
+ _scroll_backward (window, count, key, info_scroll_behaviour);
+}
+
+/* Show the previous screen of WINDOW's node but never move to previous
+ node. */
+DECLARE_INFO_COMMAND (info_scroll_backward_page_only, _("Scroll backward in this window staying within node"))
+{
+ _scroll_backward (window, count, key, IS_PageOnly);
+}
+
+/* Like info_scroll_backward_page_only, but sets default_window_size as a side
+ effect. */
+DECLARE_INFO_COMMAND (info_scroll_backward_page_only_set_window,
+ _("Scroll backward in this window staying within node and set default window size"))
+{
+ if (info_explicit_arg)
+ default_window_size = count;
+ _scroll_backward (window, count, key, IS_PageOnly);
}
/* Move to the beginning of the node. */
@@ -1301,7 +1343,7 @@ DECLARE_INFO_COMMAND (info_scroll_half_screen_down,
_("Scroll down by half screen size"))
{
if (count < 0)
- info_scroll_half_screen_up (window -count, key);
+ info_scroll_half_screen_up (window, -count, key);
else
{
int scroll_size = (the_screen->height + 1) / 2;
@@ -1327,7 +1369,7 @@ DECLARE_INFO_COMMAND (info_scroll_half_screen_up,
_("Scroll up by half screen size"))
{
if (count < 0)
- info_scroll_half_screen_down (window -count, key);
+ info_scroll_half_screen_down (window, -count, key);
else
{
int scroll_size = (the_screen->height + 1) / 2;
@@ -2028,7 +2070,19 @@ info_menu_or_ref_item (window, count, key, builder, ask_p)
refs = manpage_xrefs_in_binding (window->node, &binding);
else
#endif /* HANDLE_MAN_PAGES */
- refs = info_xrefs (&binding);
+ {
+ refs = info_xrefs (&binding);
+ if (!refs && point_line > 0)
+ {
+ /* People get annoyed that Info cannot find an xref
+ which starts on a previous line and ends on this
+ one. So if we fail to find a reference on this
+ line, let's try the one before. */
+ binding.start =
+ window->line_starts[point_line - 1] - binding.buffer;
+ refs = info_xrefs (&binding);
+ }
+ }
}
if (refs)
@@ -2062,8 +2116,8 @@ info_menu_or_ref_item (window, count, key, builder, ask_p)
which = closest;
}
- if (which < 0)
- which = 0;
+ if (which < 0)
+ which = 0;
defentry = (REFERENCE *)xmalloc (sizeof (REFERENCE));
defentry->label = xstrdup (refs[which]->label);
defentry->filename = refs[which]->filename;
@@ -2141,8 +2195,43 @@ info_menu_or_ref_item (window, count, key, builder, ask_p)
if (line)
{
- /* Find the selected label in the references. */
- entry = info_get_labeled_reference (line, menu);
+ /* It is possible that the references have more than a single
+ entry with the same label, and also LINE is down-cased, which
+ complicates matters even more. Try to be as accurate as we
+ can: if they've chosen the default, use defentry directly. */
+ if (defentry && strcmp (line, defentry->label) == 0)
+ entry = defentry;
+ else
+ /* Find the selected label in the references. If there are
+ more than one label which matches, find the one that's
+ closest to point. */
+ {
+ register int i;
+ int best = -1, min_dist = window->node->nodelen;
+ REFERENCE *ref;
+
+ for (i = 0; menu && (ref = menu[i]); i++)
+ {
+ /* Need to use strcasecmp because LINE is downcased
+ inside info_read_completing_in_echo_area. */
+ if (strcasecmp (line, ref->label) == 0)
+ {
+ /* ref->end is more accurate estimate of position
+ for menus than ref->start. Go figure. */
+ int dist = abs (window->point - ref->end);
+
+ if (dist < min_dist)
+ {
+ min_dist = dist;
+ best = i;
+ }
+ }
+ }
+ if (best != -1)
+ entry = menu[best];
+ else
+ entry = (REFERENCE *)NULL;
+ }
if (!entry && defentry)
info_error (_("The reference disappeared! (%s)."), line);
@@ -2415,7 +2504,12 @@ info_follow_menus (initial_node, menus, errstr, errarg1, errarg2)
{
if (arg == first_arg)
{
- node = make_manpage_node (first_arg);
+ /* Maybe they typed "info foo" instead of "info -f foo". */
+ node = info_get_node (first_arg, 0);
+ if (node)
+ add_file_directory_to_path (first_arg);
+ else
+ node = make_manpage_node (first_arg);
if (node)
goto maybe_got_node;
}
@@ -3875,14 +3969,27 @@ incremental_search (window, count, ignore)
if (!Meta_p (key) || key > 32)
{
- func = window->keymap[key].function;
+ func = InfoFunction(window->keymap[key].function);
+
+ if (isprint (key) || func == (VFunction *)NULL)
+ {
+ insert_and_search:
+
+ if (isearch_string_index + 2 >= isearch_string_size)
+ isearch_string = (char *)xrealloc
+ (isearch_string, isearch_string_size += 100);
- /* If this key invokes an incremental search, then this means that
- we will either search again in the same direction, search
- again in the reverse direction, or insert the last search
- string that was accepted through incremental searching. */
- if (func == isearch_forward || func == isearch_backward)
+ isearch_string[isearch_string_index++] = key;
+ isearch_string[isearch_string_index] = '\0';
+ goto search_now;
+ }
+ else if (func == isearch_forward || func == isearch_backward)
{
+ /* If this key invokes an incremental search, then this
+ means that we will either search again in the same
+ direction, search again in the reverse direction, or
+ insert the last search string that was accepted through
+ incremental searching. */
if ((func == isearch_forward && dir > 0) ||
(func == isearch_backward && dir < 0))
{
@@ -3920,18 +4027,6 @@ incremental_search (window, count, ignore)
dir = -dir;
}
}
- else if (isprint (key) || func == (VFunction *)NULL)
- {
- insert_and_search:
-
- if (isearch_string_index + 2 >= isearch_string_size)
- isearch_string = (char *)xrealloc
- (isearch_string, isearch_string_size += 100);
-
- isearch_string[isearch_string_index++] = key;
- isearch_string[isearch_string_index] = '\0';
- goto search_now;
- }
else if (func == info_abort_key)
{
/* If C-g pressed, and the search is failing, pop the search
@@ -3973,8 +4068,9 @@ incremental_search (window, count, ignore)
/* FIXME: this seems like a kludge! We need a more reliable
mechanism to know when ESC is a separate key and when it is
part of an escape sequence. */
- if (key != isearch_terminate_search_key ||
- info_any_buffered_input_p ())
+ if (key != RET /* Emacs addicts want RET to get lost */
+ && (key != isearch_terminate_search_key
+ || info_any_buffered_input_p ()))
info_set_pending_input (key);
if (func == info_abort_key)
@@ -4379,8 +4475,10 @@ DECLARE_INFO_COMMAND (info_quit, _("Quit using Info"))
/* */
/* **************************************************************** */
-/* Declaration only. Special cased in info_dispatch_on_key (). */
-DECLARE_INFO_COMMAND (info_do_lowercase_version, "")
+/* Declaration only. Special cased in info_dispatch_on_key ().
+ Doc string is to avoid ugly results with describe_key etc. */
+DECLARE_INFO_COMMAND (info_do_lowercase_version,
+ _("Run command bound to this key's lowercase variant"))
{}
static void
@@ -4405,7 +4503,6 @@ dispatch_error (keyseq)
/* Keeping track of key sequences. */
static char *info_keyseq = (char *)NULL;
-static char keyseq_rep[100];
static int info_keyseq_index = 0;
static int info_keyseq_size = 0;
static int info_keyseq_displayed_p = 0;
@@ -4430,25 +4527,6 @@ add_char_to_keyseq (character)
info_keyseq[info_keyseq_index] = '\0';
}
-/* Return the pretty printable string which represents KEYSEQ. */
-char *
-pretty_keyseq (keyseq)
- char *keyseq;
-{
- register int i;
-
- keyseq_rep[0] = '\0';
-
- for (i = 0; keyseq[i]; i++)
- {
- sprintf (keyseq_rep + strlen (keyseq_rep), "%s%s",
- strlen (keyseq_rep) ? " " : "",
- pretty_keyname (keyseq[i]));
- }
-
- return (keyseq_rep);
-}
-
/* Display the current value of info_keyseq. If argument EXPECTING is
non-zero, input is expected to be read after the key sequence is
displayed, so add an additional prompting character to the sequence. */
@@ -4515,6 +4593,7 @@ info_dispatch_on_key (key, map)
unsigned char key;
Keymap map;
{
+#if !defined(INFOKEY)
if (Meta_p (key) && (!ISO_Latin_p || map[key].function != ea_insert))
{
if (map[ESC].type == ISKMAP)
@@ -4530,6 +4609,7 @@ info_dispatch_on_key (key, map)
}
return;
}
+#endif /* INFOKEY */
switch (map[key].type)
{
@@ -4537,13 +4617,26 @@ info_dispatch_on_key (key, map)
{
VFunction *func;
- func = map[key].function;
+ func = InfoFunction(map[key].function);
if (func != (VFunction *)NULL)
{
/* Special case info_do_lowercase_version (). */
if (func == info_do_lowercase_version)
{
+#if defined(INFOKEY)
+ unsigned char lowerkey;
+
+ lowerkey = Meta_p(key) ? Meta (tolower (UnMeta (key))) : tolower (key);
+ if (lowerkey == key)
+ {
+ add_char_to_keyseq (key);
+ dispatch_error (info_keyseq);
+ return;
+ }
+ info_dispatch_on_key (lowerkey, map);
+#else /* !INFOKEY */
info_dispatch_on_key (tolower (key), map);
+#endif /* INFOKEY */
return;
}
@@ -4556,7 +4649,7 @@ info_dispatch_on_key (key, map)
WINDOW *where;
where = active_window;
- (*map[key].function)
+ (*InfoFunction(map[key].function))
(active_window, info_numeric_arg * info_numeric_arg_sign, key);
/* If we have input pending, then the last command was a prefix
@@ -4566,9 +4659,9 @@ info_dispatch_on_key (key, map)
if (!info_input_pending_p ())
{
if (where == the_echo_area)
- ea_last_executed_command = map[key].function;
+ ea_last_executed_command = InfoFunction(map[key].function);
else
- info_last_executed_command = map[key].function;
+ info_last_executed_command = InfoFunction(map[key].function);
}
}
}
@@ -4583,7 +4676,7 @@ info_dispatch_on_key (key, map)
case ISKMAP:
add_char_to_keyseq (key);
- if (map[key].function != (VFunction *)NULL)
+ if (map[key].function != (InfoCommand *)NULL)
{
unsigned char newkey;
@@ -4662,23 +4755,35 @@ DECLARE_INFO_COMMAND (info_numeric_arg_digit_loop,
pure_key = key = info_get_another_input_char ();
+#if !defined(INFOKEY)
if (Meta_p (key))
add_char_to_keyseq (ESC);
add_char_to_keyseq (UnMeta (key));
+#else /* defined(INFOKEY) */
+ add_char_to_keyseq (key);
+#endif /* defined(INFOKEY) */
}
+#if !defined(INFOKEY)
if (Meta_p (key))
key = UnMeta (key);
+#endif /* !defined(INFOKEY) */
if (keymap[key].type == ISFUNC &&
- keymap[key].function == info_universal_argument)
+ InfoFunction(keymap[key].function) == info_universal_argument)
{
info_numeric_arg *= 4;
key = 0;
continue;
}
+#if defined(INFOKEY)
+ if (Meta_p (key))
+ key = UnMeta (key);
+#endif /* !defined(INFOKEY) */
+
+
if (isdigit (key))
{
if (info_explicit_arg)
diff --git a/gnu/usr.bin/texinfo/info/termdep.h b/gnu/usr.bin/texinfo/info/termdep.h
index 4ed9db7108b..554452674b9 100644
--- a/gnu/usr.bin/texinfo/info/termdep.h
+++ b/gnu/usr.bin/texinfo/info/termdep.h
@@ -1,7 +1,7 @@
/* termdep.h -- System things that terminal.c depends on.
- $Id: termdep.h,v 1.3 2000/02/09 02:18:40 espie Exp $
+ $Id: termdep.h,v 1.4 2002/06/10 13:51:03 espie Exp $
- Copyright (C) 1993, 96, 97, 98 Free Software Foundation, Inc.
+ Copyright (C) 1993, 96, 97, 98, 2001 Free Software Foundation, Inc.
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
@@ -30,9 +30,6 @@
#ifdef HAVE_TERMIOS_H
# include <termios.h>
-# ifdef GWINSZ_IN_SYS_IOCTL
-# include <sys/ioctl.h>
-# endif
#else
# if defined (HAVE_TERMIO_H)
# include <termio.h>
@@ -50,6 +47,10 @@
# endif /* !HAVE_TERMIO_H */
#endif /* !HAVE_TERMIOS_H */
+#ifdef GWINSZ_IN_SYS_IOCTL
+# include <sys/ioctl.h>
+#endif
+
#ifdef HAVE_SYS_TTOLD_H
# include <sys/ttold.h>
#endif /* HAVE_SYS_TTOLD_H */
diff --git a/gnu/usr.bin/texinfo/info/terminal.c b/gnu/usr.bin/texinfo/info/terminal.c
index 48db13be1aa..075de35b77c 100644
--- a/gnu/usr.bin/texinfo/info/terminal.c
+++ b/gnu/usr.bin/texinfo/info/terminal.c
@@ -1,7 +1,7 @@
/* terminal.c -- How to handle the physical terminal for Info.
- $Id: terminal.c,v 1.5 2000/02/09 02:18:40 espie Exp $
+ $Id: terminal.c,v 1.6 2002/06/10 13:51:03 espie Exp $
- Copyright (C) 1988, 89, 90, 91, 92, 93, 96, 97, 98, 99
+ Copyright (C) 1988, 89, 90, 91, 92, 93, 96, 97, 98, 99, 2001
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
@@ -26,7 +26,6 @@
#include <sys/types.h>
#include <signal.h>
-#include <sys/ioctl.h> /* TIOCGWINSZ on LynxOS, at least */
/* The Unix termcap interface code. */
#ifdef HAVE_NCURSES_TERMCAP_H
@@ -217,12 +216,17 @@ int terminal_use_visible_bell_p = 0;
int terminal_can_scroll = 0;
/* The key sequences output by the arrow keys, if this terminal has any. */
-char *term_ku = (char *)NULL;
-char *term_kd = (char *)NULL;
-char *term_kr = (char *)NULL;
-char *term_kl = (char *)NULL;
-char *term_kP = (char *)NULL; /* page-up */
-char *term_kN = (char *)NULL; /* page-down */
+char *term_ku = NULL;
+char *term_kd = NULL;
+char *term_kr = NULL;
+char *term_kl = NULL;
+char *term_kP = NULL; /* page-up */
+char *term_kN = NULL; /* page-down */
+char *term_kh = NULL; /* home */
+char *term_ke = NULL; /* end */
+char *term_kD = NULL; /* delete */
+char *term_ki = NULL; /* ins */
+char *term_kx = NULL; /* del */
/* Move the cursor to the terminal location of X and Y. */
void
@@ -555,6 +559,8 @@ terminal_initialize_terminal (terminal_name)
term_up = term_dn = audible_bell = visible_bell = NULL;
term_ku = term_kd = term_kl = term_kr = NULL;
term_kP = term_kN = NULL;
+ term_kh = term_ke = NULL;
+ term_kD = NULL;
return;
}
@@ -601,7 +607,7 @@ terminal_initialize_terminal (terminal_name)
if (term_invbeg)
term_invend = tgetstr ("me", &buffer);
else
- term_invend = (char *)NULL;
+ term_invend = NULL;
if (!term_cr)
term_cr = "\r";
@@ -611,7 +617,7 @@ terminal_initialize_terminal (terminal_name)
term_up = tgetstr ("up", &buffer);
term_dn = tgetstr ("dn", &buffer);
visible_bell = tgetstr ("vb", &buffer);
- terminal_has_visible_bell_p = (visible_bell != (char *)NULL);
+ terminal_has_visible_bell_p = (visible_bell != NULL);
audible_bell = tgetstr ("bl", &buffer);
if (!audible_bell)
audible_bell = "\007";
@@ -630,8 +636,8 @@ terminal_initialize_terminal (terminal_name)
}
else
{
- term_mm = (char *)NULL;
- term_mo = (char *)NULL;
+ term_mm = NULL;
+ term_mo = NULL;
}
/* Attempt to find the arrow keys. */
@@ -643,6 +649,19 @@ terminal_initialize_terminal (terminal_name)
term_kP = tgetstr ("kP", &buffer);
term_kN = tgetstr ("kN", &buffer);
+#if defined(INFOKEY)
+ term_kh = tgetstr ("kh", &buffer);
+ term_ke = tgetstr ("@7", &buffer);
+ term_ki = tgetstr ("kI", &buffer);
+ term_kx = tgetstr ("kD", &buffer);
+#endif /* defined(INFOKEY) */
+
+ /* Home and end keys. */
+ term_kh = tgetstr ("kh", &buffer);
+ term_ke = tgetstr ("@7", &buffer);
+
+ term_kD = tgetstr ("kD", &buffer);
+
/* If this terminal is not cursor addressable, then it is really dumb. */
if (!term_goto)
terminal_is_dumb_p = 1;
@@ -736,11 +755,22 @@ terminal_prep_terminal ()
#endif /* VLNEXT */
#endif /* TERMIOS or TERMIO */
+/* cf. emacs/src/sysdep.c for being sure output is on. */
#if defined (HAVE_TERMIOS_H)
+ /* linux kernel 2.2.x needs a TCOFF followed by a TCOON to turn output
+ back on if the user presses ^S at the very beginning; just a TCOON
+ doesn't work. --Kevin Ryde <user42@zip.com.au>, 16jun2000. */
tcsetattr (tty, TCSANOW, &ttybuff);
+# ifdef TCOON
+ tcflow (tty, TCOOFF);
+ tcflow (tty, TCOON);
+# endif
#else
# if defined (HAVE_TERMIO_H)
ioctl (tty, TCSETA, &ttybuff);
+# ifdef TCXONC
+ ioctl (tty, TCXONC, 1);
+# endif
# endif
#endif
diff --git a/gnu/usr.bin/texinfo/info/userdoc.texi b/gnu/usr.bin/texinfo/info/userdoc.texi
new file mode 100644
index 00000000000..f9349c65c50
--- /dev/null
+++ b/gnu/usr.bin/texinfo/info/userdoc.texi
@@ -0,0 +1,1270 @@
+@c This file is meant to be included in any arbitrary piece of
+@c documentation that wishes to describe the info program. Some day
+@c info-stnd.texi should probably use this file instead of duplicating
+@c its contents.
+@c
+@c This file documents the use of the standalone GNU Info program,
+@c versions 2.7 and later.
+
+@ifclear InfoProgVer
+@set InfoProgVer 2.11
+@end ifclear
+@synindex vr cp
+@synindex fn cp
+@synindex ky cp
+
+@heading What is Info?
+
+This text documents the use of the GNU Info program, version
+@value{InfoProgVer}.
+
+@dfn{Info} is a program which is used to view info files on an ASCII
+terminal. @dfn{info files} are the result of processing texinfo files
+with the program @code{makeinfo} or with the Emacs command @code{M-x
+texinfo-format-buffer}. Finally, @dfn{texinfo} is a documentation
+language which allows a printed manual and online documentation (an info
+file) to be produced from a single source file.
+
+@menu
+* Options:: Options you can pass on the command line.
+* Cursor Commands:: Commands which move the cursor within a node.
+* Scrolling Commands:: Commands for moving the node around in a window.
+* Node Commands:: Commands for selecting a new node.
+* Searching Commands:: Commands for searching an info file.
+* Xref Commands:: Commands for selecting cross references.
+* Window Commands:: Commands which manipulate multiple windows.
+* Printing Nodes:: How to print out the contents of a node.
+* Miscellaneous Commands:: A few commands that defy categories.
+* Variables:: How to change the default behaviour of Info.
+@ifset NOTSET
+* Info for Sys Admins:: How to setup Info. Using special options.
+@end ifset
+@ifset STANDALONE
+* GNU Info Global Index:: Global index containing keystrokes, command names,
+ variable names, and general concepts.
+@end ifset
+@end menu
+
+@node Options
+@chapter Command Line Options
+@cindex command line options
+@cindex arguments, command line
+
+GNU Info accepts several options to control the initial node being
+viewed, and to specify which directories to search for info files. Here
+is a template showing an invocation of GNU Info from the shell:
+
+@example
+info [--@var{option-name} @var{option-value}] @var{menu-item}@dots{}
+@end example
+
+The following @var{option-names} are available when invoking Info from
+the shell:
+
+@table @code
+@cindex directory path
+@item --directory @var{directory-path}
+@itemx -d @var{directory-path}
+Adds @var{directory-path} to the list of directory paths searched when
+Info needs to find a file. You may issue @code{--directory} multiple
+times; once for each directory which contains info files.
+Alternatively, you may specify a value for the environment variable
+@code{INFOPATH}; if @code{--directory} is not given, the value of
+@code{INFOPATH} is used. The value of @code{INFOPATH} is a colon
+separated list of directory names. If you do not supply
+@code{INFOPATH} or @code{--directory-path} a default path is used.
+
+@item --file @var{filename}
+@itemx -f @var{filename}
+@cindex info file, selecting
+Specifies a particular info file to visit. Instead of visiting the file
+@code{dir}, Info will start with @code{(@var{filename})Top} as the first
+file and node.
+
+@item --node @var{nodename}
+@itemx -n @var{nodename}
+@cindex node, selecting
+Specifies a particular node to visit in the initial file loaded. This
+is especially useful in conjunction with @code{--file}@footnote{Of
+course, you can specify both the file and node in a @code{--node}
+command; but don't forget to escape the open and close parentheses from
+the shell as in: @code{info --node '(emacs)Buffers'}}. You may specify
+@code{--node} multiple times; for an interactive Info, each
+@var{nodename} is visited in its own window, for a non-interactive Info
+(such as when @code{--output} is given) each @var{nodename} is processed
+sequentially.
+
+@item --output @var{filename}
+@itemx -o @var{filename}
+@cindex file, outputting to
+@cindex outputting to a file
+Specify @var{filename} as the name of a file to output to. Each node
+that Info visits will be output to @var{filename} instead of
+interactively viewed. A value of @code{-} for @var{filename} specifies
+the standard output.
+
+@item --subnodes
+@cindex @code{--subnodes}, command line option
+This option only has meaning when given in conjunction with
+@code{--output}. It means to recursively output the nodes appearing in
+the menus of each node being output. Menu items which resolve to
+external info files are not output, and neither are menu items which are
+members of an index. Each node is only output once.
+
+@item --help
+@itemx -h
+Produces a relatively brief description of the available Info options.
+
+@item --version
+@cindex version information
+Prints the version information of Info and exits.
+
+@item @var{menu-item}
+@cindex menu, following
+Remaining arguments to Info are treated as the names of menu items. The
+first argument would be a menu item in the initial node visited, while
+the second argument would be a menu item in the first argument's node.
+You can easily move to the node of your choice by specifying the menu
+names which describe the path to that node. For example,
+
+@example
+info emacs buffers
+@end example
+
+first selects the menu item @samp{Emacs} in the node @samp{(dir)Top},
+and then selects the menu item @samp{Buffers} in the node
+@samp{(emacs)Top}.
+
+@end table
+
+@node Cursor Commands
+@chapter Moving the Cursor
+@cindex cursor, moving
+Many people find that reading screens of text page by page is made
+easier when one is able to indicate particular pieces of text with some
+kind of pointing device. Since this is the case, GNU Info (both the
+Emacs and standalone versions) have several commands which allow you to
+move the cursor about the screen. The notation used in this manual to
+describe keystrokes is identical to the notation used within the Emacs
+manual, and the GNU Readline manual. @xref{Characters, , Character
+Conventions, emacs, the GNU Emacs Manual}, if you are unfamilar with the
+notation.
+
+The following table lists the basic cursor movement commands in Info.
+Each entry consists of the key sequence you should type to execute the
+cursor movement, the @code{M-x}@footnote{@code{M-x} is also a command; it
+invokes @code{execute-extended-command}. @xref{M-x, , Executing an
+extended command, emacs, the GNU Emacs Manual}, for more detailed
+information.} command name (displayed in parentheses), and a short
+description of what the command does. All of the cursor motion commands
+can take an @dfn{numeric} argument (@pxref{Miscellaneous Commands,
+@code{universal-argument}}), to find out how to supply them. With a
+numeric argument, the motion commands are simply executed that
+many times; for example, a numeric argument of 4 given to
+@code{next-line} causes the cursor to move down 4 lines. With a
+negative numeric argument, the motion is reversed; an argument of -4
+given to the @code{next-line} command would cause the cursor to move
+@emph{up} 4 lines.
+
+@table @asis
+@item @code{C-n} (@code{next-line})
+@kindex C-n
+@findex next-line
+Moves the cursor down to the next line.
+
+@item @code{C-p} (@code{prev-line})
+@kindex C-p
+@findex prev-line
+Move the cursor up to the previous line.
+
+@item @code{C-a} (@code{beginning-of-line})
+@kindex C-a, in Info windows
+@findex beginning-of-line
+Move the cursor to the start of the current line.
+
+@item @code{C-e} (@code{end-of-line})
+@kindex C-e, in Info windows
+@findex end-of-line
+Moves the cursor to the end of the current line.
+
+@item @code{C-f} (@code{forward-char})
+@kindex C-f, in Info windows
+@findex forward-char
+Move the cursor forward a character.
+
+@item @code{C-b} (@code{backward-char})
+@kindex C-b, in Info windows
+@findex backward-char
+Move the cursor backward a character.
+
+@item @code{M-f} (@code{forward-word})
+@kindex M-f, in Info windows
+@findex forward-word
+Moves the cursor forward a word.
+
+@item @code{M-b} (@code{backward-word})
+@kindex M-b, in Info winows
+@findex backward-word
+Moves the cursor backward a word.
+
+@item @code{M-<} (@code{beginning-of-node})
+@itemx @code{b}
+@kindex b, in Info winows
+@kindex M-<
+@findex beginning-of-node
+Moves the cursor to the start of the current node.
+
+@item @code{M->} (@code{end-of-node})
+@kindex M->
+@findex end-of-node
+Moves the cursor to the end of the current node.
+
+@item @code{M-r} (@code{move-to-window-line})
+@kindex M-r
+@findex move-to-window-line
+Moves the cursor to a specific line of the window. Without a numeric
+argument, @code{M-r} moves the cursor to the start of the line in the
+center of the window. With a numeric argument of @var{n}, @code{M-r}
+moves the cursor to the start of the @var{n}th line in the window.
+@end table
+
+@node Scrolling Commands
+@chapter Moving Text Within a Window
+@cindex scrolling
+
+Sometimes you are looking at a screenful of text, and only part of the
+current paragraph you are reading is visible on the screen. The
+commands detailed in this section are used to shift which part of the
+current node is visible on the screen.
+
+@table @asis
+@item @code{SPC} (@code{scroll-forward})
+@itemx @code{C-v}
+@kindex SPC, in Info windows
+@kindex C-v
+@findex scroll-forward
+Shift the text in this window up. That is, show more of the node which
+is currently below the bottom of the window. With a numeric argument,
+show that many more lines at the bottom of the window; a numeric
+argument of 4 would shift all of the text in the window up 4 lines
+(discarding the top 4 lines), and show you four new lines at the bottom
+of the window. Without a numeric argument, @key{SPC} takes the bottom
+two lines of the window and places them at the top of the window,
+redisplaying almost a completely new screenful of lines.
+
+@item @code{DEL} (@code{scroll-backward})
+@itemx @code{M-v}
+@kindex DEL, in Info windows
+@kindex M-v
+@findex scroll-backward
+Shift the text in this window down. The inverse of
+@code{scroll-forward}.
+
+@end table
+
+@cindex scrolling through node structure
+The @code{scroll-forward} and @code{scroll-backward} commands can also
+move forward and backward through the node structure of the file. If
+you press @key{SPC} while viewing the end of a node, or @key{DEL} while
+viewing the beginning of a node, what happens is controlled by the
+variable @code{scroll-behaviour}. @xref{Variables,
+@code{scroll-behaviour}}, for more information.
+
+@table @asis
+@item @code{C-l} (@code{redraw-display})
+@kindex C-l
+@findex redraw-display
+Redraw the display from scratch, or shift the line containing the cursor
+to a specified location. With no numeric argument, @samp{C-l} clears
+the screen, and then redraws its entire contents. Given a numeric
+argument of @var{n}, the line containing the cursor is shifted so that
+it is on the @var{n}th line of the window.
+
+@item @code{C-x w} (@code{toggle-wrap})
+@kindex C-w
+@findex toggle-wrap
+Toggles the state of line wrapping in the current window. Normally,
+lines which are longer than the screen width @dfn{wrap}, i.e., they are
+continued on the next line. Lines which wrap have a @samp{\} appearing
+in the rightmost column of the screen. You can cause such lines to be
+terminated at the rightmost column by changing the state of line
+wrapping in the window with @code{C-x w}. When a line which needs more
+space than one screen width to display is displayed, a @samp{$} appears
+in the rightmost column of the screen, and the remainder of the line is
+invisible.
+@end table
+
+@node Node Commands
+@chapter Selecting a New Node
+@cindex nodes, selection of
+
+This section details the numerous Info commands which select a new node
+to view in the current window.
+
+The most basic node commands are @samp{n}, @samp{p}, @samp{u}, and
+@samp{l}.
+
+When you are viewing a node, the top line of the node contains some Info
+@dfn{pointers} which describe where the next, previous, and up nodes
+are. Info uses this line to move about the node structure of the file
+when you use the following commands:
+
+@table @asis
+@item @code{n} (@code{next-node})
+@kindex n
+@findex next-node
+Selects the `Next' node.
+
+@item @code{p} (@code{prev-node})
+@kindex p
+@findex prev-node
+Selects the `Prev' node.
+
+@item @code{u} (@code{up-node})
+@kindex u
+@findex up-node
+Selects the `Up' node.
+@end table
+
+You can easily select a node that you have already viewed in this window
+by using the @samp{l} command -- this name stands for "last", and
+actually moves through the list of already visited nodes for this
+window. @samp{l} with a negative numeric argument moves forward through
+the history of nodes for this window, so you can quickly step between
+two adjacent (in viewing history) nodes.
+
+@table @asis
+@item @code{l} (@code{history-node})
+@kindex l
+@findex history-node
+Selects the most recently selected node in this window.
+@end table
+
+Two additional commands make it easy to select the most commonly
+selected nodes; they are @samp{t} and @samp{d}.
+
+@table @asis
+@item @code{t} (@code{top-node})
+@kindex t
+@findex top-node
+Selects the node @samp{Top} in the current info file.
+
+@item @code{d} (@code{dir-node})
+@kindex d
+@findex dir-node
+Selects the directory node (i.e., the node @samp{(dir)}).
+@end table
+
+Here are some other commands which immediately result in the selection
+of a different node in the current window:
+
+@table @asis
+@item @code{<} (@code{first-node})
+@kindex <
+@findex first-node
+Selects the first node which appears in this file. This node is most
+often @samp{Top}, but it doesn't have to be.
+
+@item @code{>} (@code{last-node})
+@kindex >
+@findex last-node
+Selects the last node which appears in this file.
+
+@item @code{]} (@code{global-next-node})
+@kindex ]
+@findex global-next-node
+Moves forward or down through node structure. If the node that you are
+currently viewing has a @samp{Next} pointer, that node is selected.
+Otherwise, if this node has a menu, the first menu item is selected. If
+there is no @samp{Next} and no menu, the same process is tried with the
+@samp{Up} node of this node.
+
+@item @code{[} (@code{global-prev-node})
+@kindex [
+@findex global-prev-node
+Moves backward or up through node structure. If the node that you are
+currently viewing has a @samp{Prev} pointer, that node is selected.
+Otherwise, if the node has an @samp{Up} pointer, that node is selected,
+and if it has a menu, the last item in the menu is selected.
+@end table
+
+You can get the same behaviour as @code{global-next-node} and
+@code{global-prev-node} while simply scrolling through the file with
+@key{SPC} and @key{DEL}; @xref{Variables, @code{scroll-behaviour}}, for
+more information.
+
+@table @asis
+@item @code{g} (@code{goto-node})
+@kindex g
+@findex goto-node
+Reads the name of a node and selects it. No completion is done while
+reading the node name, since the desired node may reside in a separate
+file. The node must be typed exactly as it appears in the info file. A
+file name may be included as with any node specification, for example
+
+@example
+@code{g(emacs)Buffers}
+@end example
+
+finds the node @samp{Buffers} in the info file @file{emacs}.
+
+@item @code{C-x k} (@code{kill-node})
+@kindex C-x k
+@findex kill-node
+Kills a node. The node name is prompted for in the echo area, with a
+default of the current node. @dfn{Killing} a node means that Info tries
+hard to forget about it, removing it from the list of history nodes kept
+for the window where that node is found. Another node is selected in
+the window which contained the killed node.
+
+@item @code{C-x C-f} (@code{view-file})
+@kindex C-x C-f
+@findex view-file
+Reads the name of a file and selects the entire file. The command
+@example
+@code{C-x C-f @var{filename}}
+@end example
+is equivalent to typing
+@example
+@code{g(@var{filename})*}
+@end example
+
+@item @code{C-x C-b} (@code{list-visited-nodes})
+@kindex C-x C-b
+@findex list-visited-nodes
+Makes a window containing a menu of all of the currently visited nodes.
+This window becomes the selected window, and you may use the standard
+Info commands within it.
+
+@item @code{C-x b} (@code{select-visited-node})
+@kindex C-x b
+@findex select-visited-node
+Selects a node which has been previously visited in a visible window.
+This is similar to @samp{C-x C-b} followed by @samp{m}, but no window is
+created.
+@end table
+
+@node Searching Commands
+@chapter Searching an Info File
+@cindex searching
+
+GNU Info allows you to search for a sequence of characters throughout an
+entire info file, search through the indices of an info file, or find
+areas within an info file which discuss a particular topic.
+
+@table @asis
+@item @code{s} (@code{search})
+@kindex s
+@findex search
+Reads a string in the echo area and searches for it.
+
+@item @code{C-s} (@code{isearch-forward})
+@kindex C-s
+@findex isearch-forward
+Interactively searches forward through the info file for a string as you
+type it.
+
+@item @code{C-r} (@code{isearch-backward})
+@kindex C-r
+@findex isearch-backward
+Interactively searches backward through the info file for a string as
+you type it.
+
+@item @code{i} (@code{index-search})
+@kindex i
+@findex index-search
+Looks up a string in the indices for this info file, and selects a node
+where the found index entry points to.
+
+@item @code{,} (@code{next-index-match})
+@kindex ,
+@findex next-index-match
+Moves to the node containing the next matching index item from the last
+@samp{i} command.
+@end table
+
+The most basic searching command is @samp{s} (@code{search}). The
+@samp{s} command prompts you for a string in the echo area, and then
+searches the remainder of the info file for an ocurrence of that string.
+If the string is found, the node containing it is selected, and the
+cursor is left positioned at the start of the found string. Subsequent
+@samp{s} commands show you the default search string within @samp{[} and
+@samp{]}; pressing @key{RET} instead of typing a new string will use the
+default search string.
+
+@dfn{Incremental searching} is similar to basic searching, but the
+string is looked up while you are typing it, instead of waiting until
+the entire search string has been specified.
+
+@node Xref Commands
+@chapter Selecting Cross References
+
+We have already discussed the @samp{Next}, @samp{Prev}, and @samp{Up}
+pointers which appear at the top of a node. In addition to these
+pointers, a node may contain other pointers which refer you to a
+different node, perhaps in another info file. Such pointers are called
+@dfn{cross references}, or @dfn{xrefs} for short.
+
+@menu
+* Parts of an Xref:: What a cross reference is made of.
+* Selecting Xrefs:: Commands for selecting menu or note items.
+@end menu
+
+@node Parts of an Xref
+@section Parts of an Xref
+
+Cross references have two major parts: the first part is called the
+@dfn{label}; it is the name that you can use to refer to the cross
+reference, and the second is the @dfn{target}; it is the full name of
+the node that the cross reference points to.
+
+The target is separated from the label by a colon @samp{:}; first the
+label appears, and then the target. For example, in the sample menu
+cross reference below, the single colon separates the label from the
+target.
+
+@example
+* Foo Label: Foo Target. More information about Foo.
+@end example
+
+Note the @samp{.} which ends the name of the target. The @samp{.} is
+not part of the target; it serves only to let Info know where the target
+name ends.
+
+A shorthand way of specifying references allows two adjacent colons to
+stand for a target name which is the same as the label name:
+
+@example
+* Foo Commands:: Commands pertaining to Foo.
+@end example
+
+In the above example, the name of the target is the same as the name of
+the label, in this case @code{Foo Commands}.
+
+You will normally see two types of cross references while viewing nodes:
+@dfn{menu} references, and @dfn{note} references. Menu references
+appear within a node's menu; they begin with a @samp{*} at the beginning
+of a line, and continue with a label, a target, and a comment which
+describes what the contents of the node pointed to contains.
+
+Note references appear within the body of the node text; they begin with
+@code{*Note}, and continue with a label and a target.
+
+Like @samp{Next}, @samp{Prev} and @samp{Up} pointers, cross references
+can point to any valid node. They are used to refer you to a place
+where more detailed information can be found on a particular subject.
+Here is a cross reference which points to a node within the Texinfo
+documentation: @xref{xref, , Writing an Xref, texinfo, the Texinfo
+Manual}, for more information on creating your own texinfo cross
+references.
+
+@node Selecting Xrefs
+@section Selecting Xrefs
+
+The following table lists the Info commands which operate on menu items.
+
+@table @asis
+@item @code{1} (@code{menu-digit})
+@itemx @code{2} @dots{} @code{9}
+@cindex 1 @dots{} 9, in Info windows
+@kindex 1 @dots{} 9, in Info windows
+@findex menu-digit
+Within an Info window, pressing a single digit, (such as @samp{1}),
+selects that menu item, and places its node in the current window.
+For convenience, there is one exception; pressing @samp{0} selects the
+@emph{last} item in the node's menu.
+
+@item @code{0} (@code{last-menu-item})
+@kindex 0, in Info windows
+@findex last-menu-item
+Select the last item in the current node's menu.
+
+@item @code{m} (@code{menu-item})
+@kindex m
+@findex menu-item
+Reads the name of a menu item in the echo area and selects its node.
+Completion is available while reading the menu label.
+
+@item @code{M-x find-menu}
+@findex find-menu
+Moves the cursor to the start of this node's menu.
+@end table
+
+This table lists the Info commands which operate on note cross references.
+
+@table @asis
+@item @code{f} (@code{xref-item})
+@itemx @code{r}
+@kindex f
+@kindex r
+@findex xref-item
+Reads the name of a note cross reference in the echo area and selects
+its node. Completion is available while reading the cross reference
+label.
+@end table
+
+Finally, the next few commands operate on menu or note references alike:
+
+@table @asis
+@item @code{TAB} (@code{move-to-next-xref})
+@kindex TAB, in Info windows
+@findex move-to-next-xref
+Moves the cursor to the start of the next nearest menu item or note
+reference in this node. You can then use @key{RET}
+(@code{select-reference-this-line} to select the menu or note reference.
+
+@item @code{M-TAB} (@code{move-to-prev-xref})
+@kindex M-TAB, in Info windows
+@findex move-to-prev-xref
+Moves the cursor the start of the nearest previous menu item or note
+reference in this node.
+
+@item @code{RET} (@code{select-reference-this-line})
+@kindex RET, in Info windows
+@findex select-reference-this-line
+Selects the menu item or note reference appearing on this line.
+@end table
+
+@node Window Commands
+@chapter Manipulating Multiple Windows
+@cindex windows, manipulating
+
+A @dfn{window} is a place to show the text of a node. Windows have a
+view area where the text of the node is displayed, and an associated
+@dfn{mode line}, which briefly describes the node being viewed.
+
+GNU Info supports multiple windows appearing in a single screen; each
+window is separated from the next by its modeline. At any time, there
+is only one @dfn{active} window, that is, the window in which the cursor
+appears. There are commands available for creating windows, changing
+the size of windows, selecting which window is active, and for deleting
+windows.
+
+@menu
+* The Mode Line:: What appears in the mode line?
+* Basic Windows:: Manipulating windows in Info.
+* The Echo Area:: Used for displaying errors and reading input.
+@end menu
+
+@node The Mode Line
+@section The Mode Line
+
+A @dfn{mode line} is a line of inverse video which appears at the bottom
+of an info window. It describes the contents of the window just above
+it; this information includes the name of the file and node appearing in
+that window, the number of screen lines it takes to display the node,
+and the percentage of text that is above the top of the window. It can
+also tell you if the indirect tags table for this info file needs to be
+updated, and whether or not the info file was compressed when stored on
+disk.
+
+Here is a sample mode line for a window containing an uncompressed file
+named @file{dir}, showing the node @samp{Top}.
+
+@example
+-----Info: (dir)Top, 40 lines --Top---------------------------------------
+ ^^ ^ ^^^ ^^
+ (file)Node #lines where
+@end example
+
+When a node comes from a file which is compressed on disk, this is
+indicated in the mode line with two small @samp{z}'s. In addition, if
+the info file containing the node has been split into subfiles, the name
+of the subfile containing the node appears in the modeline as well:
+
+@example
+--zz-Info: (emacs)Top, 291 lines --Top-- Subfile: emacs-1.Z---------------
+@end example
+
+When Info makes a node internally, such that there is no corresponding
+info file on disk, the name of the node is surrounded by asterisks
+(@samp{*}). The name itself tells you what the contents of the window
+are; the sample mode line below shows an internally constructed node
+showing possible completions:
+
+@example
+-----Info: *Completions*, 7 lines --All-----------------------------------
+@end example
+
+@node Basic Windows
+@section Window Commands
+
+It can be convenient to view more than one node at a time. To allow
+this, Info can display more than one @dfn{window}. Each window has its
+own mode line (@pxref{The Mode Line}) and history of nodes viewed in that
+window (@pxref{Node Commands, , @code{history-node}}).
+
+@table @asis
+@item @code{C-x o} (@code{next-window})
+@cindex windows, selecting
+@kindex C-x o
+@findex next-window
+Selects the next window on the screen. Note that the echo area can only be
+selected if it is already in use, and you have left it temporarily.
+Normally, @samp{C-x o} simply moves the cursor into the next window on
+the screen, or if you are already within the last window, into the first
+window on the screen. Given a numeric argument, @samp{C-x o} moves over
+that many windows. A negative argument causes @samp{C-x o} to select
+the previous window on the screen.
+
+@item @code{M-x prev-window}
+@findex prev-window
+Selects the previous window on the screen. This is identical to
+@samp{C-x o} with a negative argument.
+
+@item @code{C-x 2} (@code{split-window})
+@cindex windows, creating
+@kindex C-x 2
+@findex split-window
+Splits the current window into two windows, both showing the same node.
+Each window is one half the size of the original window, and the cursor
+remains in the original window. The variable @code{automatic-tiling}
+can cause all of the windows on the screen to be resized for you
+automatically, please @pxref{Variables, , automatic-tiling} for more
+information.
+
+@item @code{C-x 0} (@code{delete-window})
+@cindex windows, deleting
+@kindex C-x 0
+@findex delete-window
+Deletes the current window from the screen. If you have made too many
+windows and your screen appears cluttered, this is the way to get rid of
+some of them.
+
+@item @code{C-x 1} (@code{keep-one-window})
+@kindex C-x 1
+@findex keep-one-window
+Deletes all of the windows excepting the current one.
+
+@item @code{ESC C-v} (@code{scroll-other-window})
+@kindex ESC C-v, in Info windows
+@findex scroll-other-window
+Scrolls the other window, in the same fashion that @samp{C-v} might
+scroll the current window. Given a negative argument, the "other"
+window is scrolled backward.
+
+@item @code{C-x ^} (@code{grow-window})
+@kindex C-x ^
+@findex grow-window
+Grows (or shrinks) the current window. Given a numeric argument, grows
+the current window that many lines; with a negative numeric argument,
+the window is shrunk instead.
+
+@item @code{C-x t} (@code{tile-windows})
+@cindex tiling
+@kindex C-x t
+@findex tile-windows
+Divides the available screen space among all of the visible windows.
+Each window is given an equal portion of the screen in which to display
+its contents. The variable @code{automatic-tiling} can cause
+@code{tile-windows} to be called when a window is created or deleted.
+@xref{Variables, , @code{automatic-tiling}}.
+@end table
+
+@node The Echo Area
+@section The Echo Area
+@cindex echo area
+
+The @dfn{echo area} is a one line window which appears at the bottom of
+the screen. It is used to display informative or error messages, and to
+read lines of input from you when that is necessary. Almost all of the
+commands available in the echo area are identical to their Emacs
+counterparts, so please refer to that documentation for greater depth of
+discussion on the concepts of editing a line of text. The following
+table briefly lists the commands that are available while input is being
+read in the echo area:
+
+@table @asis
+@item @code{C-f} (@code{echo-area-forward})
+@kindex C-f, in the echo area
+@findex echo-area-forward
+Moves forward a character.
+
+@item @code{C-b} (@code{echo-area-backward})
+@kindex C-b, in the echo area
+@findex echo-area-backward
+Moves backward a character.
+
+@item @code{C-a} (@code{echo-area-beg-of-line})
+@kindex C-a, in the echo area
+@findex echo-area-beg-of-line
+Moves to the start of the input line.
+
+@item @code{C-e} (@code{echo-area-end-of-line})
+@kindex C-e, in the echo area
+@findex echo-area-end-of-line
+Moves to the end of the input line.
+
+@item @code{M-f} (@code{echo-area-forward-word})
+@kindex M-f, in the echo area
+@findex echo-area-forward-word
+Moves forward a word.
+
+@item @code{M-b} (@code{echo-area-backward-word})
+@kindex M-b, in the echo area
+@findex echo-area-backward-word
+Moves backward a word.
+
+@item @code{C-d} (@code{echo-area-delete})
+@kindex C-d, in the echo area
+@findex echo-area-delete
+Deletes the character under the cursor.
+
+@item @code{DEL} (@code{echo-area-rubout})
+@kindex DEL, in the echo area
+@findex echo-area-rubout
+Deletes the character behind the cursor.
+
+@item @code{C-g} (@code{echo-area-abort})
+@kindex C-g, in the echo area
+@findex echo-area-abort
+Cancels or quits the current operation. If completion is being read,
+@samp{C-g} discards the text of the input line which does not match any
+completion. If the input line is empty, @samp{C-g} aborts the calling
+function.
+
+@item @code{RET} (@code{echo-area-newline})
+@kindex RET, in the echo area
+@findex echo-area-newline
+Accepts (or forces completion of) the current input line.
+
+@item @code{C-q} (@code{echo-area-quoted-insert})
+@kindex C-q, in the echo area
+@findex echo-area-quoted-insert
+Inserts the next character verbatim. This is how you can insert control
+characters into a search string, for example.
+
+@item @var{printing character} (@code{echo-area-insert})
+@kindex printing characters, in the echo area
+@findex echo-area-insert
+Inserts the character.
+
+@item @code{M-TAB} (@code{echo-area-tab-insert})
+@kindex M-TAB, in the echo area
+@findex echo-area-tab-insert
+Inserts a TAB character.
+
+@item @code{C-t} (@code{echo-area-transpose-chars})
+@kindex C-t, in the echo area
+@findex echo-area-transpose-chars
+Transposes the characters at the cursor.
+@end table
+
+The next group of commands deal with @dfn{killing}, and @dfn{yanking}
+text. For an in depth discussion of killing and yanking,
+@pxref{Killing, , Killing and Deleting, emacs, the GNU Emacs Manual}
+
+@table @asis
+@item @code{M-d} (@code{echo-area-kill-word})
+@kindex M-d, in the echo area
+@findex echo-area-kill-word
+Kills the word following the cursor.
+
+@item @code{M-DEL} (@code{echo-area-backward-kill-word})
+@kindex M-DEL, in the echo area
+@findex echo-area-backward-kill-word
+Kills the word preceding the cursor.
+
+@item @code{C-k} (@code{echo-area-kill-line})
+@kindex C-k, in the echo area
+@findex echo-area-kill-line
+Kills the text from the cursor to the end of the line.
+
+@item @code{C-x DEL} (@code{echo-area-backward-kill-line})
+@kindex C-x DEL, in the echo area
+@findex echo-area-backward-kill-line
+Kills the text from the cursor to the beginning of the line.
+
+@item @code{C-y} (@code{echo-area-yank})
+@kindex C-y, in the echo area
+@findex echo-area-yank
+Yanks back the contents of the last kill.
+
+@item @code{M-y} (@code{echo-area-yank-pop})
+@kindex M-y, in the echo area
+@findex echo-area-yank-pop
+Yanks back a previous kill, removing the last yanked text first.
+@end table
+
+Sometimes when reading input in the echo area, the command that needed
+input will only accept one of a list of several choices. The choices
+represent the @dfn{possible completions}, and you must respond with one
+of them. Since there are a limited number of responses you can make,
+Info allows you to abbreviate what you type, only typing as much of the
+response as is necessary to uniquely identify it. In addition, you can
+request Info to fill in as much of the response as is possible; this
+is called @dfn{completion}.
+
+The following commands are available when completing in the echo area:
+
+@table @asis
+@item @code{TAB} (@code{echo-area-complete})
+@itemx @code{SPC}
+@kindex TAB, in the echo area
+@kindex SPC, in the echo area
+@findex echo-area-complete
+Inserts as much of a completion as is possible.
+
+@item @code{?} (@code{echo-area-possible-completions})
+@kindex ?, in the echo area
+@findex echo-area-possible-completions
+Displays a window containing a list of the possible completions of what
+you have typed so far. For example, if the available choices are:
+@example
+bar
+foliate
+food
+forget
+@end example
+and you have typed an @samp{f}, followed by @samp{?}, the possible
+completions would contain:
+@example
+foliate
+food
+forget
+@end example
+i.e., all of the choices which begin with @samp{f}. Pressing @key{SPC}
+or @key{TAB} would result in @samp{fo} appearing in the echo area, since
+all of the choices which begin with @samp{f} continue with @samp{o}.
+Now, typing @samp{l} followed by @samp{TAB} results in @samp{foliate}
+appearing in the echo area, since that is the only choice which begins
+with @samp{fol}.
+
+@item @code{ESC C-v} (@code{echo-area-scroll-completions-window})
+@kindex ESC C-v, in the echo area
+@findex echo-area-scroll-completions-window
+Scrolls the completions window, if that is visible, or the "other"
+window if not.
+@end table
+
+@node Printing Nodes
+@chapter Printing Out Nodes
+@cindex printing
+
+You may wish to print out the contents of a node as a quick reference
+document for later use. Info provides you with a command for doing
+this. In general, we recommend that you use @TeX{} to format the
+document and print sections of it, by running @code{tex} on the texinfo
+source file.
+
+@table @asis
+@item @code{M-x print-node}
+@findex print-node
+@cindex INFO_PRINT_COMMAND, environment variable
+Pipes the contents of the current node through the command in the
+environment variable @code{INFO_PRINT_COMMAND}. If the variable doesn't
+exist, the node is simply piped to @code{lpr}.
+@end table
+
+@node Miscellaneous Commands
+@chapter Miscellaneous Commands
+
+GNU Info contains several commands which self-document GNU Info:
+
+@table @asis
+@item @code{M-x describe-command}
+@cindex functions, describing
+@cindex commands, describing
+@findex describe-command
+Reads the name of an Info command in the echo area and then displays a
+brief description of what that command does.
+
+@item @code{M-x describe-key}
+@cindex keys, describing
+@findex describe-key
+Reads a key sequence in the echo area, and then displays the name and
+documentation of the Info command that the key sequence invokes.
+
+@item @code{M-x describe-variable}
+Reads the name of a variable in the echo area and then displays a brief
+description of what the variable affects.
+
+@item @code{M-x where-is}
+@findex where-is
+Reads the name of an Info command in the echo area, and then displays
+a key sequence which can be typed in order to invoke that command.
+
+@item @code{C-h} (@code{get-help-window})
+@itemx @code{?}
+@kindex C-h
+@kindex ?, in Info windows
+@findex get-help-window
+Creates (or moves into) the window displaying @code{*Help*}, and places
+a node containing a quick reference card into it. This window displays
+the most concise information about GNU Info available.
+
+@item @code{h} (@code{get-info-help-node})
+@kindex h
+@findex get-info-help-node
+Tries hard to visit the node @code{(info)Help}. The info file
+@file{info.texi} distributed with GNU Info contains this node. Of
+course, the file must first be processed with @code{makeinfo}, and then
+placed into the location of your info directory.
+@end table
+
+Here are the commands for creating a numeric argument:
+
+@table @asis
+@item @code{C-u} (@code{universal-argument})
+@cindex numeric arguments
+@kindex C-u
+@findex universal-argument
+Starts (or multiplies by 4) the current numeric argument. @samp{C-u} is
+a good way to give a small numeric argument to cursor movement or
+scrolling commands; @samp{C-u C-v} scrolls the screen 4 lines, while
+@samp{C-u C-u C-n} moves the cursor down 16 lines.
+
+@item @code{M-1} (@code{add-digit-to-numeric-arg})
+@itemx @code{M-2} @dots{} @code{M-9}
+@kindex M-1 @dots{} M-9
+@findex add-digit-to-numeric-arg
+Adds the digit value of the invoking key to the current numeric
+argument. Once Info is reading a numeric argument, you may just type
+the digits of the argument, without the Meta prefix. For example, you
+might give @samp{C-l} a numeric argument of 32 by typing:
+
+@example
+@kbd{C-u 3 2 C-l}
+@end example
+or
+@example
+@kbd{M-3 2 C-l}
+@end example
+@end table
+
+@samp{C-g} is used to abort the reading of a multi-character key
+sequence, to cancel lengthy operations (such as multi-file searches) and
+to cancel reading input in the echo area.
+
+@table @asis
+@item @code{C-g} (@code{abort-key})
+@cindex cancelling typeahead
+@cindex cancelling the current operation
+@kindex C-g, in Info windows
+@findex abort-key
+Cancels current operation.
+@end table
+
+The @samp{q} command of Info simply quits running Info.
+
+@table @asis
+@item @code{q} (@code{quit})
+@cindex quitting
+@kindex q
+@findex quit
+Exits GNU Info.
+@end table
+
+If the operating system tells GNU Info that the screen is 60 lines tall,
+and it is actually only 40 lines tall, here is a way to tell Info that
+the operating system is correct.
+
+@table @asis
+@item @code{M-x set-screen-height}
+@findex set-screen-height
+@cindex screen, changing the height of
+Reads a height value in the echo area and sets the height of the
+displayed screen to that value.
+@end table
+
+Finally, Info provides a convenient way to display footnotes which might
+be associated with the current node that you are viewing:
+
+@table @asis
+@item @code{ESC C-f} (@code{show-footnotes})
+@kindex ESC C-f
+@findex show-footnotes
+@cindex footnotes, displaying
+Shows the footnotes (if any) associated with the current node in another
+window. You can have Info automatically display the footnotes
+associated with a node when the node is selected by setting the variable
+@code{automatic-footnotes}. @xref{Variables, , @code{automatic-footnotes}}.
+@end table
+
+@node Variables
+@chapter Manipulating Variables
+
+GNU Info contains several @dfn{variables} whose values are looked at by various
+Info commands. You can change the values of these variables, and thus
+change the behaviour of Info to more closely match your environment and
+info file reading manner.
+
+@table @asis
+@item @code{M-x set-variable}
+@cindex variables, setting
+@findex set-variable
+Reads the name of a variable, and the value for it, in the echo area and
+then sets the variable to that value. Completion is available when
+reading the variable name; often, completion is available when reading
+the value to give to the variable, but that depends on the variable
+itself. If a variable does @emph{not} supply multiple choices to
+complete over, it expects a numeric value.
+
+@item @code{M-x describe-variable}
+@cindex variables, describing
+@findex describe-variable
+Reads the name of a variable in the echo area and then displays a brief
+description of what the variable affects.
+@end table
+
+Here is a list of the variables that you can set in Info.
+
+@table @code
+@item automatic-footnotes
+@vindex automatic-footnotes
+When set to @code{On}, footnotes appear and disappear automatically.
+This variable is @code{On} by default. When a node is selected, a
+window containing the footnotes which appear in that node is created,
+and the footnotes are displayed within the new window. The window that
+Info creates to contain the footnotes is called @samp{*Footnotes*}. If
+a node is selected which contains no footnotes, and a @samp{*Footnotes*}
+window is on the screen, the @samp{*Footnotes*} window is deleted.
+Footnote windows created in this fashion are not automatically tiled so
+that they can use as little of the display as is possible.
+
+@item automatic-tiling
+@vindex automatic-tiling
+When set to @code{On}, creating or deleting a window resizes other
+windows. This variable is @code{Off} by default. Normally, typing
+@samp{C-x 2} divides the current window into two equal parts. When
+@code{automatic-tiling} is set to @code{On}, all of the windows are
+resized automatically, keeping an equal number of lines visible in each
+window. There are exceptions to the automatic tiling; specifically, the
+windows @samp{*Completions*} and @samp{*Footnotes*} are @emph{not}
+resized through automatic tiling; they remain their original size.
+
+@item visible-bell
+@vindex visible-bell
+When set to @code{On}, GNU Info attempts to flash the screen instead of
+ringing the bell. This variable is @code{Off} by default. Of course,
+Info can only flash the screen if the terminal allows it; in the case
+that the terminal does not allow it, the setting of this variable has no
+effect. However, you can make Info perform quietly by setting the
+@code{errors-ring-bell} variable to @code{Off}.
+
+@item errors-ring-bell
+@vindex errors-ring-bell
+When set to @code{On}, errors cause the bell to ring. The default
+setting of this variable is @code{On}.
+
+@item gc-compressed-files
+@vindex gc-compressed-files
+When set to @code{On}, Info garbage collects files which had to be
+uncompressed. The default value of this variable is @code{Off}.
+Whenever a node is visited in Info, the info file containing that node
+is read into core, and Info reads information about the tags and nodes
+contained in that file. Once the tags information is read by Info, it
+is never forgotten. However, the actual text of the nodes does not need
+to remain in core unless a particular info window needs it. For
+non-compressed files, the text of the nodes does not remain in core when
+it is no longer in use. But de-compressing a file can be a time
+consuming operation, and so Info tries hard not to do it twice.
+@code{gc-compressed-files} tells Info it is okay to garbage collect the
+text of the nodes of a file which was compressed on disk.
+
+@item show-index-match
+@vindex show-index-match
+When set to @code{On}, the portion of the matched search string is
+highlighted in the message which explains where the matched search
+string was found. The default value of this variable is @code{On}.
+When Info displays the location where an index match was found,
+(@pxref{Searching Commands, , @code{next-index-match}}), the portion of the
+string that you had typed is highlighted by displaying it in the inverse
+case from its surrounding characters.
+
+@item scroll-behaviour
+@vindex scroll-behaviour
+Controls what happens when forward scrolling is requested at the end of
+a node, or when backward scrolling is requested at the beginning of a
+node. The default value for this variable is @code{Continuous}. There
+are three possible values for this variable:
+
+@table @code
+@item Continuous
+Tries to get the first item in this node's menu, or failing that, the
+@samp{Next} node, or failing that, the @samp{Next} of the @samp{Up}.
+This behaviour is identical to using the @samp{]}
+(@code{global-next-node}) and @samp{[} (@code{global-prev-node})
+commands.
+
+@item Next Only
+Only tries to get the @samp{Next} node.
+
+@item Page Only
+Simply gives up, changing nothing. If @code{scroll-behaviour} is
+@code{Page Only}, no scrolling command can change the node that is being
+viewed.
+@end table
+
+@item scroll-step
+@vindex scroll-step
+The number of lines to scroll when the cursor moves out of the window.
+Scrolling happens automatically if the cursor has moved out of the
+visible portion of the node text when it is time to display. Usually
+the scrolling is done so as to put the cursor on the center line of the
+current window. However, if the variable @code{scroll-step} has a
+nonzero value, Info attempts to scroll the node text by that many lines;
+if that is enough to bring the cursor back into the window, that is what
+is done. The default value of this variable is 0, thus placing the
+cursor (and the text it is attached to) in the center of the window.
+Setting this variable to 1 causes a kind of "smooth scrolling" which
+some people prefer.
+
+@item ISO-Latin
+@cindex ISO Latin characters
+@vindex ISO-Latin
+When set to @code{On}, Info accepts and displays ISO Latin characters.
+By default, Info assumes an ASCII character set. @code{ISO-Latin} tells
+Info that it is running in an environment where the European standard
+character set is in use, and allows you to input such characters to
+Info, as well as display them.
+@end table
+
+@c The following node and its children are currently unfinished. Please feel
+@c free to finish it!
+
+@ifset NOTSET
+@node Info for Sys Admins
+@chapter Info for System Administrators
+
+This text describes some common ways of setting up an Info heierarchy
+from scratch, and details the various options that are available when
+installing Info. This text is designed for the person who is installing
+GNU Info on the system; although users may find the information present
+in this section interesting, none of it is vital to understanding how to
+use GNU Info.
+
+@menu
+* Setting the INFOPATH:: Where are my Info files kept?
+* Editing the DIR node:: What goes in `DIR', and why?
+* Storing Info files:: Alternate formats allow flexibilty in setups.
+* Using `localdir':: Building DIR on the fly.
+* Example setups:: Some common ways to origanize Info files.
+@end menu
+
+@node Setting the INFOPATH
+@section Setting the INFOPATH
+Where are my Info files kept?
+
+@node Editing the DIR node
+@section Editing the DIR node
+What goes in `DIR', and why?
+
+@node Storing Info files
+@section Storing Info files
+Alternate formats allow flexibilty in setups.
+
+@node Using `localdir'
+@section Using `localdir'
+Building DIR on the fly.
+
+@node Example setups
+@section Example setups
+Some common ways to origanize Info files.
+@end ifset
+
+@ifset STANDALONE
+@node GNU Info Global Index
+@appendix Global Index
+@printindex cp
+@end ifset
diff --git a/gnu/usr.bin/texinfo/info/variables.c b/gnu/usr.bin/texinfo/info/variables.c
index e56dae2b60d..9f30900429f 100644
--- a/gnu/usr.bin/texinfo/info/variables.c
+++ b/gnu/usr.bin/texinfo/info/variables.c
@@ -1,10 +1,7 @@
/* variables.c -- How to manipulate user visible variables in Info.
- $Id: variables.c,v 1.3 2000/02/09 02:18:40 espie Exp $
+ $Id: variables.c,v 1.4 2002/06/10 13:51:03 espie Exp $
- This file is part of GNU Info, a program for reading online documentation
- stored in Info format.
-
- Copyright (C) 1993, 97 Free Software Foundation, Inc.
+ Copyright (C) 1993, 97, 2001 Free Software Foundation, Inc.
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
@@ -273,3 +270,40 @@ make_variable_completions_array ()
return (array);
}
+
+#if defined(INFOKEY)
+
+void
+set_variable_to_value(name, value)
+ char *name;
+ char *value;
+{
+ register int i;
+
+ /* Find the variable in our list of variables. */
+ for (i = 0; info_variables[i].name; i++)
+ if (strcmp(info_variables[i].name, name) == 0)
+ break;
+
+ if (!info_variables[i].name)
+ return;
+
+ if (info_variables[i].choices)
+ {
+ register int j;
+
+ /* Find the choice in our list of choices. */
+ for (j = 0; info_variables[i].choices[j]; j++)
+ if (strcmp (info_variables[i].choices[j], value) == 0)
+ break;
+
+ if (info_variables[i].choices[j])
+ *info_variables[i].value = j;
+ }
+ else
+ {
+ *info_variables[i].value = atoi(value);
+ }
+}
+
+#endif /* INFOKEY */
diff --git a/gnu/usr.bin/texinfo/info/window.c b/gnu/usr.bin/texinfo/info/window.c
index 4bc8eb229ab..23a9c7addc5 100644
--- a/gnu/usr.bin/texinfo/info/window.c
+++ b/gnu/usr.bin/texinfo/info/window.c
@@ -1,7 +1,7 @@
/* window.c -- windows in Info.
- $Id: window.c,v 1.3 2000/02/09 02:18:40 espie Exp $
+ $Id: window.c,v 1.4 2002/06/10 13:51:03 espie Exp $
- Copyright (C) 1993, 97, 98 Free Software Foundation, Inc.
+ Copyright (C) 1993, 97, 98, 2001, 02 Free Software Foundation, Inc.
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
@@ -758,7 +758,20 @@ string_width (string, hpos)
for (width = 0, i = 0; string[i]; i++)
{
- this_char_width = character_width (string[i], hpos);
+ /* Support ANSI escape sequences for -R. */
+ if (raw_escapes_p
+ && string[i] == '\033'
+ && string[i+1] == '['
+ && isdigit (string[i+2])
+ && (string[i+3] == 'm'
+ || (isdigit (string[i+3]) && string[i+4] == 'm')))
+ {
+ while (string[i] != 'm')
+ i++;
+ this_char_width = 0;
+ }
+ else
+ this_char_width = character_width (string[i], hpos);
width += this_char_width;
hpos += this_char_width;
}
@@ -826,8 +839,33 @@ calculate_line_starts (window)
while (1)
{
- c = node->contents[i];
- cwidth = character_width (c, hpos);
+ /* The cast to unsigned char is for 8-bit characters, which
+ could be passed as negative integers to character_width
+ and wreak havoc on some naive implementations of iscntrl. */
+ c = (unsigned char) node->contents[i];
+
+ /* Support ANSI escape sequences for -R. */
+ if (raw_escapes_p
+ && c == '\033'
+ && node->contents[i+1] == '['
+ && isdigit (node->contents[i+2]))
+ {
+ if (node->contents[i+3] == 'm')
+ {
+ i += 3;
+ cwidth = 0;
+ }
+ else if (isdigit (node->contents[i+3])
+ && node->contents[i+4] == 'm')
+ {
+ i += 4;
+ cwidth = 0;
+ }
+ else
+ cwidth = character_width (c, hpos);
+ }
+ else
+ cwidth = character_width (c, hpos);
/* If this character fits within this line, just do the next one. */
if ((hpos + cwidth) < window->width)
@@ -1006,7 +1044,23 @@ window_get_cursor_column (window)
end = window->point - (line - window->node->contents);
for (hpos = 0, i = 0; i < end; i++)
- hpos += character_width (line[i], hpos);
+ {
+ /* Support ANSI escape sequences for -R. */
+ if (raw_escapes_p
+ && line[i] == '\033'
+ && line[i+1] == '['
+ && isdigit (line[i+2]))
+ {
+ if (line[i+3] == 'm')
+ i += 3;
+ else if (isdigit (line[i+3]) && line[i+4] == 'm')
+ i += 4;
+ else
+ hpos += character_width (line[i], hpos);
+ }
+ else
+ hpos += character_width (line[i], hpos);
+ }
return (hpos);
}
@@ -1022,8 +1076,17 @@ window_chars_to_goal (line, goal)
for (hpos = 0, i = 0; line[i] != '\n'; i++)
{
-
- check = hpos + character_width (line[i], hpos);
+ /* Support ANSI escape sequences for -R. */
+ if (raw_escapes_p
+ && line[i] == '\033'
+ && line[i+1] == '['
+ && isdigit (line[i+2])
+ && (line[i+3] == 'm'
+ || (isdigit (line[i+3]) && line[i+4] == 'm')))
+ while (line[i] != 'm')
+ i++;
+ else
+ check = hpos + character_width (line[i], hpos);
if (check > goal)
break;
@@ -1298,16 +1361,17 @@ message_buffer_resize (length)
/* Format MESSAGE_BUFFER with the results of printing FORMAT with ARG1 and
ARG2. */
static void
-build_message_buffer (format, arg1, arg2)
+build_message_buffer (format, arg1, arg2, arg3)
char *format;
- void *arg1, *arg2;
+ void *arg1, *arg2, *arg3;
{
register int i, len;
- void *args[2];
+ void *args[3];
int arg_index = 0;
args[0] = arg1;
args[1] = arg2;
+ args[2] = arg3;
len = strlen (format);
@@ -1326,7 +1390,9 @@ build_message_buffer (format, arg1, arg2)
char *fmt_start = format + i;
char *fmt;
int fmt_len, formatted_len;
+ int paramed = 0;
+ format_again:
i++;
while (format[i] && strchr ("-. +0123456789", format[i]))
i++;
@@ -1335,18 +1401,39 @@ build_message_buffer (format, arg1, arg2)
if (c == '\0')
abort ();
+ if (c == '$') {
+ /* position parameter parameter */
+ /* better to use bprintf from bfox's metahtml? */
+ arg_index = atoi(fmt_start + 1) - 1;
+ if (arg_index < 0)
+ arg_index = 0;
+ if (arg_index >= 2)
+ arg_index = 1;
+ paramed = 1;
+ goto format_again;
+ }
+
fmt_len = format + i - fmt_start + 1;
fmt = (char *) xmalloc (fmt_len + 1);
strncpy (fmt, fmt_start, fmt_len);
fmt[fmt_len] = '\0';
+ if (paramed) {
+ /* removed positioned parameter */
+ char *p;
+ for (p = fmt + 1; *p && *p != '$'; p++) {
+ ;
+ }
+ strcpy(fmt + 1, p + 1);
+ }
+
/* If we have "%-98s", maybe 98 calls for a longer string. */
if (fmt_len > 2)
{
int j;
- for (j = 0; j < fmt_len; j++)
- if (isdigit (fmt[j]))
+ for (j = fmt_len - 2; j >= 0; j--)
+ if (isdigit (fmt[j]) || fmt[j] == '$')
break;
formatted_len = atoi (fmt + j);
@@ -1430,7 +1517,7 @@ build_message_node (format, arg1, arg2)
NODE *node;
message_buffer_index = 0;
- build_message_buffer (format, arg1, arg2);
+ build_message_buffer (format, arg1, arg2, 0);
node = message_buffer_to_node ();
return (node);
@@ -1467,11 +1554,11 @@ initialize_message_buffer ()
/* Print FORMAT with ARG1,2 to the end of the current message buffer. */
void
-printf_to_message_buffer (format, arg1, arg2)
+printf_to_message_buffer (format, arg1, arg2, arg3)
char *format;
- void *arg1, *arg2;
+ void *arg1, *arg2, *arg3;
{
- build_message_buffer (format, arg1, arg2);
+ build_message_buffer (format, arg1, arg2, arg3);
}
/* Return the current horizontal position of the "cursor" on the most
diff --git a/gnu/usr.bin/texinfo/info/xmalloc.c b/gnu/usr.bin/texinfo/info/xmalloc.c
new file mode 100644
index 00000000000..156989ed711
--- /dev/null
+++ b/gnu/usr.bin/texinfo/info/xmalloc.c
@@ -0,0 +1,80 @@
+/* xmalloc.c -- safe versions of malloc and realloc */
+
+/* This file is part of GNU Info, a program for reading online documentation
+ stored in Info format.
+
+ This file has appeared in prior works by the Free Software Foundation;
+ thus it carries copyright dates from 1988 through 1993.
+
+ Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993 Free Software
+ Foundation, Inc.
+
+ 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 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Written by Brian Fox (bfox@ai.mit.edu). */
+
+#if !defined (ALREADY_HAVE_XMALLOC)
+#include <stdio.h>
+#include <sys/types.h>
+
+extern void *malloc (), *realloc ();
+static void memory_error_and_abort ();
+
+/* **************************************************************** */
+/* */
+/* Memory Allocation and Deallocation. */
+/* */
+/* **************************************************************** */
+
+/* Return a pointer to free()able block of memory large enough
+ to hold BYTES number of bytes. If the memory cannot be allocated,
+ print an error message and abort. */
+void *
+xmalloc (bytes)
+ int bytes;
+{
+ void *temp = malloc (bytes);
+
+ if (!temp)
+ memory_error_and_abort ("xmalloc");
+ return (temp);
+}
+
+void *
+xrealloc (pointer, bytes)
+ void *pointer;
+ int bytes;
+{
+ void *temp;
+
+ if (!pointer)
+ temp = malloc (bytes);
+ else
+ temp = realloc (pointer, bytes);
+
+ if (!temp)
+ memory_error_and_abort ("xrealloc");
+
+ return (temp);
+}
+
+static void
+memory_error_and_abort (fname)
+ char *fname;
+{
+ fprintf (stderr, "%s: Out of virtual memory!\n", fname);
+ abort ();
+}
+#endif /* !ALREADY_HAVE_XMALLOC */