Mercurial > emacs
changeset 90650:02cf29720f31
Merge from emacs--devo--0
Patches applied:
* emacs--devo--0 (patch 490-504)
- Update from CVS
- Merge from gnus--rel--5.10
* gnus--rel--5.10 (patch 161-163)
- Update from CVS
- Merge from emacs--devo--0
Revision: emacs@sv.gnu.org/emacs--unicode--0--patch-130
line wrap: on
line diff
--- a/ChangeLog Tue Nov 07 02:37:49 2006 +0000 +++ b/ChangeLog Tue Nov 07 23:22:48 2006 +0000 @@ -1,3 +1,18 @@ +2006-11-04 Romain Francoise <romain@orebokech.com> + + * Makefile.in (bootstrap-clean-before): Use new target `bootstrap-clean' + in the leim subdirectory. + Fix typo. + +2006-11-03 Giorgos Keramidas <keramida@ceid.upatras.gr> (tiny change) + + * configure.in: Enable sparc64/ia64/powerpc FreeBSD builds. + +2006-10-30 Chong Yidong <cyd@stupidchicken.com> + + * make-dist: Add makefile.w32-in to the man, lispref and lispintro + directories. + 2006-10-29 Chong Yidong <cyd@stupidchicken.com> * configure: Regenerate using autoconf 2.59.
--- a/Makefile.in Tue Nov 07 02:37:49 2006 +0000 +++ b/Makefile.in Tue Nov 07 23:22:48 2006 +0000 @@ -280,7 +280,7 @@ -e 's;/[*] *arch-tag:.*;/*;') && \ ${srcdir}/move-if-change epaths.h.$$$$ src/epaths.h -# For parallel make, src should be build before leim. +# For parallel make, src should be built before leim. # "export PARALLEL=0" is for SGI's Make, to prevent it from # running more than 1 process in the leim directory, especially for # the $TIT files there. @@ -790,6 +790,7 @@ ### Used for `bootstrap' to avoid deleting existing dumped Emacs executables. bootstrap-clean-before: bootstrap-clean-before-fast FRC (cd lisp; $(MAKE) $(MFLAGS) bootstrap-clean) + (cd leim; $(MAKE) $(MFLAGS) bootstrap-clean) ### Used for `bootfast' to avoid deleting existing dumped Emacs executables ### and compiled .elc files.
--- a/admin/ChangeLog Tue Nov 07 02:37:49 2006 +0000 +++ b/admin/ChangeLog Tue Nov 07 23:22:48 2006 +0000 @@ -1,3 +1,8 @@ +2006-11-06 Reiner Steib <Reiner.Steib@gmx.de> + + * FOR-RELEASE (BUGS): Remove "Build failure under Suse 10.0" was + due to a local miss-configuration. + 2006-10-28 Chong Yidong <cyd@stupidchicken.com> * make-announcement (OLD): Remove LEIM references in announcement
--- a/admin/FOR-RELEASE Tue Nov 07 02:37:49 2006 +0000 +++ b/admin/FOR-RELEASE Tue Nov 07 23:22:48 2006 +0000 @@ -43,7 +43,11 @@ * BUGS -** david.reitter@gmail.com, Oct 16: url-retrieve may cause hang +** triska@gmx.at, Nov 2: EMACS environment variable. + +** offby1@blarg.net, Nov 5: calendar gets wrong end for Daylight Savings Time + +** CC mode defun-finding issues. * DOCUMENTATION
--- a/configure.in Tue Nov 07 02:37:49 2006 +0000 +++ b/configure.in Tue Nov 07 23:22:48 2006 +0000 @@ -246,6 +246,9 @@ opsys=freebsd case "${canonical}" in alpha*-*-freebsd*) machine=alpha ;; + ia64-*-freebsd*) machine=ia64 ;; + sparc64-*-freebsd*) machine=sparc ;; + powerpc-*-freebsd*) machine=macppc ;; i[3456]86-*-freebsd*) machine=intel386 ;; amd64-*-freebsd*|x86_64-*-freebsd*) machine=amdx86-64 ;; esac
--- a/etc/ChangeLog Tue Nov 07 02:37:49 2006 +0000 +++ b/etc/ChangeLog Tue Nov 07 23:22:48 2006 +0000 @@ -1,3 +1,8 @@ +2006-11-05 Slawomir Nowaczyk <slawek@cs.lth.se> (tiny change) + + * emacs.py (eargs): Provide eldoc message for builtin types. + Make sure eargs always outputs sentinel, to avoid emacs freeze. + 2006-10-22 Chong Yidong <cyd@stupidchicken.com> * emacs.py (eargs): Return expected _emacs_out string even if
--- a/etc/PROBLEMS Tue Nov 07 02:37:49 2006 +0000 +++ b/etc/PROBLEMS Tue Nov 07 23:22:48 2006 +0000 @@ -1284,6 +1284,11 @@ For more about lbxproxy, see: http://www.xfree86.org/4.3.0/lbxproxy.1.html +5) If copying and killing is slow, try to disable the interaction with the + native system's clipboard by adding these lines to your .emacs file: + (setq interprogram-cut-function nil) + (setq interprogram-paste-function nil) + *** Emacs gives the error, Couldn't find per display information. This can result if the X server runs out of memory because Emacs uses @@ -2326,7 +2331,16 @@ the problem, install the current version of GNU Sed, then rerun Emacs's configure script. -*** Building the MS-Windows port with Cygwin GCC can fail. +*** Building the Cygwin port for MS-Windows can fail with some GCC version + +Building Emacs 22 with Cygwin builds of GCC 3.4.4-1 and 3.4.4-2 is +reported to either fail or cause Emacs to segfault at run time. In +addition, the Cygwin GCC 3.4.4-2 has problems with generating debug +info. Cygwin users are advised not to use these versions of GCC for +compiling Emacs. GCC versions 4.0.3 and 4.1.1 reportedly build a +working Cygwin binary of Emacs, so we recommend these GCC versions. + +*** Building the native MS-Windows port with Cygwin GCC can fail. Emacs may not build using recent Cygwin builds of GCC, such as Cygwin version 1.1.8, using the default configure settings. It appears to be
--- a/etc/emacs.py Tue Nov 07 02:37:49 2006 +0000 +++ b/etc/emacs.py Tue Nov 07 23:22:48 2006 +0000 @@ -50,11 +50,11 @@ if len (parts) > 1: exec 'import ' + parts[0] # might fail func = eval (name) - if inspect.isbuiltin (func): + if inspect.isbuiltin (func) or type(func) is type: doc = func.__doc__ if doc.find (' ->') != -1: print '_emacs_out', doc.split (' ->')[0] - elif doc.find ('\n') != -1: + else: print '_emacs_out', doc.split ('\n')[0] return if inspect.ismethod (func):
--- a/leim/ChangeLog Tue Nov 07 02:37:49 2006 +0000 +++ b/leim/ChangeLog Tue Nov 07 23:22:48 2006 +0000 @@ -1,3 +1,7 @@ +2006-11-04 Romain Francoise <romain@orebokech.com> + + * Makefile.in (bootstrap-clean): New target. + 2006-10-12 Kenichi Handa <handa@m17n.org> * Makefile.in (install): Be sure to make ${INSTALLDIR} before `cd'
--- a/leim/Makefile.in Tue Nov 07 02:37:49 2006 +0000 +++ b/leim/Makefile.in Tue Nov 07 23:22:48 2006 +0000 @@ -255,6 +255,12 @@ rm -f ${TIT-MISC} ${TIT-MISC:.elc=.el} \ leim-list.el changed.tit changed.misc +# The following target is needed because the `clean' target only removes +# TIT-generated files and doesn't touch compiled Quail packages. But +# bootstrapping should not leave non-fresh .elc files behind. +bootstrap-clean: clean + rm -f ${WORLD} + distclean: clean if test -f stamp-subdir; then rm -rf ${SUBDIRS} stamp-subdir; fi rm -f Makefile
--- a/lib-src/ChangeLog Tue Nov 07 02:37:49 2006 +0000 +++ b/lib-src/ChangeLog Tue Nov 07 23:22:48 2006 +0000 @@ -1,3 +1,119 @@ +2006-11-07 Juanma Barranquero <lekktu@gmail.com> + + * emacsclient.c (get_server_config) [WINDOWSNT]: Look for the server + file on APPDATA if it doesn't exist on HOME, even if HOME is defined. + + * emacsclient.c (get_server_config): Extract also the Emacs pid + from the server file. On Windows, try to force the Emacs frame to + the foreground. + +2006-11-06 Juanma Barranquero <lekktu@gmail.com> + + * emacsclient.c (longopts) [! NO_SOCKETS_IN_FILE_SYSTEM]: Don't show + option --socket-name. + (decode_options): Don't get EMACS_SERVER_FILE here, it could override + command line options. + (decode_options) [! NO_SOCKETS_IN_FILE_SYSTEM]: Don't parse "-s" option. + (fail): Don't check for missing arguments, it is now done in set_socket. + (file_name_absolute_p): New function (loosely based on the one in + fileio.c). + (initialize_sockets): Don't check for duplicate loading of Winsock. + (get_server_config): Only try relative paths in the default + directory locations. + (set_tcp_socket): Don't call INITIALIZE(). Warn when connecting to + a remote server. + (set_socket): Call INITIALIZE(). Search explicit command-line + arguments, then environment variable EMACS_SERVER_FILE, then implicit + socket paths, before trying the alternate editor. + (main): Use file_name_absolute_p. + +2006-11-04 Eli Zaretskii <eliz@gnu.org> + + * makefile.w32-in (../src/$(BLD)/temacs.exe): Create as temporary + file if it doesn't already exist. + +2006-11-03 Juanma Barranquero <lekktu@gmail.com> + + * emacsclient.c (initialize_sockets): Don't initialize Winsock + more than once. + +2006-11-03 Mark Davies <mark@mcs.vuw.ac.nz> + + * Makefile.in (INSTALL_SCRIPT): New macro. + ($(DESTDIR)${archlibdir}, install): Use it, instead of INSTALL_PROGRAM. + +2006-11-02 Juanma Barranquero <lekktu@gmail.com> + + * grep-changelog: When called with no arguments (not even a + filter), show help instead of blindingly dumping every single + ChangeLog available. Doc fix. Update version. + +2006-11-02 Tim Van Holder <tim.vanholder@gmail.com> (tiny change) + + * emacsclient.c [WINDOWSNT]: Define HAVE_INET_SOCKETS. + [!WINDOWSNT]: Include <netinet/in.h> if available. + [HAVE_SOCKETS]: Also require HAVE_INET_SOCKETS. + (IOCTL, IOCTL_BOOL_ARG): Remove. + (set_tcp_socket): Don't set the socket in blocking mode. + Remove c_arg. + +2006-11-01 Juanma Barranquero <lekktu@gmail.com> + + * emacsclient.c (fail) [WINDOWSNT]: Force the first argv passed to + execvp to point to alternate_editor (otherwise .BAT scripts can't run). + +2006-10-31 ,bS(Bscar Fuentes <ofv@wanadoo.es> (tiny change) + + * emacsclient.c [WINDOWSNT]: Include <malloc.h> and <stdlib.h>. + (close_winsock): Declare as __cdecl. + +2006-10-31 Jan Dj,Ad(Brv <jan.h.d@swipnet.se> + + * emacsclient.c [!WINDOWSNT]: Include <fcntl.h> if available. + (set_tcp_socket): Prefer O_NONBLOCK, then O_NDELAY, then FIONBIO + to set the socket in non-blocking mode. + +2006-10-31 Tim Van Holder <tim.vanholder@gmail.com> (tiny change) + + * emacsclient.c [!WINDOWSNT]: Include <netinet/in.h> and <sys/ioctl.h>. + (INVALID_SOCKET): Define. + (initialize_sockets): Put #endif at the right place. + (set_local_socket): Use progname, not argv[0]. + +2006-10-31 Juanma Barranquero <lekktu@gmail.com> + + * makefile.w32-in (ALL): Add emacsclient. + (ECLIENT_CFLAGS, ECLIENTOBJS): New macros. + (emacsclient, $(BLD)/emacsclient.exe): New targets. + (install): Install emacsclient. + + * emacsclient.c: Add support for TCP sockets. + (SEND_STRING, SEND_QUOTED, HSOCKET, CLOSE_SOCKET, IOCTL) + (INITIALIZE): New macros. + (IOCTL_BOOL_ARG): New typedef. + (server_file): New global variable. + (longopts): New option --server-file. + (decode_options): Process new option --server-file and environment + variable EMACS_SERVER_FILE. + (print_help_and_exit): Document new option. + (fail): If no connection available and no alternate editor, + suggest using options to make them explicit. + (AUTH_KEY_LENGTH, SEND_BUFFER_SIZE): New constants. + (send_buffer, sblen): New variables. + (send_to_emacs): New function to buffer output and send it with + send(). + (quote_file_name): Use SEND_STRING. + (close_winsock, initialize_sockets): New functions to load and + unload Winsock. + (get_server_config, set_tcp_socket): New functions to create and + set up TCP sockets. + (set_local_socket): New function to create and set up Unix + socket (code moved from previous implementation). + (set_socket): New function to chose between TCP and Unix sockets. + (main): Use SEND_STRING and SEND_QUOTED. Most code moved to + set_local_socket. Use set_socket. Get answers from server.el with + recv(), not file stream functions. + 2006-10-09 Eli Zaretskii <eliz@gnu.org> * makefile.w32-in (../src/config.h): Fix error message. @@ -13,14 +129,13 @@ 2006-08-09 Jan Dj,Ad(Brv <jan.h.d@swipnet.se> - * etags.c (readline): expect sscanf returns >= 1. + * etags.c (readline): Expect sscanf returns >= 1. (readline): Change position on %n and \" in sscanf. 2006-08-07 Masatake YAMATO <jet@gyve.org> - * etags.c (readline): expect sscanf returns 2, - not 1. - + * etags.c (readline): Expect sscanf returns 2, not 1. + 2006-08-07 Masatake YAMATO <jet@gyve.org> * etags.c (TEX_mode): Check getc returns EOF. @@ -28,7 +143,7 @@ 2002-07-30 Adrian Aichner <adrian@xemacs.org> (tiny change) - * etags.c: It's XEmacs, not Xemacs: change all the occurences. + * etags.c: It's XEmacs, not Xemacs: change all the occurrences. 2006-07-30 Francesco Potort,Al(B <pot@gnu.org> @@ -162,7 +277,7 @@ * Makefile.in (update-game-score.o): Delete spurious final `\'. -2005-11-18 Hideki IWAMOTO <h-iwamoto@kit.hi-ho.ne.jp> (tiny change) +2005-11-18 Hideki IWAMOTO <h-iwamoto@kit.hi-ho.ne.jp> (tiny change) * etags.c (main): Cxref mode writes to stdout: do not close tagf, which was never opened. @@ -199,7 +314,7 @@ 2005-09-11 Jason Rumney <jasonr@gnu.org> - * makefile.w32-in (../src/config.h): Don't overwrite. Print a + * makefile.w32-in (../src/config.h): Don't overwrite. Print a message instead. (../src/paths.h): Removed. @@ -335,12 +450,12 @@ 2004-09-13 David A. Capello <dacap@users.sourceforge.net> (tiny change) - * etags.c: (Lua_suffixes, Lua_help, lang_names, Lua_functions): + * etags.c (Lua_suffixes, Lua_help, lang_names, Lua_functions): Support the Lua scripting language <http://www.lua.org>. 2004-09-08 Francesco Potort,Al(B <pot@gnu.org> - * etags.c: [LONG_OPTIONS]: make it TRUE (ifdef) or FALSE (ifndef) + * etags.c [LONG_OPTIONS]: make it TRUE (ifdef) or FALSE (ifndef) for ease of use. 2004-07-17 Richard M. Stallman <rms@gnu.org> @@ -702,12 +817,12 @@ * emacsclient.c (quote_file_name): Quote \n. (main): Print a final \n when needed. -2002-09-03 Francesco Potorti` <pot@gnu.org> +2002-09-03 Francesco Potort,Al(B <pot@gnu.org> * etags.c (regex_tag_multiline, readline): Never pass pfnote a string that cannot be freed. -2002-08-30 Francesco Potorti` <pot@gnu.org> +2002-08-30 Francesco Potort,Al(B <pot@gnu.org> * etags.c (consider_token, C_entries): Switch to C++ parsing when auto-detection is enabled and the `::' qualifier is met. @@ -718,21 +833,21 @@ (C_entries): Several cosmetic changes. (C_entries): Invalidate the token is some cases. -2002-08-29 Francesco Potorti` <pot@gnu.org> +2002-08-29 Francesco Potort,Al(B <pot@gnu.org> * etags.c (C_entries): Correct a problem with const C++ funcs. (ignoreindent): Renamed from noindentypedefs. (cjava, cplpl): They are now macros instead of local vars. -2002-08-28 Francesco Potorti` <pot@gnu.org> +2002-08-28 Francesco Potort,Al(B <pot@gnu.org> * etags.c (HTML_labels): Tag ID= also. -2002-08-27 Francesco Potorti` <pot@gnu.org> +2002-08-27 Francesco Potort,Al(B <pot@gnu.org> * etags.c (Ada_funcs): Do not tag "use type Xxxx;". - * etags.c: (HTML_labels): New language HTML. + * etags.c (HTML_labels): New language HTML. (etags_strcasecmp): Like BSD's, for compatibility. (strcaseeq): Make it into a macro. @@ -784,9 +899,9 @@ * b2m.pl: New file. -2002-06-21 Francesco Potorti` <pot@gnu.org> - - * etags.c: (F_getit, Fortran_functions, Ada_getit, Asm_labels) +2002-06-21 Francesco Potort,Al(B <pot@gnu.org> + + * etags.c (F_getit, Fortran_functions, Ada_getit, Asm_labels) (Python_functions, PHP_functions, PHP_functions, PHP_functions) (PHP_functions, PHP_functions, Cobol_paragraphs) (Makefile_targets, Postscript_functions, Texinfo_nodes) @@ -795,7 +910,7 @@ (TeX_commands, get_tag): Use make_tag instead of pfnote. (get_tag): Prototype changed, all callers changed. -2002-06-20 Francesco Potorti` <pot@gnu.org> +2002-06-20 Francesco Potort,Al(B <pot@gnu.org> * etags.c: Implement implicit tag names, that is, unnamed tags whose name is automatically deduced by etags.el. The advantage is @@ -805,13 +920,13 @@ (make_tag): New function (was the disabled function new_pfnote). (make_C_tag): Use it. -2002-06-19 Francesco Potorti` <pot@gnu.org> +2002-06-19 Francesco Potort,Al(B <pot@gnu.org> * etags.c (add_regex): Invalid regexp modifiers are ignored. (Makefile_targets): Tag variables unless --no-globals. (LOOP_ON_INPUT_LINES): Serious bug corrected. -2002-06-13 Francesco Potorti` <pot@gnu.org> +2002-06-13 Francesco Potort,Al(B <pot@gnu.org> * etags.c (erlang_atom, erlang_attribute): Bugs corrected. (invalidate_nodes): Bug corrected. @@ -822,7 +937,7 @@ * makefile.w32-in (lisp): Add international/ucs-tables.elc and font-core.elc. -2002-06-12 Francesco Potorti` <pot@gnu.org> +2002-06-12 Francesco Potort,Al(B <pot@gnu.org> * etags.c: New multi-line regexp and new regexp syntax. (arg_type): at_icregexp label removed (obsolete). @@ -844,13 +959,13 @@ (readline_internal): If necessary, copy the whole file into filebuf. (readline): Skip multi-line regexps, leave them to regex_tag_multiline. -2002-06-11 Francesco Potorti` <pot@gnu.org> +2002-06-11 Francesco Potort,Al(B <pot@gnu.org> * etags.c (add_regex): Better check for null regexps. (readline): Check for regex matching null string. (find_entries): Reorganisation. -2002-06-07 Francesco Potorti` <pot@gnu.org> +2002-06-07 Francesco Potort,Al(B <pot@gnu.org> * etags.c (scan_separators): Support all character escape sequences supported by Gcc. @@ -865,7 +980,7 @@ (readline): Conditionally undo readline_internal increment. (readline): Do not return a value. -2002-06-06 Francesco Potorti` <pot@gnu.org> +2002-06-06 Francesco Potort,Al(B <pot@gnu.org> * etags.c: New option --parse-stdin=FILE. (enum arg_type): New label at_stdin. @@ -888,7 +1003,7 @@ (TEX_tabent, TEX_token): Deleted. (TeX_commands, TEX_decode_env): Streamlined. -2002-06-05 Francesco Potorti` <pot@gnu.org> +2002-06-05 Francesco Potort,Al(B <pot@gnu.org> * etags.c (main): Avoid a buffer overrun with sprintf. @@ -936,9 +1051,9 @@ * update-game-score.c (read_score) [HAVE_GETDELIM]: Trim trailing space. -2002-04-22 Francesco Potorti` <pot@gnu.org> - - * etags.c: (last_node): Make it a global variable. +2002-04-22 Francesco Potort,Al(B <pot@gnu.org> + + * etags.c (last_node): Make it a global variable. (process_file): Print the tags from the nodes as soon as possible, and delete the nodes. This brings down the memory occupancy as etags to almost the same level as when the #line @@ -957,11 +1072,11 @@ * update-game-score.c: Move config.h before the other headers, to avoid compiler warnings. -2002-04-16 Francesco Potorti` <pot@gnu.org> +2002-04-16 Francesco Potort,Al(B <pot@gnu.org> * etags.c (find_entries): Bug fix in list management. -2002-04-15 Francesco Potorti` <pot@gnu.org> +2002-04-15 Francesco Potort,Al(B <pot@gnu.org> * etags.c (get_language_from_filename): Add one argument. (strcaseeq): New function. @@ -970,7 +1085,7 @@ (find_entries): Try with case insensitive match. (process_file): Bug fixed. -2002-04-13 Francesco Potorti` <pot@gnu.org> +2002-04-13 Francesco Potort,Al(B <pot@gnu.org> * etags.c (find_entries): Delete tags previously obtained from file xxx.c's #line directives when parsing file xxx.y. This is @@ -1017,7 +1132,7 @@ 2002-04-10 Colin Walters <walters@verbum.org> - * update-game-score.c: (toplevel): Include stdarg.h. + * update-game-score.c (toplevel): Include stdarg.h. (MAX_DATA_LEN, MAX_SCORES): New. (SCORE_FILE_PREFIX): If HAVE_SHARED_GAME_DIR is not defined, default to ~/.emacs.d/games. @@ -1081,7 +1196,7 @@ `sort TAGFILE -o TAGFILE', as POSIX 1003.1-2001 disallows the latter usage. -2002-03-12 Francesco Potorti` <pot@gnu.org> +2002-03-12 Francesco Potort,Al(B <pot@gnu.org> * etags.c (Python_functions): Skip spaces at beginning of lines. (Python_functions, PHP_functions): Name tags, for ctags' sake. @@ -1096,7 +1211,7 @@ * etags.c (put_entries): Use #if !CTAGS, to fix link error on compilers that don't optimize out dead code. -2002-03-05 Francesco Potorti` <pot@gnu.org> +2002-03-05 Francesco Potort,Al(B <pot@gnu.org> * etags.c: Honour #line directives. (no_line_directive): New global var; set it for old behaviour. @@ -1165,7 +1280,7 @@ * cvtmail.c, emacsclient.c, emacsserver.c, pop.c, sorted-doc.c, * yow.c: Include <config.h>. -2001-12-21 Francesco Potorti` <pot@gnu.org> +2001-12-21 Francesco Potort,Al(B <pot@gnu.org> * etags.c (Perl_functions): Tag packages and use them in sub tags. (get_tag): Return a pointer to the tag that is found. @@ -1185,13 +1300,13 @@ (L_isdef, L_isquote): Removed. (Lisp_functions, L_getit): Clarified. - * etags.c: (P_): Renamed to __P for consistency with config.h. + * etags.c (P_): Renamed to __P for consistency with config.h. [HAVE_CONFIG_H]: Let config.h deal with __P. [__STDC__] [!HAVE_CONFIG_H]: Define PTR as in config.h. [!__STDC__] [!HAVE_CONFIG_H]: Do not undefine static, because gperf code needs it. - [HAVE_CONFIG_H] [!PTR]: Define PTR (for use with Xemacs). - [HAVE_CONFIG_H] [!__P]: Define __P (for use with Xemacs). + [HAVE_CONFIG_H] [!PTR]: Define PTR (for use with XEmacs). + [HAVE_CONFIG_H] [!__P]: Define __P (for use with XEmacs). (xmalloc, xrealloc): Use PTR instead of long *. (bool): Make it a define, not a typedef, for C++ compilers. (pattern): Members renamed to avoid name clash in some C++ compilers. @@ -1237,7 +1352,7 @@ not <../src/epaths.h>. (malloc, realloc) [!HAVE_STDLIB_H]: Prototype. -2001-12-12 Francesco Potorti` <pot@gnu.org> +2001-12-12 Francesco Potort,Al(B <pot@gnu.org> * etags.c (PHP_functions): New function for parsing PHP. (LOOKING_AT): New macro. @@ -1472,11 +1587,11 @@ * ebrowse.c (main): Check that the output file exists and is non-empty if invoked with `--append'. -2001-05-14 Francesco Potorti` <pot@gnu.org> +2001-05-14 Francesco Potort,Al(B <pot@gnu.org> * etags.c (add_regex): Reset the whole newly allocated pattern buffer instead of the individual members. It's safer and works - with Xemacs. + with XEmacs. * etags.1: Markups corrected. @@ -1514,7 +1629,7 @@ * makefile.w32-in: Fix copyright notice. -2001-02-23 Francesco Potorti` <pot@gnu.org> +2001-02-23 Francesco Potort,Al(B <pot@gnu.org> * etags.c (enum sym_type): New label st_C_template. (gperf input): Use it for switching to C++ from C. @@ -1541,9 +1656,9 @@ * etags.c (in_word_set): Use `static' in definition (for pcc). -2001-01-31 Francesco Potorti` <pot@gnu.org> - - * etags.c: [NDEBUG] #undef assert and #define it as ((void)0), for +2001-01-31 Francesco Potort,Al(B <pot@gnu.org> + + * etags.c [NDEBUG]: #undef assert and #define it as ((void)0), for the sake of some buggy assert.h (e.g. in MinGW and sunos4 pcc). (C_entries): Tag token renamed to still_in_token because sunos4 pcc wants to expand it as the token() macro even though it has no @@ -1554,10 +1669,10 @@ * etags.c (assert) [__MINGW32__]: Redefine assert to work around a bug in the Mingw32 assert.h header file. -2001-01-30 Francesco Potorti` <pot@gnu.org> - - * etags.c: [WIN32-NATIVE]: #undef MSDOS, #undef WINDOWSNT and - #define it for the sake of Xemacs. +2001-01-30 Francesco Potort,Al(B <pot@gnu.org> + + * etags.c [WIN32-NATIVE]: #undef MSDOS, #undef WINDOWSNT and + #define it for the sake of XEmacs. [WINDOWSNT]: #undef HAVE_NTGUI even if built without HAVE_CONFIG_H. This change only affects a standalone etags. [WINDOWSNT]: #undef DOS_NT and #define it even if built with @@ -1566,7 +1681,7 @@ [!HAVE_UNISTD_H]: use defined(WINDOWSNT) instead of the bare WINDOWSNT, as this is the correct way to use it. -2001-01-28 Francesco Potorti` <pot@gnu.org> +2001-01-28 Francesco Potort,Al(B <pot@gnu.org> * etags.c: Be capable to parse nested struct-like structures. (structdef, structtag): Struct state machine revisited. @@ -1600,7 +1715,7 @@ (matching_regexp): Use them instead of static variables in function scope. -2001-01-25 Francesco Potorti` <pot@gnu.org> +2001-01-25 Francesco Potort,Al(B <pot@gnu.org> * etags.c (struct tok): Renamed from struct token. (token): Renamed from tok. @@ -1629,12 +1744,12 @@ * ebrowse.c (xfree): New function. (member, declaration, globals): Use xmalloc instead of alloca. -2001-01-15 Francesco Potorti` <pot@gnu.org> +2001-01-15 Francesco Potort,Al(B <pot@gnu.org> * etags.c (print_language_names): Print filenames in addition to suffixes. -2001-01-14 Francesco Potorti` <pot@gnu.org> +2001-01-14 Francesco Potort,Al(B <pot@gnu.org> * etags.c (get_language_from_langname): Renamed from get_language_from_name. @@ -1873,14 +1988,14 @@ * etags.c (lisp_suffixes) Add `LSP'. -2000-02-10 Francesco Potorti` <pot@gnu.org> +2000-02-10 Francesco Potort,Al(B <pot@gnu.org> * etags.c (iswhite): Redefine not to consider '\0' as white space, and use it throughout in place of isspace, thus preventing a potential signed char to int conversion problem. (MSDOS): #undefine befere redefining -2000-02-04 Francesco Potorti` <pot@gnu.org> +2000-02-04 Francesco Potort,Al(B <pot@gnu.org> * etags.c (many functions): Add prototypes. @@ -1889,7 +2004,7 @@ * etags.c (pfnote, new_pfnote, C_entries, prolog_pred) (erlang_func): Add `static' to definitions to keep pcc happy. -2000-01-31 Francesco Potorti` <pot@gnu.org> +2000-01-31 Francesco Potort,Al(B <pot@gnu.org> * etags.c [MSDOS]: Set MSDOS to 1 if #defined, 0 otherwise. (get_compressor_from_suffix, process_file): Use MSDOS in if clause. @@ -1928,7 +2043,7 @@ * movemail.c (popmail): Allow mailbox specifications of the form `po:username:hostname'. -1999-11-19 Francesco Potorti` <pot@gnu.org> +1999-11-19 Francesco Potort,Al(B <pot@gnu.org> * etags.c (_GNU_SOURCE): Define only if undefined. (get_scheme): Declaration deleted. @@ -1949,7 +2064,7 @@ * etags.c (print_help): Change email address to send bugs to. -1999-11-01 Francesco Potorti` <pot@gnu.org>> +1999-11-01 Francesco Potort,Al(B <pot@gnu.org>> * etags.c: Add suffix psw for PSWrap. (L_getit): Generalize a "cp!=' '" into "!isspace(*cp)". @@ -2003,7 +2118,7 @@ [MSDOS]: Support DOS file names by handling e.g. foo.cgz as if it were foo.c.gz. -1999-11-01 Francesco Potorti` <pot@gnu.org> +1999-11-01 Francesco Potort,Al(B <pot@gnu.org> * etags.c (sym_type, C_stab_entry): New constant st_C_operator. (fvdev): New constant foperator. @@ -2037,7 +2152,7 @@ (add_regex): New arg determining whether to use translation table. (analyse_regex): New arg. Use it for add_regex. -1999-11-01 Francesco Potorti` <pot@gnu.org> +1999-11-01 Francesco Potort,Al(B <pot@gnu.org> * etags.c (init): Cosmetic change: NULL --> '\0'. (erlang_attribute): Bug corrected (uninitialized variable). @@ -2073,7 +2188,7 @@ Change name of local vars to avoid clashes with typedef linebuffer. (readline): Rewritten for new functionality. - * etags.c: (Scheme_suffixes): New suffix ".ss". + * etags.c (Scheme_suffixes): New suffix ".ss". (print_help): --globals is now used for more than C-type languages. (Perl_functions): Tag global variables ("my" and "local"). @@ -2101,10 +2216,9 @@ characters and compilers with default signed chars. (L_getit): Tag "(defstruct (foo", "(defun (operator" and similar constructs. - - * (C_stab_entry): "interface" in Java behaves like "class". - - * etags.c: (HAVE_NTGUI) [WINDOWSNT]: #undef if HAVE_CONFIG_H. + (C_stab_entry): "interface" in Java behaves like "class". + + * etags.c (HAVE_NTGUI) [WINDOWSNT]: #undef if HAVE_CONFIG_H. (main): Put interval syntax here. (add_regex): And remove it from here. @@ -2461,9 +2575,9 @@ 1997-10-16 Dave Love <d.love@dl.ac.uk> - * etags.c (L_getit): Always make named tags so that Emacs - completion on symbols containing `:' etc. works. - (get_scheme): Likewise. + * etags.c (L_getit): Always make named tags so that Emacs + completion on symbols containing `:' etc. works. + (get_scheme): Likewise. 1997-09-24 Jonathan I. Kamens <jik@kamens.brookline.ma.us> @@ -2523,19 +2637,19 @@ 1997-07-22 Jonathan I. Kamens <jik@kamens.brookline.ma.us> * pop.c: Support auto-configuration of both Kerberos V4 and - Kerberos V5 for movemail, including detection of V4 and V5 header - files and libraries. + Kerberos V5 for movemail, including detection of V4 and V5 header + files and libraries. Include <string.h> when STDC_HEADERS is defined, to get - declarations of string functions. + declarations of string functions. [KERBEROS5] (socket_connection): Support the current MIT Kerberos - V5 API rather than the old one. + V5 API rather than the old one. [KERBEROS] (socket_connection): Change a constant name from - SOCKET_ERROR to POP_SOCKET_ERROR to avoid a namespace conflict - with a constant in a header file. + SOCKET_ERROR to POP_SOCKET_ERROR to avoid a namespace conflict + with a constant in a header file. * Makefile.in: Support auto-configuration of both Kerberos V4 and - Kerberos V5 for movemail, including detection of V4 and V5 header - files and libraries. + Kerberos V5 for movemail, including detection of V4 and V5 header + files and libraries. 1997-07-17 Richard Stallman <rms@psilocin.gnu.ai.mit.edu> @@ -2572,14 +2686,14 @@ * b2m.c (readline): Terminate buffer properly when EOF seen. Test for valid pointer before dereferencing it. -1997-05-30 Francesco Potorti` <F.Potorti@cnuce.cnr.it> +1997-05-30 Francesco Potort,Al(B <F.Potorti@cnuce.cnr.it> * Makefile.in (etags): Remove -DETAGS_REGEXPS, because now it is defined inside etags.c if HAVE_CONFIG_H is defined. -1997-05-29 Francesco Potorti` <F.Potorti@cnuce.cnr.it> - - * etags.c: (logical): Type name changed to bool. +1997-05-29 Francesco Potort,Al(B <F.Potorti@cnuce.cnr.it> + + * etags.c (logical): Type name changed to bool. (ETAGS_REGEXPS, LONG_OPTIONS) [HAVE_CONFIG_H]: #define them. (<getopt.h>) [LONG_OPTIONS]: Include conditionally. (getopt_long) [!LONG_OPTIONS]: Redefine as macro. @@ -2589,7 +2703,7 @@ defined conditionally to ETAGS_REGEXPS. (print_help): Updated. -1997-05-22 Francesco Potorti` <F.Potorti@cnuce.cnr.it> +1997-05-22 Francesco Potort,Al(B <F.Potorti@cnuce.cnr.it> * etags.c (C_entries): Use "." instead of "::" for Java. (consider_token): is_func renamed to is_func_or_var. @@ -2604,7 +2718,7 @@ (main, C_entries): Use them. (make_C_tag, C_entries): Make tok a global variable. -1997-05-16 Francesco Potorti` <F.Potorti@cnuce.cnr.it> +1997-05-16 Francesco Potort,Al(B <F.Potorti@cnuce.cnr.it> * etags.c (funcdef): New vignore constant. (consider_token, C_entries): Use it to tag global variables. @@ -2614,7 +2728,7 @@ (Cobol_suffixes, lang_names, Cobol_paragraphs): Cobol support. (prolog_white, erlang_white): Renamed to eat_white, callers changed. -1997-05-15 Francesco Potorti` <F.Potorti@cnuce.cnr.it> +1997-05-15 Francesco Potort,Al(B <F.Potorti@cnuce.cnr.it> * etags.c (CHARS, CHAR): New constant and macro. (iswhite, begtoken, intoken, endtoken): Use them. @@ -2624,13 +2738,13 @@ (make_C_tag) [traditional_tag_style]: Use it. (traditional_tag_style): Costant set to TRUE for now. -1997-05-14 Francesco Potorti` <F.Potorti@cnuce.cnr.it> +1997-05-14 Francesco Potort,Al(B <F.Potorti@cnuce.cnr.it> * etags.c (C_entries, Pascal_functions): Cleanup. (TeX_functions): NULL as a function arg needs a cast. (Erlang_functions, erlang_func, erlang_attribute): Cleanup. -1997-05-13 Francesco Potorti` <F.Potorti@cnuce.cnr.it> +1997-05-13 Francesco Potort,Al(B <F.Potorti@cnuce.cnr.it> * etags.c (TeX_functions): Cleaned up. (tex_getit): Removed. @@ -2638,9 +2752,9 @@ 1997-05-13 Paul Eggert <eggert@twinsun.com> * rcs2log (files): When computing arguments automatically, ignore - non-files within the RCS subdirectory. - -1997-05-13 Francesco Potorti` <F.Potorti@cnuce.cnr.it> + non-files within the RCS subdirectory. + +1997-05-13 Francesco Potort,Al(B <F.Potorti@cnuce.cnr.it> * etags.c (C_JAVA): New #define. (Cjava_suffixes): .java is Java. @@ -2650,9 +2764,9 @@ (C_stab_entry): Add `extends' and `implements' keywords. (consider_token, C_entries): Recognise Java structures. -1997-05-12 Francesco Potorti` <F.Potorti@cnuce.cnr.it> - - * etags.c: (Cplusplus_suffixes): .pdb is Postscript with C syntax. +1997-05-12 Francesco Potort,Al(B <F.Potorti@cnuce.cnr.it> + + * etags.c (Cplusplus_suffixes): .pdb is Postscript with C syntax. (Postscript_suffixes): .ps is Postscript. (lang_names): Add Postscript. (Postscript_functions): New function. @@ -2662,10 +2776,10 @@ 1997-05-11 Paul Eggert <eggert@twinsun.com> * rcs2log (loginFullnameMailaddrs, logins, rlog_options, files): - Don't prepend $nl since this causes some shells to generate the - empty string when IFS is $nl. + Don't prepend $nl since this causes some shells to generate the + empty string when IFS is $nl. (printlogline): Use SOH (octal code 1), not CR, since some - PC-based shells mishandle CR. + PC-based shells mishandle CR. (initialize_fullname): Set NIS_PATH to the empty string before invoking nismatch, in case it's set to some nonstandard value. @@ -2674,7 +2788,7 @@ * pop.c (getline): Don't miss CRLF pairs when the CR and LF are read in separate blocks. -1997-04-30 Francesco Potorti` <F.Potorti@cnuce.cnr.it> +1997-04-30 Francesco Potort,Al(B <F.Potorti@cnuce.cnr.it> * etags.c [TeX_named_tokens]: Set to FALSE if undefined. (struct linebuffer): New member `len' is the length of the string. @@ -2692,14 +2806,14 @@ * makefile.nt: Change references of windowsnt.h to ms-w32.h. (obj): Change references of nt*.c files to w32*.c files. -1997-04-15 Francesco Potorti` <F.Potorti@cnuce.cnr.it> +1997-04-15 Francesco Potort,Al(B <F.Potorti@cnuce.cnr.it> * etags.c (xnew): Add support for debugging with chkmalloc. (error): Use this instead of printf whenever possible. (main): Only call xnew after having initialised progname. (substitute): Bad memory corruption error corrected. -1997-04-08 Francesco Potorti` <F.Potorti@cnuce.cnr.it> +1997-04-08 Francesco Potort,Al(B <F.Potorti@cnuce.cnr.it> * etags.c (add_regex): Undo previous change. (relative_filename): Small memory leak closed. @@ -2709,11 +2823,11 @@ 1997-03-21 Paul Eggert <eggert@twinsun.com> * rcs2log (files): Ignore files in RCS directory whose names are - of the form ,*, or *_; they are probably RCS lock files. - Also, ignore files named .rcsfreeze.log or .rcsfreeze.ver; + of the form ,*, or *_; they are probably RCS lock files. + Also, ignore files named .rcsfreeze.log or .rcsfreeze.ver; they are used by rcsfreeze. -1997-03-14 Francesco Potorti` <F.Potorti@cnuce.cnr.it> +1997-03-14 Francesco Potort,Al(B <F.Potorti@cnuce.cnr.it> * etags.c (add_regex): reset *putbuf before using it. @@ -2743,7 +2857,7 @@ 1997-01-20 Paul Eggert <eggert@twinsun.com> - * rcs2log: (--help, --version): New options, per GNU coding standards. + * rcs2log (--help, --version): New options, per GNU coding standards. (Copyright, Help, Id): New variables, for above. (rlog): Use -q option with cvs log, to avoid useless chatter. @@ -2764,26 +2878,26 @@ 1996-12-18 Jonathan I. Kamens <jik@annex-1-slip-jik.cam.ov.com> * Makefile.in (LIBMAIL): New macro. Conditionally includes -lmail. - (movemail): Use LIBMAIL, to link against -lmail. + (movemail): Use LIBMAIL, to link against -lmail. * movemail.c: Include maillock.h (conditionally). Remove a redundant inclusion of <stdio.h>. (MAIL_USE_MAILLOCK): New macro, conditionally defined. (main): Add variable spool_name. Support the usage of maillock and mailunlock to - lock and unlock mailboxes. + lock and unlock mailboxes. (mail_spool_name): New function. * movemail.c: Fix an uninitialized variable which could cause - movemail to exit with an error status incorrectly on systems which - use lock files rather than a system locking function to lock - mailboxes. + movemail to exit with an error status incorrectly on systems which + use lock files rather than a system locking function to lock + mailboxes. 1996-12-16 Richard Stallman <rms@psilocin.gnu.ai.mit.edu> * pop.c (socket_connection): Free realhost after using it. -1996-12-04 Francesco Potorti` <F.Potorti@cnuce.cnr.it> +1996-12-04 Francesco Potort,Al(B <F.Potorti@cnuce.cnr.it> * etags.c (C_entries): Test tok.valid. This handles some particular cases involving function declarations that failed. @@ -2794,14 +2908,14 @@ gethostbyname may return a pointer to static data. krb_realmofhost can clobber it. So copy it. -1996-11-14 Francesco Potorti` <F.Potorti@cnuce.cnr.it> +1996-11-14 Francesco Potort,Al(B <F.Potorti@cnuce.cnr.it> * etags.c (pfnote, fatal, error): Callers using a NULL pointer must cast it to (char *) because we have no prototypes. (make_C_tag): Macro deleted, new function. (C_entries): Calls to make_C_tag macro changed to call function. -1996-11-13 Francesco Potorti` <F.Potorti@cnuce.cnr.it> +1996-11-13 Francesco Potort,Al(B <F.Potorti@cnuce.cnr.it> * etags.c (grow_linebuffer): New function. (GROW_LINEBUFFER): Macro deleted. All callers changed. @@ -2811,7 +2925,7 @@ number of arguments. (xrealloc): fatal was called with wrong number of arguments -1996-11-08 Francesco Potorti` <F.Potorti@cnuce.cnr.it> +1996-11-08 Francesco Potort,Al(B <F.Potorti@cnuce.cnr.it> * etags.c (relative_filename): Bug corrected. (etags_getcwd): Avoid warning of unused variable. @@ -2820,7 +2934,7 @@ 1996-11-03 Paul Eggert <eggert@twinsun.com> * rcs2log: When processing cvs log output, remove `Attic/' from - repository file names. + repository file names. 1996-10-22 Karl Heuer <kwzh@gnu.ai.mit.edu> @@ -2829,7 +2943,7 @@ 1996-10-12 Paul Eggert <eggert@twinsun.com> * rcs2log (rlog_options): Look for ' option' rather than 'unknown - option', since CVS says 'invalid option'. + option', since CVS says 'invalid option'. (datearg): Use the empty string, not '-d>1970-01-01', to extract all revisions, since some hosts reject 1970-01-01 when east of UTC. (date): Remove. @@ -2838,7 +2952,7 @@ * etags.c (etags_getcwd) [WINDOWSNT]: Convert backslashes to slashes. -1996-10-02 Francesco Potorti` <F.Potorti@cnuce.cnr.it> +1996-10-02 Francesco Potort,Al(B <F.Potorti@cnuce.cnr.it> * etags.c (print_version): Print copyright info. @@ -2850,7 +2964,7 @@ 1996-09-29 Dave Love <d.love@dl.ac.uk> * rcs2log (date): Make default format acceptable to CVS post v1.8 - as well as earlier CVSs and RCS. + as well as earlier CVSs and RCS. 1996-09-29 Richard Stallman <rms@ethanol.gnu.ai.mit.edu> @@ -2860,7 +2974,7 @@ 1996-09-25 Paul Eggert <eggert@twinsun.com> * rcs2log (rlog_options): Use $rlog, not rlog, when deciding - whether to append -zLT. + whether to append -zLT. 1996-09-16 Karl Heuer <kwzh@gnu.ai.mit.edu> @@ -2890,7 +3004,7 @@ * emacsserver.c: On fatal signal, delete socket-file: * emacsserver.c: Include signal.h. - (xmalloc, fatal, error): New functions. + (xmalloc, fatal, error): New functions. (delete_socket, handle_signals): New functions. (progname, socket_name): New variables. [HAVE_SOCKETS] (main): Call handle_signals; set the new variables. @@ -2984,7 +3098,7 @@ 1996-07-15 David Mosberger-Tang <davidm@AZStarNet.com> - * cvtmail.c, sorted-doc.c, yow.c: [__GNU_LIBRARY__]: Use <string.h>. + * cvtmail.c, sorted-doc.c, yow.c [__GNU_LIBRARY__]: Use <string.h>. * emacsserver.c (main) [__GNU_LIBRARY__]: Use size_t for fromlen. * etags.c, fakemail.c, profile.c: Declare main as int, not void. @@ -3002,7 +3116,7 @@ * makefile.nt: Remove all references to wakeup. -1996-06-28 Francesco Potorti` <F.Potorti@cnuce.cnr.it> +1996-06-28 Francesco Potort,Al(B <F.Potorti@cnuce.cnr.it> * etags.c (C_stab_entry): New keywords for C++ namespace, bool, explicit, mutable, typename. @@ -3033,7 +3147,7 @@ * Version 19.31 released. -1996-05-17 Francesco Potorti` <F.Potorti@cnuce.cnr.it> +1996-05-17 Francesco Potort,Al(B <F.Potorti@cnuce.cnr.it> * etags.c (CNL_SAVE_DEFINEDEF): Set linecharno for use by readline. (Pascal_functions): Increase linecharno by the correct number of @@ -3146,21 +3260,21 @@ * makefile.nt: Change uses of del to $(DEL). -1996-03-22 Francesco Potorti` <F.Potorti@cnuce.cnr.it> +1996-03-22 Francesco Potort,Al(B <F.Potorti@cnuce.cnr.it> * etags.c (just_read_file): Reset lineno and charno on entry. 1996-03-15 Anders Lindgren <andersl@csd.uu.se> * etags.c: Prolog language totaly rewritten. - (Prolog_functions): Rewritten from scratch. + (Prolog_functions): Rewritten from scratch. (skip_comment, prolog_getit): Removed. - (prolog_skip_comment): New function, like old skip_comment. - (prolog_pred, prolog_atom, prolog_white): New functions. - (erlang_func, erlang_attributes): Forward declarations added. - (erlang_atom): Check if backslash ends line inside quoted atom. - -1996-03-14 Francesco Potorti` <F.Potorti@cnuce.cnr.it> + (prolog_skip_comment): New function, like old skip_comment. + (prolog_pred, prolog_atom, prolog_white): New functions. + (erlang_func, erlang_attributes): Forward declarations added. + (erlang_atom): Check if backslash ends line inside quoted atom. + +1996-03-14 Francesco Potort,Al(B <F.Potorti@cnuce.cnr.it> * etags.c (absolutefn): DOS_NT version corrected. (main): Append "/" to the dir name only if not already there. @@ -3248,7 +3362,7 @@ * Makefile.in (THIS_IS_MAKEFILE): Renamed from THIS_IS_YMAKEFILE. -1995-12-07 Francesco Potorti` <pot@cnuce.cnr.it> +1995-12-07 Francesco Potort,Al(B <pot@cnuce.cnr.it> * etags.c (pfnote): Don't make a tag for ctags if there is no name. (getit, Asm_labels, Perl_functions, Pascal_functions, L_getit, @@ -3260,7 +3374,7 @@ (main): Let get_language_from_name make language existence check. (streq, strneq): Check the arguments #if DEBUG. -1995-12-06 Francesco Potorti` <pot@cnuce.cnr.it> +1995-12-06 Francesco Potort,Al(B <pot@cnuce.cnr.it> * etags.c (Cplusplus_suffixes): Add .M suffix for Objective C++. (gperf): Added keywords for Objective C and GNU macros. @@ -3277,10 +3391,10 @@ (C_entries): Consider // as a comment start even in plain C for the sake of Objective C parsing. -1995-12-04 Francesco Potorti` <pot@cnuce.cnr.it> +1995-12-04 Francesco Potort,Al(B <pot@cnuce.cnr.it> * Makefile.in (ctags): depend on etags only for simplicity; - compile with regexp support enabled. + compile with regexp support enabled. 1995-11-24 Richard Stallman <rms@mole.gnu.ai.mit.edu> @@ -3306,7 +3420,7 @@ w32fns.c, w32faces.c, w32select.c, w32menu.c, w32reg.c; remove Windows 95 conditional. -1995-11-06 Francesco Potorti` (pot@cnuce.cnr.it) +1995-11-06 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (get_lang_from_name, get_lang_from_interpreter, get_lang_from_suffix): New functions. @@ -3319,7 +3433,7 @@ (Perl_functions): New function. (lang_suffixes): .pl and .pm are Perl suffixes. -1995-11-02 Francesco Potorti` (pot@cnuce.cnr.it) +1995-11-02 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (lowcase): Use the standard tolower function. (substitute): Remove some wrong and some useless code related with @@ -3347,7 +3461,7 @@ [! O_RDONLY]: Define it to zero. (main): Use O_RDONLY instead of explicit zero. -1995-08-17 Francesco Potorti` (pot@cnuce.cnr.it) +1995-08-17 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (Pascal_functions): Close comment bug corrected. (add_node): Correctly compare node file names. @@ -3402,7 +3516,7 @@ * Makefile.in.in (install, maybe-blessmail): Don't cd ..; configure has already set $(INSTALL) to the proper relative path. -1995-06-27 Francesco Potorti` (pot@cnuce.cnr.it) +1995-06-27 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (plain_C_entries): new function. (lowcase): new macro. @@ -3433,14 +3547,14 @@ 1995-06-28 Richard Stallman <rms@mole.gnu.ai.mit.edu> * emacsserver.c: Make all error messages start with `Error: '. - (fatal_error, perror_1): New functions, use throughout. + (fatal_error, perror_1): New functions, use throughout. 1995-06-28 Paul Eggert <eggert@twinsun.com> * rcs2log (CVSROOT, repository): Allow remote repositories a la CVS 1.4. -1995-06-27 Francesco Potorti` (pot@cnuce.cnr.it) +1995-06-27 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (plain_C_entries): new function. (lowcase): new macro. @@ -3458,7 +3572,7 @@ * make-docfile.c (scan_file): Make sure it never looks at filename[-1]. -1995-06-21 Francesco Potorti` (pot@cnuce.cnr.it) +1995-06-21 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (find_entries): Rewind before rereading the input file. @@ -3490,7 +3604,7 @@ * rcs2log (output_authors): Allow ':' in time zone, as per ISO 8601 and RCS 5.6.8 beta. -1995-05-29 Francesco Potorti` (pot@cnuce.cnr.it) +1995-05-29 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (etags_getcwd): Undo the /bin/pwd change. It may raise compatibility problems. @@ -3513,7 +3627,7 @@ (make-docfile.obj): Depend upon config.h. Clean up comments. -1995-05-23 Francesco Potorti` (pot@cnuce.cnr.it) +1995-05-23 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (etags_getcwd): Use /bin/pwd instead of pwd because the former gives the true path even in the presence of simlinks. @@ -3623,12 +3737,12 @@ even if HAVE_SYSVIPC. * emacsclient.c (main): Use getcwd if not BSD. -1995-03-13 Francesco Potorti` (pot@cnuce.cnr.it) +1995-03-13 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (process_file): free (filename) after using it. (readline_internal): Do not access the char before start of line. -1995-02-22 Francesco Potorti` (pot@cnuce.cnr.it) +1995-02-22 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (C_entries): token_saved removed. Initialise tok.valid and savetok.valid. Mark token as valid when it is initialised. @@ -3636,12 +3750,12 @@ (CNL_SAVE_DEFINEDEF): Test for savetok.valid instead of token_saved. (TOKEN): Added a new member: valid. -1995-02-15 Francesco Potorti` (pot@cnuce.cnr.it) +1995-02-15 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (C_entries): Bug corrected in xrealloc of token_str. (main): Do not read twice the last filename in the stdin file list. -1995-02-14 Francesco Potorti` (pot@cnuce.cnr.it) +1995-02-14 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (C_entries): Initialise the new members of TOKEN. (C_entries): Do not allocate a new space for each token found by @@ -3658,18 +3772,18 @@ * Makefile.in.in (maintainer-clean): Renamed from realclean. -1995-02-01 Francesco Potorti` (pot@cnuce.cnr.it) +1995-02-01 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (pfnote): Initialise been_warned in the node. (C_entries): Removed a speed hack for the sake of clarity. -1995-01-18 Francesco Potorti` (pot@cnuce.cnr.it) +1995-01-18 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (longopts, print_help, main): Use -I as abbreviation for the --ignore-indentation option. (main): Do not print an error message for unknown options. -1995-01-12 Francesco Potorti` (pot@cnuce.cnr.it) +1995-01-12 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (FILEPOS, GET_CHARNO, GET_FILEPOS, max, LINENO): Deleted. (append_to_tagfile, typedefs, typedefs_and_cplusplus, @@ -3701,13 +3815,13 @@ * movemail.c (main): Skip past the colon in inname. -1995-01-10 Francesco Potorti` (pot@cnuce.cnr.it) +1995-01-10 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (pfatal): New function. (main, etags_getcwd): Use pfatal. (etags_getcwd): Corrected another bug in the HAVE_GETCWD version. -1995-01-10 Francesco Potorti` (pot@cnuce.cnr.it) +1995-01-10 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (Lang_function): Use void instead to declare the language functions, because many compilers are buggy. @@ -3715,7 +3829,7 @@ (readline_internal): Discard possible \r before \n here. (C_entries): Do not deal with \r here: undo previous fix. -1995-01-09 Francesco Potorti` (pot@fly) +1995-01-09 Francesco Potort,Al(B (pot@fly) * b2m.c (concat, xmalloc, xrealloc, readline, xnew): Four new functions and a macro that allow the program to work on input @@ -3756,12 +3870,12 @@ * emacsclient.c [!HAVE_SYSVIPC] (main): Fix error message diction. -1994-11-22 Francesco Potorti` (pot@cnuce.cnr.it) +1994-11-22 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (print_help): print --regex usage for ctags also. (main): use -h in addition to -H as abbreviation for --help. -1994-11-16 Francesco Potorti` (pot@cnuce.cnr.it) +1994-11-16 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c [ETAGS_REGEXP]: All the new code that deals with regexps is compiled if this is defined. The new functions and variables @@ -3790,7 +3904,7 @@ (prolog_getit, skip_comment): Rewritten for speed. (readline): Rewritten to deal with regexps. -1994-11-16 Francesco Potorti` (pot@cnuce.cnr.it) +1994-11-16 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (<errno.h>): #include added. (etags_getcwd): Check return value from getcwd. @@ -3822,7 +3936,7 @@ to grow the input buffer, take into account the null that's stored at the end of already-read input in the buffer. -1994-10-21 Francesco Potorti` (pot@cnuce.cnr.it) +1994-10-21 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (prestr, substr): return a logical type. (consider_token): Comment out "EXFUN". Use "DEFUN" instead of "DEF". @@ -3845,7 +3959,7 @@ 1994-10-19 David J. MacKenzie <djm@duality.gnu.ai.mit.edu> * rcs-checkin: Use test -r instead of < to check readability, to - avoid syntax error. + avoid syntax error. 1994-10-19 Jonathan I. Kamens (jik@cam.ov.com) @@ -3907,7 +4021,7 @@ * Makefile.in.in (regex.o): Use full path to find regex.c. -1994-10-17 Francesco Potorti` (pot@fly.cnuce.cnr.it) +1994-10-17 Francesco Potort,Al(B (pot@fly.cnuce.cnr.it) * Makefile.in.in (etags): add dependency on regex.o, link with it. (REGEXPOBJ, REGEXPDEPS, regex.o): target and macros added. @@ -3934,7 +4048,7 @@ * Makefile.in.in (libexecdir): Renamed from libdir. -1994-10-11 Francesco Potorti` (pot@cnuce.cnr.it) +1994-10-11 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (C_entries): Name the #define's that are macros. @@ -3943,7 +4057,7 @@ * emacsserver.c [! SYSVIPC] (main): Fix uses of FD_* macros: fd_set arg is a pointer, descriptor arg comes first. -1994-09-29 Francesco Potorti` (pot@cnuce.cnr.it) +1994-09-29 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (C_entries): Recognise typedef of ANSI style functions. (C_entries): Recognise #define inside a struct. @@ -4060,12 +4174,12 @@ 1994-07-08 Dave Love (d.love@dl.ac.uk) - * etags.c (takeprec): recognise `character*(*) function' - -1994-07-08 Francesco Potorti` (pot@cnuce.cnr.it) - - * etags.c (main): Don't barf on obsolete -t and -T switches. - (main): Print an explicative message when a switch is not known. + * etags.c (takeprec): recognise `character*(*) function' + +1994-07-08 Francesco Potort,Al(B (pot@cnuce.cnr.it) + + * etags.c (main): Don't barf on obsolete -t and -T switches. + (main): Print an explicative message when a switch is not known. 1994-06-23 Richard Stallman (rms@mole.gnu.ai.mit.edu) @@ -4078,12 +4192,12 @@ * Makefile.in.in (test-distrib): Use ALL_CFLAGS. -1994-06-03 Francesco Potorti` (pot@fly.cnuce.cnr.it) +1994-06-03 Francesco Potort,Al(B (pot@fly.cnuce.cnr.it) * etags.c (absolute_filename): Remove infinite loop bug when accessing files in directories whose name begins with a dot. -1994-06-03 Francesco Potorti` (pot@fly.cnuce.cnr.it) +1994-06-03 Francesco Potort,Al(B (pot@fly.cnuce.cnr.it) * etags.c (etags_getcwd): Delete the trailing newline from cwd. @@ -4206,11 +4320,11 @@ * fakemail.c (readline): When extending the buffer, calculate end afresh using the new size. -1994-04-18 Francesco Potorti` (pot@fly.cnuce.cnr.it) +1994-04-18 Francesco Potort,Al(B (pot@fly.cnuce.cnr.it) * etags.c (main, print_help): eliminate the -F option. -1994-04-18 Francesco Potorti` (pot@fly.cnuce.cnr.it) +1994-04-18 Francesco Potort,Al(B (pot@fly.cnuce.cnr.it) * etags.c (absolute_filename): compare against '\0' instead of NULL. @@ -4227,7 +4341,7 @@ * movemail.c [HAVE_UNISTD_H]: Include unistd.h. -1994-04-12 Francesco Potorti` (pot@fly.cnuce.cnr.it) +1994-04-12 Francesco Potort,Al(B (pot@fly.cnuce.cnr.it) * etags.c (etags_getcwd): Initialize bufsize. @@ -4244,7 +4358,7 @@ * etags.c: #undef static. -1994-04-08 Francesco Potorti` (pot@fly.cnuce.cnr.it) +1994-04-08 Francesco Potort,Al(B (pot@fly.cnuce.cnr.it) * etags.c (outf, outfiledir): renamed to tagf, tagfiledir. (PF_funcs, Asm_funcs, L_funcs, PAS_funcs, TEX_funcs, @@ -4257,7 +4371,7 @@ (find_entries): added more suffixes for assembler files. (Asm_funcs): Now finds labels even without an ending colon. -1994-03-30 Francesco Potorti` (pot@fly.cnuce.cnr.it) +1994-03-30 Francesco Potort,Al(B (pot@fly.cnuce.cnr.it) * etags.c (main): use etags_getcwd for compatibility. (etags_getcwd): new function. @@ -4266,7 +4380,7 @@ * Makefile.in (etags, ctags): Pass -D for VERSION. -1994-03-25 Francesco Potorti` (pot@cnuce.cnr.it) +1994-03-25 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (emacs_tags_format, ETAGS): removed. Use CTAGS instead. (main): don't allow the use of -t and -T in etags mode. @@ -4274,7 +4388,7 @@ (print_version): show the emacs version number if VERSION is #defined. (find_entries): add "ss" as suffix for Chez Scheme. -1994-03-23 Francesco Potorti` (pot@cnuce.cnr.it) +1994-03-23 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (cwd, outfiledir): vars added. (relative_filename, absolute_filename, absolute_dirname): @@ -4296,7 +4410,7 @@ * Makefile.in (install, ${archlibdir}): Switch back to .. before running INSTALL_PROGRAM. -1994-03-14 Francesco Potorti` (pot@cnuce.cnr.it) +1994-03-14 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (TYPEDST): added the `tignore' value. (C_entries): corrected various bugs, now correctly parses the @@ -4342,7 +4456,7 @@ * profile.c (get_time): Simplify; avoid calling index. (main): exit on EOF. -1994-02-17 Francesco Potorti` (pot@cnuce.cnr.it) +1994-02-17 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (--absolute-pathnames): Option removed. @@ -4350,7 +4464,7 @@ * fakemail.c (put_line): Don't break the line if it all fits. -1994-02-14 Francesco Potorti` (pot@fly) +1994-02-14 Francesco Potort,Al(B (pot@fly) * etags.c (absolute_pathnames, cwd): added global vars. (longopts, print_help, main, process_file): put absolute filenames @@ -4382,7 +4496,7 @@ look like lisp call prototypes: (function ARG1 ARG2), upcasing args. (scan_c_file): Pass BUF to write_c_args for FUNC arg. -1994-01-14 Francesco Potorti` (pot@cnuce.cnr.it) +1994-01-14 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (stab_entry, stab_create, stab_find, stab_search, stab_type, add_keyword, C_reate_stab, C_create_stabs): deleted. @@ -4526,7 +4640,7 @@ 1993-11-08 Tom Hageman (tom@basil.icce.rug.nl) - * etags.c: (C_entries): Keep track of ()-parenthesis level so that + * etags.c (C_entries): Keep track of ()-parenthesis level so that functions returning a pointer to a function, a la `signal', can be parsed. This also required new state `fstartlist' to `FUNCST'. (SAVE_TOKEN, RESTORE_TOKEN, TOKEN_SAVED_P): 1-deep token save stack. @@ -4534,7 +4648,7 @@ from the other state engines. (begtk): add '~', for C++ class destructors. -1993-11-02 Francesco Potorti` (pot@cnuce.cnr.it) +1993-11-02 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (consider_token): removed unused variable firsttok. (prolog_getit): call pfnote with the right number of arguments. @@ -4554,7 +4668,7 @@ * Makefile.in: Fixed typos or brainos of whoever thought `@' was the comment character. -1993-10-01 Francesco Potorti` (pot@cnuce.cnr.it) +1993-10-01 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (process_file): dead code removed. (S_ISREG): #define it using S_IFREG if not defined. @@ -4585,7 +4699,7 @@ By default, look for *,v files as well as RCS/*,v files. Use $TMPDIR (default /tmp) instead of /tmp. -1993-09-20 Francesco Potorti` (pot@fly) +1993-09-20 Francesco Potort,Al(B (pot@fly) * etags.c (C_entries): is_func is initialised here instead of in consider_token for the sake of the yacc rules section. @@ -4639,7 +4753,7 @@ * Version 19.18 released. -1993-08-04 Francesco Potorti` (pot@spiff.gnu.ai.mit.edu) +1993-08-04 Francesco Potort,Al(B (pot@spiff.gnu.ai.mit.edu) * etags.c (L_isdef, L_isquote, L_getit): small optimisations. (L_funcs): the (foo::defmumble stuff now should work. @@ -4655,9 +4769,9 @@ * timer.c (main): Generate a SIGIO as soon as we've initialized. -1993-07-30 Francesco Potorti` (pot@cnuce.cnr.it) - - * etags.c (FINCST): added the fignore status. Means we are +1993-07-30 Francesco Potort,Al(B (pot@cnuce.cnr.it) + + * etags.c (FINCST): Added the fignore status. Means we are after the parameter list and before the open curly brace. Allows correct parsing of C++ constructors. (C_entries, consider_token): make use of fignore. @@ -4683,7 +4797,7 @@ 1993-07-18 Richard Stallman (rms@mole.gnu.ai.mit.edu) - * Version 19.17 released. + * Version 19.17 released. 1993-07-15 Jim Blandy (jimb@totoro.cs.oberlin.edu) @@ -4694,14 +4808,14 @@ * wakeup.c: Use CPP tangle from autoconf manual to #include the correct combination of <time.h> and <sys/time.h>. -1993-07-08 Francesco Potorti` (pot@cnuce.cnr.it) +1993-07-08 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (alloca): removed all references to it. (main): now calls xnew instead of alloca for portability. (../src/config.h): included only if HAVE_CONFIG_H. (const): void definition removed--config.h takes care of it. -1993-07-08 Francesco Potorti` (pot@cnuce.cnr.it) +1993-07-08 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (consider_token): was `==', now is `='. (consider_token): DEFUNs now treated like funcs in ctags mode. @@ -4748,7 +4862,7 @@ 1993-06-16 Jim Blandy (jimb@wookumz.gnu.ai.mit.edu) - Bring mumbleclean targets into conformance with GNU coding standards. + Bring mumbleclean targets into conformance with GNU coding standards. * Makefile.in (distclean): Call clean to do most of the work. Delete aixcc.c and TAGS. (realclean): Just call distclean. @@ -4805,7 +4919,7 @@ 1993-05-30 Jim Blandy (jimb@wookumz.gnu.ai.mit.edu) - * Makefile.in: (${archlibdir}): Use `(cd foo && pwd)' instead of + * Makefile.in (${archlibdir}): Use `(cd foo && pwd)' instead of `(cd foo ; pwd)' to get the canonical name of a directory; cd might fail, and have pwd print out the current directory. @@ -4891,7 +5005,7 @@ 1993-05-22 Jim Blandy (jimb@geech.gnu.ai.mit.edu) - * Version 19.7 released. + * Version 19.7 released. 1993-05-22 Richard Stallman (rms@mole.gnu.ai.mit.edu) @@ -4983,7 +5097,7 @@ (CFLAGS): Include C_SWITCH_SYSTEM in the flags to pass to the compiler. -1993-03-22 Francesco Potorti` (pot@cnuce.cnr.it) +1993-03-22 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (YACC): flag added to c_ext. (c_ext): no more a synonim for c_ext&C_PLPL because of YACC. @@ -4994,13 +5108,13 @@ (C_entries): logical yacc_rules means we are after the first %%. (C_entries): added logic for yacc files. -1993-03-16 Francesco Potorti` (pot@cnuce.cnr.it) +1993-03-16 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (C_entries): ':' case moved to the second switch. (C_entries): do not examine token if structdef==scolonseen. (consider_token): structtag set to null string for enum. -1993-03-12 Francesco Potorti` (pot@cnuce.cnr.it) +1993-03-12 Francesco Potort,Al(B (pot@cnuce.cnr.it) * etags.c (GET_COOKIE): and related macros removed. (logical): is now int, no more a char. @@ -5018,19 +5132,19 @@ (condider_token): complete rewrite. (getline): deleted. -1993-03-01 Francesco Potorti` (pot@fly.CNUCE.CNR.IT) +1993-03-01 Francesco Potort,Al(B (pot@fly.CNUCE.CNR.IT) * etags.c (C_entries): Added the quotednl logical variable. Used for parsing of #define's spanning multiple lines. -1993-02-23 Francesco Potorti` (pot@fly.CNUCE.CNR.IT) +1993-02-23 Francesco Potort,Al(B (pot@fly.CNUCE.CNR.IT) * etags.c (C_entries): Save the definedef status even when a newline is met inside a string. 1993-03-19 Eric S. Raymond (eric@geech.gnu.ai.mit.edu) - * Makefile.in (EXECUTABLES): added rcs-checkin. + * Makefile.in (EXECUTABLES): added rcs-checkin. * Makefile.in (unlock, relock): New productions. @@ -5054,7 +5168,7 @@ * b2m.c (main): Don't exit upon reading a blank line. -1993-03-01 Francesco Potorti` (pot@fly.CNUCE.CNR.IT) +1993-03-01 Francesco Potort,Al(B (pot@fly.CNUCE.CNR.IT) * etags.c (C_entries): New local variable quotednl. Used for parsing of #define's spanning multiple lines. @@ -5066,7 +5180,7 @@ * timer.c (notify): Initialize waitfor properly. -1993-02-22 Francesco Potorti` (pot@CNUCE.CNR.IT) +1993-02-22 Francesco Potort,Al(B (pot@CNUCE.CNR.IT) * etags.c (C_entries): Don't reset definedef when a newline inside a comment is met. @@ -5395,7 +5509,7 @@ 1992-03-31 Jim Blandy (jimb@pogo.cs.oberlin.edu) - * lib-src/Makefile, etc/MACHINES, etc/NEWS: Changed references to + * lib-src/Makefile, etc/MACHINES, etc/NEWS: Changed references to `config.emacs' to `configure'. * lib-src/Makefile: Adjusted for renaming of share-lib to etc. @@ -5562,7 +5676,7 @@ 1990-08-30 David Lawrence (tale@pogo.ai.mit.edu) - * emacs.1: Add break before -nw option. + * emacs.1: Add break before -nw option. 1990-08-19 David J. MacKenzie (djm@apple-gunkies) @@ -5769,8 +5883,8 @@ 1988-12-31 Richard Mlynarik (mly@rice-chex.ai.mit.edu) - * env.c: Add decl for my-index - * etags.c (file-entries): .oak => scheme + * env.c: Add decl for my-index + * etags.c (file-entries): .oak => scheme 1988-12-30 Richard Stallman (rms@sugar-bombs.ai.mit.edu) @@ -5814,8 +5928,8 @@ 1988-11-29 Richard Mlynarik (mly@pickled-brain.ai.mit.edu) - * movemail.c: Better error message when can't create tempname. - This file needs a great deal of extra error-checking and lucid reporting... + * movemail.c: Better error message when can't create tempname. + This file needs a great deal of extra error-checking and lucid reporting... 1988-11-16 Richard Stallman (rms@sugar-bombs.ai.mit.edu)
--- a/lib-src/Makefile.in Tue Nov 07 02:37:49 2006 +0000 +++ b/lib-src/Makefile.in Tue Nov 07 23:22:48 2006 +0000 @@ -94,6 +94,7 @@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ # By default, we uphold the dignity of our programs. INSTALL_STRIP = @@ -319,7 +320,7 @@ if [ `(cd $(DESTDIR)${archlibdir} && /bin/pwd)` \ != `(cd ${srcdir} && /bin/pwd)` ]; then \ for file in ${SCRIPTS}; do \ - $(INSTALL_PROGRAM) ${srcdir}/$$file $(DESTDIR)${archlibdir}/$$file; \ + $(INSTALL_SCRIPT) ${srcdir}/$$file $(DESTDIR)${archlibdir}/$$file; \ done ; \ fi @@ -331,7 +332,7 @@ chmod a+rx $(DESTDIR)${bindir}/`echo $${file} | sed '$(TRANSFORM)'`; \ done for file in ${INSTALLABLE_SCRIPTS} ; do \ - $(INSTALL_PROGRAM) ${srcdir}/$${file} $(DESTDIR)${bindir}/`echo $${file} | sed '$(TRANSFORM)'` ; \ + $(INSTALL_SCRIPT) ${srcdir}/$${file} $(DESTDIR)${bindir}/`echo $${file} | sed '$(TRANSFORM)'` ; \ chmod a+rx $(DESTDIR)${bindir}/`echo $${file} | sed '$(TRANSFORM)'`; \ done
--- a/lib-src/emacsclient.c Tue Nov 07 02:37:49 2006 +0000 +++ b/lib-src/emacsclient.c Tue Nov 07 23:22:48 2006 +0000 @@ -26,19 +26,49 @@ #include <config.h> #endif +#ifdef WINDOWSNT + +# include <malloc.h> +# include <stdlib.h> + +# define HAVE_SOCKETS +# define HAVE_INET_SOCKETS +# define NO_SOCKETS_IN_FILE_SYSTEM + +# define HSOCKET SOCKET +# define CLOSE_SOCKET closesocket +# define INITIALIZE() (initialize_sockets ()) + +#else /* !WINDOWSNT */ + +# ifdef HAVE_INET_SOCKETS +# include <netinet/in.h> +# endif + +# define INVALID_SOCKET -1 +# define HSOCKET int +# define CLOSE_SOCKET close +# define INITIALIZE() + +#endif /* !WINDOWSNT */ + #undef signal #include <ctype.h> #include <stdio.h> -#include <getopt.h> +#include "getopt.h" #ifdef HAVE_UNISTD_H #include <unistd.h> #endif #ifdef VMS # include "vms-pwd.h" -#else +#else /* not VMS */ +#ifdef WINDOWSNT +# include <io.h> +#else /* not WINDOWSNT */ # include <pwd.h> +#endif /* not WINDOWSNT */ #endif /* not VMS */ char *getenv (), *getwd (); @@ -48,6 +78,29 @@ #define VERSION "unspecified" #endif +#define SEND_STRING(data) (send_to_emacs (s, (data))) +#define SEND_QUOTED(data) (quote_file_name (s, (data))) + +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif + +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef NO_RETURN +#define NO_RETURN +#endif + /* Name used to invoke this program. */ char *progname; @@ -62,11 +115,14 @@ /* If non-NULL, the name of an editor to fallback to if the server is not running. --alternate-editor. */ -const char * alternate_editor = NULL; +const char *alternate_editor = NULL; /* If non-NULL, the filename of the UNIX socket. */ char *socket_name = NULL; +/* If non-NULL, the filename of the authentication file. */ +char *server_file = NULL; + void print_help_and_exit () NO_RETURN; struct option longopts[] = @@ -76,7 +132,10 @@ { "help", no_argument, NULL, 'H' }, { "version", no_argument, NULL, 'V' }, { "alternate-editor", required_argument, NULL, 'a' }, +#ifndef NO_SOCKETS_IN_FILE_SYSTEM { "socket-name", required_argument, NULL, 's' }, +#endif + { "server-file", required_argument, NULL, 'f' }, { "display", required_argument, NULL, 'd' }, { 0, 0, 0, 0 } }; @@ -94,7 +153,12 @@ while (1) { int opt = getopt_long (argc, argv, - "VHnea:s:d:", longopts, 0); +#ifndef NO_SOCKETS_IN_FILE_SYSTEM + "VHnea:s:f:d:", +#else + "VHnea:f:d:", +#endif + longopts, 0); if (opt == EOF) break; @@ -110,9 +174,15 @@ alternate_editor = optarg; break; +#ifndef NO_SOCKETS_IN_FILE_SYSTEM case 's': socket_name = optarg; break; +#endif + + case 'f': + server_file = optarg; + break; case 'd': display = optarg; @@ -156,9 +226,13 @@ -H, --help Print this usage information message\n\ -n, --no-wait Don't wait for the server to return\n\ -e, --eval Evaluate the FILE arguments as ELisp expressions\n\ --d, --display=DISPLAY Visit the file in the given display\n\ --s, --socket-name=FILENAME\n\ - Set the filename of the UNIX socket for communication\n\ +-d, --display=DISPLAY Visit the file in the given display\n" +#ifndef NO_SOCKETS_IN_FILE_SYSTEM +"-s, --socket-name=FILENAME\n\ + Set the filename of the UNIX socket for communication\n" +#endif +"-f, --server-file=FILENAME\n\ + Set the filename of the TCP configuration file\n\ -a, --alternate-editor=EDITOR\n\ Editor to fallback to if the server is not running\n\ \n\ @@ -166,14 +240,112 @@ exit (EXIT_SUCCESS); } + +/* + Try to run a different command, or --if no alternate editor is + defined-- exit with an errorcode. +*/ +void +fail (argc, argv) + int argc; + char **argv; +{ + if (alternate_editor) + { + int i = optind - 1; +#ifdef WINDOWSNT + argv[i] = (char *)alternate_editor; +#endif + execvp (alternate_editor, argv + i); + fprintf (stderr, "%s: error executing alternate editor \"%s\"\n", + progname, alternate_editor); + } + exit (EXIT_FAILURE); +} + + +#if !defined (HAVE_SOCKETS) || !defined (HAVE_INET_SOCKETS) + +int +main (argc, argv) + int argc; + char **argv; +{ + fprintf (stderr, "%s: Sorry, the Emacs server is supported only\n", + argv[0]); + fprintf (stderr, "on systems with Berkeley sockets.\n"); + + fail (argc, argv); +} + +#else /* HAVE_SOCKETS && HAVE_INET_SOCKETS */ + +#ifdef WINDOWSNT +# include <winsock2.h> +#else +# include <sys/types.h> +# include <sys/socket.h> +# include <sys/un.h> +# include <sys/stat.h> +# include <errno.h> +#endif + +#define AUTH_KEY_LENGTH 64 +#define SEND_BUFFER_SIZE 4096 + +extern char *strerror (); +extern int errno; + +/* Buffer to accumulate data to send in TCP connections. */ +char send_buffer[SEND_BUFFER_SIZE + 1]; +int sblen = 0; /* Fill pointer for the send buffer. */ + +/* Let's send the data to Emacs when either + - the data ends in "\n", or + - the buffer is full (but this shouldn't happen) + Otherwise, we just accumulate it. */ +void +send_to_emacs (s, data) + HSOCKET s; + char *data; +{ + while (data) + { + int dlen = strlen (data); + if (dlen + sblen >= SEND_BUFFER_SIZE) + { + int part = SEND_BUFFER_SIZE - sblen; + strncpy (&send_buffer[sblen], data, part); + data += part; + sblen = SEND_BUFFER_SIZE; + } + else if (dlen) + { + strcpy (&send_buffer[sblen], data); + data = NULL; + sblen += dlen; + } + else + break; + + if (sblen == SEND_BUFFER_SIZE + || (sblen > 0 && send_buffer[sblen-1] == '\n')) + { + int sent = send (s, send_buffer, sblen, 0); + if (sent != sblen) + strcpy (send_buffer, &send_buffer[sent]); + sblen -= sent; + } + } +} + /* In NAME, insert a & before each &, each space, each newline, and any initial -. Change spaces to underscores, too, so that the return value never contains a space. */ - void -quote_file_name (name, stream) +quote_file_name (s, name) + HSOCKET s; char *name; - FILE *stream; { char *copy = (char *) malloc (strlen (name) * 2 + 1); char *p, *q; @@ -203,73 +375,202 @@ } *q++ = 0; - fprintf (stream, "%s", copy); + SEND_STRING (copy); free (copy); } -/* Like malloc but get fatal error if memory is exhausted. */ - -long * -xmalloc (size) - unsigned int size; +int +file_name_absolute_p (filename) + const unsigned char *filename; { - long *result = (long *) malloc (size); - if (result == NULL) - { - perror ("malloc"); - exit (EXIT_FAILURE); - } - return result; + /* Sanity check, it shouldn't happen. */ + if (! filename) return FALSE; + + /* /xxx is always an absolute path. */ + if (filename[0] == '/') return TRUE; + + /* Empty filenames (which shouldn't happen) are relative. */ + if (filename[0] == '\0') return FALSE; + +#ifdef WINDOWSNT + /* X:\xxx is always absolute; X:xxx is an error and will fail. */ + if (islower (tolower (filename[0])) + && filename[1] == ':' && filename[2] == '\\') + return TRUE; + + /* Both \xxx and \\xxx\yyy are absolute. */ + if (filename[0] == '\\') return TRUE; +#endif + + return FALSE; } + +#ifdef WINDOWSNT +/* Wrapper to make WSACleanup a cdecl, as required by atexit(). */ +void +__cdecl close_winsock () +{ + WSACleanup (); +} + +/* Initialize the WinSock2 library. */ +void +initialize_sockets () +{ + WSADATA wsaData; + + if (WSAStartup (MAKEWORD (2, 0), &wsaData)) + { + fprintf (stderr, "%s: error initializing WinSock2", progname); + exit (EXIT_FAILURE); + } + + atexit (close_winsock); +} +#endif /* WINDOWSNT */ /* - Try to run a different command, or --if no alternate editor is - defined-- exit with an errorcode. + * Read the information needed to set up a TCP comm channel with + * the Emacs server: host, port, pid and authentication string. */ -void -fail (argc, argv) - int argc; - char **argv; +int +get_server_config (server, authentication) + struct sockaddr_in *server; + char *authentication; { - if (alternate_editor) + char dotted[32]; + char *port; + char *pid; + FILE *config = NULL; + + if (file_name_absolute_p (server_file)) + config = fopen (server_file, "rb"); + else { - int i = optind - 1; - execvp (alternate_editor, argv + i); - return; + char *home = getenv ("HOME"); + + if (home) + { + char *path = alloca (32 + strlen (home) + strlen (server_file)); + sprintf (path, "%s/.emacs.d/server/%s", home, server_file); + config = fopen (path, "rb"); + } +#ifdef WINDOWSNT + if (!config && (home = getenv ("APPDATA"))) + { + char *path = alloca (32 + strlen (home) + strlen (server_file)); + sprintf (path, "%s/.emacs.d/server/%s", home, server_file); + config = fopen (path, "rb"); + } +#endif + } + + if (! config) + return FALSE; + + if (fgets (dotted, sizeof dotted, config) + && (port = strchr (dotted, ':')) + && (pid = strchr (port, ' '))) + { + *port++ = '\0'; + *pid++ = '\0'; } else { + fprintf (stderr, "%s: invalid configuration info", progname); + exit (EXIT_FAILURE); + } + + server->sin_family = AF_INET; + server->sin_addr.s_addr = inet_addr (dotted); + server->sin_port = htons (atoi (port)); + + if (! fread (authentication, AUTH_KEY_LENGTH, 1, config)) + { + fprintf (stderr, "%s: cannot read authentication info", progname); exit (EXIT_FAILURE); } + + fclose (config); + +#ifdef WINDOWSNT + /* + Modern Windows restrict which processes can set the foreground window. + So, for emacsclient to be able to force Emacs into the foreground, we + have to call AllowSetForegroundWindow(). Unfortunately, older Windows + (W95, W98 and NT) don't have this function, so we have to check first. + + We're doing this here because it has to be done before sending info + to Emacs, and otherwise we'll need a global variable just to pass around + the pid, which is also inelegant. + */ + { + HMODULE hUser32; + + if (hUser32 = LoadLibrary ("user32.dll")) + { + void (*set_fg)(DWORD); + if (set_fg = GetProcAddress (hUser32, "AllowSetForegroundWindow")) + set_fg (atoi (pid)); + FreeLibrary (hUser32); + } + } +#endif + + return TRUE; } +HSOCKET +set_tcp_socket () +{ + HSOCKET s; + struct sockaddr_in server; + struct linger l_arg = {1, 1}; + char auth_string[AUTH_KEY_LENGTH + 1]; - -#if !defined (HAVE_SOCKETS) || defined (NO_SOCKETS_IN_FILE_SYSTEM) + if (! get_server_config (&server, auth_string)) + return INVALID_SOCKET; + + if (server.sin_addr.s_addr != inet_addr ("127.0.0.1")) + fprintf (stderr, "%s: connected to remote socket at %s\n", + progname, inet_ntoa (server.sin_addr)); -int -main (argc, argv) - int argc; - char **argv; -{ - fprintf (stderr, "%s: Sorry, the Emacs server is supported only\n", - argv[0]); - fprintf (stderr, "on systems with Berkeley sockets.\n"); + /* + * Open up an AF_INET socket + */ + if ((s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) + { + fprintf (stderr, "%s: ", progname); + perror ("socket"); + return INVALID_SOCKET; + } - fail (argc, argv); + /* + * Set up the socket + */ + if (connect (s, (struct sockaddr *) &server, sizeof server) < 0) + { + fprintf (stderr, "%s: ", progname); + perror ("connect"); + return INVALID_SOCKET; + } + + setsockopt (s, SOL_SOCKET, SO_LINGER, (char *) &l_arg, sizeof l_arg); + + /* + * Send the authentication + */ + auth_string[AUTH_KEY_LENGTH] = '\0'; + + SEND_STRING ("-auth "); + SEND_STRING (auth_string); + SEND_STRING ("\n"); + + return s; } -#else /* HAVE_SOCKETS */ - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <sys/stat.h> -#include <errno.h> - -extern char *strerror (); -extern int errno; +#if !defined (NO_SOCKETS_IN_FILE_SYSTEM) /* Three possibilities: 2 - can't be `stat'ed (sets errno) @@ -291,28 +592,11 @@ return 0; } -int -main (argc, argv) - int argc; - char **argv; +HSOCKET +set_local_socket () { - int s, i, needlf = 0; - FILE *out, *in; + HSOCKET s; struct sockaddr_un server; - char *cwd, *str; - char string[BUFSIZ]; - - progname = argv[0]; - - /* Process options. */ - decode_options (argc, argv); - - if ((argc - optind < 1) && !eval) - { - fprintf (stderr, "%s: file name or argument required\n", progname); - fprintf (stderr, "Try `%s --help' for more information\n", progname); - exit (EXIT_FAILURE); - } /* * Open up an AF_UNIX socket in this person's home directory @@ -320,9 +604,9 @@ if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) { - fprintf (stderr, "%s: ", argv[0]); + fprintf (stderr, "%s: ", progname); perror ("socket"); - fail (argc, argv); + return INVALID_SOCKET; } server.sun_family = AF_UNIX; @@ -352,7 +636,7 @@ else { fprintf (stderr, "%s: socket-name %s too long", - argv[0], socket_name); + progname, socket_name); exit (EXIT_FAILURE); } @@ -387,7 +671,7 @@ else { fprintf (stderr, "%s: socket-name %s too long", - argv[0], socket_name); + progname, socket_name); exit (EXIT_FAILURE); } @@ -399,60 +683,128 @@ } } - switch (sock_status) - { - case 1: - /* There's a socket, but it isn't owned by us. This is OK if - we are root. */ - if (0 != geteuid ()) - { - fprintf (stderr, "%s: Invalid socket owner\n", argv[0]); - fail (argc, argv); - } - break; + switch (sock_status) + { + case 1: + /* There's a socket, but it isn't owned by us. This is OK if + we are root. */ + if (0 != geteuid ()) + { + fprintf (stderr, "%s: Invalid socket owner\n", progname); + return INVALID_SOCKET; + } + break; - case 2: - /* `stat' failed */ - if (saved_errno == ENOENT) - fprintf (stderr, - "%s: can't find socket; have you started the server?\n\ + case 2: + /* `stat' failed */ + if (saved_errno == ENOENT) + fprintf (stderr, + "%s: can't find socket; have you started the server?\n\ To start the server in Emacs, type \"M-x server-start\".\n", - argv[0]); - else - fprintf (stderr, "%s: can't stat %s: %s\n", - argv[0], server.sun_path, strerror (saved_errno)); - fail (argc, argv); - break; - } + progname); + else + fprintf (stderr, "%s: can't stat %s: %s\n", + progname, server.sun_path, strerror (saved_errno)); + return INVALID_SOCKET; + } } if (connect (s, (struct sockaddr *) &server, strlen (server.sun_path) + 2) < 0) { - fprintf (stderr, "%s: ", argv[0]); + fprintf (stderr, "%s: ", progname); perror ("connect"); - fail (argc, argv); + return INVALID_SOCKET; + } + + return s; +} +#endif /* ! NO_SOCKETS_IN_FILE_SYSTEM */ + +HSOCKET +set_socket () +{ + HSOCKET s; + + INITIALIZE (); + +#ifndef NO_SOCKETS_IN_FILE_SYSTEM + /* Explicit --socket-name argument. */ + if (socket_name) + { + s = set_local_socket (); + if ((s != INVALID_SOCKET) || alternate_editor) + return s; + + fprintf (stderr, "%s: error accessing socket \"%s\"", + progname, socket_name); + exit (EXIT_FAILURE); + } +#endif + + /* Explicit --server-file arg or EMACS_SERVER_FILE variable. */ + if (!server_file) + server_file = getenv ("EMACS_SERVER_FILE"); + + if (server_file) + { + s = set_tcp_socket (); + if ((s != INVALID_SOCKET) || alternate_editor) + return s; + + fprintf (stderr, "%s: error accessing server file \"%s\"", + progname, server_file); + exit (EXIT_FAILURE); } - /* We use the stream OUT to send our command to the server. */ - if ((out = fdopen (s, "r+")) == NULL) +#ifndef NO_SOCKETS_IN_FILE_SYSTEM + /* Implicit local socket. */ + s = set_local_socket (); + if (s != INVALID_SOCKET) + return s; +#endif + + /* Implicit server file. */ + server_file = "server"; + s = set_tcp_socket (); + if ((s != INVALID_SOCKET) || alternate_editor) + return s; + + /* No implicit or explicit socket, and no alternate editor. */ + fprintf (stderr, "%s: No socket or alternate editor. Please use:\n\n" +#ifndef NO_SOCKETS_IN_FILE_SYSTEM +"\t--socket-name\n" +#endif +"\t--server-file (or environment variable EMACS_SERVER_FILE)\n\ +\t--alternate-editor (or environment variable ALTERNATE_EDITOR)\n", + progname); + exit (EXIT_FAILURE); +} + +int +main (argc, argv) + int argc; + char **argv; +{ + HSOCKET s; + int i, rl, needlf = 0; + char *cwd; + char string[BUFSIZ+1]; + + progname = argv[0]; + + /* Process options. */ + decode_options (argc, argv); + + if ((argc - optind < 1) && !eval) { - fprintf (stderr, "%s: ", argv[0]); - perror ("fdopen"); - fail (argc, argv); + fprintf (stderr, "%s: file name or argument required\n", progname); + fprintf (stderr, "Try `%s --help' for more information\n", progname); + exit (EXIT_FAILURE); } - /* We use the stream IN to read the response. - We used to use just one stream for both output and input - on the socket, but reversing direction works nonportably: - on some systems, the output appears as the first input; - on other systems it does not. */ - if ((in = fdopen (s, "r+")) == NULL) - { - fprintf (stderr, "%s: ", argv[0]); - perror ("fdopen"); - fail (argc, argv); - } + if ((s = set_socket ()) == INVALID_SOCKET) + fail (argc, argv); #ifdef HAVE_GETCWD cwd = getcwd (string, sizeof string); @@ -462,27 +814,26 @@ if (cwd == 0) { /* getwd puts message in STRING if it fails. */ - #ifdef HAVE_GETCWD - fprintf (stderr, "%s: %s (%s)\n", argv[0], + fprintf (stderr, "%s: %s (%s)\n", progname, "Cannot get current working directory", strerror (errno)); #else - fprintf (stderr, "%s: %s (%s)\n", argv[0], string, strerror (errno)); + fprintf (stderr, "%s: %s (%s)\n", progname, string, strerror (errno)); #endif fail (argc, argv); } if (nowait) - fprintf (out, "-nowait "); + SEND_STRING ("-nowait "); if (eval) - fprintf (out, "-eval "); + SEND_STRING ("-eval "); if (display) { - fprintf (out, "-display "); - quote_file_name (display, out); - fprintf (out, " "); + SEND_STRING ("-display "); + SEND_QUOTED (display); + SEND_STRING (" "); } if ((argc - optind > 0)) @@ -497,61 +848,62 @@ while (isdigit ((unsigned char) *p) || *p == ':') p++; if (*p != 0) { - quote_file_name (cwd, out); - fprintf (out, "/"); + SEND_QUOTED (cwd); + SEND_STRING ("/"); } } - else if (*argv[i] != '/') + else if (! file_name_absolute_p (argv[i])) { - quote_file_name (cwd, out); - fprintf (out, "/"); + SEND_QUOTED (cwd); + SEND_STRING ("/"); } - quote_file_name (argv[i], out); - fprintf (out, " "); + SEND_QUOTED (argv[i]); + SEND_STRING (" "); } } else { - while ((str = fgets (string, BUFSIZ, stdin))) + while (fgets (string, BUFSIZ, stdin)) { - quote_file_name (str, out); + SEND_QUOTED (string); } - fprintf (out, " "); + SEND_STRING (" "); } - fprintf (out, "\n"); - fflush (out); + SEND_STRING ("\n"); /* Maybe wait for an answer. */ - if (nowait) - return EXIT_SUCCESS; - - if (!eval) + if (!nowait) { - printf ("Waiting for Emacs..."); - needlf = 2; - } - fflush (stdout); + if (!eval) + { + printf ("Waiting for Emacs..."); + needlf = 2; + } + fflush (stdout); - /* Now, wait for an answer and print any messages. */ - while ((str = fgets (string, BUFSIZ, in))) - { - if (needlf == 2) - printf ("\n"); - printf ("%s", str); - needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n'; + /* Now, wait for an answer and print any messages. */ + while ((rl = recv (s, string, BUFSIZ, 0)) > 0) + { + string[rl] = '\0'; + if (needlf == 2) + printf ("\n"); + printf ("%s", string); + needlf = string[0] == '\0' ? needlf : string[strlen (string) - 1] != '\n'; + } + + if (needlf) + printf ("\n"); + fflush (stdout); } - if (needlf) - printf ("\n"); - fflush (stdout); - + CLOSE_SOCKET (s); return EXIT_SUCCESS; } -#endif /* HAVE_SOCKETS */ - +#endif /* HAVE_SOCKETS && HAVE_INET_SOCKETS */ + #ifndef HAVE_STRERROR char * strerror (errnum)
--- a/lib-src/grep-changelog Tue Nov 07 02:37:49 2006 +0000 +++ b/lib-src/grep-changelog Tue Nov 07 23:22:48 2006 +0000 @@ -36,22 +36,33 @@ @entries); use Getopt::Long; -my $result = GetOptions ("author=s" => \$author, - "text=s" => \$regexp, - "exclude=s" => \$exclude, - "from-date=s" => \$from_date, - "to-date=s" => \$to_date, - "rcs-log" => \$rcs_log, - "with-date" => \$with_date, - "reverse!" => \$reverse, - "version" => \$version, - "help" => \$help); + +my $result; + +if (@ARGV == 0) { + + # No arguments cannot posibly mean "show everything"!! + $result = 0; + +} else { -# If date options are specified, check that they have the format -# YYYY-MM-DD. + $result = GetOptions ("author=s" => \$author, + "text=s" => \$regexp, + "exclude=s" => \$exclude, + "from-date=s" => \$from_date, + "to-date=s" => \$to_date, + "rcs-log" => \$rcs_log, + "with-date" => \$with_date, + "reverse!" => \$reverse, + "version" => \$version, + "help" => \$help); -$result = 0 if $from_date && $from_date !~ /^\d\d\d\d-\d\d-\d\d$/; -$result = 0 if $to_date && $to_date !~ /^\d\d\d\d-\d\d-\d\d$/; + # If date options are specified, check that they have the format + # YYYY-MM-DD. + + $result = 0 if $from_date && $from_date !~ /^\d\d\d\d-\d\d-\d\d$/; + $result = 0 if $to_date && $to_date !~ /^\d\d\d\d-\d\d-\d\d$/; +} # Print usage information and exit when necessary. @@ -77,7 +88,7 @@ --help Print this help If no CHANGELOG is specified scan the files "ChangeLog" and -"ChangeLog.1+" in the current directory. Old-style dates in ChangeLogs +"ChangeLog.N+" in the current directory. Old-style dates in ChangeLogs are not recognized. USAGE exit !$help; @@ -86,7 +97,7 @@ # Print version info and exit if `--version' was specified. if ($version) { - print "0.2\n"; + print "0.3\n"; exit 0; } @@ -233,7 +244,7 @@ # If files were specified on the command line, parse those files in the # order supplied by the user; otherwise parse default files ChangeLog and -# ChangeLog.1+ according to $reverse. +# ChangeLog.NNN according to $reverse. unless (@ARGV > 0) { @ARGV = ("ChangeLog");
--- a/lib-src/makefile.w32-in Tue Nov 07 02:37:49 2006 +0000 +++ b/lib-src/makefile.w32-in Tue Nov 07 23:22:48 2006 +0000 @@ -20,7 +20,7 @@ # Boston, MA 02110-1301, USA. # -ALL = make-docfile hexl ctags etags movemail ebrowse sorted-doc digest-doc +ALL = make-docfile hexl ctags etags movemail ebrowse sorted-doc digest-doc emacsclient .PHONY: $(ALL) @@ -32,7 +32,6 @@ # # $(BLD)/server.exe \ # $(BLD)/emacstool.exe \ -# $(BLD)/emacsclient.exe \ # $(BLD)/cvtmail.exe \ LIBS = $(BASE_LIBS) $(ADVAPI32) @@ -59,6 +58,7 @@ fakemail: $(BLD) $(BLD)/fakemail.exe sorted-doc: $(BLD) $(BLD)/sorted-doc.exe digest-doc: $(BLD) $(BLD)/digest-doc.exe +emacsclient: $(BLD) $(BLD)/emacsclient.exe test-distrib: $(BLD) $(BLD)/test-distrib.exe "$(BLD)/test-distrib.exe" "$(SRC)/testfile" @@ -74,6 +74,19 @@ # put wsock32.lib before $(LIBS) to ensure we don't link to ws2_32.lib $(LINK) $(LINK_OUT)$@ $(LINK_FLAGS) $(MOVEMAILOBJS) $(WSOCK32) $(LIBS) +ECLIENT_CFLAGS = -DWINDOWSNT -DHAVE_GETCWD -DHAVE_STRERROR -c +ECLIENTOBJS = $(BLD)/emacsclient.$(O) \ + $(BLD)/getopt.$(O) \ + $(BLD)/getopt1.$(O) \ + $(BLD)/ntlib.$(O) + +$(BLD)/emacsclient.exe: $(ECLIENTOBJS) +# put wsock32.lib before $(LIBS) to ensure we don't link to ws2_32.lib + $(LINK) $(LINK_OUT)$@ $(LINK_FLAGS) $(ECLIENTOBJS) $(WSOCK32) $(LIBS) + +$(BLD)/emacsclient.$(O): emacsclient.c + $(CC) $(ECLIENT_CFLAGS) $(CC_OUT)$@ emacsclient.c + ETAGSOBJ = $(BLD)/etags.$(O) \ $(BLD)/getopt.$(O) \ $(BLD)/getopt1.$(O) \ @@ -253,6 +266,15 @@ $(lispsource)window.elc \ $(lispsource)version.el +# This is needed the first time we build the tree, since temacs.exe +# does not exist yet, and the DOC rule needs it to rebuild DOC whenever +# Emacs is rebuilt. +../src/$(BLD)/temacs.exe: + - mkdir "../src/$(OBJDIR)" + - mkdir "../src/$(BLD)" + @echo temacs > temacs.exe + $(CP) temacs.exe ../src/$(BLD) + - $(DEL) temacs.exe DOC = DOC $(DOC): $(BLD) $(BLD)/make-docfile.exe ../src/$(BLD)/temacs.exe $(lisp1) $(lisp2) @@ -286,6 +308,7 @@ $(CP) $(BLD)/movemail.exe $(INSTALL_DIR)/bin $(CP) $(BLD)/sorted-doc.exe $(INSTALL_DIR)/bin $(CP) $(BLD)/digest-doc.exe $(INSTALL_DIR)/bin + $(CP) $(BLD)/emacsclient.exe $(INSTALL_DIR)/bin - mkdir "$(INSTALL_DIR)/etc" $(CP) $(DOC) $(INSTALL_DIR)/etc
--- a/lisp/ChangeLog Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/ChangeLog Tue Nov 07 23:22:48 2006 +0000 @@ -1,15 +1,439 @@ -2006-10-29 Stephen Leake <stephen_leake@stephe_leake.org> +2006-11-07 Chong Yidong <cyd@stupidchicken.com> + + * whitespace.el (whitespace-buffer): Call remove-overlays after + overlay-recenter for performance. Suggested by Martin Rudalics. + +2006-11-07 Michael Albinus <michael.albinus@gmx.de> + + * net/tramp.el (tramp-default-method): scp is the default method. + +2006-11-07 Juanma Barranquero <lekktu@gmail.com> + + * server.el (server-start): Save also the Emacs pid in the server file. + +2006-11-07 Carsten Dominik <dominik@science.uva.nl> + + * textmodes/reftex-cite.el (reftex-pop-to-bibtex-entry): Preserve + point when displaying a bibtex cross reference in the echo area. + +2006-11-06 Juanma Barranquero <lekktu@gmail.com> + + * international/mule.el (make-char): Fix typo in docstring. + (load-with-code-conversion, charsetp): Doc fixes. + + * international/ja-dic-cnv.el (skkdic-convert): + * cus-edit.el (hook): Fix typo in docstring. + +2006-11-06 Chong Yidong <cyd@stupidchicken.com> + + * cus-edit.el (custom-mode-map): Move defvar above code using it. + (custom-mode-link-map): New variable. + (custom-group-link, custom-manual): Use follow-link. + +2006-11-06 Roland Winkler <Roland.Winkler@physik.uni-erlangen.de> + + * textmodes/bibtex.el: Fix typo in name of author of bibtex.el, + "Mark Shapiro" -> "Marc Shapiro". Update his email address. + +2006-11-06 Richard Stallman <rms@gnu.org> + + * textmodes/flyspell.el (flyspell-correct-word-before-point): + New function broken out of flyspell-correct-word. + (flyspell-mode-map): Bind it to M-RET. + (flyspell-correct-word): Call it. + + * textmodes/fill.el (fill-minibuffer-function): New function. + (fill-paragraph): Bind fill-paragraph-function to + fill-minibuffer-function. + + * ruler-mode.el (ruler-mode-map): Add bindings for up-events + so that they aren't undefined. + + * dired.el (dired-readin): Locally bind file-name-coding-system. + + * bindings.el: Shorten and clarify usual mode line mouse help string. + + * Makefile.in (autoloads): Don't include `obsolete'. + +2006-11-06 Chong Yidong <cyd@stupidchicken.com> + + * printing.el (pr-alist-custom-set, pr-ps-utility-custom-set) + (pr-ps-name-custom-set, pr-txt-name-custom-set): Don't update the + Printing menu if it's not initialized. + (pr-menu-bind): Act on menu-bar-file-menu directly. + +2006-11-06 Juanma Barranquero <lekktu@gmail.com> + + * help.el (view-emacs-news): Fix typo in error message. + + * menu-bar.el (menu-bar-update-buffers): Fix typo in menu entry. + + * shadowfile.el (shadow-define-regexp-group) + (shadow-literal-groups, shadow-insert-var): Doc fixes. + (shadow-read-files): Fix typo in message. + (shadow-inhibit-overload, shadow-find, shadow-suffix) + (shadow-site-match, shadow-write-todo-file, shadow-insert-var) + (shadow-suffix, shadow-site-match, shadow-expand-file-name) + (shadow-file-match): Fix typos in docstrings. + + * terminal.el (terminal-emulator): Fix typo in message. + + * emacs-lisp/authors.el (authors-fixed-entries): Fix typo. + + * emacs-lisp/lselect.el (x-kill-primary-selection) + (x-delete-primary-selection, x-copy-primary-selection): + Fix typos in error messages. + + * emulation/edt-mapper.el: Fix typo in interactive message. + + * mail/emacsbug.el (report-emacs-bug): Fix typos in output message. + + * textmodes/ispell.el (ispell, ispell-local-dictionary-alist) + (ispell-help): Fix typos in docstrings. + (ispell-help): Fix typo in output message. + + * allout.el (allout-adjust-file-variable) + (allout-passphrase-verifier-string) + (allout-passphrase-hint-string) + (allout-toggle-current-subtree-encryption): + * apropos.el (apropos-synonyms): + * cus-edit.el (hook): + * emacs-lock.el (emacs-lock-from-exiting): + * follow.el (follow-avoid-tail-recenter-p): + * hexl.el (hexl-mode): + * mouse-copy.el (mouse-copy-work-around-drag-bug): + * mouse.el (mouse-set-font): + * resume.el (resume-emacs-args-file): + * rfn-eshadow.el (file-name-shadow-tty-properties): + * t-mouse.el (t-mouse-process, t-mouse-mode): + * emacs-lisp/cust-print.el (custom-print-install) + (custom-print-uninstall, custom-format): + * emacs-lisp/shadow.el (list-load-path-shadows): + * emulation/tpu-edt.el (tpu-help-text) + (tpu-save-all-buffers-kill-emacs, tpu-emacs-replace) + (tpu-reset-control-keys): + * emulation/vip.el (vip-emacs-local-map) + (vip-change-mode-to-emacs): + * emulation/viper.el (viper-mode, viper-set-hooks) + (viper-major-mode-modifier-list): + * emulation/viper-init.el (viper-emacs-state-cursor-color): + * emulation/viper-keym.el (viper-emacs-kbd-map) + (viper-toggle-key): + * mail/feedmail.el (feedmail-queue-reminder) + (feedmail-queue-reminder-alist, feedmail-confirm-outgoing) + (feedmail-confirm-outgoing-timeout, feedmail-nuke-bcc) + (feedmail-nuke-resent-bcc, feedmail-fill-to-cc-fill-column) + (feedmail-sender-line, feedmail-force-binary-write) + (feedmail-from-line, feedmail-deduce-envelope-from) + (feedmail-x-mailer-line, feedmail-message-id-generator) + (feedmail-date-generator, feedmail-fiddle-plex-user-list) + (feedmail-enable-spray, feedmail-spray-this-address) + (feedmail-spray-address-fiddle-plex-list, feedmail-enable-queue) + (feedmail-queue-runner-confirm-global) + (feedmail-ask-before-queue-prompt) + (feedmail-ask-before-queue-reprompt) + (feedmail-prompt-before-queue-standard-alist) + (feedmail-prompt-before-queue-user-alist) + (feedmail-prompt-before-queue-help-supplement) + (feedmail-queue-use-send-time-for-message-id) + (feedmail-queue-default-file-slug, feedmail-queue-fqm-suffix) + (feedmail-mail-send-hook-splitter, feedmail-mail-send-hook) + (feedmail-mail-send-hook-queued) + (feedmail-confirm-addresses-hook-example) + (feedmail-last-chance-hook, feedmail-before-fcc-hook) + (feedmail-queue-runner-mode-setter) + (feedmail-queue-alternative-mail-header-separator) + (feedmail-queue-runner-message-sender) + (feedmail-buffer-eating-function, feedmail-binmail-template) + (feedmail-run-the-queue-no-prompts) + (feedmail-run-the-queue-global-prompt) + (feedmail-queue-subject-slug-maker, feedmail-fiddle-header) + (feedmail-envelope-deducer, feedmail-fiddle-date) + (feedmail-default-message-id-generator) + (feedmail-fiddle-message-id, feedmail-fiddle-x-mailer) + (feedmail-fiddle-spray-address, feedmail-deduce-address-list): + * mail/vms-pmail.el (vms-pmail-save-and-exit, vms-pmail-abort) + (vms-pmail-setup): + * play/dunnet.el (dun-help): + * play/handwrite.el (handwrite): + * play/hanoi.el (hanoi-unix-64): + * progmodes/idlwave.el (idlwave-rescan-asynchronously): + * textmodes/enriched.el (fixed): + * textmodes/org.el (org-file-apps) + (org-emphasis-regexp-components, org-emphasis-alist): + * textmodes/texinfmt.el (batch-texinfo-format): + Fix typos in docstrings. + +2006-11-05 Juanma Barranquero <lekktu@gmail.com> + + * loadhist.el (read-feature): Don't complete features not loaded + from a file (which make `unload-feature' to fail). + +2006-11-05 Reiner Steib <Reiner.Steib@gmx.de> + + * add-log.el (add-log-time-zone-rule): Mark as safe-local-variable. + +2006-11-05 Chong Yidong <cyd@stupidchicken.com> + + * startup.el (command-line-1): Kill emacs if the last frame is + deleted while evaluating the command-line arguments. + +2006-11-05 Richard Stallman <rms@gnu.org> + + * startup.el (init-file-had-error): Add doc string. + (fancy-splash-text, fancy-splash-head, fancy-splash-tail): + Use fixed-width font for keyboard key descriptions. + + * cus-edit.el (custom-save-all): Error if saving in .emacs + and it had an error when loaded. + + * dired-aux.el (dired-copy-file-recursive): Catch errors + from recursive copies in the loop, around the recursive call. + +2006-11-05 Micha,Ak(Bl Cadilhac <michael.cadilhac@lrde.org> + + * battery.el (battery-linux-proc-acpi): Search an ac_adapter in + `/proc/acpi/ac_adapter/*'. Ditto for the thermometers in + `/proc/acpi/thermal_zone/*'. + (battery-search-for-one-match-in-files): New. Search a regexp in + the content of some files. + +2006-11-05 Martin Rudalics <rudalics@gmx.at> + + * window.el (mouse-autoselect-window-now): Remove variable. + (mouse-autoselect-window-state): New variable. + (mouse-autoselect-window-start, mouse-autoselect-window-cancel) + (mouse-autoselect-window-select, handle-select-window): + Rewritten to make mouse-autoselect-window-timer a one-shot timer. + Suspend delayed autoselection during menu or popup dialog. + + * info-look.el (info-lookup-guess-custom-symbol): New function + for retrieving symbol at point in custom buffers. + (top level) <info-lookup-maybe-add-help>: Add backquote and + comma to ignored characters in regexps of help specifications + for emacs-lisp-mode and lisp-interaction-mode. This permits + looking up symbols in `...' and after a comma. Add help + specifications for custom-mode and help-mode. + +2006-11-04 Eli Zaretskii <eliz@gnu.org> + + * mail/rmail.el (rmail-redecode-body): New optional argument RAW. + Don't encode body if RAW is non-nil, or if the old encoding is + identical to the new encoding, or if the body contains only + eight-bit-* characters. + +2006-11-04 Yoni Rabkin Katzenell <yoni-r@actcom.com> (tiny change) + + * faces.el (faces-sample-overlay, describe-face): Revert last + changes. + (faces-sample-overlay): Remove variable. + (describe-face): Insert sample text in the face being described. + +2006-11-04 Martin Rudalics <rudalics@gmx.at> + + * whitespace.el (whitespace-indent-regexp): Make this match any + multiples of eight spaces near the beginning of a line. + (whitespace-buffer): Use `remove-overlays' instead of + `whitespace-unhighlight-the-space' and `overlay-recenter' to + speed up overlay handling. + (whitespace-buffer-leading, whitespace-buffer-trailing): Make + these functions highlight the text removed by + `whitespace-buffer-leading-cleanup' and + `whitespace-buffer-trailing-cleanup' respectively. + (whitespace-buffer-search): Use `with-local-quit'. Move + `format' out of loop to speed up scanning larger buffers. + (whitespace-unhighlight-the-space): Remove `remove-hook' since + that function is never added to a hook. + (whitespace-spacetab-regexp, whitespace-ateol-regexp) + (whitespace-buffer-leading-cleanup) + (whitespace-refresh-rescan-list): Fix docstrings. + +2006-11-03 Ken Manheimer <ken.manheimer@gmail.com> + + * allout.el (allout-during-yank-processing): Cue for inhibiting + aberrance processing during yanks. + (allout-doublecheck-at-and-shallower): Reduce the limit to reduce + the amount of yanked topics that can be aberrant. + (allout-do-doublecheck): Encapsulate this multiply-used recipe in + a function, and supplement with inihibition of doublechecking + during yanks. + (allout-beginning-of-line, allout-next-heading) + (allout-previous-heading, allout-goto-prefix-doublechecked) + (allout-back-to-current-heading, allout-next-visible-heading) + (allout-next-sibling): Use new allout-do-doublecheck function. + (allout-next-sibling): Ensure we made progress when returning + other than nil. + (allout-rebullet-heading): Preserve text property annotations + indicating the text was hidden, if it was. + (allout-kill-line): Remove any added was-hidden annotations. + (allout-kill-topic): Remove any added was-hidden annotations. + (allout-annotate-hidden): Inhibit adding was-hidden text + properties to the undo list. + (allout-deannotate-hidden): New function to remove was-hidden + annotation. + (allout-hide-by-annotation): Use new allout-deannotate-hidden. + (allout-remove-exposure-annotation): Replaced by + allout-deannotate-hidden. + (allout-yank-processing): Signal that yank processing is happening + with allout-during-yank-processing. Also, wrap + allout-unprotected's closer to the text changes, for easier + debugging. We need to inhibit-field-text-motion explicitly, in + lieu of the encompassing allout-unprotected. + (outlineify-sticky): Adjust criteria for triggering new outline + decorations to presence or absence of any topics, not just a topic + at the beginning of the buffer. + +2006-11-03 Juanma Barranquero <lekktu@gmail.com> + + * bs.el (bs--show-all, bs--redisplay): + * cus-edit.el (custom-unlispify-menu-entries) + (custom-unlispify-tag-names, custom-prompt-variable): + * expand.el (expand-pos): + * speedbar.el (speedbar-generic-list-tag-p): + * wid-edit.el (widget-image-enable): + * emacs-lisp/checkdoc.el (checkdoc-rogue-space-check-engine): + * emacs-lisp/find-func.el (find-function-noselect) + (find-function, find-variable-noselect, find-variable) + (find-definition-noselect, find-face-definition): + * mail/rmail-spam-filter.el (rsf-scanning-messages-now): + * net/eudc-vars.el (eudc-expansion-overwrites-query): + * progmodes/ada-xref.el (ada-find-in-ali): + * textmodes/flyspell.el (flyspell-check-tex-math-command): + * textmodes/org.el (org-copy-subtree): + * textmodes/table.el (table--row-column-insertion-point-p): + Use "non-nil" in docstrings. + +2006-11-03 Mark Davies <mark@mcs.vuw.ac.nz> + + * sort.el (sort-columns): Set the field separator to tab; on + NetBSD, sort complains if "\n" is used as field separator. + +2006-11-03 NIIMI Satoshi <sa2c@sa2c.net> + + * emacs-lisp/pp.el (pp-eval-last-sexp): Evaluate target sexp. + +2006-11-02 Stefan Monnier <monnier@iro.umontreal.ca> + + * server.el (server-auth-key): Remove. Replace by a process-property. + (server-start): Don't remove the file of the previous process, but + instead clear out the place for the new file. + (server-start): Set the :auth-key property. + (server-process-filter): Use the :auth-key property. + +2006-11-02 Carsten Dominik <dominik@science.uva.nl> + + * textmodes/org.el (org-mode-map): No longer copy + `outline-mode-map' explicitly - this is already done by + `define-derived-mode'. + +2006-11-02 Juanma Barranquero <lekktu@gmail.com> + + * server.el (server-visit-files): Use `when'. + (server-process-filter): When authentication fails, send error + message to client. Wrap `process-send-region' in `ignore-errors' + instead of `condition-case', and remove misleading comment. + +2006-11-01 Juri Linkov <juri@jurta.org> + + * simple.el (yank): Doc fix. + +2006-11-01 Stefan Monnier <monnier@iro.umontreal.ca> + + * server.el: Try and fit within 80 columns. + (server-start): Make the auth file unreadable by other users. + +2006-10-31 Andreas Seltenreich <uwi7@rz.uni-karlsruhe.de> + + * battery.el (battery-linux-proc-acpi): Prevent range error when + `full-capacity' is 0. + +2006-10-31 Yoni Rabkin Katzenell <yoni-r@actcom.com> (tiny change) + + * faces.el (faces-sample-overlay): New defvar. + (faces-sample-overlay): New function to show face sample text. + (describe-face): Use it. + +2006-10-31 Stephen Leake <stephen_leake@stephe-leake.org> + + * progmodes/ada-stmt.el: Change maintainer, apply + whitespace-cleanup, checkdoc. + (ada-func-or-proc-name): Add doc string. + + * progmodes/ada-prj.el (ada-prj-new): Change maintainer, apply + whitespace-cleanup, checkdoc. Minor improvements to many doc + strings and comments. + (ada-prj-display-page): Change buffer name to more accurately + reflect function. + + * progmodes/ada-xref.el: Change maintainer, apply + whitespace-cleanup, checkdoc. Minor improvements to many doc + strings and comments. Don't look for `gvd' or `ddd' debuggers. + (ada-compile-current): Don't add newlines to commands. + +2006-10-31 Juanma Barranquero <lekktu@gmail.com> + + * server.el: Add support for TCP sockets. + (server-use-tcp, server-host, server-auth-dir): New options. + (server-auth-key): New variable. + (server-ensure-safe-dir): Create nonexistent parent dirs. + Ignore Unix-style file modes on Windows. + (server-start): Crete a TCP or Unix socket according to the value + of `server-use-tcp'. For TCP sockets, create the id/auth file in + `server-auth-dir' directory. + (server-process-filter): Delete process if authentication + fails (which never happens for Unix sockets). + +2006-10-30 David Kastrup <dak@gnu.org> + + * subr.el (add-to-list): Don't continue checking if a match has + been found. + +2006-10-30 Chong Yidong <cyd@stupidchicken.com> + + * tutorial.el: Move defvars to avoid bytecomp warnings. + (tutorial--find-changed-keys): Check if viper-current-state is + bound before using it. + (help-with-tutorial): Check if viper-tutorial is defined before + using it. + +2006-10-30 Lennart Borgman <lennart.borgman.073@student.lu.se> + + * help-fns.el (help-with-tutorial): Moved to tutorial.el. + + * tutorial.el: New file. + (help-with-tutorial): Moved here from help-fns.el. Added help for + rebound keys. Fixed resume of tutorial. + (tutorial--describe-nonstandard-key, tutorial--sort-keys) + (tutorial--find-changed-keys, tutorial--display-changes) + (tutorial--saved-dir, tutorial--saved-file) + (tutorial--save-tutorial): New functions to support the changes in + help-with-tutorial. + +2006-10-30 Kenichi Handa <handa@m17n.org> + + * files.el (revert-buffer): If a unibyte buffer is being reverted + with a coding system for multibyte, set buffer multibyte before + calling insert-file-contents. + +2006-10-30 Stefan Monnier <monnier@iro.umontreal.ca> + + * server.el (server-select-display): Use a dummy buffer to detect when + the frame is later used. + (server-select-display): New function. + (server-process-filter): Use it to detect unused temp frames. + +2006-10-29 Stephen Leake <stephen_leake@stephe-leake.org> * progmodes/ada-mode.el: Change maintainer, apply - whitespace-clean, checkdoc. Minor improvements to many doc - strings. + whitespace-clean, checkdoc. Minor improvements to many doc strings. (ada-mode-version): New function. (ada-create-menu): Menu operations are available for all supported compilers. 2006-10-29 Lars Hansen <larsh@soem.dk> - * net/tramp.el (with-parsed-tramp-file-name): Correct debug - spec. Highlight as keyword. + + * net/tramp.el (with-parsed-tramp-file-name): Correct debug spec. + Highlight as keyword. (tramp-do-copy-or-rename-file): Correct data for 'file-already-exists. Don't call tramp-method-out-of-band-p for local files. (tramp-touch): Quote file name. @@ -18,8 +442,7 @@ * calendar/calendar.el (cal-html-cursor-month) (cal-html-cursor-year): Add autoloads for this new package. - (calendar-mode-map): Bind cal-html-cursor-month, - cal-html-cursor-year. + (calendar-mode-map): Bind cal-html-cursor-month, cal-html-cursor-year. 2006-10-28 Anna Bigatti <bigatti@dima.unige.it> @@ -64,7 +487,7 @@ * midnight.el (midnight-buffer-display-time): Doc fix. (clean-buffer-list-kill-never-buffer-names): Add "*server*". -2006-10-22 martin rudalics <rudalics@gmx.at> +2006-10-22 Martin Rudalics <rudalics@gmx.at> * textmodes/flyspell.el (flyspell-check-region-doublons): Fix last fix. @@ -81,7 +504,7 @@ event to unread-command-events as (t . EVENT) so it will be added to this-command-keys by read-key-sequence. -2006-10-22 martin rudalics <rudalics@gmx.at> +2006-10-22 Martin Rudalics <rudalics@gmx.at> * textmodes/flyspell.el (flyspell-word): Skip past all previous whitespace when checking doublons. @@ -1205,7 +1628,7 @@ * select.el (xselect-convert-to-string): If UTF8_STRING is requested and the data doesn't look like UTF8, send STRING instead. -2006-09-16 Agustin Martin <agustin.martin@hispalinux.es> +2006-09-16 Agustin Martin <agustin.martin@hispalinux.es> * textmodes/flyspell.el (flyspell-check-region-doublons): New function to detect duplicated words. @@ -1271,8 +1694,8 @@ (allout-mode): Make allout-old-style-prefixes (ie, enabling use with outline.el outlines) functional again. Change the primary bullet along with the header-lead - level 1 new-style bullets now work. - Engage allout-before-change-handler in mainline emacs, not just - xemacs, to do undo handling. + Engage allout-before-change-handler in mainline Emacs, not just + XEmacs, to do undo handling. (allout-before-change-handler): Expose undo changes occurring in hidden regions. Use allout-get-invisibility-overlay instead of reimplementing it inline. @@ -1666,7 +2089,7 @@ * net/ldap.el (ldap-search-internal): Handle `auth' key. -2006-09-07 Magnus Henoch <mange@freemail.hu> +2006-09-07 Magnus Henoch <mange@freemail.hu> * net/rcirc.el (rcirc-activity-string): Don't quote value in case clause. @@ -12248,7 +12671,7 @@ Add fset of allout-real-isearch-abort during compile to fix byte-compilation warnings. (allout-mode-p): Move definition of this macro above all uses, or - byte compilation in barren emacs (eg, during emacs build) will + byte compilation in barren Emacs (eg, during Emacs build) will lack the definition. (allout-mode): Move this variable above any uses, or byte compilation will fail. @@ -13893,7 +14316,7 @@ 2005-11-02 Mark A. Hershberger <mah@everybody.org> - * xml.el (xml-syntax-table): Allow xml.el to compile in xemacs. + * xml.el (xml-syntax-table): Allow xml.el to compile in XEmacs. (xml-parse-tag): Join strings separated by a comment properly. 2005-11-02 Andreas Schwab <schwab@suse.de> @@ -18642,7 +19065,7 @@ 2005-07-21 Kim F. Storm <storm@cua.dk> * mail/emacsbug.el (report-emacs-bug): Request that backtraces are - included when reporting an emacs crash, and tell about the DEBUG file. + included when reporting an Emacs crash, and tell about the DEBUG file. * image-file.el (insert-image-file): Add yank-handler. (image-file-yank-handler): Yank handler to make unique copies of @@ -19597,7 +20020,7 @@ 2005-07-06 Richard M. Stallman <rms@gnu.org> * progmodes/flymake.el (flymake-float-time): Instead of - with-no-warnings, test for xemacs. + with-no-warnings, test for XEmacs. (flymake-replace-regexp-in-string): Test fboundp of replace-in-string to avoid warning.
--- a/lisp/ChangeLog.3 Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/ChangeLog.3 Tue Nov 07 23:22:48 2006 +0000 @@ -11829,7 +11829,7 @@ * dbx.el (run-dbx): Set dbx-process. (dbx-stop-at): Use that to decide where to send the string. -1989-02-13 Marc Shapiro (shapiro@sor.inria.fr) +1989-02-13 Marc Shapiro (marc.shapiro@acm.org) * bibtex.el (bibtex-clean-entry, bibtex-empty-field, bibtex-find-text, bibtex-kill-optional-field, bibtex-next-field, bibtex-pop-next,
--- a/lisp/Makefile.in Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/Makefile.in Tue Nov 07 23:22:48 2006 +0000 @@ -76,6 +76,8 @@ esac; \ done +# Find all subdirectories except `obsolete'. + setwins_almost=subdirs=`(cd $$wd; find . -type d -print)`; \ for file in $$subdirs; do \ case $$file in */Old | */RCS | */CVS | */CVS/* | */.* | */.*/* | */=* | */obsolete | */term ) ;; \ @@ -108,7 +110,7 @@ echo ";; End:" >> $@ echo ";;; loaddefs.el ends here" >> $@ autoloads: $(lisp)/loaddefs.el doit - wd=$(lisp); $(setwins); \ + wd=$(lisp); $(setwins_almost); \ echo Directories: $$wins; \ LC_ALL=C $(EMACS) $(EMACSOPT) -l autoload --eval '(setq generated-autoload-file "$(lisp)/loaddefs.el")' -f batch-update-autoloads $$wins
--- a/lisp/add-log.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/add-log.el Tue Nov 07 23:22:48 2006 +0000 @@ -293,6 +293,8 @@ It takes the same format as the TZ argument of `set-time-zone-rule'. If nil, use local time. If t, use universal time.") +(put 'add-log-time-zone-rule 'safe-local-variable + '(lambda (x) (or (booleanp x) (stringp x)))) (defun add-log-iso8601-time-zone (&optional time) (let* ((utc-offset (or (car (current-time-zone time)) 0))
--- a/lisp/allout.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/allout.el Tue Nov 07 23:22:48 2006 +0000 @@ -66,7 +66,7 @@ ;; ;; The outline menubar additions provide quick reference to many of ;; the features, and see the docstring of the variable `allout-init' -;; for instructions on priming your emacs session for automatic +;; for instructions on priming your Emacs session for automatic ;; activation of allout-mode. ;; ;; See the docstring of the variables `allout-layout' and @@ -891,13 +891,18 @@ (make-variable-buffer-local 'allout-plain-bullets-string-len) ;;;_ = allout-doublecheck-at-and-shallower -(defconst allout-doublecheck-at-and-shallower 3 - "Verify apparent topics of this depth and shallower as being non-aberrant. +(defconst allout-doublecheck-at-and-shallower 2 + "Validate apparent topics of this depth and shallower as being non-aberrant. Verified with `allout-aberrant-container-p'. This check's usefulness is limited to shallow prospects, because the determination of aberrance depends on the mistaken item being followed by a legitimate item of -excessively greater depth.") +excessively greater depth. + +A level of 2 is safest, so that yanks, which must ignore +aberrance while rectifying the yanked text to their new location, +is least likely to be fooled by aberrant topics in the yanked +text.") ;;;_ X allout-reset-header-lead (header-lead) (defun allout-reset-header-lead (header-lead) "*Reset the leading string used to identify topic headers." @@ -1380,7 +1385,7 @@ search attacks. The verifier string is retained as an Emacs file variable, as well as in -the emacs buffer state, if file variable adjustments are enabled. See +the Emacs buffer state, if file variable adjustments are enabled. See `allout-enable-file-variable-adjustment' for details about that.") (make-variable-buffer-local 'allout-passphrase-verifier-string) ;;;###autoload @@ -1392,7 +1397,7 @@ See the description of `allout-passphrase-hint-handling' for details about how the reminder is deployed. -The hint is retained as an Emacs file variable, as well as in the emacs buffer +The hint is retained as an Emacs file variable, as well as in the Emacs buffer state, if file variable adjustments are enabled. See `allout-enable-file-variable-adjustment' for details about that.") (make-variable-buffer-local 'allout-passphrase-hint-string) @@ -1506,6 +1511,13 @@ (goto-char (cadr allout-after-save-decrypt)) (setq allout-after-save-decrypt nil)) ) +;;;_ = allout-during-yank-processing nil +;; XXX allout yanks adjust the level of the topic being pasted to that of +;; their target location. aberrance must be inhibited to allow that +;; reconciliation. (this means that actually aberrant topics won't be +;; treated specially while being pasted.) +(defvar allout-during-yank-processing nil + "Internal state, inhibits aberrance doublecheck while adjusting yanks.") ;;;_ #2 Mode activation ;;;_ = allout-explicitly-deactivated @@ -2194,27 +2206,16 @@ ;;;_ - Position Assessment ;;;_ : Location Predicates -;;;_ > allout-on-current-heading-p () -(defun allout-on-current-heading-p () - "Return non-nil if point is on current visible topics' header line. - -Actually, returns prefix beginning point." - (save-excursion - (allout-beginning-of-current-line) - (and (looking-at allout-regexp) - (allout-prefix-data) - (or (> allout-recent-depth allout-doublecheck-at-and-shallower) - (not (allout-aberrant-container-p)))))) -;;;_ > allout-on-heading-p () -(defalias 'allout-on-heading-p 'allout-on-current-heading-p) -;;;_ > allout-e-o-prefix-p () -(defun allout-e-o-prefix-p () - "True if point is located where current topic prefix ends, heading begins." - (and (save-excursion (let ((inhibit-field-text-motion t)) - (beginning-of-line)) - (looking-at allout-regexp)) - (= (point)(save-excursion (allout-end-of-prefix)(point))))) -;;;_ > allout-aberrant-container-p () +;;;_ > allout-do-doublecheck () +(defsubst allout-do-doublecheck () + "True if current item conditions qualify for checking on topic aberrance." + (and + ;; presume integrity of outline and yanked content during yank - necessary, + ;; to allow for level disparity of yank location and yanked text: + (not allout-during-yank-processing) + ;; allout-doublecheck-at-and-shallower is ceiling for doublecheck: + (<= allout-recent-depth allout-doublecheck-at-and-shallower))) +;;;_ > allout-aberrant-container-p () (defun allout-aberrant-container-p () "True if topic, or next sibling with children, contains them discontinuously. @@ -2247,7 +2248,7 @@ (goto-char allout-recent-prefix-beginning) (cond ;; sibling - continue: - ((eq allout-recent-depth depth)) + ((eq allout-recent-depth depth)) ;; first offspring is excessive - aberrant: ((> allout-recent-depth (1+ depth)) (setq done t aberrant t)) @@ -2259,6 +2260,26 @@ ;; recalibrate allout-recent-* (allout-depth) nil))) +;;;_ > allout-on-current-heading-p () +(defun allout-on-current-heading-p () + "Return non-nil if point is on current visible topics' header line. + +Actually, returns prefix beginning point." + (save-excursion + (allout-beginning-of-current-line) + (and (looking-at allout-regexp) + (allout-prefix-data) + (or (not (allout-do-doublecheck)) + (not (allout-aberrant-container-p)))))) +;;;_ > allout-on-heading-p () +(defalias 'allout-on-heading-p 'allout-on-current-heading-p) +;;;_ > allout-e-o-prefix-p () +(defun allout-e-o-prefix-p () + "True if point is located where current topic prefix ends, heading begins." + (and (save-excursion (let ((inhibit-field-text-motion t)) + (beginning-of-line)) + (looking-at allout-regexp)) + (= (point)(save-excursion (allout-end-of-prefix)(point))))) ;;;_ : Location attributes ;;;_ > allout-depth () (defun allout-depth () @@ -2390,8 +2411,7 @@ (allout-depth) (let ((beginning-of-body (save-excursion - (while (and (<= allout-recent-depth - allout-doublecheck-at-and-shallower) + (while (and (allout-do-doublecheck) (allout-aberrant-container-p) (allout-previous-visible-heading 1))) (allout-beginning-of-current-entry) @@ -2443,7 +2463,7 @@ (when (re-search-forward allout-line-boundary-regexp nil 0) (allout-prefix-data) - (and (<= allout-recent-depth allout-doublecheck-at-and-shallower) + (and (allout-do-doublecheck) ;; this will set allout-recent-* on the first non-aberrant topic, ;; whether it's the current one or one that disqualifies it: (allout-aberrant-container-p)) @@ -2464,13 +2484,13 @@ (if (bobp) nil - ;; allout-goto-prefix-doublechecked calls us, so we can't use it here. (let ((start-point (point))) + ;; allout-goto-prefix-doublechecked calls us, so we can't use it here. (allout-goto-prefix) (when (or (re-search-backward allout-line-boundary-regexp nil 0) (looking-at allout-bob-regexp)) (goto-char (allout-prefix-data)) - (if (and (<= allout-recent-depth allout-doublecheck-at-and-shallower) + (if (and (allout-do-doublecheck) (allout-aberrant-container-p)) (or (allout-previous-heading) (and (goto-char start-point) @@ -2705,11 +2725,11 @@ `allout-doublecheck-at-and-shallower') are checked and disqualified for child containment discontinuity, according to `allout-aberrant-container-p'." - (allout-goto-prefix) - (if (and (<= allout-recent-depth allout-doublecheck-at-and-shallower) - (allout-aberrant-container-p)) - (allout-previous-heading) - (point))) + (if (allout-goto-prefix) + (if (and (allout-do-doublecheck) + (allout-aberrant-container-p)) + (allout-previous-heading) + (point)))) ;;;_ > allout-end-of-prefix () (defun allout-end-of-prefix (&optional ignore-decorations) @@ -2745,13 +2765,13 @@ (allout-beginning-of-current-line) (let ((bol-point (point))) - (allout-goto-prefix-doublechecked) - (if (<= (point) bol-point) - (if (interactive-p) - (allout-end-of-prefix) - (point)) - (goto-char (point-min)) - nil))) + (if (allout-goto-prefix-doublechecked) + (if (<= (point) bol-point) + (if (interactive-p) + (allout-end-of-prefix) + (point)) + (goto-char (point-min)) + nil)))) ;;;_ > allout-back-to-heading () (defalias 'allout-back-to-heading 'allout-back-to-current-heading) ;;;_ > allout-pre-next-prefix () @@ -2918,6 +2938,7 @@ nil (let ((target-depth (or depth (allout-depth))) (start-point (point)) + (start-prefix-beginning allout-recent-prefix-beginning) (count 0) leaping last-depth) @@ -2941,7 +2962,9 @@ nil))) ((and (not (eobp)) (and (> (or last-depth (allout-depth)) 0) - (= allout-recent-depth target-depth))) + (= allout-recent-depth target-depth)) + (not (= start-prefix-beginning + allout-recent-prefix-beginning))) allout-recent-prefix-beginning) (t (goto-char start-point) @@ -3067,8 +3090,7 @@ ;; not a header line, keep looking: t (allout-prefix-data) - (if (and (<= allout-recent-depth - allout-doublecheck-at-and-shallower) + (if (and (allout-do-doublecheck) (allout-aberrant-container-p)) ;; skip this aberrant prospective header line: t @@ -3480,7 +3502,7 @@ If OFFER-RECENT-BULLET is true, offer to use the bullet of the prior sibling. -Runs +Runs Nuances: @@ -3828,6 +3850,7 @@ (mb allout-recent-prefix-beginning) (me allout-recent-prefix-end) (current-bullet (buffer-substring-no-properties (- me 1) me)) + (has-annotation (get-text-property mb 'allout-was-hidden)) (new-prefix (allout-make-topic-prefix current-bullet nil new-depth @@ -3854,6 +3877,11 @@ (allout-unprotected (delete-region (match-beginning 0)(match-end 0)))) + ;; convey 'allout-was-hidden annotation, if original had it: + (if has-annotation + (put-text-property 0 (length new-prefix) 'allout-was-hidden t + new-prefix)) + ; Put in new prefix: (allout-unprotected (insert new-prefix)) @@ -4183,10 +4211,11 @@ (depth (allout-depth))) (allout-annotate-hidden beg end) - (if (and (not beg-hidden) (not end-hidden)) (allout-unprotected (kill-line arg)) (kill-line arg)) + (allout-deannotate-hidden beg end) + (if allout-numbered-bullet (save-excursion ; Renumber subsequent topics if needed: (if (not (looking-at allout-regexp)) @@ -4218,6 +4247,7 @@ (interactive) (let* ((inhibit-field-text-motion t) (beg (prog1 (allout-back-to-current-heading) (beginning-of-line))) + end (depth allout-recent-depth)) (allout-end-of-current-subtree) (if (and (/= (current-column) 0) (not (eobp))) @@ -4231,9 +4261,13 @@ (string= (buffer-substring (- beg 2) beg) "\n\n")))) (forward-char 1))) - (allout-annotate-hidden beg (point)) - - (allout-unprotected (kill-region beg (point))) + (allout-annotate-hidden beg (setq end (point))) + (unwind-protect + (allout-unprotected (kill-region beg end)) + (if buffer-read-only + ;; eg, during copy-as-kill. + (allout-deannotate-hidden beg end))) + (save-excursion (allout-renumber-to-depth depth)) (run-hook-with-args 'allout-structure-deleted-hook depth (point)))) @@ -4251,8 +4285,7 @@ (let ((was-modified (buffer-modified-p)) (buffer-read-only nil)) - (allout-unprotected - (remove-text-properties begin end '(allout-was-hidden t))) + (allout-deannotate-hidden begin end) (save-excursion (goto-char begin) (let (done next prev overlay) @@ -4279,9 +4312,19 @@ (when next (goto-char next) (allout-unprotected - (put-text-property (overlay-start overlay) next - 'allout-was-hidden t)))))))) + (let ((buffer-undo-list t)) + (put-text-property (overlay-start overlay) next + 'allout-was-hidden t))))))))) (set-buffer-modified-p was-modified))) +;;;_ > allout-deannotate-hidden (begin end) +(defun allout-deannotate-hidden (begin end) + "Remove allout hidden-text annotation between BEGIN and END." + + (allout-unprotected + (let ((inhibit-read-only t) + (buffer-undo-list t)) + ;(remove-text-properties begin end '(allout-was-hidden t)) + ))) ;;;_ > allout-hide-by-annotation (begin end) (defun allout-hide-by-annotation (begin end) "Translate text properties indicating exposure status into actual exposure." @@ -4309,16 +4352,10 @@ nil end)) (overlay-put (make-overlay prev next) 'category 'allout-exposure-category) - (allout-unprotected - (remove-text-properties prev next '(allout-was-hidden t))) + (allout-deannotate-hidden prev next) (setq prev next) (if next (goto-char next))))) (set-buffer-modified-p was-modified)))) -;;;_ > allout-remove-exposure-annotation (begin end) -(defun allout-remove-exposure-annotation (begin end) - "Remove text properties indicating exposure status." - (remove-text-properties begin end '(allout-was-hidden t))) - ;;;_ > allout-yank-processing () (defun allout-yank-processing (&optional arg) @@ -4345,108 +4382,117 @@ ; region around subject: (if (< (allout-mark-marker t) (point)) (exchange-point-and-mark)) - (allout-unprotected - (let* ((subj-beg (point)) - (into-bol (bolp)) - (subj-end (allout-mark-marker t)) - ;; 'resituate' if yanking an entire topic into topic header: - (resituate (and (allout-e-o-prefix-p) - (looking-at allout-regexp) - (allout-prefix-data))) - ;; `rectify-numbering' if resituating (where several topics may - ;; be resituating) or yanking a topic into a topic slot (bol): - (rectify-numbering (or resituate - (and into-bol (looking-at allout-regexp))))) - (if resituate + (let* ( ;; inhibit aberrance doublecheck while reconciling disparate pastes: + (allout-during-yank-processing t) + (subj-beg (point)) + (into-bol (bolp)) + (subj-end (allout-mark-marker t)) + ;; 'resituate' if yanking an entire topic into topic header: + (resituate (and (allout-e-o-prefix-p) + (looking-at allout-regexp) + (allout-prefix-data))) + ;; `rectify-numbering' if resituating (where several topics may + ;; be resituating) or yanking a topic into a topic slot (bol): + (rectify-numbering (or resituate + (and into-bol (looking-at allout-regexp))))) + (if resituate ; The yanked stuff is a topic: - (let* ((prefix-len (- (match-end 1) subj-beg)) - (subj-depth allout-recent-depth) - (prefix-bullet (allout-recent-bullet)) - (adjust-to-depth - ;; Nil if adjustment unnecessary, otherwise depth to which - ;; adjustment should be made: - (save-excursion - (and (goto-char subj-end) - (eolp) - (goto-char subj-beg) - (and (looking-at allout-regexp) - (progn - (beginning-of-line) - (not (= (point) subj-beg))) - (looking-at allout-regexp) - (allout-prefix-data)) - allout-recent-depth))) - (more t)) - (setq rectify-numbering allout-numbered-bullet) - (if adjust-to-depth + (let* ((inhibit-field-text-motion t) + (prefix-len (if (not (match-end 1)) + 1 + (- (match-end 1) subj-beg))) + (subj-depth allout-recent-depth) + (prefix-bullet (allout-recent-bullet)) + (adjust-to-depth + ;; Nil if adjustment unnecessary, otherwise depth to which + ;; adjustment should be made: + (save-excursion + (and (goto-char subj-end) + (eolp) + (goto-char subj-beg) + (and (looking-at allout-regexp) + (progn + (beginning-of-line) + (not (= (point) subj-beg))) + (looking-at allout-regexp) + (allout-prefix-data)) + allout-recent-depth))) + (more t)) + (setq rectify-numbering allout-numbered-bullet) + (if adjust-to-depth ; Do the adjustment: - (progn - (save-restriction - (narrow-to-region subj-beg subj-end) + (progn + (save-restriction + (narrow-to-region subj-beg subj-end) ; Trim off excessive blank ; line at end, if any: - (goto-char (point-max)) - (if (looking-at "^$") - (allout-unprotected (delete-char -1))) + (goto-char (point-max)) + (if (looking-at "^$") + (allout-unprotected (delete-char -1))) ; Work backwards, with each ; shallowest level, ; successively excluding the ; last processed topic from ; the narrow region: - (while more - (allout-back-to-current-heading) + (while more + (allout-back-to-current-heading) ; go as high as we can in each bunch: - (while (allout-ascend)) - (save-excursion + (while (allout-ascend)) + (save-excursion + (allout-unprotected (allout-rebullet-topic-grunt (- adjust-to-depth - subj-depth)) - (allout-depth)) - (if (setq more (not (bobp))) - (progn (widen) - (forward-char -1) - (narrow-to-region subj-beg (point)))))) - ;; Preserve new bullet if it's a distinctive one, otherwise - ;; use old one: - (if (string-match (regexp-quote prefix-bullet) - allout-distinctive-bullets-string) + subj-depth))) + (allout-depth)) + (if (setq more (not (bobp))) + (progn (widen) + (forward-char -1) + (narrow-to-region subj-beg (point)))))) + ;; Preserve new bullet if it's a distinctive one, otherwise + ;; use old one: + (if (string-match (regexp-quote prefix-bullet) + allout-distinctive-bullets-string) ; Delete from bullet of old to ; before bullet of new: - (progn - (beginning-of-line) - (delete-region (point) subj-beg) - (set-marker (allout-mark-marker t) subj-end) - (goto-char subj-beg) - (allout-end-of-prefix)) + (progn + (beginning-of-line) + (allout-unprotected + (delete-region (point) subj-beg)) + (set-marker (allout-mark-marker t) subj-end) + (goto-char subj-beg) + (allout-end-of-prefix)) ; Delete base subj prefix, ; leaving old one: - (delete-region (point) (+ (point) - prefix-len - (- adjust-to-depth subj-depth))) + (allout-unprotected + (progn + (delete-region (point) (+ (point) + prefix-len + (- adjust-to-depth subj-depth))) ; and delete residual subj ; prefix digits and space: - (while (looking-at "[0-9]") (delete-char 1)) - (if (looking-at " ") (delete-char 1)))) - (exchange-point-and-mark)))) - (if rectify-numbering - (progn - (save-excursion + (while (looking-at "[0-9]") (delete-char 1)) + (if (looking-at " ") (delete-char 1)))))) + (exchange-point-and-mark)))) + (if rectify-numbering + (progn + (save-excursion ; Give some preliminary feedback: - (message "... reconciling numbers") + (message "... reconciling numbers") ; ... and renumber, in case necessary: - (goto-char subj-beg) - (if (allout-goto-prefix-doublechecked) + (goto-char subj-beg) + (if (allout-goto-prefix-doublechecked) + (allout-unprotected (allout-rebullet-heading nil ;;; solicit - (allout-depth) ;;; depth - nil ;;; number-control - nil ;;; index - t)) - (message "")))) - (if (or into-bol resituate) - (allout-hide-by-annotation (point) (allout-mark-marker t)) - (allout-remove-exposure-annotation (allout-mark-marker t) (point))) - (if (not resituate) - (exchange-point-and-mark)) - (run-hook-with-args 'allout-structure-added-hook subj-beg subj-end)))) + (allout-depth) ;;; depth + nil ;;; number-control + nil ;;; index + t))) + (message "")))) + (if (or into-bol resituate) + (allout-hide-by-annotation (point) (allout-mark-marker t)) + (allout-deannotate-hidden (allout-mark-marker t) (point))) + (if (not resituate) + (exchange-point-and-mark)) + (run-hook-with-args 'allout-structure-added-hook subj-beg subj-end))) ;;;_ > allout-yank (&optional arg) (defun allout-yank (&optional arg) "`allout-mode' yank, with depth and numbering adjustment of yanked topics. @@ -5671,7 +5717,7 @@ non-nil, an entry for `allout-passphrase-verifier-string' and its value is added to an Emacs 'local variables' section at the end of the file, which is created if necessary. That setting is for retention of the passphrase -verifier across emacs sessions. +verifier across Emacs sessions. Similarly, `allout-passphrase-hint-string' stores a user-provided reminder about their passphrase, and `allout-passphrase-hint-handling' specifies @@ -6356,7 +6402,7 @@ (save-excursion (goto-char (point-min)) - (if (looking-at allout-regexp) + (if (allout-goto-prefix) t (allout-open-topic 2) (insert (concat "Dummy outline topic header - see" @@ -6393,7 +6439,7 @@ ) ;;;_ > allout-adjust-file-variable (varname value) (defun allout-adjust-file-variable (varname value) - "Adjust the setting of an emacs file variable named VARNAME to VALUE. + "Adjust the setting of an Emacs file variable named VARNAME to VALUE. This activity is inhibited if either `enable-local-variables' `allout-enable-file-variable-adjustment' are nil. @@ -6404,7 +6450,7 @@ section lines \(including the section line) exist as second-level topics in a top-level topic at the end of the file. -enable-local-variables must be true for any of this to happen." +`enable-local-variables' must be true for any of this to happen." (if (not (and enable-local-variables allout-enable-file-variable-adjustment)) nil
--- a/lisp/apropos.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/apropos.el Tue Nov 07 23:22:48 2006 +0000 @@ -171,7 +171,7 @@ ("yank" "paste") ("region" "selection")) "List of synonyms known by apropos. -Each element is a list of words where the first word is the standard emacs +Each element is a list of words where the first word is the standard Emacs term, and the rest of the words are alternative terms.")
--- a/lisp/battery.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/battery.el Tue Nov 07 23:22:48 2006 +0000 @@ -49,8 +49,8 @@ (file-directory-p "/proc/acpi/battery")) 'battery-linux-proc-acpi) ((and (eq system-type 'darwin) - (condition-case nil - (with-temp-buffer + (condition-case nil + (with-temp-buffer (and (eq (call-process "pmset" nil t nil "-g" "ps") 0) (> (buffer-size) 0))) (error nil))) @@ -355,45 +355,19 @@ 60))) hours (/ minutes 60))) (list (cons ?c (or (and capacity (number-to-string capacity)) "N/A")) - (cons ?L (or (when (file-exists-p "/proc/acpi/ac_adapter/AC/state") - (with-temp-buffer - (insert-file-contents - "/proc/acpi/ac_adapter/AC/state") - (when (re-search-forward "state: +\\(.*\\)$" nil t) - (match-string 1)))) + (cons ?L (or (battery-search-for-one-match-in-files + (mapcar (lambda (e) (concat e "/state")) + (directory-files "/proc/acpi/ac_adapter/" + t "\\`[^.]")) + "state: +\\(.*\\)$" 1) + "N/A")) - (cons ?d (or (when (file-exists-p - "/proc/acpi/thermal_zone/THRM/temperature") - (with-temp-buffer - (insert-file-contents - "/proc/acpi/thermal_zone/THRM/temperature") - (when (re-search-forward - "temperature: +\\([0-9]+\\) C$" nil t) - (match-string 1)))) - (when (file-exists-p - "/proc/acpi/thermal_zone/THM/temperature") - (with-temp-buffer - (insert-file-contents - "/proc/acpi/thermal_zone/THM/temperature") - (when (re-search-forward - "temperature: +\\([0-9]+\\) C$" nil t) - (match-string 1)))) - (when (file-exists-p - "/proc/acpi/thermal_zone/THM0/temperature") - (with-temp-buffer - (insert-file-contents - "/proc/acpi/thermal_zone/THM0/temperature") - (when (re-search-forward - "temperature: +\\([0-9]+\\) C$" nil t) - (match-string 1)))) - (when (file-exists-p - "/proc/acpi/thermal_zone/THR2/temperature") - (with-temp-buffer - (insert-file-contents - "/proc/acpi/thermal_zone/THR2/temperature") - (when (re-search-forward - "temperature: +\\([0-9]+\\) C$" nil t) - (match-string 1)))) + (cons ?d (or (battery-search-for-one-match-in-files + (mapcar (lambda (e) (concat e "/temperature")) + (directory-files "/proc/acpi/thermal_zone/" + t "\\`[^.]")) + "temperature: +\\([0-9]+\\) C$" 1) + "N/A")) (cons ?r (or (and rate (concat (number-to-string rate) " " rate-type)) "N/A")) @@ -408,6 +382,7 @@ (format "%d:%02d" hours (- minutes (* 60 hours)))) "N/A")) (cons ?p (or (and full-capacity capacity + (> full-capacity 0) (number-to-string (floor (/ capacity (/ (float full-capacity) 100))))) @@ -478,6 +453,17 @@ (or (cdr (assoc char alist)) "")))) format t t)) +(defun battery-search-for-one-match-in-files (files regexp match-num) + "Search REGEXP in the content of the files listed in FILES. +If a match occured, return the parenthesized expression numbered by +MATCH-NUM in the match. Otherwise, return nil." + (with-temp-buffer + (catch 'found + (dolist (file files) + (and (ignore-errors (insert-file-contents file nil nil nil 'replace)) + (re-search-forward regexp nil t) + (throw 'found (match-string match-num))))))) + (provide 'battery)
--- a/lisp/bindings.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/bindings.el Tue Nov 07 23:22:48 2006 +0000 @@ -279,7 +279,7 @@ ;; "\ ;; mouse-1: select window, mouse-2: delete others, mouse-3: delete, ;; drag-mouse-1: resize, C-mouse-2: split horizontally" - "mouse-1: select (drag to resize), mouse-2: delete others, mouse-3: delete this") + "mouse-1: select (drag to resize), mouse-2 = C-x 1, mouse-3 = C-x 0") (dashes (propertize "--" 'help-echo help-echo)) (standard-mode-line-format (list
--- a/lisp/bs.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/bs.el Tue Nov 07 23:22:48 2006 +0000 @@ -441,7 +441,7 @@ (defvar bs--show-all nil "Flag whether showing all buffers regardless of current configuration. -Non nil means to show all buffers. Otherwise show buffers +Non-nil means to show all buffers. Otherwise show buffers defined by current configuration `bs-current-configuration'.") (defvar bs--window-config-coming-from nil @@ -583,7 +583,7 @@ (defun bs--redisplay (&optional keep-line-p sort-description) "Redisplay whole Buffer Selection Menu. -If KEEP-LINE-P is non nil the point will stay on current line. +If KEEP-LINE-P is non-nil the point will stay on current line. SORT-DESCRIPTION is an element of `bs-sort-functions'" (let ((line (1+ (count-lines 1 (point))))) (bs-show-in-buffer (bs-buffer-list nil sort-description))
--- a/lisp/cus-edit.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/cus-edit.el Tue Nov 07 23:22:48 2006 +0000 @@ -466,6 +466,37 @@ :version "22.1" :prefix "mac-") +;;; Custom mode keymaps + +(defvar custom-mode-map + ;; This keymap should be dense, but a dense keymap would prevent inheriting + ;; "\r" bindings from the parent map. + ;; Actually, this misfeature of dense keymaps was fixed on 2001-11-26. + (let ((map (make-keymap))) + (set-keymap-parent map widget-keymap) + (define-key map [remap self-insert-command] 'Custom-no-edit) + (define-key map "\^m" 'Custom-newline) + (define-key map " " 'scroll-up) + (define-key map "\177" 'scroll-down) + (define-key map "\C-c\C-c" 'Custom-set) + (define-key map "\C-x\C-s" 'Custom-save) + (define-key map "q" 'Custom-buffer-done) + (define-key map "u" 'Custom-goto-parent) + (define-key map "n" 'widget-forward) + (define-key map "p" 'widget-backward) + map) + "Keymap for `custom-mode'.") + +(defvar custom-mode-link-map + (let ((map (make-keymap))) + (set-keymap-parent map custom-mode-map) + (define-key map [down-mouse-2] nil) + (define-key map [down-mouse-1] 'mouse-drag-region) + (define-key map [mouse-2] 'widget-move-and-invoke) + map) + "Local keymap for links in `custom-mode'.") + + ;;; Utilities. (defun custom-split-regexp-maybe (regexp) @@ -521,7 +552,7 @@ "List of prefixes that should be ignored by `custom-unlispify'.") (defcustom custom-unlispify-menu-entries t - "Display menu entries as words instead of symbols if non nil." + "Display menu entries as words instead of symbols if non-nil." :group 'custom-menu :type 'boolean) @@ -568,7 +599,7 @@ (buffer-string))))) (defcustom custom-unlispify-tag-names t - "Display tag names as words instead of symbols if non nil." + "Display tag names as words instead of symbols if non-nil." :group 'custom-buffer :type 'boolean) @@ -846,7 +877,7 @@ If the variable has a `custom-type' property, it must be a widget and the `:prompt-value' property of that widget will be used for reading the value. -If optional COMMENT argument is non nil, also prompt for a comment and return +If optional COMMENT argument is non-nil, also prompt for a comment and return it as the third element in the list." (let* ((var (read-variable prompt-var)) (minibuffer-help-form '(describe-variable var)) @@ -1781,6 +1812,8 @@ (define-widget 'custom-manual 'info-link "Link to the manual entry for this customization option." :help-echo "Read the manual entry for this option." + :keymap custom-mode-link-map + :follow-link 'mouse-face :button-face 'custom-link :mouse-face 'highlight :pressed-face 'highlight @@ -3631,7 +3664,7 @@ ;;; The `hook' Widget. (define-widget 'hook 'list - "A emacs lisp hook" + "An Emacs Lisp hook." :value-to-internal (lambda (widget value) (if (and value (symbolp value)) (list value) @@ -3673,6 +3706,8 @@ :mouse-face 'highlight :pressed-face 'highlight :help-echo "Create customization buffer for this group." + :keymap custom-mode-link-map + :follow-link 'mouse-face :action 'custom-group-link-action) (defun custom-group-link-action (widget &rest ignore) @@ -4149,6 +4184,8 @@ ;;;###autoload (defun custom-save-all () "Save all customizations in `custom-file'." + (when (and (null custom-file) init-file-had-error) + (error "Cannot save customizations; init file was not fully loaded")) (let* ((filename (custom-file)) (recentf-exclude (if recentf-mode (cons (concat "\\`" @@ -4267,7 +4304,7 @@ (eq (get symbol 'force-value) 'rogue)))) (comment (get symbol 'saved-variable-comment))) - ;; Check REQUESTS for validity. + ;; Check REQUESTS for validity. (dolist (request requests) (when (and (symbolp request) (not (featurep request))) (message "Unknown requested feature: %s" request) @@ -4449,25 +4486,6 @@ ;;; The Custom Mode. -(defvar custom-mode-map - ;; This keymap should be dense, but a dense keymap would prevent inheriting - ;; "\r" bindings from the parent map. - ;; Actually, this misfeature of dense keymaps was fixed on 2001-11-26. - (let ((map (make-keymap))) - (set-keymap-parent map widget-keymap) - (define-key map [remap self-insert-command] 'Custom-no-edit) - (define-key map "\^m" 'Custom-newline) - (define-key map " " 'scroll-up) - (define-key map "\177" 'scroll-down) - (define-key map "\C-c\C-c" 'Custom-set) - (define-key map "\C-x\C-s" 'Custom-save) - (define-key map "q" 'Custom-buffer-done) - (define-key map "u" 'Custom-goto-parent) - (define-key map "n" 'widget-forward) - (define-key map "p" 'widget-backward) - map) - "Keymap for `custom-mode'.") - (defun Custom-no-edit (pos &optional event) "Invoke button at POS, or refuse to allow editing of Custom buffer." (interactive "@d")
--- a/lisp/dired-aux.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/dired-aux.el Tue Nov 07 23:22:48 2006 +0000 @@ -1182,12 +1182,20 @@ dired-create-files-failures) (setq files nil) (dired-log "Copying error for %s:\n%s\n" from err))))) - (while files - (dired-copy-file-recursive - (expand-file-name (car files) from) - (expand-file-name (car files) to) - ok-flag preserve-time nil recursive) - (pop files))) + (dolist (file files) + (let ((thisfrom (expand-file-name file from)) + (thisto (expand-file-name file to))) + ;; Catch errors copying within a directory, + ;; and report them through the dired log mechanism + ;; just as our caller will do for the top level files. + (condition-case err + (dired-copy-file-recursive + thisfrom thisto + ok-flag preserve-time nil recursive) + (file-error + (push (dired-make-relative thisfrom) + dired-create-files-failures) + (dired-log "Copying error for %s:\n%s\n" thisfrom err)))))) ;; Not a directory. (or top (dired-handle-overwrite to)) (condition-case err @@ -1198,11 +1206,7 @@ (file-date-error (push (dired-make-relative from) dired-create-files-failures) - (dired-log "Can't set date on %s:\n%s\n" from err)) - (file-error - (push (dired-make-relative from) - dired-create-files-failures) - (dired-log "Copying error for %s:\n%s\n" from err)))))) + (dired-log "Can't set date on %s:\n%s\n" from err)))))) ;;;###autoload (defun dired-rename-file (file newname ok-if-already-exists)
--- a/lisp/dired.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/dired.el Tue Nov 07 23:22:48 2006 +0000 @@ -791,6 +791,9 @@ (run-hooks 'dired-before-readin-hook) (if (consp buffer-undo-list) (setq buffer-undo-list nil)) + (make-local-variable 'file-name-coding-system) + (setq file-name-coding-system + (or coding-system-for-read file-name-coding-system)) (let (buffer-read-only ;; Don't make undo entries for readin. (buffer-undo-list t))
--- a/lisp/emacs-lisp/authors.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/emacs-lisp/authors.el Tue Nov 07 23:22:48 2006 +0000 @@ -176,7 +176,7 @@ Changes to files in this list are not listed.") (defconst authors-fixed-entries - '(("Richard M. Stallman" :wrote "[The original GNU emacs and numerous files]") + '(("Richard M. Stallman" :wrote "[The original GNU Emacs and numerous files]") ("Joseph Arceneaux" :wrote "xrdb.c") ("Blitz Product Development Corporation" :wrote "ispell.el") ("Frank Bresz" :wrote "diff.el")
--- a/lisp/emacs-lisp/checkdoc.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/emacs-lisp/checkdoc.el Tue Nov 07 23:22:48 2006 +0000 @@ -2155,7 +2155,7 @@ (defun checkdoc-rogue-space-check-engine (&optional start end interact) "Return a message list if there is a line with white space at the end. If `checkdoc-autofix-flag' permits, delete that whitespace instead. -If optional arguments START and END are non nil, bound the check to +If optional arguments START and END are non-nil, bound the check to this region. Optional argument INTERACT may permit the user to fix problems on the fly." (let ((p (point))
--- a/lisp/emacs-lisp/cust-print.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/emacs-lisp/cust-print.el Tue Nov 07 23:22:48 2006 +0000 @@ -256,7 +256,7 @@ (defun custom-print-install () "Replace print functions with general, customizable, Lisp versions. -The emacs subroutines are saved away, and you can reinstall them +The Emacs subroutines are saved away, and you can reinstall them by running `custom-print-uninstall'." (interactive) (mapcar 'cust-print-set-function-cell @@ -271,7 +271,7 @@ t) (defun custom-print-uninstall () - "Reset print functions to their emacs subroutines." + "Reset print functions to their Emacs subroutines." (interactive) (mapcar 'cust-print-set-function-cell '((prin1 cust-print-original-prin1) @@ -375,7 +375,7 @@ the argument used by %d, %b, %o, %x or %c must be a number. This is the custom-print replacement for the standard `format'. It -calls the emacs `format' after first making strings for list, +calls the Emacs `format' after first making strings for list, vector, or symbol args. The format specification for such args should be `%s' in any case, so a string argument will also work. The string is generated with `custom-prin1-to-string', which quotes quotable
--- a/lisp/emacs-lisp/find-func.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/emacs-lisp/find-func.el Tue Nov 07 23:22:48 2006 +0000 @@ -264,7 +264,7 @@ the buffer, returns (BUFFER). If the file where FUNCTION is defined is not known, then it is -searched for in `find-function-source-path' if non nil, otherwise +searched for in `find-function-source-path' if non-nil, otherwise in `load-path'." (if (not function) (error "You didn't specify a function")) @@ -357,7 +357,7 @@ Set mark before moving, if the buffer already existed. The library where FUNCTION is defined is searched for in -`find-function-source-path', if non nil, otherwise in `load-path'. +`find-function-source-path', if non-nil, otherwise in `load-path'. See also `find-function-recenter-line' and `find-function-after-hook'." (interactive (find-function-read)) (find-function-do-it function nil 'switch-to-buffer)) @@ -387,7 +387,7 @@ If the variable's definition can't be found in the buffer, return (BUFFER). The library where VARIABLE is defined is searched for in FILE or -`find-function-source-path', if non nil, otherwise in `load-path'." +`find-function-source-path', if non-nil, otherwise in `load-path'." (if (not variable) (error "You didn't specify a variable") (let ((library (or file @@ -406,7 +406,7 @@ Set mark before moving, if the buffer already existed. The library where VARIABLE is defined is searched for in -`find-function-source-path', if non nil, otherwise in `load-path'. +`find-function-source-path', if non-nil, otherwise in `load-path'. See also `find-function-recenter-line' and `find-function-after-hook'." (interactive (find-function-read 'defvar)) (find-function-do-it variable 'defvar 'switch-to-buffer)) @@ -436,7 +436,7 @@ buffer nor display it. The library where SYMBOL is defined is searched for in FILE or -`find-function-source-path', if non nil, otherwise in `load-path'." +`find-function-source-path', if non-nil, otherwise in `load-path'." (cond ((not symbol) (error "You didn't specify a symbol")) @@ -461,7 +461,7 @@ Set mark before moving, if the buffer already existed. The library where FACE is defined is searched for in -`find-function-source-path', if non nil, otherwise in `load-path'. +`find-function-source-path', if non-nil, otherwise in `load-path'. See also `find-function-recenter-line' and `find-function-after-hook'." (interactive (find-function-read 'defface)) (find-function-do-it face 'defface 'switch-to-buffer))
--- a/lisp/emacs-lisp/lselect.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/emacs-lisp/lselect.el Tue Nov 07 23:22:48 2006 +0000 @@ -191,7 +191,7 @@ "If there is a selection, delete the text it covers, and copy it to both the kill ring and the Clipboard." (interactive) - (or (x-selection-owner-p) (error "emacs does not own the primary selection")) + (or (x-selection-owner-p) (error "Emacs does not own the primary selection")) (setq last-command nil) (or primary-selection-extent (error "the primary selection is not an extent?")) @@ -205,7 +205,7 @@ "If there is a selection, delete the text it covers *without* copying it to the kill ring or the Clipboard." (interactive) - (or (x-selection-owner-p) (error "emacs does not own the primary selection")) + (or (x-selection-owner-p) (error "Emacs does not own the primary selection")) (setq last-command nil) (or primary-selection-extent (error "the primary selection is not an extent?")) @@ -219,7 +219,7 @@ "If there is a selection, copy it to both the kill ring and the Clipboard." (interactive) (setq last-command nil) - (or (x-selection-owner-p) (error "emacs does not own the primary selection")) + (or (x-selection-owner-p) (error "Emacs does not own the primary selection")) (or primary-selection-extent (error "the primary selection is not an extent?")) (save-excursion
--- a/lisp/emacs-lisp/pp.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/emacs-lisp/pp.el Tue Nov 07 23:22:48 2006 +0000 @@ -161,7 +161,7 @@ (set-syntax-table stab) (if arg (insert (pp-to-string (eval exp))) - (pp-eval-expression exp)))) + (pp-eval-expression (eval exp))))) ;;; Test cases for quote ;; (pp-eval-expression ''(quote quote))
--- a/lisp/emacs-lisp/shadow.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/emacs-lisp/shadow.el Tue Nov 07 23:22:48 2006 +0000 @@ -184,17 +184,17 @@ XXX.el in the site-lisp directory is referred to by all of: \(require 'XXX\), \(autoload .... \"XXX\"\), \(load-library \"XXX\"\) etc. -The first XXX.el file prevents emacs from seeing the second \(unless -the second is loaded explicitly via load-file\). +The first XXX.el file prevents Emacs from seeing the second \(unless +the second is loaded explicitly via `load-file'\). When not intended, such shadowings can be the source of subtle problems. For example, the above situation may have arisen because the -XXX package was not distributed with versions of emacs prior to -19.30. An emacs maintainer downloaded XXX from elsewhere and installed -it. Later, XXX was updated and included in the emacs distribution. -Unless the emacs maintainer checks for this, the new version of XXX +XXX package was not distributed with versions of Emacs prior to +19.30. An Emacs maintainer downloaded XXX from elsewhere and installed +it. Later, XXX was updated and included in the Emacs distribution. +Unless the Emacs maintainer checks for this, the new version of XXX will be hidden behind the old \(which may no longer work with the new -emacs version\). +Emacs version\). This function performs these checks and flags all possible shadowings. Because a .el file may exist without a corresponding .elc
--- a/lisp/emacs-lock.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/emacs-lock.el Tue Nov 07 23:22:48 2006 +0000 @@ -38,7 +38,7 @@ ;;; Code: (defvar emacs-lock-from-exiting nil - "Whether emacs is locked to prevent exiting. See `check-emacs-lock'.") + "Whether Emacs is locked to prevent exiting. See `check-emacs-lock'.") (make-variable-buffer-local 'emacs-lock-from-exiting) (defvar emacs-lock-buffer-locked nil
--- a/lisp/emulation/edt-mapper.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/emulation/edt-mapper.el Tue Nov 07 23:22:48 2006 +0000 @@ -202,7 +202,7 @@ Sometimes, edt-mapper will ignore a key you press, and just continue to prompt for the same key. This can happen when your window manager sucks - up the key and doesn't pass it on to emacs, or it could be an emacs bug. + up the key and doesn't pass it on to Emacs, or it could be an Emacs bug. Either way, there's nothing that edt-mapper can do about it. You must press RETURN, to skip the current key and continue. Later, you and/or your local system guru can try to figure out why the key is being ignored.
--- a/lisp/emulation/tpu-edt.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/emulation/tpu-edt.el Tue Nov 07 23:22:48 2006 +0000 @@ -432,7 +432,7 @@ (let ((map (make-keymap))) (define-key map "\e[" GOLD-CSI-map) ; GOLD-CSI map (define-key map "\eO" GOLD-SS3-map) ; GOLD-SS3 map - ;; + ;; (define-key map "\C-A" 'tpu-toggle-overwrite-mode) ; ^A (define-key map "\C-B" 'nil) ; ^B (define-key map "\C-C" 'nil) ; ^C @@ -557,7 +557,7 @@ (defvar SS3-map (let ((map (make-sparse-keymap))) (define-key map "P" GOLD-map) ; GOLD map - ;; + ;; (define-key map "A" 'tpu-previous-line) ; up (define-key map "B" 'tpu-next-line) ; down (define-key map "C" 'tpu-forward-char) ; right @@ -1141,7 +1141,7 @@ R Toggle rectangular mode for remove and insert S Search and substitute - line mode REPLACE command - ^T Toggle control key bindings between TPU and emacs + ^T Toggle control key bindings between TPU and Emacs U Undo - undo the last edit W Write - save current buffer X Exit - save all modified buffers and exit @@ -1292,7 +1292,7 @@ (kill-buffer (current-buffer))) (defun tpu-save-all-buffers-kill-emacs nil - "Save all buffers and exit emacs." + "Save all buffers and exit Emacs." (interactive) (let ((delete-old-versions t)) (save-buffers-kill-emacs t))) @@ -1852,8 +1852,8 @@ (message "Replaced %s occurrence%s." strings (if (not (= 1 strings)) "s" "")))) (defun tpu-emacs-replace (&optional dont-ask) - "A TPU-edt interface to the emacs replace functions. If TPU-edt is -currently in regular expression mode, the emacs regular expression + "A TPU-edt interface to the Emacs replace functions. If TPU-edt is +currently in regular expression mode, the Emacs regular expression replace functions are used. If an argument is supplied, replacements are performed without asking. Only works in forward direction." (interactive "P") @@ -2285,7 +2285,7 @@ (setq tpu-control-keys t)) (defun tpu-reset-control-keys (tpu-style) - "Set control keys to TPU or emacs style functions." + "Set control keys to TPU or Emacs style functions." (let* ((tpu (and tpu-style (not tpu-control-keys))) (emacs (and (not tpu-style) tpu-control-keys)) (doit (or tpu emacs)))
--- a/lisp/emulation/vip.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/emulation/vip.el Tue Nov 07 23:22:48 2006 +0000 @@ -45,7 +45,7 @@ ;; external variables (defvar vip-emacs-local-map nil - "Local map used in emacs mode. (Buffer-specific.)") + "Local map used in Emacs mode. (Buffer-specific.)") (defvar vip-insert-local-map nil "Local map used in insert command mode. (Buffer-specific.)") @@ -447,7 +447,7 @@ (vip-change-mode 'insert-mode)) (defun vip-change-mode-to-emacs () - "Change mode to emacs mode." + "Change mode to Emacs mode." (interactive) (vip-change-mode 'emacs-mode))
--- a/lisp/emulation/viper-init.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/emulation/viper-init.el Tue Nov 07 23:22:48 2006 +0000 @@ -438,7 +438,7 @@ ;; confused in some cases. So, this var is nulled for now. ;; (defcustom viper-emacs-state-cursor-color "Magenta" (defcustom viper-emacs-state-cursor-color nil - "Cursor color when Viper is in emacs state." + "Cursor color when Viper is in Emacs state." :type 'string :group 'viper) (if (fboundp 'make-variable-frame-local)
--- a/lisp/emulation/viper-keym.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/emulation/viper-keym.el Tue Nov 07 23:22:48 2006 +0000 @@ -144,7 +144,7 @@ "Auxiliary map for global user-defined bindings in Emacs state.") (defvar viper-emacs-kbd-map (make-sparse-keymap) - "This keymap keeps Vi-style kbd macros for emacs mode.") + "This keymap keeps Vi-style kbd macros for Emacs mode.") (viper-deflocalvar viper-emacs-local-user-map (make-sparse-keymap) "Auxiliary map for local user-defined bindings in Emacs state.") @@ -160,10 +160,10 @@ ;; Some important keys used in viper (defcustom viper-toggle-key [(control ?z)] ; "\C-z" - "The key used to change states from emacs to Vi and back. + "The key used to change states from Emacs to Vi and back. In insert mode, this key also functions as Meta. -Enter as a sexp. Examples: \"\\C-z\", [(control ?z)]." +Enter as a sexp. Examples: \"\\C-z\", [(control ?z)]." :type 'sexp :group 'viper :set (lambda (symbol value)
--- a/lisp/emulation/viper.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/emulation/viper.el Tue Nov 07 23:22:48 2006 +0000 @@ -359,7 +359,7 @@ (defcustom viper-mode (cond (noninteractive nil) (t 'ask)) "To Viperize or not to Viperize. -If t, viperize emacs. If nil -- don't. If `ask', ask the user. +If t, viperize Emacs. If nil -- don't. If `ask', ask the user. This variable is used primatily when Viper is being loaded. Must be set in `~/.emacs' before Viper is loaded. @@ -502,10 +502,10 @@ The list has the structure: ((mode viper-state keymap) (mode viper-state keymap) ...). If `mode' is on the list, the `kemap' will be made active (on the minor-mode-map-alist) in the specified viper state. -If you change this list, have to restart emacs for the change to take effect. -However, if you did the change through the customization widget, then emacs +If you change this list, have to restart Emacs for the change to take effect. +However, if you did the change through the customization widget, then Emacs needs to be restarted only if you deleted a triple mode-state-keymap from the -list. No need to restart emacs in case of insertion or modification of an +list. No need to restart Emacs in case of insertion or modification of an existing triple." :type '(repeat (list symbol @@ -891,7 +891,7 @@ (eval-after-load "passwd" '(defadvice read-passwd-1 (before viper-passwd-ad activate) - "Switch to emacs state while reading password." + "Switch to Emacs state while reading password." (viper-change-state-to-emacs))) (defadvice self-insert-command (around viper-self-insert-ad activate) @@ -939,7 +939,7 @@ (eval-after-load "rmailedit" '(defadvice rmail-cease-edit (after viper-rmail-advice activate) - "Switch to emacs state when done editing message." + "Switch to Emacs state when done editing message." (viper-change-state-to-emacs))) ;; In case RMAIL was loaded before Viper. (defadvice rmail-cease-edit (after viper-rmail-advice activate) @@ -1121,7 +1121,7 @@ (save-window-excursion (with-output-to-temp-buffer " *viper-info*" (princ " -You have loaded Viper, and are about to Viperize your emacs! +You have loaded Viper, and are about to Viperize your Emacs! Viper is a Package for Emacs Rebels and a venomous VI PERil,
--- a/lisp/erc/ChangeLog Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/erc/ChangeLog Tue Nov 07 23:22:48 2006 +0000 @@ -1,3 +1,11 @@ +2006-11-06 Juanma Barranquero <lekktu@gmail.com> + + * erc-dcc.el (erc-dcc-send-file): Fix typo in error message. + + * erc.el (read-passwd): + * erc-autoaway.el (erc-autoaway-reestablish-idletimer): + * erc-truncate.el (truncate): Fix typo in docstring. + 2006-08-13 Romain Francoise <romain@orebokech.com> * erc-match.el (erc-log-matches-make-buffer): End `y-or-n-p' @@ -256,7 +264,7 @@ 2006-05-01 Edward O'Connor <ted@oconnor.cx> - * erc-goodies.el: (erc-handle-irc-url): New function, suitable as + * erc-goodies.el (erc-handle-irc-url): New function, suitable as a value for `url-irc-function'. 2006-04-18 Diane Murray <disumu@x3y2z1.net> @@ -360,14 +368,14 @@ 2006-02-12 Michael Olson <mwolson@gnu.org> - * erc-autoaway.el, erc-dcc.el, erc-ezbounce.el, erc-fill.el, - erc-goodies.el, erc-hecomplete.el, erc-ibuffer.el, erc-identd.el, - erc-imenu.el, erc-join.el, erc-lang.el, erc-list.el, erc-log.el, - erc-match.el, erc-menu.el, erc-netsplit.el, erc-networks.el, - erc-notify.el, erc-page.el, erc-pcomplete.el, erc-replace.el, - erc-ring.el, erc-services.el, erc-sound.el, erc-speedbar.el, - erc-spelling.el, erc-track.el, erc-truncate.el, erc-xdcc.el: Add - 2006 to copyright years, to comply with the changed guidelines. + * erc-autoaway.el, erc-dcc.el, erc-ezbounce.el, erc-fill.el + * erc-goodies.el, erc-hecomplete.el, erc-ibuffer.el, erc-identd.el + * erc-imenu.el, erc-join.el, erc-lang.el, erc-list.el, erc-log.el + * erc-match.el, erc-menu.el, erc-netsplit.el, erc-networks.el + * erc-notify.el, erc-page.el, erc-pcomplete.el, erc-replace.el + * erc-ring.el, erc-services.el, erc-sound.el, erc-speedbar.el + * erc-spelling.el, erc-track.el, erc-truncate.el, erc-xdcc.el: + Add 2006 to copyright years, to comply with the changed guidelines. 2006-02-11 Michael Olson <mwolson@gnu.org> @@ -528,7 +536,7 @@ 2006-01-29 Edward O'Connor <ted@oconnor.cx> - * erc-viper.el: Remove. Now that ERC is included in Emacs, these + * erc-viper.el: Remove. Now that ERC is included in Emacs, these work-arounds live in Viper itself. 2006-01-28 Michael Olson <mwolson@gnu.org> @@ -669,10 +677,10 @@ 2006-01-22 Johan Bockgård <bojohan@users.sourceforge.net> * erc-track.el: Use `(eval-when-compile (require 'cl))' (for - `case'). Doc fixes. + `case'). Doc fixes. (erc-find-parsed-property): Simplify. - (erc-track-get-active-buffer): Fix logic. Simplify. - (erc-track-switch-buffer): Remove unused variable `dir'. Simplify. + (erc-track-get-active-buffer): Fix logic. Simplify. + (erc-track-switch-buffer): Remove unused variable `dir'. Simplify. * erc-speak.el: Doc fixes. (erc-speak-region): `propertize' --> `erc-propertize'.
--- a/lisp/erc/erc-autoaway.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/erc/erc-autoaway.el Tue Nov 07 23:22:48 2006 +0000 @@ -136,7 +136,7 @@ (eval-when-compile (defvar erc-autoaway-idle-seconds)) (defun erc-autoaway-reestablish-idletimer () - "Reestablish the emacs idletimer. + "Reestablish the Emacs idletimer. If `erc-autoaway-idle-method' is 'emacs, you must call this function each time you change `erc-autoaway-idle-seconds'." (interactive)
--- a/lisp/erc/erc-dcc.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/erc/erc-dcc.el Tue Nov 07 23:22:48 2006 +0000 @@ -808,7 +808,7 @@ (erc-ip-to-decimal (nth 0 contact)) (nth 1 contact) size))) - (error "`make-network-process' not supported by your emacs."))) + (error "`make-network-process' not supported by your Emacs"))) ;;; GET handling
--- a/lisp/erc/erc-truncate.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/erc/erc-truncate.el Tue Nov 07 23:22:48 2006 +0000 @@ -48,7 +48,7 @@ (define-erc-module truncate nil "Truncate a query buffer if it gets too large. This prevents the query buffer from getting too large, which can -bring any grown emacs to its knees after a few days worth of +bring any grown Emacs to its knees after a few days worth of tracking heavy-traffic channels." ;;enable ((add-hook 'erc-insert-post-hook 'erc-truncate-buffer))
--- a/lisp/erc/erc.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/erc/erc.el Tue Nov 07 23:22:48 2006 +0000 @@ -2002,7 +2002,7 @@ (if (not (fboundp 'read-passwd)) (defun read-passwd (prompt) - "Substitute for read-passwd in early emacsen" + "Substitute for `read-passwd' in early emacsen." (read-from-minibuffer prompt))) (defcustom erc-before-connect nil
--- a/lisp/expand.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/expand.el Tue Nov 07 23:22:48 2006 +0000 @@ -296,7 +296,7 @@ (defvar expand-list nil "Temporary variable used by the Expand package.") (defvar expand-pos nil - "If non nil, stores a vector containing markers to positions defined by the last expansion. + "If non-nil, stores a vector containing markers to positions defined by the last expansion. This variable is local to a buffer.") (make-variable-buffer-local 'expand-pos)
--- a/lisp/faces.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/faces.el Tue Nov 07 23:22:48 2006 +0000 @@ -1351,6 +1351,7 @@ (insert " undefined face.\n") (let ((customize-label "customize this face") file-name) + (insert (concat " (" (propertize "sample" 'font-lock-face f) ")")) (princ (concat " (" customize-label ")\n")) (insert "Documentation: " (or (face-documentation f)
--- a/lisp/ffap.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/ffap.el Tue Nov 07 23:22:48 2006 +0000 @@ -4,7 +4,7 @@ ;; 2005, 2006 Free Software Foundation, Inc. ;; Author: Michelangelo Grigni <mic@mathcs.emory.edu> -;; Maintainer: Rajesh Vaidheeswarran <rv@gnu.org> +;; Maintainer: FSF ;; Created: 29 Mar 1993 ;; Keywords: files, hypermedia, matching, mouse, convenience ;; X-URL: ftp://ftp.mathcs.emory.edu/pub/mic/emacs/
--- a/lisp/files.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/files.el Tue Nov 07 23:22:48 2006 +0000 @@ -4094,6 +4094,15 @@ (if auto-save-p 'auto-save-coding (or coding-system-for-read buffer-file-coding-system-explicit)))) + (if (and (not enable-multibyte-characters) + (not (memq (coding-system-base + coding-system-for-read) + '(no-conversion raw-text)))) + ;; As a coding system suitable for multibyte + ;; buffer is specified, make the current + ;; buffer multibyte. + (set-buffer-multibyte t)) + ;; This force after-insert-file-set-coding ;; (called from insert-file-contents) to set ;; buffer-file-coding-system to a proper value.
--- a/lisp/follow.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/follow.el Tue Nov 07 23:22:48 2006 +0000 @@ -449,7 +449,7 @@ (if follow-mode menu '(["Activate " follow-mode t])))) - + mainmap) "Minor mode keymap for Follow mode.") @@ -473,7 +473,7 @@ :group 'follow) (defvar follow-avoid-tail-recenter-p (not (featurep 'xemacs)) - "*When non-nil, patch emacs so that tail windows won't be recentered. + "*When non-nil, patch Emacs so that tail windows won't be recentered. A \"tail window\" is a window that displays only the end of the buffer. Normally it is practical for the user that empty
--- a/lisp/gnus/ChangeLog Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/gnus/ChangeLog Tue Nov 07 23:22:48 2006 +0000 @@ -1,7 +1,23 @@ +2006-11-03 Juanma Barranquero <lekktu@gmail.com> + + * gnus-diary.el (gnus-diary-delay-format-function): + * nndiary.el (nndiary-reminders): + * nnsoup.el (nnsoup-always-save): Use "non-nil" in docstrings. + +2006-11-01 Reiner Steib <Reiner.Steib@gmx.de> + + * gnus-art.el (article-hide-boring-headers): Fetch date from + gnus-original-article-buffer to avoid problems with localized date + strings. + +2006-10-30 Katsumi Yamaoka <yamaoka@jpl.org> + + * html2text.el (html2text-format-tags): Avoid infloop on open tags. + 2006-10-29 Reiner Steib <Reiner.Steib@gmx.de> - * mm-util.el (mm-codepage-iso-8859-list, mm-codepage-ibm-list): New - variables. + * mm-util.el (mm-codepage-iso-8859-list, mm-codepage-ibm-list): + New variables. (mm-setup-codepage-iso-8859, mm-setup-codepage-ibm): New functions. (mm-charset-synonym-alist): Move some entries to mm-codepage-iso-8859-list. @@ -610,7 +626,7 @@ (rfc2231-encode-string): Be sure to work on multibyte buffer at first, and after mm-encode-body, change the buffer to unibyte. -2006-03-21 Daniel Pittman <daniel@rimspace.net> +2006-03-21 Daniel Pittman <daniel@rimspace.net> * nnimap.el (nnimap-request-update-info-internal): Optimize. Don't `gnus-uncompress-range' to avoid excessive memory usage.
--- a/lisp/gnus/gnus-art.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/gnus/gnus-art.el Tue Nov 07 23:22:48 2006 +0000 @@ -1917,7 +1917,11 @@ 'string<)))) (gnus-article-hide-header "reply-to"))))) ((eq elem 'date) - (let ((date (message-fetch-field "date"))) + (let ((date (with-current-buffer gnus-original-article-buffer + ;; If date in `gnus-article-buffer' is localized + ;; (`gnus-treat-date-user-defined'), + ;; `days-between' might fail. + (message-fetch-field "date")))) (when (and date (< (days-between (current-time-string) date) 4))
--- a/lisp/gnus/gnus-diary.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/gnus/gnus-diary.el Tue Nov 07 23:22:48 2006 +0000 @@ -121,7 +121,7 @@ (defcustom gnus-diary-delay-format-function 'gnus-diary-delay-format-english "*Function called to format a diary delay string. -It is passed two arguments. The first one is non nil if the delay is in +It is passed two arguments. The first one is non-nil if the delay is in the past. The second one is of the form ((NUM . UNIT) ...) where NUM is an integer and UNIT is one of 'year 'month 'week 'day 'hour or 'minute. It should return strings like \"In 2 months, 3 weeks\", \"3 hours,
--- a/lisp/gnus/html2text.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/gnus/html2text.el Tue Nov 07 23:22:48 2006 +0000 @@ -423,7 +423,9 @@ (p3) (p4)) (search-backward "<" (point-min) t) (setq p1 (point)) - (re-search-forward (format "</%s>" tag) (point-max) t) + (unless (search-forward (format "</%s>" tag) (point-max) t) + (goto-char p2) + (insert (format "</%s>" tag))) (setq p4 (point)) (search-backward "</" (point-min) t) (setq p3 (point))
--- a/lisp/gnus/nndiary.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/gnus/nndiary.el Tue Nov 07 23:22:48 2006 +0000 @@ -263,7 +263,7 @@ NOTE: the units of measure actually express dates, not durations: if you use 'week, messages will pop up on Sundays at 00:00 (or Mondays if -`nndiary-week-starts-on-monday' is non nil) and *not* 7 days before the +`nndiary-week-starts-on-monday' is non-nil) and *not* 7 days before the appointement, if you use 'month, messages will pop up on the first day of each months, at 00:00 and so on.
--- a/lisp/gnus/nnsoup.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/gnus/nnsoup.el Tue Nov 07 23:22:48 2006 +0000 @@ -75,7 +75,7 @@ "*Regular expression matching SOUP packets in `nnsoup-packet-directory'.") (defvoo nnsoup-always-save t - "If non nil commit the reply buffer on each message send. + "If non-nil commit the reply buffer on each message send. This is necessary if using message mode outside Gnus with nnsoup as a backend for the messages.")
--- a/lisp/help-fns.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/help-fns.el Tue Nov 07 23:22:48 2006 +0000 @@ -35,72 +35,6 @@ (require 'help-mode) - -;;;###autoload -(defun help-with-tutorial (&optional arg) - "Select the Emacs learn-by-doing tutorial. -If there is a tutorial version written in the language -of the selected language environment, that version is used. -If there's no tutorial in that language, `TUTORIAL' is selected. -With ARG, you are asked to choose which language." - (interactive "P") - (let ((lang (if arg - (let ((minibuffer-setup-hook minibuffer-setup-hook)) - (add-hook 'minibuffer-setup-hook - 'minibuffer-completion-help) - (read-language-name 'tutorial "Language: " "English")) - (if (get-language-info current-language-environment 'tutorial) - current-language-environment - "English"))) - file filename) - (setq filename (get-language-info lang 'tutorial)) - (setq file (expand-file-name (concat "~/" filename))) - (delete-other-windows) - (if (get-file-buffer file) - (switch-to-buffer (get-file-buffer file)) - (switch-to-buffer (create-file-buffer file)) - (setq buffer-file-name file) - (setq default-directory (expand-file-name "~/")) - (setq buffer-auto-save-file-name nil) - (insert-file-contents (expand-file-name filename data-directory)) - (hack-local-variables) - (goto-char (point-min)) - (search-forward "\n<<") - (beginning-of-line) - ;; Convert the <<...>> line to the proper [...] line, - ;; or just delete the <<...>> line if a [...] line follows. - (cond ((save-excursion - (forward-line 1) - (looking-at "\\[")) - (delete-region (point) (progn (forward-line 1) (point)))) - ((looking-at "<<Blank lines inserted.*>>") - (replace-match "[Middle of page left blank for didactic purposes. Text continues below]")) - (t - (looking-at "<<") - (replace-match "[") - (search-forward ">>") - (replace-match "]"))) - (beginning-of-line) - (let ((n (- (window-height (selected-window)) - (count-lines (point-min) (point)) - 6))) - (if (< n 8) - (progn - ;; For a short gap, we don't need the [...] line, - ;; so delete it. - (delete-region (point) (progn (end-of-line) (point))) - (newline n)) - ;; Some people get confused by the large gap. - (newline (/ n 2)) - - ;; Skip the [...] line (don't delete it). - (forward-line 1) - (newline (- n (/ n 2))))) - (goto-char (point-min)) - (setq buffer-undo-list nil) - (set-buffer-modified-p nil)))) - - ;; Functions ;;;###autoload
--- a/lisp/help.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/help.el Tue Nov 07 23:22:48 2006 +0000 @@ -361,7 +361,7 @@ ((<= version 18) (setq version (format "%d" version))) ((> version emacs-major-version) - (error "No news about emacs %d (yet)" version)))) + (error "No news about Emacs %d (yet)" version)))) (let* ((vn (if (stringp version) (string-to-number version) version))
--- a/lisp/hexl.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/hexl.el Tue Nov 07 23:22:48 2006 +0000 @@ -169,7 +169,7 @@ 000000b0: 7461 626c 6520 6368 6172 6163 7465 7220 table character 000000c0: 7265 6769 6f6e 2e0a region.. -Movement is as simple as movement in a normal emacs text buffer. Most +Movement is as simple as movement in a normal Emacs text buffer. Most cursor movement bindings are the same (ie. Use \\[hexl-backward-char], \\[hexl-forward-char], \\[hexl-next-line], and \\[hexl-previous-line] to move the cursor left, right, down, and up).
--- a/lisp/info-look.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/info-look.el Tue Nov 07 23:22:48 2006 +0000 @@ -250,10 +250,10 @@ ;;;###autoload (defun info-lookup-symbol (symbol &optional mode) "Display the definition of SYMBOL, as found in the relevant manual. -When this command is called interactively, it reads SYMBOL from the minibuffer. -In the minibuffer, use M-n to yank the default argument value -into the minibuffer so you can edit it. -The default symbol is the one found at point. +When this command is called interactively, it reads SYMBOL from the +minibuffer. In the minibuffer, use M-n to yank the default argument +value into the minibuffer so you can edit it. The default symbol is the +one found at point. With prefix arg a query for the symbol help mode is offered." (interactive @@ -566,6 +566,45 @@ (concat prefix name)))) (error nil))) +(defun info-lookup-guess-custom-symbol () + "Get symbol at point in custom buffers." + (condition-case nil + (save-excursion + (let ((case-fold-search t) + (ignored-chars "][()`',:.\" \t\n") + (significant-chars "^][()`',:.\" \t\n") + beg end) + (cond + ((and (memq (get-char-property (point) 'face) + '(custom-variable-tag custom-variable-tag-face)) + (setq beg (previous-single-char-property-change + (point) 'face nil (line-beginning-position))) + (setq end (next-single-char-property-change + (point) 'face nil (line-end-position))) + (> end beg)) + (subst-char-in-string + ?\ ?\- (buffer-substring-no-properties beg end))) + ((or (and (looking-at (concat "[" significant-chars "]")) + (save-excursion + (skip-chars-backward significant-chars) + (setq beg (point))) + (skip-chars-forward significant-chars) + (setq end (point)) + (> end beg)) + (and (looking-at "[ \t\n]") + (looking-back (concat "[" significant-chars "]")) + (setq end (point)) + (skip-chars-backward significant-chars) + (setq beg (point)) + (> end beg)) + (and (skip-chars-forward ignored-chars) + (setq beg (point)) + (skip-chars-forward significant-chars) + (setq end (point)) + (> end beg))) + (buffer-substring-no-properties beg end))))) + (error nil))) + ;;;###autoload (defun info-complete-symbol (&optional mode) "Perform completion on symbol preceding point." @@ -789,7 +828,7 @@ (info-lookup-maybe-add-help :mode 'emacs-lisp-mode - :regexp "[^][()'\" \t\n]+" + :regexp "[^][()`',\" \t\n]+" :doc-spec '(;; Commands with key sequences appear in nodes as `foo' and ;; those without as `M-x foo'. ("(emacs)Command Index" nil "`\\(M-x[ \t\n]+\\)?" "'") @@ -806,13 +845,13 @@ (info-lookup-maybe-add-help :mode 'lisp-interaction-mode - :regexp "[^][()'\" \t\n]+" + :regexp "[^][()`',\" \t\n]+" :parse-rule 'ignore :other-modes '(emacs-lisp-mode)) (info-lookup-maybe-add-help :mode 'lisp-mode - :regexp "[^()'\" \t\n]+" + :regexp "[^()`',\" \t\n]+" :parse-rule 'ignore :other-modes '(emacs-lisp-mode)) @@ -913,6 +952,18 @@ ;; This gets functions in evaluated classes. Other ;; possible patterns don't seem to work too well. "`" "("))) + +(info-lookup-maybe-add-help + :mode 'custom-mode + :ignore-case t + :regexp "[^][()`',:\" \t\n]+" + :parse-rule 'info-lookup-guess-custom-symbol + :other-modes '(emacs-lisp-mode)) + +(info-lookup-maybe-add-help + :mode 'help-mode + :regexp "[^][()`',:\" \t\n]+" + :other-modes '(emacs-lisp-mode)) (provide 'info-look)
--- a/lisp/international/ja-dic-cnv.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/international/ja-dic-cnv.el Tue Nov 07 23:22:48 2006 +0000 @@ -345,7 +345,7 @@ (insert ")\n\n"))) (defun skkdic-convert (filename &optional dirname) - "Generate Emacs lisp file form Japanese dictionary file FILENAME. + "Generate Emacs Lisp file form Japanese dictionary file FILENAME. The format of the dictionary file should be the same as SKK dictionaries. Optional argument DIRNAME if specified is the directory name under which the generated Emacs Lisp is saved.
--- a/lisp/international/mule.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/international/mule.el Tue Nov 07 23:22:48 2006 +0000 @@ -296,10 +296,10 @@ (defun load-with-code-conversion (fullname file &optional noerror nomessage) "Execute a file of Lisp code named FILE whose absolute name is FULLNAME. The file contents are decoded before evaluation if necessary. -If optional second arg NOERROR is non-nil, +If optional third arg NOERROR is non-nil, report no error if FILE doesn't exist. Print messages at start and end of loading unless - optional third arg NOMESSAGE is non-nil. + optional fourth arg NOMESSAGE is non-nil. Return t if file exists." (if (null (file-readable-p fullname)) (and (null noerror) @@ -358,7 +358,7 @@ (kill-buffer buffer))) (unless purify-flag (do-after-load-evaluation fullname)) - + (unless (or nomessage noninteractive) (if source (message "Loading %s (source)...done" file) @@ -1665,8 +1665,7 @@ system and SOURCE is a symbol `auto-coding-alist', `auto-coding-regexp-alist', `coding:', or `auto-coding-functions' indicating by what CODING is specified. Note that the validity -of CODING is not checked; it's callers responsibility to check -it. +of CODING is not checked; it's callers responsibility to check it. If nothing is specified, the return value is nil." (or (let ((coding-system (auto-coding-alist-lookup filename))) @@ -1687,7 +1686,7 @@ ;; and for "unibyte:" at the head and tail of SIZE bytes. (setq head-found (or (search-forward "coding:" head-end t) (search-forward "unibyte:" head-end t) - (search-forward "enable-character-translation:" + (search-forward "enable-character-translation:" head-end t))) (if (and head-found (> head-found tail-start)) ;; Head and tail are overlapped.
--- a/lisp/loadhist.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/loadhist.el Tue Nov 07 23:22:48 2006 +0000 @@ -119,7 +119,9 @@ (mapcar (lambda (feature) (list (symbol-name feature))) features) - nil t))) + ;; Complete only features loaded from a file + #'(lambda (f) (feature-file (intern (car f)))) + t))) (defvaralias 'loadhist-hook-functions 'unload-feature-special-hooks) (defvar unload-feature-special-hooks
--- a/lisp/mail/emacsbug.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/mail/emacsbug.el Tue Nov 07 23:22:48 2006 +0000 @@ -126,7 +126,7 @@ (setq user-point (point)) (insert "\n\n") - (insert "If emacs crashed, and you have the emacs process in the gdb debugger,\n" + (insert "If Emacs crashed, and you have the Emacs process in the gdb debugger,\n" "please include the output from the following gdb commands:\n" " `bt full' and `xbacktrace'.\n")
--- a/lisp/mail/feedmail.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/mail/feedmail.el Tue Nov 07 23:22:48 2006 +0000 @@ -330,11 +330,11 @@ looking at the top of the message in a buffer when you get the prompt. If set to the symbol 'queued, give the confirmation prompt only while running the queue (however, the prompt is always suppressed if you are -processing the queue via feedmail-run-the-queue-no-prompts). If set +processing the queue via `feedmail-run-the-queue-no-prompts'). If set to the symbol 'immediate, give the confirmation prompt only when sending immediately. For any other non-nil value, prompt in both cases. You can give a timeout for the prompt; see variable -feedmail-confirm-outgoing-timeout." +`feedmail-confirm-outgoing-timeout'." :group 'feedmail-misc :type 'boolean ) @@ -344,7 +344,7 @@ "*If non-nil, a timeout in seconds at the send confirmation prompt. If a positive number, it's a timeout before sending. If a negative number, it's a timeout before not sending. This will not work if your -version of Emacs doesn't include the function y-or-n-p-with-timeout +version of Emacs doesn't include the function `y-or-n-p-with-timeout' \(e.g., some versions of XEmacs\)." :group 'feedmail-misc :type '(choice (const nil) integer) @@ -355,7 +355,7 @@ "*If non-nil remove Bcc: lines from the message headers. In any case, the Bcc: lines do participate in the composed address list. You may want to leave them in if you're using sendmail -\(see feedmail-buffer-eating-function\)." +\(see `feedmail-buffer-eating-function'\)." :group 'feedmail-headers :type 'boolean ) @@ -365,7 +365,7 @@ "*If non-nil remove Resent-Bcc: lines from the message headers. In any case, the Resent-Bcc: lines do participate in the composed address list. You may want to leave them in if you're using sendmail -\(see feedmail-buffer-eating-function\)." +\(see `feedmail-buffer-eating-function'\)." :group 'feedmail-headers :type 'boolean ) @@ -410,7 +410,7 @@ (defcustom feedmail-fill-to-cc-fill-column default-fill-column - "*Fill column used by feedmail-fill-to-cc." + "*Fill column used by `feedmail-fill-to-cc'." :group 'feedmail-headers :type 'integer ) @@ -481,7 +481,7 @@ should be just the contents of the header, not the name of the header itself nor the trailing newline. If a function, it will be called with no arguments. For an explanation of fiddle-plexes, see the -documentation for the variable feedmail-fiddle-plex-blurb. In all +documentation for the variable `feedmail-fiddle-plex-blurb'. In all cases the name element of the fiddle-plex is ignored and is hardwired by feedmail to either \"X-Sender\" or \"X-Resent-Sender\". @@ -498,7 +498,7 @@ "*If non-nil, force writing file as binary (this applies to queues and Fcc:). On systems where there is a difference between binary and text files, feedmail will temporarily manipulate the values of `buffer-file-type' -and/or default-buffer-file-type to make the writing as binary. If +and/or `default-buffer-file-type' to make the writing as binary. If nil, writing will be in text mode. On systems where there is no distinction or where it is controlled by other variables or other means, this option has no effect." @@ -521,7 +521,7 @@ should be just the contents of the header, not the name of the header itself nor the trailing newline. If a function, it will be called with no arguments. For an explanation of fiddle-plexes, see the -documentation for the variable feedmail-fiddle-plex-blurb. In all +documentation for the variable `feedmail-fiddle-plex-blurb'. In all cases the name element of the fiddle-plex is ignored and is hardwired by feedmail to either \"X-From\" or \"X-Resent-From\". @@ -544,7 +544,7 @@ is being sent. If there is no Sender: header, use the From: header, if any. Address values are taken from the actual message just before it is sent, and the process is independent of the values of -feedmail-from-line and/or feedmail-sender-line. +`feedmail-from-line' and/or `feedmail-sender-line'. There are many and good reasons for having the message header From:/Sender: be different from the message envelope \"from\" @@ -595,7 +595,7 @@ should be just the contents of the header, not the name of the header itself nor the trailing newline. If a function, it will be called with no arguments. For an explanation of fiddle-plexes, see the -documentation for the variable feedmail-fiddle-plex-blurb. In all +documentation for the variable `feedmail-fiddle-plex-blurb'. In all cases the name element of the fiddle-plex is ignored and is hardwired by feedmail to either \"X-Mailer\" or \"X-Resent-Mailer\"." :group 'feedmail-headers @@ -619,7 +619,7 @@ itself nor the trailing newline. If a function, it will be called with one argument: the possibly-nil name of the file associated with the message buffer. For an explanation of fiddle-plexes, see the -documentation for the variable feedmail-fiddle-plex-blurb. In all +documentation for the variable `feedmail-fiddle-plex-blurb'. In all cases the name element of the fiddle-plex is ignored and is hardwired by feedmail to either \"Message-Id\" or \"Resent-Message-Id\". @@ -655,7 +655,7 @@ If t, a Date: header of a predetermined format is produced, but only if there is not already a Date: in the message. A value of t is -equivalent to using the function feedmail-default-date-generator. +equivalent to using the function `feedmail-default-date-generator'. If neither nil nor t, it may be a string, a fiddle-plex, or a function which returns either nil, t, a string, or a fiddle-plex (or, in fact, @@ -664,7 +664,7 @@ itself nor the trailing newline. If a function, it will be called with one argument: the possibly-nil name of the file associated with the message buffer. For an explanation of fiddle-plexes, see the -documentation for the variable feedmail-fiddle-plex-blurb. In all +documentation for the variable `feedmail-fiddle-plex-blurb'. In all cases the name element of the fiddle-plex is ignored and is hardwired by feedmail to either \"Date\" or \"Resent-Date\". @@ -700,10 +700,10 @@ feedmail will use this list of fiddle-plexes to manipulate user-specified message header fields. It does this after it has completed all normal -message header field manipulation and before calling feedmail-last-chance-hook. +message header field manipulation and before calling `feedmail-last-chance-hook'. For an explanation of fiddle-plexes, see the documentation for the -variable feedmail-fiddle-plex-blurb. In contrast to some other fiddle-plex +variable `feedmail-fiddle-plex-blurb'. In contrast to some other fiddle-plex manipulation functions, in this context, it makes no sense to have an element which is nil, t, or a simple string." :group 'feedmail-headers @@ -727,7 +727,7 @@ multiple delivery. One reason to use it is to overcome mis-featured mail transports which betray your trust by revealing Bcc: addressees in the headers of a message. Another use is to do a crude form of mailmerge, for -which see feedmail-spray-address-fiddle-plex-list. +which see `feedmail-spray-address-fiddle-plex-list'. If one of the calls to the buffer-eating function results in an error, what happens next is carelessly defined, so beware." @@ -736,12 +736,12 @@ ) (defvar feedmail-spray-this-address nil - "Do not set or change this variable. See feedmail-spray-address-fiddle-plex-list.") + "Do not set or change this variable. See `feedmail-spray-address-fiddle-plex-list'.") (defcustom feedmail-spray-address-fiddle-plex-list nil "User-supplied specification for a crude form of mailmerge capability. When spraying is enabled, feedmail composes a list of envelope addresses. -In turn, feedmail-spray-this-address is temporarily set to each address +In turn, `feedmail-spray-this-address' is temporarily set to each address \(stripped of any comments and angle brackets\) and calls a function which fiddles message headers according to this variable. See the documentation for `feedmail-fiddle-plex-blurb', for an overview of fiddle-plex data structures. @@ -772,15 +772,15 @@ The idea of the example is that, during spray mode, as each message is about to be transmitted to an individual address, the function will be -called and will consult feedmail-spray-this-address to find the +called and will consult `feedmail-spray-this-address' to find the stripped envelope email address (no comments or angle brackets). The function should return an embellished form of the address. The recipe for sending form letters is: (1) create a message with all addressees on Bcc: headers; (2) tell feedmail to remove Bcc: headers before sending the message; (3) create a function which will embellish -stripped addresses, if desired; (4) define feedmail-spray-address-fiddle-plex-list -appropriately; (5) send the message with feedmail-enable-spray set +stripped addresses, if desired; (4) define `feedmail-spray-address-fiddle-plex-list' +appropriately; (5) send the message with `feedmail-enable-spray' set non-nil; (6) stand back and watch co-workers wonder at how efficient you are at accomplishing inherently inefficient things." :group 'feedmail-spray @@ -809,7 +809,7 @@ directory you want at the prompt. The right thing will happen. To transmit all the messages in the queue, invoke the command -feedmail-run-the-queue or feedmail-run-the-queue-no-prompts." +`feedmail-run-the-queue' or `feedmail-run-the-queue-no-prompts'." :group 'feedmail-queue :type 'boolean ) @@ -818,7 +818,7 @@ (defcustom feedmail-queue-runner-confirm-global nil "*If non-nil, give a y-or-n confirmation prompt before running the queue. Prompt even if the queue is about to be processed as a result of a call to -feedmail-run-the-queue-no-prompts. This gives you a way to bail out +`feedmail-run-the-queue-no-prompts'. This gives you a way to bail out without having to answer no to the individual message prompts." :group 'feedmail-queue :type 'boolean) @@ -868,7 +868,7 @@ (defcustom feedmail-ask-before-queue-prompt "FQM: Message action (q, i, d, e, ?)? [%s]: " "*A string which will be used for the message action prompt. If it contains a \"%s\", that will be replaced with the value of -feedmail-ask-before-queue-default." +`feedmail-ask-before-queue-default'." :group 'feedmail-queue :type 'string ) @@ -877,7 +877,7 @@ (defcustom feedmail-ask-before-queue-reprompt "FQM: Please type q, i, d, or e; or ? for help [%s]: " "*A string which will be used for repompting after invalid input. If it contains a \"%s\", that will be replaced with the value of -feedmail-ask-before-queue-default." +`feedmail-ask-before-queue-default'." :group 'feedmail-queue :type 'string ) @@ -921,7 +921,7 @@ All of the values are function names, except help, which is a special symbol that calls up help for the prompt (the help describes the actions from the standard alist). To customize your own choices, -define a similar alist called feedmail-prompt-before-queue-user-alist. +define a similar alist called `feedmail-prompt-before-queue-user-alist'. The actual alist used for message action will be the standard alist overlaid with the user-alist. To neutralize an item in the standard alist without providing a replacement, define an appropriate element @@ -929,7 +929,7 @@ (defcustom feedmail-prompt-before-queue-user-alist nil - "See feedmail-prompt-before-queue-standard-alist." + "See `feedmail-prompt-before-queue-standard-alist'." :group 'feedmail-queue :type '(repeat (cons character function)) ) @@ -940,10 +940,10 @@ When the message action prompt is shown, the user can as for verbose help, at which point a buffer pops up describing the meaning of possible responses to the prompt. Through various customizations (see, for -example, feedmail-prompt-before-queue-user-alist), the available responses +example, `feedmail-prompt-before-queue-user-alist'), the available responses and the prompt itself can be changed. If this variable is set to a string value, that string is written to the help buffer after the standard info. -It may contain embedded line breaks. It will be printed via princ." +It may contain embedded line breaks. It will be printed via `princ'." :group 'feedmail-queue :type '(choice (const nil) string) ) @@ -955,7 +955,7 @@ (after-draft . feedmail-queue-reminder-medium) (after-run . feedmail-queue-reminder-brief) (on-demand . feedmail-run-the-queue-global-prompt)) - "See feedmail-queue-reminder." + "See `feedmail-queue-reminder'." :group 'feedmail-queue :type '(repeat (cons (choice :tag "Event" (const on-demand) @@ -1017,7 +1017,7 @@ (defcustom feedmail-queue-use-send-time-for-message-id nil "*If non-nil, use send time for the Message-Id: header value. This variable is used by the default Message-Id: generating function, -feedmail-default-message-id-generator. If nil, the default, the +`feedmail-default-message-id-generator'. If nil, the default, the last-modified timestamp of the queue file is used to create the message Message-Id: header; if there is no queue file, the current time is used." @@ -1061,7 +1061,7 @@ When feedmail queues a message, it creates a unique file name. By default, the file name is based in part on the subject of the message being queued. If there is no subject, consult this variable. See documentation for the -function feedmail-queue-subject-slug-maker. +function `feedmail-queue-subject-slug-maker'. If t, an innocuous default is used. @@ -1083,8 +1083,8 @@ "*The FQM suffix used to distinguish feedmail queued message files. You probably want this to be a period followed by some letters and/or digits. The distinction is to be able to tell them from other random -files that happen to be in the feedmail-queue-directory or -feedmail-queue-draft-directory. By the way, FQM stands for feedmail +files that happen to be in the `feedmail-queue-directory' or +`feedmail-queue-draft-directory'. By the way, FQM stands for feedmail queued message." :group 'feedmail-queue :type 'string @@ -1133,20 +1133,20 @@ (defun feedmail-mail-send-hook-splitter () - "Facilitate dividing mail-send-hook things into queued and immediate cases. -If you have mail-send-hook functions that should only be called for sending/ + "Facilitate dividing `mail-send-hook' things into queued and immediate cases. +If you have `mail-send-hook' functions that should only be called for sending/ queueing messages or only be called for the sending of queued messages, this is -for you. Add this function to mail-send-hook with something like this: +for you. Add this function to `mail-send-hook' with something like this: (add-hook 'mail-send-hook 'feedmail-mail-send-hook-splitter) -Then add the functions you want called to either feedmail-mail-send-hook-queued -or feedmail-mail-send-hook, as apprpriate. The distinction is that -feedmail-mail-send-hook will be called when you send mail from a composition +Then add the functions you want called to either `feedmail-mail-send-hook-queued' +or `feedmail-mail-send-hook', as apprpriate. The distinction is that +`feedmail-mail-send-hook' will be called when you send mail from a composition buffer (typically by typing C-c C-c), whether the message is sent immediately -or placed in the queue or drafts directory. feedmail-mail-send-hook-queued is +or placed in the queue or drafts directory. `feedmail-mail-send-hook-queued' is called when messages are being sent from the queue directory, typically via a -call to feedmail-run-the-queue." +call to `feedmail-run-the-queue'." (if feedmail-queue-runner-is-active (run-hooks 'feedmail-mail-send-hook-queued) (run-hooks 'feedmail-mail-send-hook)) @@ -1154,15 +1154,15 @@ (defvar feedmail-mail-send-hook nil - "*See documentation for feedmail-mail-send-hook-splitter.") + "*See documentation for `feedmail-mail-send-hook-splitter'.") (defvar feedmail-mail-send-hook-queued nil - "*See documentation for feedmail-mail-send-hook-splitter.") + "*See documentation for `feedmail-mail-send-hook-splitter'.") (defun feedmail-confirm-addresses-hook-example () - "An example of a feedmail-last-chance-hook. + "An example of a `feedmail-last-chance-hook'. It shows the simple addresses and gets a confirmation. Use as: (setq feedmail-last-chance-hook 'feedmail-confirm-addresses-hook-example)." (save-window-excursion @@ -1179,10 +1179,10 @@ It has already had all the header prepping from the standard package. The next step after running the hook will be to push the buffer into a subprocess that mails the mail. The hook might be interested in -these: (1) feedmail-prepped-text-buffer contains the header and body -of the message, ready to go; (2) feedmail-address-list contains a list +these: (1) `feedmail-prepped-text-buffer' contains the header and body +of the message, ready to go; (2) `feedmail-address-list' contains a list of simplified recipients of addresses which are to be given to the -subprocess (the hook may change the list); (3) feedmail-error-buffer +subprocess (the hook may change the list); (3) `feedmail-error-buffer' is an empty buffer intended to soak up errors for display to the user. If the hook allows interactive activity, the user should not send more mail while in the hook since some of the internal buffers will be @@ -1197,10 +1197,10 @@ It has already had all the header prepping from the standard package. The next step after running the hook will be to save the message via Fcc: processing. The hook might be interested in these: (1) -feedmail-prepped-text-buffer contains the header and body of the -message, ready to go; (2) feedmail-address-list contains a list of +`feedmail-prepped-text-buffer' contains the header and body of the +message, ready to go; (2) `feedmail-address-list' contains a list of simplified recipients of addressees to whom the message was sent (3) -feedmail-error-buffer is an empty buffer intended to soak up errors +`feedmail-error-buffer' is an empty buffer intended to soak up errors for display to the user. If the hook allows interactive activity, the user should not send more mail while in the hook since some of the internal buffers will be reused and things will get confused." @@ -1213,7 +1213,7 @@ "*A function to set the proper mode of a message file. Called when the message is read back out of the queue directory with a single argument, the optional argument used in the call to -feedmail-run-the-queue or feedmail-run-the-queue-no-prompts. +`feedmail-run-the-queue' or `feedmail-run-the-queue-no-prompts'. Most people want `mail-mode', so the default value is an anonymous function which is just a wrapper to ignore the supplied argument when @@ -1235,7 +1235,7 @@ non-nil, feedmail will first try to send the message using the value of `mail-header-separator'. If it can't find that, it will temporarily set `mail-header-separator' to the value of -feedmail-queue-alternative-mail-header-separator and try again." +`feedmail-queue-alternative-mail-header-separator' and try again." :group 'feedmail-queue :type '(choice (const nil) string) ) @@ -1245,11 +1245,11 @@ "*Function to initiate sending a message file. Called for each message read back out of the queue directory with a single argument, the optional argument used in the call to -feedmail-run-the-queue or feedmail-run-the-queue-no-prompts. +`feedmail-run-the-queue' or `feedmail-run-the-queue-no-prompts'. Interactively, that argument will be the prefix argument. Most people -want mail-send-and-exit (bound to C-c C-c in mail-mode), but here's -your chance to have something different. Called with funcall, not -call-interactively." +want `mail-send-and-exit' (bound to C-c C-c in mail-mode), but here's +your chance to have something different. Called with `funcall', not +`call-interactively'." :group 'feedmail-queue :type 'function ) @@ -1291,11 +1291,11 @@ containing the prepped message; (2) a buffer where errors should be directed; and (3) a list containing the addresses individually as strings. Three popular choices for this are -feedmail-buffer-to-binmail, feedmail-buffer-to-smtpmail, and -feedmail-buffer-to-sendmail. If you use the sendmail form, you -probably want to set feedmail-nuke-bcc and/or feedmail-nuke-resent-bcc +`feedmail-buffer-to-binmail', `feedmail-buffer-to-smtpmail', and +`feedmail-buffer-to-sendmail'. If you use the sendmail form, you +probably want to set `feedmail-nuke-bcc' and/or `feedmail-nuke-resent-bcc' to nil. If you use the binmail form, check the value of -feedmail-binmail-template." +`feedmail-binmail-template'." :group 'feedmail-misc :type 'function ) @@ -1306,7 +1306,7 @@ It can result in any command understandable by /bin/sh. Might not work at all in non-Unix environments. The single '%s', if present, gets replaced by the space-separated, simplified list of addressees. -Used in feedmail-buffer-to-binmail to form the shell command which +Used in `feedmail-buffer-to-binmail' to form the shell command which will receive the contents of the prepped buffer as stdin. If you'd like your errors to come back as mail instead of immediately in a buffer, try /bin/rmail instead of /bin/mail (this can be accomplished @@ -1535,13 +1535,13 @@ ;;;###autoload (defun feedmail-run-the-queue-no-prompts (&optional arg) - "Like feedmail-run-the-queue, but suppress confirmation prompts." + "Like `feedmail-run-the-queue', but suppress confirmation prompts." (interactive "p") (let ((feedmail-confirm-outgoing nil)) (feedmail-run-the-queue arg))) ;;;###autoload (defun feedmail-run-the-queue-global-prompt (&optional arg) - "Like feedmail-run-the-queue, but with a global confirmation prompt. + "Like `feedmail-run-the-queue', but with a global confirmation prompt. This is generally most useful if run non-interactively, since you can bail out with an appropriate answer to the global confirmation prompt." (interactive "p") @@ -1678,7 +1678,7 @@ "Perform some kind of reminder activity about queued and draft messages. Called with an optional symbol argument which says what kind of event is triggering the reminder activity. The default is 'on-demand, which -is what you typically would use if you were putting this in your emacs start-up +is what you typically would use if you were putting this in your Emacs start-up or mail hook code. Other recognized values for WHAT-EVENT (these are passed internally by feedmail): @@ -1687,11 +1687,11 @@ after-draft (a message has just been placed in the draft directory) after-run (the queue has just been run, possibly sending messages) -WHAT-EVENT is used as a key into the table feedmail-queue-reminder-alist. If +WHAT-EVENT is used as a key into the table `feedmail-queue-reminder-alist'. If the associated value is a function, it is called without arguments and is expected to perform the reminder activity. You can supply your own reminder functions -by redefining feedmail-queue-reminder-alist. If you don't want any reminders, -you can set feedmail-queue-reminder-alist to nil." +by redefining `feedmail-queue-reminder-alist'. If you don't want any reminders, +you can set `feedmail-queue-reminder-alist' to nil." (interactive "p") (let ((key (if (and what-event (symbolp what-event)) what-event 'on-demand)) entry reminder) (setq entry (assoc key feedmail-queue-reminder-alist)) @@ -1871,7 +1871,7 @@ Optional argument QUEUE-DIRECTORY specifies into which directory the file will be placed. The name is based on the Subject: header (if there is one). If there is no subject, -feedmail-queue-default-file-slug is consulted Special characters are +`feedmail-queue-default-file-slug' is consulted. Special characters are mapped to mostly alphanumerics for safety." (let ((eoh-marker) (case-fold-search t) (subject "") (s-point)) (setq eoh-marker (feedmail-find-eoh)) @@ -2152,7 +2152,7 @@ "Internal feedmail function for jamming fields into message header. NAME, VALUE, ACTION, and FOLDING are the four elements of a fiddle-plex, as described in the documentation for the variable -feedmail-fiddle-plex-blurb." +`feedmail-fiddle-plex-blurb'." (let ((case-fold-search t) (header-colon (concat (regexp-quote name) ":")) header-regexp eoh-marker has-like ag-like val-like that-point) @@ -2249,7 +2249,7 @@ (defun feedmail-envelope-deducer (eoh-marker) - "If feedmail-deduce-envelope-from is false, simply return `user-mail-address'. + "If `feedmail-deduce-envelope-from' is false, simply return `user-mail-address'. Else, look for Sender: or From: (or Resent-*) and return that value." (if (not feedmail-deduce-envelope-from) @@ -2345,7 +2345,7 @@ (defun feedmail-fiddle-date (maybe-file) - "Fiddle Date:. See documentation of feedmail-date-generator." + "Fiddle Date:. See documentation of `feedmail-date-generator'." ;; default is to fall off the end of the list and do nothing (cond ;; nil means do nothing @@ -2377,7 +2377,7 @@ (defun feedmail-default-message-id-generator (maybe-file) "Default function for generating Message-Id: header contents. Based on a date and a sort of random number for tie breaking. Unless -feedmail-message-id-suffix is defined, uses `user-mail-address', so be +`feedmail-message-id-suffix' is defined, uses `user-mail-address', so be sure it's set." (let ((date-time) (end-stuff (if feedmail-message-id-suffix feedmail-message-id-suffix user-mail-address))) @@ -2395,7 +2395,7 @@ ) (defun feedmail-fiddle-message-id (maybe-file) - "Fiddle Message-Id:. See documentation of feedmail-message-id-generator." + "Fiddle Message-Id:. See documentation of `feedmail-message-id-generator'." ;; default is to fall off the end of the list and do nothing (cond ;; nil means do nothing @@ -2436,7 +2436,7 @@ (defun feedmail-fiddle-x-mailer () - "Fiddle X-Mailer:. See documentation of feedmail-x-mailer-line." + "Fiddle X-Mailer:. See documentation of `feedmail-x-mailer-line'." ;; default is to fall off the end of the list and do nothing (cond ;; t is the same a using the function feedmail-default-x-mailer-generator, so let it and recurse @@ -2464,7 +2464,7 @@ (defun feedmail-fiddle-spray-address (addy-plex) - "Fiddle header for single spray address. Uses feedmail-spray-this-address." + "Fiddle header for single spray address. Uses `feedmail-spray-this-address'." ;; default is to fall off the end of the list and do nothing (cond ;; nil means do nothing @@ -2607,7 +2607,7 @@ (defun feedmail-deduce-address-list (message-buffer header-start header-end addr-regexp address-list) "Get address list with all comments and other excitement trimmed. Addresses are collected only from headers whose names match the fourth -argument Returns a list of strings. Duplicate addresses will have +argument. Returns a list of strings. Duplicate addresses will have been weeded out." (let ((simple-address) (address-blob)
--- a/lisp/mail/rmail-spam-filter.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/mail/rmail-spam-filter.el Tue Nov 07 23:22:48 2006 +0000 @@ -211,7 +211,7 @@ :group 'rmail-spam-filter) (defvar rsf-scanning-messages-now nil - "Non nil when `rmail-spam-filter' scans messages. + "Non-nil when `rmail-spam-filter' scans messages. This is for interaction with `rsf-bbdb-auto-delete-spam-entries'.") ;; the advantage over the automatic filter definitions is the AND conjunction
--- a/lisp/mail/rmail.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/mail/rmail.el Tue Nov 07 23:22:48 2006 +0000 @@ -2828,7 +2828,7 @@ (if blurb (message blurb)))))) -(defun rmail-redecode-body (coding) +(defun rmail-redecode-body (coding &optional raw) "Decode the body of the current message using coding system CODING. This is useful with mail messages that have malformed or missing charset= headers. @@ -2838,6 +2838,16 @@ decode it was incorrect. It then encodes the message back to its original form, and decodes it again, using the coding system CODING. +Optional argument RAW, if non-nil, means don't encode the message +before decoding it with the new CODING. This is useful if the current +message text was produced by some function which invokes `insert', +since `insert' leaves unibyte character codes 128 through 255 unconverted +to multibyte. One example of such a situation is when the text was +produced by `base64-decode-region'. + +Interactively, invoke the function with a prefix argument to set RAW +non-nil. + Note that if Emacs erroneously auto-detected one of the iso-2022 encodings in the message, this function might fail because the escape sequences that switch between character sets and also single-shift and @@ -2849,7 +2859,8 @@ (or (eq major-mode 'rmail-mode) (switch-to-buffer rmail-buffer)) (save-excursion - (let ((pruned (rmail-msg-is-pruned))) + (let ((pruned (rmail-msg-is-pruned)) + (raw (or raw current-prefix-arg))) (unwind-protect (let ((msgbeg (rmail-msgbeg rmail-current-message)) (msgend (rmail-msgend rmail-current-message)) @@ -2883,7 +2894,22 @@ (car (find-coding-systems-region msgbeg msgend)))) (setq x-coding-header (point-marker)) (narrow-to-region msgbeg msgend) - (encode-coding-region (point) msgend old-coding) + (and (null raw) + ;; If old and new encoding are the same, it + ;; clearly doesn't make sense to encode. + (not (coding-system-equal + (coding-system-base old-coding) + (coding-system-base coding))) + ;; If the body includes only eight-bit-* + ;; characters, encoding might fail, e.g. with + ;; UTF-8, and isn't needed anyway. + (> (length (delq 'ascii + (delq 'eight-bit-graphic + (delq 'eight-bit-control + (find-charset-region + msgbeg msgend))))) + 0) + (encode-coding-region (point) msgend old-coding)) (decode-coding-region (point) msgend coding) (setq last-coding-system-used coding) ;; Rewrite the coding-system header according
--- a/lisp/mail/vms-pmail.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/mail/vms-pmail.el Tue Nov 07 23:22:48 2006 +0000 @@ -40,9 +40,9 @@ ;;; then execute them as though emacs were just starting up. ;;; (defun vms-pmail-save-and-exit () - "Save current buffer and exit emacs. -If this emacs cannot be suspended, you will be prompted about modified -buffers other than the mail buffer. BEWARE --- suspending emacs without + "Save current buffer and exit Emacs. +If this Emacs cannot be suspended, you will be prompted about modified +buffers other than the mail buffer. BEWARE --- suspending Emacs without saving your mail buffer causes mail to abort the send (potentially useful since the mail buffer is still here)." (interactive) @@ -55,7 +55,7 @@ (suspend-emacs))) (defun vms-pmail-abort () - "Mark buffer as unmodified and exit emacs. + "Mark buffer as unmodified and exit Emacs. When the editor is exited without saving its buffer, VMS mail does not send a message. If you have other modified buffers you will be prompted for what to do with them." @@ -78,7 +78,7 @@ \\[vms-pmail-save-and-exit] vms-pmail-save-and-exit \\[vms-pmail-abort] vms-pmail-abort -All other emacs commands are still available." +All other Emacs commands are still available." (interactive) (auto-save-mode -1) (text-mode)
--- a/lisp/menu-bar.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/menu-bar.el Tue Nov 07 23:22:48 2006 +0000 @@ -1669,7 +1669,7 @@ 'menu-item "List All Buffers" 'list-buffers - :help "Pop up a window listing all emacs buffers" + :help "Pop up a window listing all Emacs buffers" )))) (setq buffers-menu (nconc buffers-menu menu-bar-buffers-menu-command-entries))
--- a/lisp/mouse-copy.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/mouse-copy.el Tue Nov 07 23:22:48 2006 +0000 @@ -111,9 +111,9 @@ See `mouse-copy-work-around-drag-bug' for details.") (defun mouse-copy-work-around-drag-bug (start-event end-event) - "Code to work around a bug in post-19.29 emacs: it drops mouse-drag events. + "Code to work around a bug in post-19.29 Emacs: it drops mouse-drag events. The problem occurs under XFree86-3.1.1 (X11R6pl11) but not under X11R5, -and under post-19.29 but not early versions of emacs. +and under post-19.29 but not early versions of Emacs. 19.29 and 19.30 seems to drop mouse drag events sometimes. (Reproducible under XFree86-3.1.1 (X11R6pl11) and
--- a/lisp/mouse.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/mouse.el Tue Nov 07 23:22:48 2006 +0000 @@ -846,7 +846,7 @@ ;; Should we instead decide that `action' takes a `posn'? (if (consp pos) (with-current-buffer (window-buffer (posn-window pos)) - (funcall action (posn-point pos))) + (funcall action (posn-point pos))) (funcall action pos))) (t action)))) @@ -889,7 +889,7 @@ (let ((range (mouse-start-end start end mode))) (move-overlay ol (car range) (nth 1 range)))) -(defun mouse-drag-track (start-event &optional +(defun mouse-drag-track (start-event &optional do-mouse-drag-region-post-process) "Track mouse drags by highlighting area between point and cursor. The region will be defined with mark and point, and the overlay @@ -983,8 +983,8 @@ (let* ((fun (key-binding (vector (car event)))) (do-multi-click (and (> (event-click-count event) 0) (functionp fun) - (not (memq fun - '(mouse-set-point + (not (memq fun + '(mouse-set-point mouse-set-region)))))) ;; Run the binding of the terminating up-event, if possible. (if (and (not (= (overlay-start mouse-drag-overlay) @@ -2377,7 +2377,7 @@ "X fonts suitable for use in Emacs.") (defun mouse-set-font (&rest fonts) - "Select an emacs font from a list of known good fonts and fontsets." + "Select an Emacs font from a list of known good fonts and fontsets." (interactive (progn (unless (display-multi-font-p) (error "Cannot change fonts on this display"))
--- a/lisp/net/eudc-vars.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/net/eudc-vars.el Tue Nov 07 23:22:48 2006 +0000 @@ -165,7 +165,7 @@ :group 'eudc) (defcustom eudc-expansion-overwrites-query t - "*If non nil, expanding a query overwrites the query string." + "*If non-nil, expanding a query overwrites the query string." :type 'boolean :group 'eudc)
--- a/lisp/net/tramp.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/net/tramp.el Tue Nov 07 23:22:48 2006 +0000 @@ -676,7 +676,7 @@ (if (and (fboundp 'executable-find) (executable-find "plink")) "plink" - "ssh") + "scp") "*Default method to use for transferring files. See `tramp-methods' for possibilities. Also see `tramp-default-method-alist'."
--- a/lisp/play/dunnet.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/play/dunnet.el Tue Nov 07 23:22:48 2006 +0000 @@ -935,7 +935,7 @@ - If you go down a hole in the floor without an aid such as a ladder, you probably won't be able to get back up the way you came, if at all. -- To run this game in batch mode (no emacs window), use: +- To run this game in batch mode (no Emacs window), use: emacs -batch -l dunnet NOTE: This game *should* be run in batch mode!
--- a/lisp/play/handwrite.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/play/handwrite.el Tue Nov 07 23:22:48 2006 +0000 @@ -77,7 +77,7 @@ ;; Variables (defgroup handwrite nil - "Turns your emacs buffer into a handwritten document." + "Turns your Emacs buffer into a handwritten document." :prefix "handwrite-" :group 'games)
--- a/lisp/play/hanoi.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/play/hanoi.el Tue Nov 07 23:22:48 2006 +0000 @@ -133,7 +133,7 @@ ;;;###autoload (defun hanoi-unix-64 () "Like hanoi-unix, but pretend to have a 64-bit clock. -This is, necessarily (as of emacs 20.3), a crock. When the +This is, necessarily (as of Emacs 20.3), a crock. When the current-time interface is made s2G-compliant, hanoi.el will need to be updated." (interactive) @@ -152,7 +152,7 @@ (buffer-disable-undo (current-buffer)) (unwind-protect (let* - (;; These lines can cause emacs to crash if you ask for too + (;; These lines can cause Emacs to crash if you ask for too ;; many rings. If you uncomment them, on most systems you ;; can get 10,000+ rings. ;;(max-specpdl-size (max max-specpdl-size (* nrings 15)))
--- a/lisp/printing.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/printing.el Tue Nov 07 23:22:48 2006 +0000 @@ -1144,6 +1144,7 @@ "Set the value of custom variables for printer & utility selection." (set symbol value) (and (featurep 'printing) ; update only after printing is loaded + (not pr-menu-print-item) (pr-update-menus t))) @@ -1151,6 +1152,7 @@ "Update utility menu entry." (set symbol value) (and (featurep 'printing) ; update only after printing is loaded + (not pr-menu-print-item) (pr-menu-set-utility-title value))) @@ -1158,6 +1160,7 @@ "Update `PostScript Printer:' menu entry." (set symbol value) (and (featurep 'printing) ; update only after printing is loaded + (not pr-menu-print-item) (pr-menu-set-ps-title value))) @@ -1165,6 +1168,7 @@ "Update `Text Printer:' menu entry." (set symbol value) (and (featurep 'printing) ; update only after printing is loaded + (not pr-menu-print-item) (pr-menu-set-txt-title value))) @@ -3096,23 +3100,21 @@ (pr-get-symbol "Printing"))))) ;; Emacs 21 & 22 (t - (let* ((has-file (lookup-key global-map (vector 'menu-bar 'file))) - (item-file (if has-file '("file") '("files")))) - (cond - (pr-menu-print-item - (easy-menu-change item-file "Print" pr-menu-spec "print-buffer") - (let ((items '("print-buffer" "print-region" - "ps-print-buffer-faces" "ps-print-region-faces" - "ps-print-buffer" "ps-print-region"))) - (while items - (easy-menu-remove-item nil item-file (car items)) - (setq items (cdr items))) - (setq pr-menu-print-item nil - pr-menu-bar (vector 'menu-bar - (if has-file 'file 'files) - (pr-get-symbol "Print"))))) - (t - (easy-menu-change item-file "Print" pr-menu-spec)))))))) + (cond + (pr-menu-print-item + (easy-menu-add-item menu-bar-file-menu nil + (easy-menu-create-menu "Print" pr-menu-spec) + "print-buffer") + (dolist (item '("print-buffer" "print-region" + "ps-print-buffer-faces" "ps-print-region-faces" + "ps-print-buffer" "ps-print-region")) + (easy-menu-remove-item menu-bar-file-menu nil item)) + (setq pr-menu-print-item nil + pr-menu-bar (vector 'menu-bar + 'file + (pr-get-symbol "Print")))) + (t + (easy-menu-change '("file") "Print" pr-menu-spec))))))) (pr-update-menus t))
--- a/lisp/progmodes/ada-prj.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/progmodes/ada-prj.el Tue Nov 07 23:22:48 2006 +0000 @@ -1,9 +1,10 @@ -;;; ada-prj.el --- easy editing of project files for the ada-mode +;;; ada-prj.el --- GUI editing of project files for the ada-mode -;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 ;; Free Software Foundation, Inc. ;; Author: Emmanuel Briot <briot@gnat.com> +;; Maintainer: Stephen Leake <stephen_leake@stephe-leake.org> ;; Keywords: languages, ada, project file ;; This file is part of GNU Emacs. @@ -33,6 +34,10 @@ ;;; Internally, a project file is represented as a property list, with each ;;; field of the project file matching one property of the list. + +;;; History: +;; + ;;; Code: @@ -64,7 +69,7 @@ ;; ----- Functions -------------------------------------------------------- (defun ada-prj-new () - "Open a new project file" + "Open a new project file." (interactive) (let* ((prj (if (and ada-prj-default-project-file @@ -93,7 +98,7 @@ "Set SYMBOL to the property list of the project file FILENAME. If FILENAME is null, read the file associated with ADA-BUFFER. If no project file is found, returns the default values." - +;; FIXME: rationalize arguments; make ada-buffer optional? (if (and filename (not (string= filename "")) (assoc filename ada-xref-project-files)) @@ -108,7 +113,7 @@ (defun ada-prj-save-specific-option (field) - "Returns the string to print in the project file to save FIELD. + "Return the string to print in the project file to save FIELD. If the current value of FIELD is the default value, returns an empty string." (if (string= (plist-get ada-prj-current-values field) (plist-get ada-prj-default-values field)) @@ -170,7 +175,7 @@ (kill-buffer nil) ;; kill the editor buffer - (kill-buffer "*Customize Ada Mode*") + (kill-buffer "*Edit Ada Mode Project*") ;; automatically set the new project file as the active one (set 'ada-prj-default-project-file file-name) @@ -208,7 +213,7 @@ )) (defun ada-prj-subdirs-of (dir) - "Returns a list of all the subdirectories of dir, recursively." + "Return a list of all the subdirectories of DIR, recursively." (let ((subdirs (directory-files dir t "^[^.].*")) (dirlist (list dir))) (while subdirs @@ -220,7 +225,7 @@ dirlist)) (defun ada-prj-load-directory (field &optional file-name) - "Append the content of FILE-NAME to FIELD in the current project file. + "Append to FIELD in the current project the subdirectories of FILE-NAME. If FILE-NAME is nil, ask the user for the name." ;; Do not use an external dialog for this, since it wouldn't allow @@ -238,8 +243,7 @@ (ada-prj-display-page 2)) (defun ada-prj-display-page (tab-num) - "Display one of the pages available in the notebook. TAB-NUM should have -a value between 1 and the maximum number of pages. + "Display page TAB-NUM in the notebook. The current buffer must be the project editing buffer." (let ((inhibit-read-only t)) @@ -255,7 +259,7 @@ ;; Display the tabs - (widget-insert "\n Project and Editor configuration.\n + (widget-insert "\n Project configuration.\n ___________ ____________ ____________ ____________ ____________\n / ") (widget-create 'push-button :notify (lambda (&rest dummy) (ada-prj-display-page 1)) "General") @@ -346,9 +350,9 @@ and the standard runtime." t t (mapconcat (lambda(x) - (concat " " x)) - ada-xref-runtime-library-specs-path - "\n") + (concat " " x)) + ada-xref-runtime-library-specs-path + "\n") ) (widget-insert "\n\n") @@ -361,9 +365,9 @@ and the standard runtime." t t (mapconcat (lambda(x) - (concat " " x)) - ada-xref-runtime-library-ali-path - "\n") + (concat " " x)) + ada-xref-runtime-library-ali-path + "\n") ) (widget-insert "\n\n") ) @@ -512,7 +516,7 @@ (ada-reread-prj-file))) ;; Else start the interactive editor - (switch-to-buffer "*Customize Ada Mode*") + (switch-to-buffer "*Edit Ada Mode Project*") (ada-xref-set-default-prj-values 'ada-prj-default-values ada-buffer) (ada-prj-initialize-values 'ada-prj-current-values @@ -536,30 +540,30 @@ ;; ---------------- Utilities -------------------------------- (defun ada-prj-set-list (string ada-list &optional is-directory) - "Join the strings in ADA-LIST into a single string. -Each name is put on a separate line that begins with STRING. -If IS-DIRECTORY is non-nil, each name is explicitly converted to a -directory name." + "Prepend STRING to strings in ADA-LIST, return new-line separated string. +If IS-DIRECTORY is non-nil, each element of ADA-LIST is explicitly +converted to a directory name." (mapconcat (lambda (x) (concat string "=" (if is-directory (file-name-as-directory x) x))) - ada-list "\n")) + ada-list "\n")) (defun ada-prj-field-modified (widget &rest dummy) - "Callback called each time the value of WIDGET is modified. Save the -change in ada-prj-current-values so that selecting another page and coming -back keeps the new value." + "Callback for modification of WIDGET. +Remaining args DUMMY are ignored. +Save the change in `ada-prj-current-values' so that selecting +another page and coming back keeps the new value." (set 'ada-prj-current-values (plist-put ada-prj-current-values (widget-get widget ':prj-field) (widget-value widget)))) (defun ada-prj-display-help (widget widget-modified event) - "An help button in WIDGET was clicked on. The parameters are so that -this function can be used as :notify for the widget." + "Callback for help button in WIDGET. +Parameters WIDGET-MODIFIED, EVENT match :notify for the widget." (let ((text (widget-get widget 'prj-help))) (if event ;; If we have a mouse-event, popup a menu @@ -575,6 +579,8 @@ ))) (defun ada-prj-show-value (widget widget-modified event) + "Show the current field value in WIDGET. +Parameters WIDGET-MODIFIED, EVENT match :notify for the widget." (let* ((field (widget-get widget ':prj-field)) (value (plist-get ada-prj-current-values field)) (inhibit-read-only t)
--- a/lisp/progmodes/ada-stmt.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/progmodes/ada-stmt.el Tue Nov 07 23:22:48 2006 +0000 @@ -6,9 +6,8 @@ ;; This file is part of GNU Emacs. ;; Authors: Daniel Pfeiffer, Markus Heritsch, Rolf Ebert <ebert@waporo.muc.de> -;; Maintainer: Emmanuel Briot <briot@gnat.com> +;; Maintainer: Stephen Leake <stephen_leake@stephe-leake.org> ;; Keywords: languages, ada -;; Rolf Ebert's version: 2.26 ;;; Commentary: ;; This file is now automatically loaded from ada-mode.el, and creates a submenu @@ -64,7 +63,7 @@ (require 'ada-mode) (defun ada-func-or-proc-name () - ;; Get the name of the current function or procedure." + "Return the name of the current function or procedure." (save-excursion (let ((case-fold-search t)) (if (re-search-backward ada-procedure-start-regexp nil t) @@ -305,7 +304,7 @@ (backward-char 1) (forward-sexp 1))) (if (looking-at ";") - (delete-char 1))) + (delete-char 1))) " is" \n _ \n < "begin" \n
--- a/lisp/progmodes/ada-xref.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/progmodes/ada-xref.el Tue Nov 07 23:22:48 2006 +0000 @@ -1,4 +1,4 @@ -;;; ada-xref.el --- for lookup and completion in Ada mode +;; ada-xref.el --- for lookup and completion in Ada mode ;; Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, ;; 2004, 2005, 2006 Free Software Foundation, Inc. @@ -6,8 +6,7 @@ ;; Author: Markus Heritsch <Markus.Heritsch@studbox.uni-stuttgart.de> ;; Rolf Ebert <ebert@inf.enst.fr> ;; Emmanuel Briot <briot@gnat.com> -;; Maintainer: Emmanuel Briot <briot@gnat.com> -;; Ada Core Technologies's version: Revision: 1.181 +;; Maintainer: Stephen Leake <stephen_leake@stephe-leake.org> ;; Keywords: languages ada xref ;; This file is part of GNU Emacs. @@ -38,6 +37,10 @@ ;;; You need Emacs >= 20.2 to run this package + +;;; History: +;; + ;;; Code: ;; ----- Requirements ----------------------------------------------------- @@ -47,7 +50,7 @@ (require 'find-file) (require 'ada-mode) -;; ------ Use variables +;; ------ User variables (defcustom ada-xref-other-buffer t "*If nil, always display the cross-references in the same buffer. Otherwise create either a new buffer or a new frame." @@ -59,7 +62,7 @@ :type 'boolean :group 'ada) (defcustom ada-xref-confirm-compile nil - "*If non-nil, ask for confirmation before compiling or running the application." + "*Non-nil means ask for confirmation before compiling or running the application." :type 'boolean :group 'ada) (defcustom ada-krunch-args "0" @@ -105,26 +108,25 @@ (concat "${cross_prefix}gnatmake -u -c ${gnatmake_opt} ${full_current} -cargs" " ${comp_opt}") "*Default command to be used to compile a single file. -Emacs will add the filename at the end of this command. This is the same -syntax as in the project file." +Emacs will substitute the current filename for ${full_current}, or add +the filename at the end. This is the same syntax as in the project file." :type 'string :group 'ada) (defcustom ada-prj-default-debugger "${cross_prefix}gdb" - "*Default name of the debugger. We recommend either `gdb', -`gdb --emacs_gdbtk' or `ddd --tty -fullname'." + "*Default name of the debugger." :type 'string :group 'ada) (defcustom ada-prj-default-make-cmd (concat "${cross_prefix}gnatmake -o ${main} ${main_unit} ${gnatmake_opt} " - "-cargs ${comp_opt} -bargs ${bind_opt} -largs ${link_opt}") + "-cargs ${comp_opt} -bargs ${bind_opt} -largs ${link_opt}") "*Default command to be used to compile the application. This is the same syntax as in the project file." :type 'string :group 'ada) (defcustom ada-prj-default-project-file "" - "*Name of the project file to use for every Ada file. -Emacs will not try to use the standard algorithm to find the project file if -this string is not empty." + "*Name of the current project file. +Emacs will not try to use the search algorithm to find the project file if +this string is not empty. It is set whenever a project file is found." :type '(file :must-match t) :group 'ada) (defcustom ada-gnatstub-opts "-q -I${src_dir}" @@ -238,7 +240,7 @@ (defmacro ada-set-on-declaration (ident value) (list 'aset ident 7 value)) (defsubst ada-get-ali-buffer (file) - "Reads the ali file into a new buffer, and returns this buffer's name" + "Read the ali file FILE into a new buffer, and return the buffer's name." (find-file-noselect (ada-get-ali-file-name file))) @@ -250,7 +252,7 @@ (defun ada-initialize-runtime-library (cross-prefix) "Initialize the variables for the runtime library location. -CROSS-PREFIX is the prefix to use for the gnatls command." +CROSS-PREFIX is the prefix to use for the `gnatls' command." (save-excursion (setq ada-xref-runtime-library-specs-path '() ada-xref-runtime-library-ali-path '()) @@ -305,9 +307,9 @@ (defun ada-treat-cmd-string (cmd-string) "Replace meta-sequences like ${...} in CMD-STRING with the appropriate value. -The project file must have been loaded first. -As a special case, ${current} is replaced with the name of the currently -edited file, minus extension but with directory, and ${full_current} is +Assumes project exists. +As a special case, ${current} is replaced with the name of the current +file, minus extension but with directory, and ${full_current} is replaced by the name including the extension." (while (string-match "\\(-[^-\$IO]*[IO]\\)?\${\\([^}]+\\)}" cmd-string) @@ -349,9 +351,8 @@ (set-buffer ada-buffer) (set 'plist - ;; Try hard to find a default value for filename, so that the user - ;; can edit his project file even if the current buffer is not an - ;; Ada file or not even associated with a file + ;; Try hard to find a project file, even if the current + ;; buffer is not an Ada file or not associated with a file (list 'filename (expand-file-name (cond (ada-prj-default-project-file @@ -403,8 +404,7 @@ (defun ada-xref-get-project-field (field) "Extract the value of FIELD from the current project file. -The project file must have been loaded first. -A default value is returned if the file was not found. +Project variables are substituted. Note that for src_dir and obj_dir, you should rather use `ada-xref-get-src-dir-field' or `ada-xref-get-obj-dir-field' which will in @@ -443,7 +443,6 @@ ) )) - (defun ada-xref-get-src-dir-field () "Return the full value for src_dir, including the default directories. All the directories are returned as absolute directories." @@ -529,6 +528,7 @@ "Completion function when reading a file from the minibuffer. Completion is attempted in all the directories in the source path, as defined in the project file." + ;; FIXME: doc arguments (let (list (dirs (ada-xref-get-src-dir-field))) @@ -547,7 +547,7 @@ ;;;###autoload (defun ada-find-file (filename) - "Open a file anywhere in the source path. + "Open FILENAME, from anywhere in the source path. Completion is available." (interactive (list (completing-read "File: " 'ada-do-file-completion))) @@ -582,9 +582,10 @@ (goto-char (car pos))))) (defun ada-convert-file-name (name) - "Converts from NAME to a name that can be used by the compilation commands. + "Convert from NAME to a name that can be used by the compilation commands. This is overriden on VMS to convert from VMS filenames to Unix filenames." name) +;; FIXME: use convert-standard-filename instead (defun ada-set-default-project-file (name &optional keep-existing) "Set the file whose name is NAME as the default project file. @@ -694,12 +695,12 @@ (defun ada-parse-prj-file (prj-file) - "Reads and parses the PRJ-FILE file if it was found. -The current buffer should be the ada-file buffer." + "Read PRJ-FILE, set it as the active project." + ;; FIXME: doc nil, search, etc. (if prj-file (let (project src_dir obj_dir make_cmd comp_cmd check_cmd casing run_cmd debug_pre_cmd debug_post_cmd - (ada-buffer (current-buffer))) + (ada-buffer (current-buffer))) (setq prj-file (expand-file-name prj-file)) ;; Set the project file as the active one. @@ -728,6 +729,8 @@ (while (not (eobp)) (if (looking-at "^\\([^=]+\\)=\\(.*\\)") (cond + ;; fields that are lists or paths require special processing + ;; FIXME: strip trailing spaces ((string= (match-string 1) "src_dir") (add-to-list 'src_dir (file-name-as-directory (match-string 2)))) @@ -753,6 +756,7 @@ ((string= (match-string 1) "debug_post_cmd") (add-to-list 'debug_post_cmd (match-string 2))) (t + ;; any other field in the file is just copied (set 'project (plist-put project (intern (match-string 1)) (match-string 2)))))) (forward-line 1)) @@ -783,20 +787,20 @@ ;; Else the file wasn't readable (probably the default project). ;; We initialize it with the current environment variables. - ;; We need to add the startup directory in front so that - ;; files locally redefined are properly found. We cannot - ;; add ".", which varies too much depending on what the - ;; current buffer is. + ;; We need to add the startup directory in front so that + ;; files locally redefined are properly found. We cannot + ;; add ".", which varies too much depending on what the + ;; current buffer is. (set 'project (plist-put project 'src_dir (append - (list command-line-default-directory) + (list command-line-default-directory) (split-string (or (getenv "ADA_INCLUDE_PATH") "") ":") (list "." default-directory)))) (set 'project (plist-put project 'obj_dir (append - (list command-line-default-directory) + (list command-line-default-directory) (split-string (or (getenv "ADA_OBJECTS_PATH") "") ":") (list "." default-directory)))) ) @@ -817,11 +821,11 @@ ;; go to the source of the errors in a compilation buffer (setq compilation-search-path (ada-xref-get-src-dir-field)) - ;; Set the casing exceptions file list - (if casing - (progn - (setq ada-case-exception-file (reverse casing)) - (ada-case-read-exceptions))) + ;; Set the casing exceptions file list + (if casing + (progn + (setq ada-case-exception-file (reverse casing)) + (ada-case-read-exceptions))) ;; Add the directories to the search path for ff-find-other-file ;; Do not add the '/' or '\' at the end @@ -850,21 +854,21 @@ (ada-require-project-file) (let* ((identlist (ada-read-identifier pos)) - (alifile (ada-get-ali-file-name (ada-file-of identlist))) + (alifile (ada-get-ali-file-name (ada-file-of identlist))) (process-environment (ada-set-environment))) (set-buffer (get-file-buffer (ada-file-of identlist))) ;; if the file is more recent than the executable (if (or (buffer-modified-p (current-buffer)) - (file-newer-than-file-p (ada-file-of identlist) alifile)) - (ada-find-any-references (ada-name-of identlist) - (ada-file-of identlist) - nil nil local-only arg) + (file-newer-than-file-p (ada-file-of identlist) alifile)) + (ada-find-any-references (ada-name-of identlist) + (ada-file-of identlist) + nil nil local-only arg) (ada-find-any-references (ada-name-of identlist) - (ada-file-of identlist) - (ada-line-of identlist) - (ada-column-of identlist) local-only arg))) + (ada-file-of identlist) + (ada-line-of identlist) + (ada-column-of identlist) local-only arg))) ) (defun ada-find-local-references (&optional pos arg) @@ -897,9 +901,9 @@ (switches (ada-xref-get-project-field 'gnatfind_opt)) (command (concat "gnat find " switches " " quote-entity - (if file (concat ":" (file-name-nondirectory file))) - (if line (concat ":" line)) - (if column (concat ":" column)) + (if file (concat ":" (file-name-nondirectory file))) + (if line (concat ":" line)) + (if column (concat ":" column)) (if local-only (concat " " (file-name-nondirectory file))) )) old-contents) @@ -907,10 +911,10 @@ ;; If a project file is defined, use it (if (and ada-prj-default-project-file (not (string= ada-prj-default-project-file ""))) - (if (string-equal (file-name-extension ada-prj-default-project-file) - "gpr") - (setq command (concat command " -P" ada-prj-default-project-file)) - (setq command (concat command " -p" ada-prj-default-project-file)))) + (if (string-equal (file-name-extension ada-prj-default-project-file) + "gpr") + (setq command (concat command " -P" ada-prj-default-project-file)) + (setq command (concat command " -p" ada-prj-default-project-file)))) (if (and append (get-buffer "*gnatfind*")) (save-excursion @@ -937,21 +941,19 @@ ;; ----- Identifier Completion -------------------------------------------- (defun ada-complete-identifier (pos) - "Tries to complete the identifier around POS. -The feature is only available if the files where compiled without -the option `-gnatx'." + "Try to complete the identifier around POS, using compiler cross-reference information." (interactive "d") (ada-require-project-file) ;; Initialize function-local variables and jump to the .ali buffer ;; Note that for regexp search is case insensitive too (let* ((curbuf (current-buffer)) - (identlist (ada-read-identifier pos)) - (sofar (concat "^[0-9]+[a-zA-Z][0-9]+[ *]\\(" - (regexp-quote (ada-name-of identlist)) - "[a-zA-Z0-9_]*\\)")) - (completed nil) - (symalist nil)) + (identlist (ada-read-identifier pos)) + (sofar (concat "^[0-9]+[a-zA-Z][0-9]+[ *]\\(" + (regexp-quote (ada-name-of identlist)) + "[a-zA-Z0-9_]*\\)")) + (completed nil) + (symalist nil)) ;; Open the .ali file (set-buffer (ada-get-ali-buffer (buffer-file-name))) @@ -990,6 +992,7 @@ (defun ada-goto-body (pos &optional other-frame) "Display the body of the entity around POS. +OTHER-FRAME non-nil means display in another frame. If the entity doesn't have a body, display its declaration. As a side effect, the buffer for the declaration is also open." (interactive "d") @@ -1023,7 +1026,7 @@ ;; entity, whose references are not given by GNAT (if (and (file-exists-p ali-file) (file-newer-than-file-p ali-file (ada-file-of identlist))) - (message "No cross-reference found--may be a predefined entity.") + (message "No cross-reference found -- may be a predefined entity.") ;; Else, look in every ALI file, except if the user doesn't want that (if ada-xref-search-with-egrep @@ -1048,8 +1051,8 @@ command)))) (defun ada-get-absolute-dir-list (dir-list root-dir) - "Returns the list of absolute directories found in dir-list. -If a directory is a relative directory, add the value of ROOT-DIR in front." + "Return the list of absolute directories found in DIR-LIST. +If a directory is a relative directory, ROOT-DIR is prepended." (mapcar (lambda (x) (expand-file-name x root-dir)) dir-list)) (defun ada-set-environment () @@ -1134,12 +1137,6 @@ (if (or ada-xref-confirm-compile arg) (setq cmd (read-from-minibuffer "enter command to compile: " cmd))) - ;; Insert newlines so as to separate the name of the commands to run - ;; and the output of the commands. This doesn't work with cmdproxy.exe, - ;; which gets confused by newline characters. - (if (not (string-match ".exe" shell-file-name)) - (setq cmd (concat cmd "\n\n"))) - (compile (ada-quote-cmd cmd)))) (defun ada-check-current (&optional arg) @@ -1162,7 +1159,7 @@ ;; Guess the command if it wasn't specified (if (not command) - (set 'command (list (file-name-sans-extension (buffer-name))))) + (set 'command (list (file-name-sans-extension (buffer-name))))) ;; Modify the command to run remotely (setq command (ada-remote (mapconcat 'identity command @@ -1197,9 +1194,9 @@ (defun ada-gdb-application (&optional arg executable-name) "Start the debugger on the application. +If ARG is non-nil, ask the user to confirm the command. EXECUTABLE-NAME, if non-nil, is debugged instead of the file specified in the -project file. -If ARG is non-nil, ask the user to confirm the command." +project file." (interactive "P") (let ((buffer (current-buffer)) cmd pre-cmd post-cmd) @@ -1303,13 +1300,8 @@ (switch-to-buffer buffer) ))) - (defun ada-reread-prj-file (&optional filename) - "Forces Emacs to read either FILENAME or the project file associated -with the current buffer. -Otherwise, this file is only read once, and never read again. -Since the information in the project file is shared between all buffers, this -automatically modifies the setup for all the Ada buffer that use this file." + "Reread either the current project, or FILENAME if non-nil." (interactive "P") (if filename (ada-parse-prj-file filename) @@ -1330,7 +1322,7 @@ replacing the file extension with `.ali'." ;; kill old buffer (if (and ali-file-name - (get-file-buffer ali-file-name)) + (get-file-buffer ali-file-name)) (kill-buffer (get-file-buffer ali-file-name))) (let* ((name (ada-convert-file-name file)) @@ -1375,15 +1367,15 @@ found)) (defun ada-find-ali-file-in-dir (file) - "Find an .ali file in obj_dir. The current buffer must be the Ada file. + "Find the ali file FILE, searching obj_dir for the current project. Adds build_dir in front of the search path to conform to gnatmake's behavior, and the standard runtime location at the end." (ada-find-file-in-dir file (ada-xref-get-obj-dir-field))) (defun ada-find-src-file-in-dir (file) - "Find a source file in src_dir. The current buffer must be the Ada file. -Adds src_dir in front of the search path to conform to gnatmake's behavior, -and the standard runtime location at the end." + "Find the source file FILE, searching src_dir for the current project. +Adds the standard runtime location at the end of the search path to conform +to gnatmake's behavior." (ada-find-file-in-dir file (ada-xref-get-src-dir-field))) (defun ada-get-ali-file-name (file) @@ -1414,9 +1406,9 @@ (save-excursion (set-buffer (get-file-buffer file)) (let ((short-ali-file-name - (concat (file-name-sans-extension (file-name-nondirectory file)) - ".ali")) - ali-file-name + (concat (file-name-sans-extension (file-name-nondirectory file)) + ".ali")) + ali-file-name is-spec) ;; If we have a non-standard file name, and this is a spec, we first @@ -1514,15 +1506,15 @@ ;; return the absolute file name (let ((filename (ada-find-src-file-in-dir file))) (if filename - (expand-file-name filename) - (error (concat - (file-name-nondirectory file) - " not found in src_dir; please check your project file"))) + (expand-file-name filename) + (error (concat + (file-name-nondirectory file) + " not found in src_dir; please check your project file"))) ))) (defun ada-find-file-number-in-ali (file) - "Returns the file number for FILE in the associated ali file." + "Return the file number for FILE in the associated ali file." (set-buffer (ada-get-ali-buffer file)) (goto-char (point-min)) @@ -1532,7 +1524,7 @@ (count-lines begin (point)))) (defun ada-read-identifier (pos) - "Returns the identlist around POS and switch to the .ali buffer. + "Return the identlist around POS and switch to the .ali buffer. The returned list represents the entity, and can be manipulated through the macros `ada-name-of', `ada-line-of', `ada-column-of', `ada-file-of',..." @@ -1553,7 +1545,7 @@ ;; Just in front of a string => we could have an operator declaration, ;; as in "+", "-", .. (if (= (char-after) ?\") - (forward-char 1)) + (forward-char 1)) ;; if looking at an operator ;; This is only true if: @@ -1563,19 +1555,19 @@ (or (not (= (char-syntax (char-after)) ?w)) (not (or (= (char-syntax (char-after (match-end 0))) ?w) (= (char-after (match-end 0)) ?_))))) - (progn - (if (and (= (char-before) ?\") - (= (char-after (+ (length (match-string 0)) (point))) ?\")) - (forward-char -1)) - (set 'identifier (regexp-quote (concat "\"" (match-string 0) "\"")))) + (progn + (if (and (= (char-before) ?\") + (= (char-after (+ (length (match-string 0)) (point))) ?\")) + (forward-char -1)) + (set 'identifier (regexp-quote (concat "\"" (match-string 0) "\"")))) (if (ada-in-string-p) - (error "Inside string or character constant")) + (error "Inside string or character constant")) (if (looking-at (concat ada-keywords "[^a-zA-Z_]")) - (error "No cross-reference available for reserved keyword")) + (error "No cross-reference available for reserved keyword")) (if (looking-at "[a-zA-Z0-9_]+") - (set 'identifier (match-string 0)) - (error "No identifier around"))) + (set 'identifier (match-string 0)) + (error "No identifier around"))) ;; Build the identlist (set 'identlist (ada-make-identlist)) @@ -1589,8 +1581,8 @@ )) (defun ada-get-all-references (identlist) - "Completes and returns IDENTLIST with the information extracted -from the ali file (definition file and places where it is referenced)." + "Complete IDENTLIST with definition file and places where it is referenced. +Information is extracted from the ali file." (let ((ali-buffer (ada-get-ali-buffer (ada-file-of identlist))) declaration-found) @@ -1605,8 +1597,8 @@ (if (re-search-forward (concat "^X [0-9]+ " (file-name-nondirectory (ada-file-of identlist))) nil t) - (let ((bound (save-excursion (re-search-forward "^X " nil t)))) - (set 'declaration-found + (let ((bound (save-excursion (re-search-forward "^X " nil t)))) + (set 'declaration-found (re-search-forward (concat "^" (ada-line-of identlist) "." (ada-column-of identlist) @@ -1636,10 +1628,10 @@ (ada-column-of identlist) "\\>") nil t) - ;; if we did not find it, it may be because the first reference - ;; is not required to have a 'unit_number|' item included. - ;; Or maybe we are already on the declaration... - (unless (re-search-forward + ;; if we did not find it, it may be because the first reference + ;; is not required to have a 'unit_number|' item included. + ;; Or maybe we are already on the declaration... + (unless (re-search-forward (concat "^[0-9]+.[0-9]+[ *]" (ada-name-of identlist) @@ -1653,7 +1645,7 @@ ;; or the source file has been modified since the ali file was ;; created (set 'declaration-found nil) - ) + ) ) ;; Last check to be completly sure we have found the correct line (the @@ -1688,15 +1680,15 @@ ;; information available (beginning-of-line) (if declaration-found - (let ((current-line (buffer-substring + (let ((current-line (buffer-substring (point) (save-excursion (end-of-line) (point))))) - (save-excursion - (next-line 1) - (beginning-of-line) - (while (looking-at "^\\.\\(.*\\)") - (set 'current-line (concat current-line (match-string 1))) - (next-line 1)) - ) + (save-excursion + (next-line 1) + (beginning-of-line) + (while (looking-at "^\\.\\(.*\\)") + (set 'current-line (concat current-line (match-string 1))) + (next-line 1)) + ) (if (re-search-backward "^X [0-9]+ \\([a-zA-Z0-9_.-]+\\)" nil t) @@ -1725,7 +1717,7 @@ (unless (= (string-to-char (ada-name-of identlist)) ?\") (progn - (let ((declist '()) ;;; ( (line_in_ali_file line_in_ada) ( ... )) + (let ((declist '()) ;;; ( (line_in_ali_file line_in_ada) ( ... )) (my-regexp (concat "[ *]" (regexp-quote (ada-name-of identlist)) " ")) (line-ada "--") @@ -1735,43 +1727,43 @@ (choice 0) (ali-buffer (current-buffer))) - (goto-char (point-max)) - (while (re-search-backward my-regexp nil t) - (save-excursion - (set 'line-ali (count-lines 1 (point))) - (beginning-of-line) - ;; have a look at the line and column numbers - (if (looking-at "^\\([0-9]+\\).\\([0-9]+\\)[ *]") - (progn - (setq line-ada (match-string 1)) - (setq col-ada (match-string 2))) - (setq line-ada "--") - (setq col-ada "--") - ) - ;; construct a list with the file names and the positions within - (if (re-search-backward "^X [0-9]+ \\([a-zA-Z0-9._-]+\\)" nil t) + (goto-char (point-max)) + (while (re-search-backward my-regexp nil t) + (save-excursion + (set 'line-ali (count-lines 1 (point))) + (beginning-of-line) + ;; have a look at the line and column numbers + (if (looking-at "^\\([0-9]+\\).\\([0-9]+\\)[ *]") + (progn + (setq line-ada (match-string 1)) + (setq col-ada (match-string 2))) + (setq line-ada "--") + (setq col-ada "--") + ) + ;; construct a list with the file names and the positions within + (if (re-search-backward "^X [0-9]+ \\([a-zA-Z0-9._-]+\\)" nil t) (add-to-list 'declist (list line-ali (match-string 1) line-ada col-ada)) - ) - ) - ) + ) + ) + ) - ;; how many possible declarations have we found ? - (setq len (length declist)) - (cond - ;; none => error - ((= len 0) - (kill-buffer (current-buffer)) - (error (concat "No declaration of " - (ada-name-of identlist) - " recorded in .ali file"))) + ;; how many possible declarations have we found ? + (setq len (length declist)) + (cond + ;; none => error + ((= len 0) + (kill-buffer (current-buffer)) + (error (concat "No declaration of " + (ada-name-of identlist) + " recorded in .ali file"))) - ;; one => should be the right one - ((= len 1) - (goto-line (caar declist))) + ;; one => should be the right one + ((= len 1) + (goto-line (caar declist))) - ;; more than one => display choice list - (t + ;; more than one => display choice list + (t (save-window-excursion (with-output-to-temp-buffer "*choice list*" @@ -1782,13 +1774,13 @@ (let ((counter 0)) (while (< counter len) (princ (format " %2d) %-21s %4s %4s\n" - (1+ counter) + (1+ counter) (ada-get-ada-file-name (nth 1 (nth counter declist)) (ada-file-of identlist)) - (nth 2 (nth counter declist)) - (nth 3 (nth counter declist)) - )) + (nth 2 (nth counter declist)) + (nth 3 (nth counter declist)) + )) (setq counter (1+ counter)) ) ; end of while ) ; end of let @@ -1804,13 +1796,13 @@ (read-from-minibuffer "Enter No. of your choice: ")))) ) (set-buffer ali-buffer) - (goto-line (car (nth (1- choice) declist))) - )))))) + (goto-line (car (nth (1- choice) declist))) + )))))) (defun ada-find-in-ali (identlist &optional other-frame) "Look in the .ali file for the definition of the identifier in IDENTLIST. -If OTHER-FRAME is non nil, and `ada-xref-other-buffer' is non nil, +If OTHER-FRAME is non-nil, and `ada-xref-other-buffer' is non-nil, opens a new window to show the declaration." (ada-get-all-references identlist) @@ -1899,7 +1891,7 @@ This works well when one is using an external librarie and wants to find the declaration and documentation of the subprograms one is is using." - +;; FIXME: what does this function do? (let (list (dirs (ada-xref-get-obj-dir-field)) (regexp (concat "[ *]" (ada-name-of identlist))) @@ -2020,12 +2012,12 @@ ;; Select and display the destination buffer (if ada-xref-other-buffer - (if other-frame - (find-file-other-frame file) - (set 'declaration-buffer (find-file-noselect file)) - (set-buffer declaration-buffer) - (switch-to-buffer-other-window declaration-buffer) - ) + (if other-frame + (find-file-other-frame file) + (set 'declaration-buffer (find-file-noselect file)) + (set-buffer declaration-buffer) + (switch-to-buffer-other-window declaration-buffer) + ) (find-file file) ) @@ -2043,11 +2035,11 @@ (defun ada-xref-search-nearest (name) - "Searches for NAME nearest to the position recorded in the Xref file. -It returns the position of the declaration in the buffer or nil if not found." + "Search for NAME nearest to the position recorded in the Xref file. +Return the position of the declaration in the buffer, or nil if not found." (let ((orgpos (point)) - (newpos nil) - (diff nil)) + (newpos nil) + (diff nil)) (goto-char (point-max)) @@ -2056,33 +2048,33 @@ ;; check if it really is a complete Ada identifier (if (and - (not (save-excursion - (goto-char (match-end 0)) - (looking-at "_"))) - (not (ada-in-string-or-comment-p)) - (or - ;; variable declaration ? - (save-excursion - (skip-chars-forward "a-zA-Z_0-9" ) - (ada-goto-next-non-ws) - (looking-at ":[^=]")) - ;; procedure, function, task or package declaration ? - (save-excursion - (ada-goto-previous-word) - (looking-at "\\<[pP][rR][oO][cC][eE][dD][uU][rR][eE]\\>\\|\\<[fF][uU][nN][cC][tT][iI][oO][nN]\\>\\|\\<[tT][yY][pP][eE]\\>\\|\\<[tT][aA][sS][kK]\\>\\|\\<[pP][aA][cC][kK][aA][gG][eE]\\>\\|\\<[bB][oO][dD][yY]\\>")))) + (not (save-excursion + (goto-char (match-end 0)) + (looking-at "_"))) + (not (ada-in-string-or-comment-p)) + (or + ;; variable declaration ? + (save-excursion + (skip-chars-forward "a-zA-Z_0-9" ) + (ada-goto-next-non-ws) + (looking-at ":[^=]")) + ;; procedure, function, task or package declaration ? + (save-excursion + (ada-goto-previous-word) + (looking-at "\\<[pP][rR][oO][cC][eE][dD][uU][rR][eE]\\>\\|\\<[fF][uU][nN][cC][tT][iI][oO][nN]\\>\\|\\<[tT][yY][pP][eE]\\>\\|\\<[tT][aA][sS][kK]\\>\\|\\<[pP][aA][cC][kK][aA][gG][eE]\\>\\|\\<[bB][oO][dD][yY]\\>")))) - ;; check if it is nearer than the ones before if any - (if (or (not diff) - (< (abs (- (point) orgpos)) diff)) - (progn - (setq newpos (point) + ;; check if it is nearer than the ones before if any + (if (or (not diff) + (< (abs (- (point) orgpos)) diff)) + (progn + (setq newpos (point) diff (abs (- newpos orgpos)))))) ) (if newpos - (progn - (message "ATTENTION: this declaration is only a (good) guess ...") - (goto-char newpos)) + (progn + (message "ATTENTION: this declaration is only a (good) guess ...") + (goto-char newpos)) nil))) @@ -2093,26 +2085,26 @@ (ada-require-project-file) (let ((buffer (ada-get-ali-buffer (buffer-file-name))) - (unit-name nil) - (body-name nil) - (ali-name nil)) + (unit-name nil) + (body-name nil) + (ali-name nil)) (save-excursion (set-buffer buffer) (goto-char (point-min)) (re-search-forward "^U \\([^ \t%]+\\)%[bs][ \t]+\\([^ \t]+\\)") (setq unit-name (match-string 1)) (if (not (string-match "\\(.*\\)\\.[^.]+" unit-name)) - (progn - (kill-buffer buffer) - (error "No parent unit !")) - (setq unit-name (match-string 1 unit-name)) - ) + (progn + (kill-buffer buffer) + (error "No parent unit !")) + (setq unit-name (match-string 1 unit-name)) + ) ;; look for the file name for the parent unit specification (goto-char (point-min)) (re-search-forward (concat "^W " unit-name - "%s[ \t]+\\([^ \t]+\\)[ \t]+" - "\\([^ \t\n]+\\)")) + "%s[ \t]+\\([^ \t]+\\)[ \t]+" + "\\([^ \t\n]+\\)")) (setq body-name (match-string 1)) (setq ali-name (match-string 2)) (kill-buffer buffer) @@ -2123,15 +2115,15 @@ (save-excursion ;; Tries to open the new ali file to find the spec file (if ali-name - (progn - (find-file ali-name) - (goto-char (point-min)) - (re-search-forward (concat "^U " unit-name "%s[ \t]+" - "\\([^ \t]+\\)")) - (setq body-name (match-string 1)) - (kill-buffer (current-buffer)) - ) - ) + (progn + (find-file ali-name) + (goto-char (point-min)) + (re-search-forward (concat "^U " unit-name "%s[ \t]+" + "\\([^ \t]+\\)")) + (setq body-name (match-string 1)) + (kill-buffer (current-buffer)) + ) + ) ) (find-file body-name) @@ -2146,14 +2138,14 @@ (set-buffer krunch-buf) ;; send adaname to external process `gnatkr'. (call-process "gnatkr" nil krunch-buf nil - adaname ada-krunch-args) + adaname ada-krunch-args) ;; fetch output of that process (setq adaname (buffer-substring - (point-min) - (progn - (goto-char (point-min)) - (end-of-line) - (point)))) + (point-min) + (progn + (goto-char (point-min)) + (end-of-line) + (point)))) (kill-buffer krunch-buf))) adaname ) @@ -2187,10 +2179,10 @@ ;; Call the external process gnatstub (let* ((gnatstub-opts (ada-treat-cmd-string ada-gnatstub-opts)) - (filename (buffer-file-name (car (buffer-list)))) - (output (concat (file-name-sans-extension filename) ".adb")) - (gnatstub-cmd (concat "gnatstub " gnatstub-opts " " filename)) - (buffer (get-buffer-create "*gnatstub*"))) + (filename (buffer-file-name (car (buffer-list)))) + (output (concat (file-name-sans-extension filename) ".adb")) + (gnatstub-cmd (concat "gnatstub " gnatstub-opts " " filename)) + (buffer (get-buffer-create "*gnatstub*"))) (save-excursion (set-buffer buffer) @@ -2203,25 +2195,25 @@ (call-process shell-file-name nil buffer nil "-c" gnatstub-cmd) (if (save-excursion - (set-buffer buffer) - (goto-char (point-min)) - (search-forward "command not found" nil t)) - (progn - (message "gnatstub was not found -- using the basic algorithm") - (sleep-for 2) - (kill-buffer buffer) - (ada-make-body)) + (set-buffer buffer) + (goto-char (point-min)) + (search-forward "command not found" nil t)) + (progn + (message "gnatstub was not found -- using the basic algorithm") + (sleep-for 2) + (kill-buffer buffer) + (ada-make-body)) ;; Else clean up the output (if (file-exists-p output) - (progn - (find-file output) - (kill-buffer buffer)) + (progn + (find-file output) + (kill-buffer buffer)) - ;; display the error buffer - (display-buffer buffer) - ) + ;; display the error buffer + (display-buffer buffer) + ) ))) (defun ada-xref-initialize () @@ -2237,22 +2229,9 @@ (ada-xref-update-project-menu) ) - ;; ----- Add to ada-mode-hook --------------------------------------------- -;; Use gvd or ddd as the default debugger if it was found -;; On windows, do not use the --tty switch for GVD, since this is -;; not supported. Actually, we do not use this on Unix either, -;; since otherwise there is no console window left in GVD, -;; and people have to use the Emacs one. ;; This must be done before initializing the Ada menu. -(if (ada-find-file-in-dir "gvd" exec-path) - (set 'ada-prj-default-debugger "gvd ") - (if (ada-find-file-in-dir "gvd.exe" exec-path) - (set 'ada-prj-default-debugger "gvd ") - (if (ada-find-file-in-dir "ddd" exec-path) - (set 'ada-prj-default-debugger "ddd --tty -fullname -toolbar")))) - (add-hook 'ada-mode-hook 'ada-xref-initialize) ;; Initializes the cross references to the runtime library
--- a/lisp/progmodes/idlwave.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/progmodes/idlwave.el Tue Nov 07 23:22:48 2006 +0000 @@ -4387,7 +4387,7 @@ (idlwave-update-routine-info '(16))) (defun idlwave-rescan-asynchronously () - "Dispatch another emacs instance to update the idlwave catalog. + "Dispatch another Emacs instance to update the idlwave catalog. After the process finishes normally, the first access to routine info will re-read the catalog." (interactive)
--- a/lisp/resume.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/resume.el Tue Nov 07 23:22:48 2006 +0000 @@ -49,7 +49,7 @@ ;;; Code: (defvar resume-emacs-args-file (expand-file-name "~/.emacs_args") - "*This file is where arguments are placed for a suspended emacs job.") + "*This file is where arguments are placed for a suspended Emacs job.") (defvar resume-emacs-args-buffer " *Command Line Args*" "Buffer that is used by resume-process-args.")
--- a/lisp/rfn-eshadow.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/rfn-eshadow.el Tue Nov 07 23:22:48 2006 +0000 @@ -106,8 +106,8 @@ (defcustom file-name-shadow-tty-properties '(before-string "{" after-string "} " field shadow) "Properties given to the `shadowed' part of a filename in the minibuffer. -Only used when `file-name-shadow-mode' is active and emacs -is not running under a window-system; if emacs is running under a window +Only used when `file-name-shadow-mode' is active and Emacs +is not running under a window-system; if Emacs is running under a window system, `file-name-shadow-properties' is used instead." :type file-name-shadow-properties-custom-type :group 'minibuffer
--- a/lisp/ruler-mode.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/ruler-mode.el Tue Nov 07 23:22:48 2006 +0000 @@ -526,6 +526,16 @@ #'ruler-mode-mouse-del-tab-stop) (define-key km [header-line (control down-mouse-2)] #'ruler-mode-toggle-show-tab-stops) + (define-key km [header-line (shift mouse-1)] + 'ignore) + (define-key km [header-line (shift mouse-3)] + 'ignore) + (define-key km [header-line (control mouse-1)] + 'ignore) + (define-key km [header-line (control mouse-3)] + 'ignore) + (define-key km [header-line (control mouse-2)] + 'ignore) km) "Keymap for ruler minor mode.")
--- a/lisp/server.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/server.el Tue Nov 07 23:22:48 2006 +0000 @@ -82,6 +82,36 @@ "Emacs running as a server process." :group 'external) +(defcustom server-use-tcp nil + "If non-nil, use TCP sockets instead of local sockets." + :set #'(lambda (sym val) + (unless (featurep 'make-network-process '(:family local)) + (setq val t) + (unless load-in-progress + (message "Local sockets unsupported, using TCP sockets"))) + (when val (random t)) + (set-default sym val)) + :group 'server + :type 'boolean + :version "22.1") + +(defcustom server-host nil + "The name or IP address to use as host address of the server process. +If set, the server accepts remote connections; otherwise it is local." + :group 'server + :type '(choice + (string :tag "Name or IP address") + (const :tag "Local" nil)) + :version "22.1") +(put 'server-host 'risky-local-variable t) + +(defcustom server-auth-dir "~/.emacs.d/server/" + "Directory for server authentication files." + :group 'server + :type 'directory + :version "22.1") +(put 'server-auth-dir 'risky-local-variable t) + (defcustom server-visit-hook nil "*Hook run when visiting a file for the Emacs server." :group 'server @@ -151,7 +181,7 @@ :version "21.1") (or (assq 'server-buffer-clients minor-mode-alist) - (setq minor-mode-alist (cons '(server-buffer-clients " Server") minor-mode-alist))) + (push '(server-buffer-clients " Server") minor-mode-alist)) (defvar server-existing-buffer nil "Non-nil means the buffer existed before the server was asked to visit it. @@ -166,13 +196,13 @@ (defun server-log (string &optional client) "If a *server* buffer exists, write STRING to it for logging purposes." - (if (get-buffer "*server*") - (with-current-buffer "*server*" - (goto-char (point-max)) - (insert (current-time-string) - (if client (format " %s:" client) " ") - string) - (or (bolp) (newline))))) + (when (get-buffer "*server*") + (with-current-buffer "*server*" + (goto-char (point-max)) + (insert (current-time-string) + (if client (format " %s:" client) " ") + string) + (or (bolp) (newline))))) (defun server-sentinel (proc msg) (let ((client (assq proc server-clients))) @@ -194,6 +224,12 @@ (when (and (eq (process-status proc) 'open) (process-query-on-exit-flag proc)) (set-process-query-on-exit-flag proc nil)) + ;; Delete the associated connection file, if applicable. + ;; This is actually problematic: the file may have been overwritten by + ;; another Emacs server in the mean time, so it's not ours any more. + ;; (and (process-contact proc :server) + ;; (eq (process-status proc) 'closed) + ;; (ignore-errors (delete-file (process-get proc :server-file)))) (server-log (format "Status changed to %s" (process-status proc)) proc)) (defun server-select-display (display) @@ -205,12 +241,34 @@ (select-frame frame))) ;; If there's no frame on that display yet, create and select one. (unless (equal (frame-parameter (selected-frame) 'display) display) - (select-frame - (make-frame-on-display - display - ;; This frame may be deleted later (see server-process-filter) - ;; so we want it to be as unobtrusive as possible. - '((visibility . nil))))))) + (let* ((buffer (generate-new-buffer " *server-dummy*")) + (frame (make-frame-on-display + display + ;; Make it display (and remember) some dummy buffer, so + ;; we can detect later if the frame is in use or not. + `((server-dummmy-buffer . ,buffer) + ;; This frame may be deleted later (see + ;; server-unselect-display) so we want it to be as + ;; unobtrusive as possible. + (visibility . nil))))) + (select-frame frame) + (set-window-buffer (selected-window) buffer))))) + +(defun server-unselect-display (frame) + ;; If the temporary frame is in use (displays something real), make it + ;; visible. If not (which can happen if the user's customizations call + ;; pop-to-buffer etc.), delete it to avoid preserving the connection after + ;; the last real frame is deleted. + (if (and (eq (frame-first-window frame) + (next-window (frame-first-window frame) 'nomini)) + (eq (window-buffer (frame-first-window frame)) + (frame-parameter frame 'server-dummy-buffer))) + ;; The temp frame still only shows one buffer, and that is the + ;; internal temp buffer. + (delete-frame frame) + (set-frame-parameter frame 'visibility t)) + (kill-buffer (frame-parameter frame 'server-dummy-buffer)) + (set-frame-parameter frame 'server-dummy-buffer nil)) (defun server-unquote-arg (arg) (replace-regexp-in-string @@ -231,11 +289,12 @@ (setq dir (directory-file-name dir)) (let ((attrs (file-attributes dir))) (unless attrs - (letf (((default-file-modes) ?\700)) (make-directory dir)) + (letf (((default-file-modes) ?\700)) (make-directory dir t)) (setq attrs (file-attributes dir))) ;; Check that it's safe for use. (unless (and (eq t (car attrs)) (eq (nth 2 attrs) (user-uid)) - (zerop (logand ?\077 (file-modes dir)))) + (or (eq system-type 'windows-nt) + (zerop (logand ?\077 (file-modes dir))))) (error "The directory %s is unsafe" dir)))) ;;;###autoload @@ -248,33 +307,61 @@ Prefix arg means just kill any existing server communications subprocess." (interactive "P") - ;; kill it dead! - (if server-process - (condition-case () (delete-process server-process) (error nil))) - ;; Delete the socket files made by previous server invocations. - (condition-case () - (delete-file (expand-file-name server-name server-socket-dir)) - (error nil)) + (when server-process + ;; kill it dead! + (ignore-errors (delete-process server-process))) ;; If this Emacs already had a server, clear out associated status. (while server-clients (let ((buffer (nth 1 (car server-clients)))) (server-buffer-done buffer))) ;; Now any previous server is properly stopped. (unless leave-dead - ;; Make sure there is a safe directory in which to place the socket. - (server-ensure-safe-dir server-socket-dir) - (if server-process - (server-log (message "Restarting server"))) - (letf (((default-file-modes) ?\700)) - (setq server-process - (make-network-process - :name "server" :family 'local :server t :noquery t - :service (expand-file-name server-name server-socket-dir) - :sentinel 'server-sentinel :filter 'server-process-filter - ;; We must receive file names without being decoded. - ;; Those are decoded by server-process-filter according - ;; to file-name-coding-system. - :coding 'raw-text))))) + (let* ((server-dir (if server-use-tcp server-auth-dir server-socket-dir)) + (server-file (expand-file-name server-name server-dir))) + ;; Make sure there is a safe directory in which to place the socket. + (server-ensure-safe-dir server-dir) + ;; Remove any leftover socket or authentication file. + (ignore-errors (delete-file server-file)) + (when server-process + (server-log (message "Restarting server"))) + (letf (((default-file-modes) ?\700)) + (setq server-process + (apply #'make-network-process + :name server-name + :server t + :noquery t + :sentinel 'server-sentinel + :filter 'server-process-filter + ;; We must receive file names without being decoded. + ;; Those are decoded by server-process-filter according + ;; to file-name-coding-system. + :coding 'raw-text + ;; The rest of the args depends on the kind of socket used. + (if server-use-tcp + (list :family nil + :service t + :host (or server-host 'local) + :plist '(:authenticated nil)) + (list :family 'local + :service server-file + :plist '(:authenticated t))))) + (unless server-process (error "Could not start server process")) + (when server-use-tcp + (let ((auth-key + (loop + ;; The auth key is a 64-byte string of random chars in the + ;; range `!'..`~'. + for i below 64 + collect (+ 33 (random 94)) into auth + finally return (concat auth)))) + (process-put server-process :auth-key auth-key) + (with-temp-file server-file + (set-buffer-multibyte nil) + (setq buffer-file-coding-system 'no-conversion) + (insert (format-network-address + (process-contact server-process :local)) + " " (int-to-string (emacs-pid)) + "\n" auth-key)))))))) ;;;###autoload (define-minor-mode server-mode @@ -289,14 +376,27 @@ ;; nothing if there is one (for multiple Emacs sessions)? (server-start (not server-mode))) -(defun server-process-filter (proc string) +(defun* server-process-filter (proc string) "Process a request from the server to edit some files. PROC is the server process. Format of STRING is \"PATH PATH PATH... \\n\"." + ;; First things first: let's check the authentication + (unless (process-get proc :authenticated) + (if (and (string-match "-auth \\(.*?\\)\n" string) + (equal (match-string 1 string) (process-get proc :auth-key))) + (progn + (setq string (substring string (match-end 0))) + (process-put proc :authenticated t) + (server-log "Authentication successful" proc)) + (server-log "Authentication failed" proc) + (process-send-string proc "Authentication failed") + (delete-process proc) + ;; We return immediately + (return-from server-process-filter))) (server-log string proc) - (let ((prev (process-get proc 'previous-string))) + (let ((prev (process-get proc :previous-string))) (when prev (setq string (concat prev string)) - (process-put proc 'previous-string nil))) + (process-put proc :previous-string nil))) ;; If the input is multiple lines, ;; process each line individually. (while (string-match "\n" string) @@ -307,7 +407,7 @@ client nowait eval (files nil) (lineno 1) - (tmp-frame nil) ; Sometimes used to embody the selected display. + (tmp-frame nil) ;; Sometimes used to embody the selected display. (columnno 0)) ;; Remove this line from STRING. (setq string (substring string (match-end 0))) @@ -316,51 +416,48 @@ (let ((arg (substring request (match-beginning 0) (1- (match-end 0))))) (setq request (substring request (match-end 0))) (cond - ((equal "-nowait" arg) (setq nowait t)) - ((equal "-eval" arg) (setq eval t)) - ((and (equal "-display" arg) (string-match "\\([^ ]*\\) " request)) - (let ((display (server-unquote-arg (match-string 1 request)))) - (setq request (substring request (match-end 0))) - (condition-case err - (setq tmp-frame (server-select-display display)) - (error (process-send-string proc (nth 1 err)) - (setq request ""))))) - ;; ARG is a line number option. - ((string-match "\\`\\+[0-9]+\\'" arg) - (setq lineno (string-to-number (substring arg 1)))) - ;; ARG is line number:column option. - ((string-match "\\`+\\([0-9]+\\):\\([0-9]+\\)\\'" arg) - (setq lineno (string-to-number (match-string 1 arg)) - columnno (string-to-number (match-string 2 arg)))) - (t - ;; Undo the quoting that emacsclient does - ;; for certain special characters. - (setq arg (server-unquote-arg arg)) - ;; Now decode the file name if necessary. - (if coding-system - (setq arg (decode-coding-string arg coding-system))) - (if eval - (let* (errorp - (v (condition-case errobj - (eval (car (read-from-string arg))) - (error (setq errorp t) errobj)))) - (when v - (with-temp-buffer - (let ((standard-output (current-buffer))) - (if errorp (princ "error: ")) - (pp v) - ;; Suppress the error rose when the pipe to PROC is closed. - (condition-case err - (process-send-region proc (point-min) (point-max)) - (file-error nil) - (error nil)) - )))) - ;; ARG is a file name. - ;; Collapse multiple slashes to single slashes. - (setq arg (command-line-normalize-file-name arg)) - (push (list arg lineno columnno) files)) - (setq lineno 1) - (setq columnno 0))))) + ((equal "-nowait" arg) (setq nowait t)) + ((equal "-eval" arg) (setq eval t)) + ((and (equal "-display" arg) (string-match "\\([^ ]*\\) " request)) + (let ((display (server-unquote-arg (match-string 1 request)))) + (setq request (substring request (match-end 0))) + (condition-case err + (setq tmp-frame (server-select-display display)) + (error (process-send-string proc (nth 1 err)) + (setq request ""))))) + ;; ARG is a line number option. + ((string-match "\\`\\+[0-9]+\\'" arg) + (setq lineno (string-to-number (substring arg 1)))) + ;; ARG is line number:column option. + ((string-match "\\`+\\([0-9]+\\):\\([0-9]+\\)\\'" arg) + (setq lineno (string-to-number (match-string 1 arg)) + columnno (string-to-number (match-string 2 arg)))) + (t + ;; Undo the quoting that emacsclient does + ;; for certain special characters. + (setq arg (server-unquote-arg arg)) + ;; Now decode the file name if necessary. + (when coding-system + (setq arg (decode-coding-string arg coding-system))) + (if eval + (let* (errorp + (v (condition-case errobj + (eval (car (read-from-string arg))) + (error (setq errorp t) errobj)))) + (when v + (with-temp-buffer + (let ((standard-output (current-buffer))) + (when errorp (princ "error: ")) + (pp v) + (ignore-errors + (process-send-region proc (point-min) (point-max))) + )))) + ;; ARG is a file name. + ;; Collapse multiple slashes to single slashes. + (setq arg (command-line-normalize-file-name arg)) + (push (list arg lineno columnno) files)) + (setq lineno 1) + (setq columnno 0))))) (when files (run-hooks 'pre-command-hook) (server-visit-files files client nowait) @@ -378,24 +475,20 @@ (run-hooks 'server-switch-hook) (unless nowait (message "%s" (substitute-command-keys - "When done with a buffer, type \\[server-edit]"))))) - ;; If the temporary frame is still the selected frame, make it - ;; real. If not (which can happen if the user's customizations - ;; call pop-to-buffer etc.), delete it to avoid preserving the - ;; connection after the last real frame is deleted. - (if tmp-frame - (if (eq (selected-frame) tmp-frame) - (set-frame-parameter tmp-frame 'visibility t) - (delete-frame tmp-frame))))) + "When done with a buffer, type \\[server-edit]"))))) + (when (frame-live-p tmp-frame) + ;; Delete tmp-frame or make it visible depending on whether it's + ;; been used or not. + (server-unselect-display tmp-frame)))) ;; Save for later any partial line that remains. (when (> (length string) 0) - (process-put proc 'previous-string string))) + (process-put proc :previous-string string))) (defun server-goto-line-column (file-line-col) (goto-line (nth 1 file-line-col)) (let ((column-number (nth 2 file-line-col))) - (if (> column-number 0) - (move-to-column (1- column-number))))) + (when (> column-number 0) + (move-to-column (1- column-number))))) (defun server-visit-files (files client &optional nowait) "Find FILES and return the list CLIENT with the buffers nconc'd. @@ -418,14 +511,14 @@ (if (and obuf (set-buffer obuf)) (progn (cond ((file-exists-p filen) - (if (not (verify-visited-file-modtime obuf)) - (revert-buffer t nil))) + (when (not (verify-visited-file-modtime obuf)) + (revert-buffer t nil))) (t - (if (y-or-n-p - (concat "File no longer exists: " - filen - ", write buffer to file? ")) - (write-file filen)))) + (when (y-or-n-p + (concat "File no longer exists: " + filen + ", write buffer to file? ")) + (write-file filen)))) (setq server-existing-buffer t) (server-goto-line-column file)) (set-buffer (find-file-noselect filen)) @@ -467,33 +560,33 @@ (server-log "Close" (car client)) (setq server-clients (delq client server-clients)))) (setq old-clients (cdr old-clients))) - (if (and (bufferp buffer) (buffer-name buffer)) - ;; We may or may not kill this buffer; - ;; if we do, do not call server-buffer-done recursively - ;; from kill-buffer-hook. - (let ((server-kill-buffer-running t)) - (with-current-buffer buffer - (setq server-buffer-clients nil) - (run-hooks 'server-done-hook)) - ;; Notice whether server-done-hook killed the buffer. - (if (null (buffer-name buffer)) + (when (and (bufferp buffer) (buffer-name buffer)) + ;; We may or may not kill this buffer; + ;; if we do, do not call server-buffer-done recursively + ;; from kill-buffer-hook. + (let ((server-kill-buffer-running t)) + (with-current-buffer buffer + (setq server-buffer-clients nil) + (run-hooks 'server-done-hook)) + ;; Notice whether server-done-hook killed the buffer. + (if (null (buffer-name buffer)) + (setq killed t) + ;; Don't bother killing or burying the buffer + ;; when we are called from kill-buffer. + (unless for-killing + (when (and (not killed) + server-kill-new-buffers + (with-current-buffer buffer + (not server-existing-buffer))) (setq killed t) - ;; Don't bother killing or burying the buffer - ;; when we are called from kill-buffer. - (unless for-killing - (when (and (not killed) - server-kill-new-buffers - (with-current-buffer buffer - (not server-existing-buffer))) - (setq killed t) - (bury-buffer buffer) - (kill-buffer buffer)) - (unless killed - (if (server-temp-file-p buffer) - (progn - (kill-buffer buffer) - (setq killed t)) - (bury-buffer buffer))))))) + (bury-buffer buffer) + (kill-buffer buffer)) + (unless killed + (if (server-temp-file-p buffer) + (progn + (kill-buffer buffer) + (setq killed t)) + (bury-buffer buffer))))))) (list next-buffer killed))) (defun server-temp-file-p (&optional buffer) @@ -520,10 +613,10 @@ (let ((version-control nil) (buffer-backed-up nil)) (save-buffer)) - (if (and (buffer-modified-p) - buffer-file-name - (y-or-n-p (concat "Save file " buffer-file-name "? "))) - (save-buffer))) + (when (and (buffer-modified-p) + buffer-file-name + (y-or-n-p (concat "Save file " buffer-file-name "? "))) + (save-buffer))) (server-buffer-done (current-buffer)))) ;; Ask before killing a server buffer. @@ -543,8 +636,8 @@ (tail server-clients)) ;; See if any clients have any buffers that are still alive. (while tail - (if (memq t (mapcar 'stringp (mapcar 'buffer-name (cdr (car tail))))) - (setq live-client t)) + (when (memq t (mapcar 'stringp (mapcar 'buffer-name (cdr (car tail))))) + (setq live-client t)) (setq tail (cdr tail))) (or (not live-client) (yes-or-no-p "Server buffers still have clients; exit anyway? ")))) @@ -579,12 +672,12 @@ starts server process and that is all. Invoked by \\[server-edit]." (interactive "P") (cond - ((or arg - (not server-process) - (memq (process-status server-process) '(signal exit))) - (server-mode 1)) - (server-clients (apply 'server-switch-buffer (server-done))) - (t (message "No server editing buffers exist")))) + ((or arg + (not server-process) + (memq (process-status server-process) '(signal exit))) + (server-mode 1)) + (server-clients (apply 'server-switch-buffer (server-done))) + (t (message "No server editing buffers exist")))) (defun server-switch-buffer (&optional next-buffer killed-one) "Switch to another buffer, preferably one that has a client. @@ -610,8 +703,8 @@ (if (and win (not server-window)) ;; The buffer is already displayed: just reuse the window. (let ((frame (window-frame win))) - (if (eq (frame-visible-p frame) 'icon) - (raise-frame frame)) + (when (eq (frame-visible-p frame) 'icon) + (raise-frame frame)) (select-window win) (set-buffer next-buffer)) ;; Otherwise, let's find an appropriate window. @@ -619,11 +712,11 @@ (window-live-p server-window)) (select-window server-window)) ((framep server-window) - (if (not (frame-live-p server-window)) - (setq server-window (make-frame))) + (unless (frame-live-p server-window) + (setq server-window (make-frame))) (select-window (frame-selected-window server-window)))) - (if (window-minibuffer-p (selected-window)) - (select-window (next-window nil 'nomini 0))) + (when (window-minibuffer-p (selected-window)) + (select-window (next-window nil 'nomini 0))) ;; Move to a non-dedicated window, if we have one. (when (window-dedicated-p (selected-window)) (select-window
--- a/lisp/shadowfile.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/shadowfile.el Tue Nov 07 23:22:48 2006 +0000 @@ -97,12 +97,12 @@ :group 'shadow) (defcustom shadow-inhibit-message nil - "*If nonnil, do not display a message when a file needs copying." + "*If non-nil, do not display a message when a file needs copying." :type 'boolean :group 'shadow) (defcustom shadow-inhibit-overload nil - "If nonnil, shadowfile won't redefine \\[save-buffers-kill-emacs]. + "If non-nil, shadowfile won't redefine \\[save-buffers-kill-emacs]. Normally it overloads the function `save-buffers-kill-emacs' to check for files have been changed and need to be copied to other systems." :type 'boolean @@ -146,7 +146,7 @@ (defvar shadow-literal-groups nil "List of files that are shared between hosts. This list contains shadow structures with literal filenames, created by -shadow-define-group.") +`shadow-define-literal-group'.") (defvar shadow-regexp-groups nil "List of file types that are shared between hosts. @@ -178,7 +178,7 @@ (shadow-union (cdr a) (cons (car a) b))))) (defun shadow-find (func list) - "If FUNC applied to some element of LIST is nonnil, return first such element." + "If FUNC applied to some element of LIST is non-nil, return first such element." (while (and list (not (funcall func (car list)))) (setq list (cdr list))) (car list)) @@ -205,7 +205,7 @@ (defun shadow-suffix (prefix string) "If PREFIX begins STRING, return the rest. -Return value is nonnil if PREFIX and STRING are string= up to the length of +Return value is non-nil if PREFIX and STRING are `string=' up to the length of PREFIX." (let ((lp (length prefix)) (ls (length string))) @@ -285,9 +285,9 @@ ans))) (defun shadow-site-match (site1 site2) - "Nonnil iff SITE1 is or includes SITE2. -Each may be a host or cluster name; if they are clusters, regexp of site1 will -be matched against the primary of site2." + "Non-nil iff SITE1 is or includes SITE2. +Each may be a host or cluster name; if they are clusters, regexp of SITE1 will +be matched against the primary of SITE2." (or (string-equal site1 site2) ; quick check (let* ((cluster1 (shadow-get-cluster site1)) (primary2 (shadow-site-primary site2))) @@ -355,7 +355,7 @@ (nth 2 hup)))))) (defun shadow-expand-file-name (file &optional default) - "Expand file name and get file's true name." + "Expand file name and get FILE's true name." (file-truename (expand-file-name file default))) (defun shadow-contract-file-name (file) @@ -398,7 +398,7 @@ "Return t if PATTERN matches FILE. If REGEXP is supplied and non-nil, the file part of the pattern is a regular expression, otherwise it must match exactly. The sites and usernames must -match---see shadow-same-site. The pattern must be in full ange-ftp format, but +match---see `shadow-same-site'. The pattern must be in full ange-ftp format, but the file can be any valid filename. This function does not do any filename expansion or contraction, you must do that yourself first." (let* ((pattern-sup (shadow-parse-fullname pattern)) @@ -475,7 +475,7 @@ "Make each of a group of files be shared between hosts. Prompts for regular expression; files matching this are shared between a list of sites, which are also prompted for. The filenames must be identical on all -hosts \(if they aren't, use shadow-define-group instead of this function). +hosts \(if they aren't, use `shadow-define-literal-group' instead of this function). Each site can be either a hostname or the name of a cluster \(see `shadow-define-cluster')." (interactive) @@ -661,7 +661,7 @@ (or (stringp (file-locked-p shadow-info-file)) (stringp (file-locked-p shadow-todo-file)))) (progn - (message "Shadowfile is running in another emacs; can't have two.") + (message "Shadowfile is running in another Emacs; can't have two.") (beep) (sit-for 3) nil) @@ -707,8 +707,8 @@ (shadow-insert-var 'shadow-regexp-groups)))) (defun shadow-write-todo-file (&optional save) - "Write out information to shadow-todo-file. -With nonnil argument also saves the buffer." + "Write out information to `shadow-todo-file'. +With non-nil argument also saves the buffer." (save-excursion (if (not shadow-todo-buffer) (setq shadow-todo-buffer (find-file-noselect shadow-todo-file))) @@ -731,9 +731,9 @@ (setq shadow-hashtable (make-vector 37 0))) (defun shadow-insert-var (variable) - "Prettily insert a setq command for VARIABLE. + "Prettily insert a `setq' command for VARIABLE, which, when later evaluated, will restore it to its current setting. -SYMBOL must be the name of a variable whose value is a list." +VARIABLE must be the name of a variable whose value is a list." (let ((standard-output (current-buffer))) (insert (format "(setq %s" variable)) (cond ((consp (eval variable))
--- a/lisp/simple.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/simple.el Tue Nov 07 23:22:48 2006 +0000 @@ -2725,7 +2725,7 @@ `yank-excluded-properties' and `yank-handler' as described in the doc string for `insert-for-yank-1', which see. -See also the command \\[yank-pop]." +See also the command `yank-pop' (\\[yank-pop])." (interactive "*P") (setq yank-window-start (window-start)) ;; If we don't get all the way thru, make last-command indicate that
--- a/lisp/sort.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/sort.el Tue Nov 07 23:22:48 2006 +0000 @@ -505,8 +505,9 @@ ;; Use the sort utility if we can; it is 4 times as fast. ;; Do not use it if there are any non-font-lock properties ;; in the region, since the sort utility would lose the - ;; properties. - (let ((sort-args (list (if reverse "-rt\n" "-t\n") + ;; properties. Tabs are used as field separator; on NetBSD, + ;; sort complains if "\n" is used as field separator. + (let ((sort-args (list (if reverse "-rt\t" "-t\t") (format "-k1.%d,1.%d" (1+ col-start) (1+ col-end)))))
--- a/lisp/speedbar.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/speedbar.el Tue Nov 07 23:22:48 2006 +0000 @@ -2157,7 +2157,7 @@ )))) (defun speedbar-generic-list-tag-p (sublst) - "Non nil if SUBLST is a tag." + "Non-nil if SUBLST is a tag." (and (stringp (car-safe sublst)) (or (and (number-or-marker-p (cdr-safe sublst)) (not (cdr-safe (cdr-safe sublst))))
--- a/lisp/startup.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/startup.el Tue Nov 07 23:22:48 2006 +0000 @@ -283,7 +283,8 @@ (defvar init-file-debug nil) -(defvar init-file-had-error nil) +(defvar init-file-had-error nil + "Non-nil if there was an error loading the user's init file.") (defvar normal-top-level-add-subdirs-inode-list nil) @@ -1150,8 +1151,16 @@ More Manuals / Ordering Manuals Buying printed manuals from the FSF\n") (:face (variable-pitch :weight bold) "Useful File menu items:\n" - :face variable-pitch "\ -Exit Emacs\t\t(Or type Control-x followed by Control-c) + :face variable-pitch + "Exit Emacs\t\t(Or type " + :face default + "Control-x" + :face variable-pitch + " followed by " + :face default + "Control-c" + :face variable-pitch + ") Recover Crashed Session\tRecover files you were editing before a crash @@ -1269,16 +1278,19 @@ :face 'variable-pitch "You can do basic editing with the menu bar and scroll bar \ using the mouse.\n\n") - (if fancy-splash-outer-buffer - (fancy-splash-insert - :face 'variable-pitch - (substitute-command-keys - (concat - "Type \\[recenter] to begin editing" - (if (equal (buffer-name fancy-splash-outer-buffer) - "*scratch*") - ".\n" - " your file.\n")))))) + (when fancy-splash-outer-buffer + (fancy-splash-insert + :face 'variable-pitch + "Type " + :face 'default + (substitute-command-keys + "\\[recenter]") + :face 'variable-pitch + " to begin editing" + (if (equal (buffer-name fancy-splash-outer-buffer) + "*scratch*") + ".\n" + " your file.\n")))) (defun fancy-splash-tail () "Insert the tail part of the splash screen into the current buffer." @@ -1305,7 +1317,11 @@ t) (fancy-splash-insert :face '(variable-pitch :foreground "red") "\n\nIf an Emacs session crashed recently, " - "type Meta-x recover-session RET\nto recover" + "type " + :face '(fixed-pitch :foreground "red") + "Meta-x recover-session RET" + :face '(variable-pitch :foreground "red") + "\nto recover" " the files you were editing.")))) (defun fancy-splash-screens-1 (buffer) @@ -1881,7 +1897,12 @@ (setq line 0) (unless (< column 1) (move-to-column (1- column))) - (setq column 0)))))))) + (setq column 0)))))) + ;; In unusual circumstances, the execution of Lisp code due + ;; to command-line options can cause the last visible frame + ;; to be deleted. In this case, kill emacs to avoid an + ;; abort later. + (unless (frame-live-p (selected-frame)) (kill-emacs nil)))) ;; If 3 or more files visited, and not all visible, ;; show user what they all are. But leave the last one current.
--- a/lisp/subr.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/subr.el Tue Nov 07 23:22:48 2006 +0000 @@ -1108,11 +1108,11 @@ ((eq compare-fn 'eql) (memql element (symbol-value list-var))) (t - (let (present) - (dolist (elt (symbol-value list-var)) - (if (funcall compare-fn element elt) - (setq present t))) - present))) + (let ((lst (symbol-value list-var))) + (while (and lst + (not (funcall compare-fn element (car lst)))) + (setq lst (cdr lst))) + lst))) (symbol-value list-var) (set list-var (if append
--- a/lisp/t-mouse.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/t-mouse.el Tue Nov 07 23:22:48 2006 +0000 @@ -38,7 +38,7 @@ ;; now position sensitive. (defvar t-mouse-process nil - "Embeds the process which passes mouse events to emacs. + "Embeds the process which passes mouse events to Emacs. It is used by the program t-mouse.") (defvar t-mouse-filter-accumulator "" @@ -123,7 +123,7 @@ (if (null l1) l2 (append (mapcar (function (lambda (x) (append (nth 0 l1) x))) l2) (t-mouse-cartesian (cdr l1) l2)))) - + (let* ((modifier-sets (t-mouse-powerset '(control meta shift))) (typed-sets (t-mouse-cartesian '((down) (drag)) '((mouse-1) (mouse-2) (mouse-3)))) @@ -178,9 +178,9 @@ ((event-name-string (symbol-name event-type)) end-of-root-event-name new-event-name-string) - + (if (string-match "-\\(21\\|\\12\\)$" event-name-string) - + ;;Transform the name to what it should have been. (progn (setq end-of-root-event-name (match-beginning 0)) @@ -188,12 +188,12 @@ (concat (substring event-name-string 0 end-of-root-event-name) "-3")) - + ;;Change the event to the symbol that corresponds to the ;;name we made. The proper symbol already exists. (setq event-type (intern new-event-name-string)))))) - + ;;store current position for mouse-position (setq t-mouse-current-xy (nth 0 current-xy-avec-time)) @@ -269,7 +269,7 @@ "Toggle t-mouse mode. With prefix arg, turn t-mouse mode on iff arg is positive. -Turn it on to use emacs mouse commands, and off to use t-mouse commands." +Turn it on to use Emacs mouse commands, and off to use t-mouse commands." nil " Mouse" nil :global t (if t-mouse-mode ;; Turn it on
--- a/lisp/terminal.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/terminal.el Tue Nov 07 23:22:48 2006 +0000 @@ -1162,7 +1162,7 @@ (setq inhibit-quit t) ;sport death (use-local-map terminal-map) (run-hooks 'terminal-mode-hook) - (message "Entering emacs terminal-emulator... Type %s %s for help" + (message "Entering Emacs terminal-emulator... Type %s %s for help" (single-key-description terminal-escape-char) (mapconcat 'single-key-description (where-is-internal 'te-escape-help terminal-escape-map t)
--- a/lisp/textmodes/bibtex.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/textmodes/bibtex.el Tue Nov 07 23:22:48 2006 +0000 @@ -5,7 +5,7 @@ ;; Author: Stefan Schoef <schoef@offis.uni-oldenburg.de> ;; Bengt Martensson <bengt@mathematik.uni-Bremen.de> -;; Mark Shapiro <shapiro@corto.inria.fr> +;; Marc Shapiro <marc.shapiro@acm.org> ;; Mike Newton <newton@gumby.cs.caltech.edu> ;; Aaron Larson <alarson@src.honeywell.com> ;; Dirk Herrmann <D.Herrmann@tu-bs.de>
--- a/lisp/textmodes/enriched.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/textmodes/enriched.el Tue Nov 07 23:22:48 2006 +0000 @@ -66,7 +66,7 @@ (defface fixed '((t (:weight bold))) "Face used for text that must be shown in fixed width. -Currently, emacs can only display fixed-width fonts, but this may change. +Currently, Emacs can only display fixed-width fonts, but this may change. This face is used for text specifically marked as fixed-width, for example in text/enriched files." :group 'enriched)
--- a/lisp/textmodes/fill.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/textmodes/fill.el Tue Nov 07 23:22:48 2006 +0000 @@ -746,6 +746,12 @@ (looking-at (regexp-quote prefix)))) (goto-char (match-end 0)))) +(defun fill-minibuffer-function (arg) + "Fill a paragraph in the minibuffer, ignoring the prompt." + (save-restriction + (narrow-to-region (minibuffer-prompt-end) (point-max)) + (fill-paragraph arg))) + (defun fill-paragraph (arg) "Fill paragraph at or after point. Prefix ARG means justify as well. If `sentence-end-double-space' is non-nil, then period followed by one @@ -760,8 +766,13 @@ (barf-if-buffer-read-only) (list (if current-prefix-arg 'full)))) ;; First try fill-paragraph-function. - (or (and fill-paragraph-function - (let ((function fill-paragraph-function) + (or (and (or fill-paragraph-function + (and (window-minibuffer-p (selected-window)) + (= 1 (point-min)))) + (let ((function (or fill-paragraph-function + ;; In the minibuffer, don't count the width + ;; of the prompt. + 'fill-minibuffer-function)) ;; If fill-paragraph-function is set, it probably takes care ;; of comments and stuff. If not, it will have to set ;; fill-paragraph-handle-comment back to t explicitly or
--- a/lisp/textmodes/flyspell.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/textmodes/flyspell.el Tue Nov 07 23:22:48 2006 +0000 @@ -189,7 +189,7 @@ :type 'string) (defcustom flyspell-check-tex-math-command nil - "Non nil means check even inside TeX math environment. + "Non-nil means check even inside TeX math environment. TeX math environments are discovered by the TEXMATHP that implemented inside the texmathp.el Emacs package. That package may be found at: http://strw.leidenuniv.nl/~dominik/Tools" @@ -412,6 +412,7 @@ (define-key map flyspell-auto-correct-binding 'flyspell-auto-correct-previous-word) (define-key map [(control ?\,)] 'flyspell-goto-next-error) (define-key map [(control ?\.)] 'flyspell-auto-correct-word) + (define-key map [(meta ?\^m)] 'flyspell-correct-word-before-point) map) "Minor mode keymap for Flyspell mode--for the whole buffer.") @@ -1999,52 +2000,62 @@ ;;*---------------------------------------------------------------------*/ ;;* flyspell-correct-word ... */ ;;*---------------------------------------------------------------------*/ + (defun flyspell-correct-word (event) "Pop up a menu of possible corrections for a misspelled word. The word checked is the word at the mouse position." (interactive "e") - ;; use the correct dictionary - (flyspell-accept-buffer-local-defs) - ;; retain cursor location (I don't know why but save-excursion here fails). (let ((save (point))) (mouse-set-point event) - (let ((cursor-location (point)) - (word (flyspell-get-word nil))) - (if (consp word) - (let ((start (car (cdr word))) - (end (car (cdr (cdr word)))) - (word (car word)) - poss ispell-filter) - ;; now check spelling of word. - (ispell-send-string "%\n") ;put in verbose mode - (ispell-send-string (concat "^" word "\n")) - ;; wait until ispell has processed word - (while (progn - (accept-process-output ispell-process) - (not (string= "" (car ispell-filter))))) - ;; Remove leading empty element - (setq ispell-filter (cdr ispell-filter)) - ;; ispell process should return something after word is sent. - ;; Tag word as valid (i.e., skip) otherwise - (or ispell-filter - (setq ispell-filter '(*))) - (if (consp ispell-filter) - (setq poss (ispell-parse-output (car ispell-filter)))) - (cond - ((or (eq poss t) (stringp poss)) - ;; don't correct word - t) - ((null poss) - ;; ispell error - (error "Ispell: error in Ispell process")) - ((featurep 'xemacs) - (flyspell-xemacs-popup - poss word cursor-location start end save)) - (t - ;; The word is incorrect, we have to propose a replacement. - (flyspell-do-correct (flyspell-emacs-popup event poss word) - poss word cursor-location start end save))) - (ispell-pdict-save t)))))) + (flyspell-correct-word-before-point event save))) + +(defun flyspell-correct-word-before-point (&optional event opoint) + "Pop up a menu of possible corrections for misspelled word before point. +If EVENT is non-nil, it is the mouse event that invoked this operation; +that controls where to put the menu. +If OPOINT is non-nil, restore point there after adjusting it for replacement." + (interactive) + (unless (mouse-position) + (error "Pop-up menus do not work on this terminal")) + ;; use the correct dictionary + (flyspell-accept-buffer-local-defs) + (let ((cursor-location (point)) + (word (flyspell-get-word nil))) + (if (consp word) + (let ((start (car (cdr word))) + (end (car (cdr (cdr word)))) + (word (car word)) + poss ispell-filter) + ;; now check spelling of word. + (ispell-send-string "%\n") ;put in verbose mode + (ispell-send-string (concat "^" word "\n")) + ;; wait until ispell has processed word + (while (progn + (accept-process-output ispell-process) + (not (string= "" (car ispell-filter))))) + ;; Remove leading empty element + (setq ispell-filter (cdr ispell-filter)) + ;; ispell process should return something after word is sent. + ;; Tag word as valid (i.e., skip) otherwise + (or ispell-filter + (setq ispell-filter '(*))) + (if (consp ispell-filter) + (setq poss (ispell-parse-output (car ispell-filter)))) + (cond + ((or (eq poss t) (stringp poss)) + ;; don't correct word + t) + ((null poss) + ;; ispell error + (error "Ispell: error in Ispell process")) + ((featurep 'xemacs) + (flyspell-xemacs-popup + poss word cursor-location start end opoint)) + (t + ;; The word is incorrect, we have to propose a replacement. + (flyspell-do-correct (flyspell-emacs-popup event poss word) + poss word cursor-location start end opoint))) + (ispell-pdict-save t))))) ;;*---------------------------------------------------------------------*/ ;;* flyspell-do-correct ... */
--- a/lisp/textmodes/ispell.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/textmodes/ispell.el Tue Nov 07 23:22:48 2006 +0000 @@ -217,7 +217,7 @@ "Empty replacement for defgroup when not supplied."))) (defgroup ispell nil - "User variables for emacs ispell interface." + "User variables for Emacs ispell interface." :group 'applications) (if (not (fboundp 'buffer-substring-no-properties)) @@ -496,7 +496,7 @@ To make permanent changes to your dictionary definitions, you will need to make your changes in this variable, save, and then -re-start emacs." +re-start Emacs." :type '(repeat (list (choice :tag "Dictionary" (string :tag "Dictionary name") (const :tag "default" nil)) @@ -900,13 +900,13 @@ (buffer-string)))) ;; Search for the named dictionaries. (found - (delq nil + (delq nil (mapcar #'ispell-aspell-find-dictionary dictionaries)))) ;; Ensure aspell's alias dictionary will override standard ;; definitions. (setq found (ispell-aspell-add-aliases found)) ;; Merge into FOUND any elements from the standard ispell-dictionary-alist - ;; which have no element in FOUND at all. + ;; which have no element in FOUND at all. (dolist (dict ispell-dictionary-alist) (unless (assoc (car dict) found) (setq found (nconc found (list dict))))) @@ -2074,7 +2074,7 @@ `m': Place typed-in value in personal dictionary, then recheck current word. `C-l': redraws screen `C-r': recursive edit -`C-z': suspend emacs or iconify frame" +`C-z': suspend Emacs or iconify frame" (if (equal ispell-help-in-bufferp 'electric) (progn @@ -2106,7 +2106,7 @@ `m': Place typed-in value in personal dictionary, then recheck current word. `C-l': redraws screen `C-r': recursive edit -`C-z': suspend emacs or iconify frame") +`C-z': suspend Emacs or iconify frame") nil ;undocumented requirement of with-electric-help ))))
--- a/lisp/textmodes/org.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/textmodes/org.el Tue Nov 07 23:22:48 2006 +0000 @@ -1103,7 +1103,7 @@ See `org-file-apps'.") (defconst org-file-apps-defaults-windowsnt - (list + (list '(remote . emacs) (cons t (list (if (featurep 'xemacs) @@ -1132,7 +1132,7 @@ \"ext\" A string identifying an extension `directory' Matches a directory `remote' Matches a remote file, accessible through tramp or efs. - Remote files most likely should be visited through emacs + Remote files most likely should be visited through Emacs because external applications cannot handle such paths. t Default for all remaining files @@ -2342,7 +2342,7 @@ export. When this is set, all marker characters (as given in `org-emphasis-alist') will be allowed as pre/post, aiding inside-out matching. -Use customize to modify this, or restart emacs after changing it." +Use customize to modify this, or restart Emacs after changing it." :group 'org-font-lock :set 'org-set-emph-re :type '(list @@ -2360,12 +2360,12 @@ ("=" shadow "<code>" "</code>") ("+" (:strike-through t) "<del>" "</del>") ) -"Special syntax for emphasised text. +"Special syntax for emphasized text. Text starting and ending with a special character will be emphasized, for example *bold*, _underlined_ and /italic/. This variable sets the marker characters, the face to bbe used by font-lock for highlighting in Org-mode -emacs buffers, and the HTML tags to be used for this. -Use customize to modify this, or restart emacs after changing it." +Emacs buffers, and the HTML tags to be used for this. +Use customize to modify this, or restart Emacs after changing it." :group 'org-font-lock :set 'org-set-emph-re :type '(repeat @@ -2897,11 +2897,8 @@ ;;; Define the mode -(defvar org-mode-map - (if (and (not (keymapp outline-mode-map)) (featurep 'allout)) - (error "Conflict with outdated version of allout.el. Load org.el before allout.el, or ugrade to newer allout, for example by switching to Emacs 22.") - (copy-keymap outline-mode-map)) - "Keymap for Org-mode.") +(if (and (not (keymapp outline-mode-map)) (featurep 'allout)) + (error "Conflict with outdated version of allout.el. Load org.el before allout.el, or ugrade to newer allout, for example by switching to Emacs 22.")) (defvar org-struct-menu) ; defined later in this file (defvar org-org-menu) ; defined later in this file @@ -2913,6 +2910,7 @@ "Indicates that a table might need an update. This variable is set by `org-before-change-function'. `org-table-align' sets it back to nil.") +(defvar org-mode-map) (defvar org-mode-hook nil) (defvar org-inhibit-startup nil) ; Dynamically-scoped param. (defvar org-agenda-keep-modes nil) ; Dynamically-scoped param. @@ -3453,7 +3451,7 @@ (call-interactively 'org-table-next-field))))) ((eq arg t) ;; Global cycling - + (cond ((and (eq last-command this-command) (eq org-cycle-global-status 'overview)) @@ -3953,7 +3951,7 @@ (let ((end (save-excursion (outline-next-heading) (point-marker))) (prohibit (if (> diff 0) - "^\\S-" + "^\\S-" (concat "^ \\{0," (int-to-string (- diff)) "\\}\\S-"))) col) (unless (save-excursion (re-search-forward prohibit end t)) @@ -4029,7 +4027,7 @@ (defun org-copy-subtree (&optional cut) "Cut the current subtree into the clipboard. This is a short-hand for marking the subtree and then copying it. -If CUT is non nil, actually cut the subtree." +If CUT is non-nil, actually cut the subtree." (interactive) (let (beg end folded) (org-back-to-heading) @@ -4217,7 +4215,7 @@ (setq status (equal (match-string 0) "[X]")) (when (eq firstnew 'unknown) (setq firstnew (not status))) - (replace-match + (replace-match (if (if arg (not status) firstnew) "[X]" "[ ]") t t)) (beginning-of-line 2)))))) @@ -4513,7 +4511,7 @@ (if find-done (org-archive-all-done) ;; Save all relevant TODO keyword-relatex variables - + (let ((tr-org-todo-line-regexp org-todo-line-regexp) ; keep despite compiler (tr-org-todo-keywords org-todo-keywords) (tr-org-todo-interpretation org-todo-interpretation) @@ -4620,7 +4618,7 @@ (if (org-on-heading-p) (progn (setq re1 (concat "^" (regexp-quote - (make-string + (make-string (1+ (- (match-end 0) (match-beginning 0))) ?*)) " ")) @@ -4751,7 +4749,7 @@ (org-end-of-subtree) (throw :skip t)) (if (equal (char-after p) ?#) (throw :skip t)))) - + (defun org-agenda-toggle-archive-tag () "Toggle the archive tag for the current entry." (interactive) @@ -6192,12 +6190,12 @@ (apply 'encode-time (org-parse-time-string te))))) (move-marker ins (point)) (setq ipos (point)) - (insert-before-markers "Clock summary at [" + (insert-before-markers "Clock summary at [" (substring (format-time-string (cdr org-time-stamp-formats)) 1 -1) "]." - (if block + (if block (format " Considered range is /%s/." block) "") "\n\n|L|Headline|Time|\n") @@ -6223,7 +6221,7 @@ (goto-char ins) (if (= level 1) (insert-before-markers "|-\n")) (insert-before-markers - "| " (int-to-string level) "|" hlc hdl hlc " |" + "| " (int-to-string level) "|" hlc hdl hlc " |" (make-string (1- level) ?|) hlc (format "%d:%02d" h m) @@ -8818,7 +8816,7 @@ nil nil current 'org-tags-history)))) (while (string-match "[-+&]+" tags) (setq tags (replace-match ":" t t tags)))) - + (unless (setq empty (string-match "\\`[\t ]*\\'" tags)) (unless (string-match ":$" tags) (setq tags (concat tags ":"))) (unless (string-match "^:" tags) (setq tags (concat ":" tags)))) @@ -9971,7 +9969,7 @@ ((eq major-mode 'image-mode) (setq cpltxt (concat "file:" (abbreviate-file-name buffer-file-name)) - link (org-make-link cpltxt))) + link (org-make-link cpltxt))) ((org-mode-p) ;; Just link to current headline @@ -13354,7 +13352,7 @@ ;; Convert LaTeX fragments to images (when (memq :LaTeX-fragments parameters) - (org-format-latex + (org-format-latex (concat "ltxpng/" (file-name-sans-extension (file-name-nondirectory org-current-export-file))) @@ -13873,7 +13871,7 @@ (all_lines (org-skip-comments (org-split-string (org-cleaned-string-for-export - region :emph-multiline + region :emph-multiline (if (plist-get opt-plist :LaTeX-fragments) :LaTeX-fragments)) "[\r\n]"))) @@ -14137,7 +14135,7 @@ (setq valid (if (functionp link-validate) (funcall link-validate filename current-dir) - t)) + t)) (setq file-is-image-p (string-match (org-image-file-name-regexp) filename)) (setq thefile (if abs-p (expand-file-name filename) filename)) @@ -14993,7 +14991,7 @@ (defvar org-cdlatex-texmathp-advice-is-done nil "Flag remembering if we have applied the advice to texmathp already.") -(define-minor-mode org-cdlatex-mode +(define-minor-mode org-cdlatex-mode "Toggle the minor `org-cdlatex-mode'. This mode supports entering LaTeX environment and math in LaTeX fragments in Org-mode. @@ -15121,7 +15119,7 @@ If the cursor is in a LaTeX fragment, create the image and overlay it over the source code. If there is no fragment at point, display all fragments in the current text, from one headline to the next. With -prefix SUBTREE, display all fragments in the current subtree. With a +prefix SUBTREE, display all fragments in the current subtree. With a double prefix `C-u C-u', or when the cursor is before the first headline, display all fragments in the buffer. The images can be removed again with \\[org-ctrl-c-ctrl-c]." @@ -15209,16 +15207,16 @@ (progn (org-overlay-put ov 'invisible t) (org-overlay-put - ov 'end-glyph + ov 'end-glyph (make-glyph (vector 'png :file movefile)))) - (org-overlay-put - ov 'display + (org-overlay-put + ov 'display (list 'image :type 'png :file movefile :ascent 'center))) (push ov org-latex-fragment-image-overlays) (goto-char end)) (delete-region beg end) (insert link)))))))) - + ;; This function borrows from Ganesh Swami's latex2png.el (defun org-create-formula-image (string tofile options) (let* ((tmpdir (if (featurep 'xemacs) @@ -15870,7 +15868,7 @@ :style toggle :selected (not org-agenda-skip-archived-trees)] "--" ["Move Subtree to Archive" org-archive-subtree t] - ["Check and Move Children" (org-archive-subtree '(4)) + ["Check and Move Children" (org-archive-subtree '(4)) :active t :keys "C-u C-c $"]) "--" ("TODO Lists" @@ -15940,14 +15938,14 @@ "--" ["Export/Publish" org-export t] ("LaTeX" - ["Org CDLaTeX mode" org-cdlatex-mode :style toggle + ["Org CDLaTeX mode" org-cdlatex-mode :style toggle :selected org-cdlatex-mode] ["Insert Environment" cdlatex-environment (fboundp 'cdlatex-environment)] ["Insert math symbol" cdlatex-math-symbol (fboundp 'cdlatex-math-symbol)] ["Modify math symbol" org-cdlatex-math-modify (org-inside-LaTeX-fragment-p)] ["Export LaTeX fragments as images" - (setq org-export-with-LaTeX-fragments (not org-export-with-LaTeX-fragments)) + (setq org-export-with-LaTeX-fragments (not org-export-with-LaTeX-fragments)) :style toggle :selected org-export-with-LaTeX-fragments]) "--" ("Documentation" @@ -16097,13 +16095,13 @@ (push (org-point-in-group p 0 :radio-target) clist)) (goto-char p)) ((setq o (car (delq nil - (mapcar + (mapcar (lambda (x) (if (memq x org-latex-fragment-image-overlays) x)) (org-overlays-at (point)))))) - (push (list :latex-fragment + (push (list :latex-fragment (org-overlay-start o) (org-overlay-end o)) clist) - (push (list :latex-preview + (push (list :latex-preview (org-overlay-start o) (org-overlay-end o)) clist)) ((org-inside-LaTeX-fragment-p) ;; FIXME: positions wring. @@ -16413,7 +16411,7 @@ ;;; Finish up - + (provide 'org) (run-hooks 'org-load-hook)
--- a/lisp/textmodes/reftex-cite.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/textmodes/reftex-cite.el Tue Nov 07 23:22:48 2006 +0000 @@ -125,7 +125,7 @@ ;; If MARK-TO-KILL is non-nil, mark new buffer to kill. ;; If HIGHLIGHT is non-nil, highlight the match. ;; If ITEM in non-nil, search for bibitem instead of database entry. - ;; If RETURN is non-nil, just return the entry. + ;; If RETURN is non-nil, just return the entry and restore point. (let* ((re (if item @@ -133,7 +133,7 @@ (concat "@[a-zA-Z]+[ \t\n\r]*[{(][ \t\n\r]*" (regexp-quote key) "[, \t\r\n}]"))) (buffer-conf (current-buffer)) - file buf pos) + file buf pos oldpos) (catch 'exit (while file-list @@ -142,9 +142,11 @@ (unless (setq buf (reftex-get-file-buffer-force file mark-to-kill)) (error "No such file %s" file)) (set-buffer buf) + (setq oldpos (point)) (widen) (goto-char (point-min)) - (when (re-search-forward re nil t) + (if (not (re-search-forward re nil t)) + (goto-char oldpos) ;; restore previous position of point (goto-char (match-beginning 0)) (setq pos (point)) (when return @@ -152,6 +154,7 @@ (if item (goto-char (match-end 0))) (setq return (buffer-substring (point) (reftex-end-of-bib-entry item))) + (goto-char oldpos) ;; restore point. (set-buffer buffer-conf) (throw 'exit return)) (switch-to-buffer-other-window buf)
--- a/lisp/textmodes/table.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/textmodes/table.el Tue Nov 07 23:22:48 2006 +0000 @@ -4692,7 +4692,7 @@ (point))) (defun table--row-column-insertion-point-p (&optional columnp) - "Return non nil if it makes sense to insert a row or a column at point." + "Return non-nil if it makes sense to insert a row or a column at point." (and (not buffer-read-only) (or (get-text-property (point) 'table-cell) (let ((column (current-column)))
--- a/lisp/textmodes/texinfmt.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/textmodes/texinfmt.el Tue Nov 07 23:22:48 2006 +0000 @@ -2125,7 +2125,7 @@ (setq tab-number (1+ tab-number))) (let ((needed-tabs (- (length table-widths) tab-number))) (when (> needed-tabs 0) - (goto-char (point-min)) + (goto-char (point-min)) (end-of-line) (while (> needed-tabs 0) (insert "@w{ }\n@tab") @@ -4292,7 +4292,7 @@ (defun batch-texinfo-format () "Runs texinfo-format-buffer on the files remaining on the command line. -Must be used only with -batch, and kills emacs on completion. +Must be used only with -batch, and kills Emacs on completion. Each file will be processed even if an error occurred previously. For example, invoke \"emacs -batch -funcall batch-texinfo-format $docs/ ~/*.texinfo\"."
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lisp/tutorial.el Tue Nov 07 23:22:48 2006 +0000 @@ -0,0 +1,1005 @@ +;;; tutorial.el --- tutorial for Emacs + +;; Copyright (C) 2006 Free Software Foundation, Inc. + +;; Maintainer: FSF +;; Keywords: help, internal + +;; This file is part of GNU Emacs. + +;; GNU Emacs 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. + +;; GNU Emacs 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 GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;; Code for running the Emacs tutorial. + +;;; History: + +;; File was created 2006-09. + +;;; Code: + +(require 'help-mode) ;; for function help-buffer +(eval-when-compile (require 'cl)) + +(defvar tutorial--point-before-chkeys 0 + "Point before display of key changes.") +(make-variable-buffer-local 'tutorial--point-before-chkeys) + +(defvar tutorial--point-after-chkeys 0 + "Point after display of key changes.") +(make-variable-buffer-local 'tutorial--point-after-chkeys) + +(defvar tutorial--lang nil + "Tutorial language.") +(make-variable-buffer-local 'tutorial--lang) + +(defun tutorial--describe-nonstandard-key (value) + "Give more information about a changed key binding. +This is used in `help-with-tutorial'. The information includes +the key sequence that no longer has a default binding, the +default binding and the current binding. It also tells in what +keymap the new binding has been done and how to access the +function in the default binding from the keyboard. + +For `cua-mode' key bindings that try to combine CUA key bindings +with default Emacs bindings information about this is shown. + +VALUE should have either of these formats: + + \(cua-mode) + \(current-binding KEY-FUN DEF-FUN KEY WHERE) + +Where + KEY is a key sequence whose standard binding has been changed + KEY-FUN is the actual binding for KEY + DEF-FUN is the standard binding of KEY + WHERE is a text describing the key sequences to which DEF-FUN is + bound now (or, if it is remapped, a key sequence + for the function it is remapped to)" + (with-output-to-temp-buffer (help-buffer) + (help-setup-xref (list #'tutorial--describe-nonstandard-key value) + (interactive-p)) + (with-current-buffer (help-buffer) + (insert + "Your Emacs customizations override the default binding for this key:" + "\n\n") + (let ((inhibit-read-only t)) + (cond + ((eq (car value) 'cua-mode) + (insert + "CUA mode is enabled. + +When CUA mode is enabled, you can use C-z, C-x, C-c, and C-v to +undo, cut, copy, and paste in addition to the normal Emacs +bindings. The C-x and C-c keys only do cut and copy when the +region is active, so in most cases, they do not conflict with the +normal function of these prefix keys. + +If you really need to perform a command which starts with one of +the prefix keys even when the region is active, you have three +options: +- press the prefix key twice very quickly (within 0.2 seconds), +- press the prefix key and the following key within 0.2 seconds, or +- use the SHIFT key with the prefix key, i.e. C-S-x or C-S-c.")) + ((eq (car value) 'current-binding) + (let ((cb (nth 1 value)) + (db (nth 2 value)) + (key (nth 3 value)) + (where (nth 4 value)) + map + (maps (current-active-maps)) + mapsym) + ;; Look at the currently active keymaps and try to find + ;; first the keymap where the current binding occurs: + (while maps + (let* ((m (car maps)) + (mb (lookup-key m key t))) + (setq maps (cdr maps)) + (when (eq mb cb) + (setq map m) + (setq maps nil)))) + ;; Now, if a keymap was found we must found the symbol + ;; name for it to display to the user. This can not + ;; always be found since all keymaps does not have a + ;; symbol pointing to them, but here they should have + ;; that: + (when map + (mapatoms (lambda (s) + (and + ;; If not already found + (not mapsym) + ;; and if s is a keymap + (and (boundp s) + (keymapp (symbol-value s))) + ;; and not the local symbol map + (not (eq s 'map)) + ;; and the value of s is map + (eq map (symbol-value s)) + ;; then save this value in mapsym + (setq mapsym s))))) + (insert "The default Emacs binding for the key " + (key-description key) + " is the command `") + (insert (format "%s" db)) + (insert "'. " + "However, your customizations have rebound it to the command `") + (insert (format "%s" cb)) + (insert "'.") + (when mapsym + (insert " (For the more advanced user:" + " This binding is in the keymap `" + (format "%s" mapsym) + "'.)")) + (if (string= where "") + (unless (keymapp db) + (insert "\n\nYou can use M-x " + (format "%s" db) + " RET instead.")) + (insert "\n\nWith you current key bindings" + " you can use the key " + where + " to get the function `" + (format "%s" db) + "'.")) + ) + (fill-region (point-min) (point))))) + (print-help-return-message)))) + +(defun tutorial--sort-keys (left right) + "Sort predicate for use with `tutorial--default-keys'. +This is a predicate function to `sort'. + +The sorting is for presentation purpose only and is done on the +key sequence. + +LEFT and RIGHT are the elements to compare." + (let ((x (append (cadr left) nil)) + (y (append (cadr right) nil))) + ;; Skip the front part of the key sequences if they are equal: + (while (and x y + (listp x) (listp y) + (equal (car x) (car y))) + (setq x (cdr x)) + (setq y (cdr y))) + ;; Try to make a comparision that is useful for presentation (this + ;; could be made nicer perhaps): + (let ((cx (car x)) + (cy (car y))) + ;;(message "x=%s, y=%s;;;; cx=%s, cy=%s" x y cx cy) + (cond + ;; Lists? Then call this again + ((and cx cy + (listp cx) + (listp cy)) + (tutorial--sort-keys cx cy)) + ;; Are both numbers? Then just compare them + ((and (wholenump cx) + (wholenump cy)) + (> cx cy)) + ;; Is one of them a number? Let that be bigger then. + ((wholenump cx) + t) + ((wholenump cy) + nil) + ;; Are both symbols? Compare the names then. + ((and (symbolp cx) + (symbolp cy)) + (string< (symbol-name cy) + (symbol-name cx))) + )))) + +(defconst tutorial--default-keys + (let* ( + ;; On window system suspend Emacs is replaced in the + ;; default keymap so honor this here. + (suspend-emacs (if window-system + 'iconify-or-deiconify-frame + 'suspend-emacs)) + (default-keys + `( + ;; These are not mentioned but are basic: + (ESC-prefix [27]) + (Control-X-prefix [?\C-x]) + (mode-specific-command-prefix [?\C-c]) + + (save-buffers-kill-emacs [?\C-x ?\C-c]) + + + ;; * SUMMARY + (scroll-up [?\C-v]) + (scroll-down [?\M-v]) + (recenter [?\C-l]) + + + ;; * BASIC CURSOR CONTROL + (forward-char [?\C-f]) + (backward-char [?\C-b]) + + (forward-word [?\M-f]) + (backward-word [?\M-b]) + + (next-line [?\C-n]) + (previous-line [?\C-p]) + + (move-beginning-of-line [?\C-a]) + (move-end-of-line [?\C-e]) + + (backward-sentence [?\M-a]) + (forward-sentence [?\M-e]) + + + (beginning-of-buffer [?\M-<]) + (end-of-buffer [?\M->]) + + (universal-argument [?\C-u]) + + + ;; * WHEN EMACS IS HUNG + (keyboard-quit [?\C-g]) + + + ;; * DISABLED COMMANDS + (downcase-region [?\C-x ?\C-l]) + + + ;; * WINDOWS + (delete-other-windows [?\C-x ?1]) + ;; C-u 0 C-l + ;; Type CONTROL-h k CONTROL-f. + + + ;; * INSERTING AND DELETING + ;; C-u 8 * to insert ********. + + (delete-backward-char [backspace]) + (delete-char [?\C-d]) + + (backward-kill-word [(meta backspace)]) + (kill-word [?\M-d]) + + (kill-line [?\C-k]) + (kill-sentence [?\M-k]) + + (set-mark-command [?\C-@]) + (set-mark-command [?\C- ]) + (kill-region [?\C-w]) + (yank [?\C-y]) + (yank-pop [?\M-y]) + + + ;; * UNDO + (advertised-undo [?\C-x ?u]) + (advertised-undo [?\C-x ?u]) + + + ;; * FILES + (find-file [?\C-x ?\C-f]) + (save-buffer [?\C-x ?\C-s]) + + + ;; * BUFFERS + (list-buffers [?\C-x ?\C-b]) + (switch-to-buffer [?\C-x ?b]) + (save-some-buffers [?\C-x ?s]) + + + ;; * EXTENDING THE COMMAND SET + ;; C-x Character eXtend. Followed by one character. + (execute-extended-command [?\M-x]) + + ;; C-x C-f Find file + ;; C-x C-s Save file + ;; C-x s Save some buffers + ;; C-x C-b List buffers + ;; C-x b Switch buffer + ;; C-x C-c Quit Emacs + ;; C-x 1 Delete all but one window + ;; C-x u Undo + + + ;; * MODE LINE + (describe-mode [?\C-h ?m]) + + (set-fill-column [?\C-x ?f]) + (fill-paragraph [?\M-q]) + + + ;; * SEARCHING + (isearch-forward [?\C-s]) + (isearch-backward [?\C-r]) + + + ;; * MULTIPLE WINDOWS + (split-window-vertically [?\C-x ?2]) + (scroll-other-window [?\C-\M-v]) + (other-window [?\C-x ?o]) + (find-file-other-window [?\C-x ?4 ?\C-f]) + + + ;; * RECURSIVE EDITING LEVELS + (keyboard-escape-quit [27 27 27]) + + + ;; * GETTING MORE HELP + ;; The most basic HELP feature is C-h c + (describe-key-briefly [?\C-h ?c]) + (describe-key [?\C-h ?k]) + + + ;; * MORE FEATURES + ;; F10 + + + ;; * CONCLUSION + ;;(iconify-or-deiconify-frame [?\C-z]) + (,suspend-emacs [?\C-z]) + ))) + (sort default-keys 'tutorial--sort-keys)) + "Default Emacs key bindings that the tutorial depends on.") + +(defun tutorial--detailed-help (button) + "Give detailed help about changed keys." + (with-output-to-temp-buffer (help-buffer) + (help-setup-xref (list #'tutorial--detailed-help button) + (interactive-p)) + (with-current-buffer (help-buffer) + (let* ((tutorial-buffer (button-get button 'tutorial-buffer)) + ;;(tutorial-arg (button-get button 'tutorial-arg)) + (explain-key-desc (button-get button 'explain-key-desc)) + (changed-keys (with-current-buffer tutorial-buffer + (tutorial--find-changed-keys tutorial--default-keys)))) + (when changed-keys + (insert + "The following key bindings used in the tutorial had been changed +from Emacs default in the " (buffer-name tutorial-buffer) " buffer:\n\n" ) + (let ((frm " %-9s %-27s %-11s %s\n")) + (insert (format frm "Key" "Standard Binding" "Is Now On" "Remark"))) + (dolist (tk changed-keys) + (let* ((def-fun (nth 1 tk)) + (key (nth 0 tk)) + (def-fun-txt (nth 2 tk)) + (where (nth 3 tk)) + (remark (nth 4 tk)) + (rem-fun (command-remapping def-fun)) + (key-txt (key-description key)) + (key-fun (with-current-buffer tutorial-buffer (key-binding key))) + tot-len) + (unless (eq def-fun key-fun) + ;; Insert key binding description: + (when (string= key-txt explain-key-desc) + (put-text-property 0 (length key-txt) 'face '(:background "yellow") key-txt)) + (insert " " key-txt " ") + (setq tot-len (length key-txt)) + (when (> 9 tot-len) + (insert (make-string (- 9 tot-len) ? )) + (setq tot-len 9)) + ;; Insert a link describing the old binding: + (insert-button def-fun-txt + 'value def-fun + 'action + (lambda(button) (interactive) + (describe-function + (button-get button 'value))) + 'follow-link t) + (setq tot-len (+ tot-len (length def-fun-txt))) + (when (> 36 tot-len) + (insert (make-string (- 36 tot-len) ? ))) + (when (listp where) + (setq where "list")) + ;; Tell where the old binding is now: + (insert (format " %-11s " where)) + ;; Insert a link with more information, for example + ;; current binding and keymap or information about + ;; cua-mode replacements: + (insert-button (car remark) + 'action + (lambda(b) (interactive) + (let ((value (button-get b 'value))) + (tutorial--describe-nonstandard-key value))) + 'value (cdr remark) + 'follow-link t) + (insert "\n"))))) + + (insert " +It is legitimate to change key bindings, but changed bindings do not +correspond to what the tutorial says. (See also " ) + (insert-button "Key Binding Conventions" + 'action + (lambda(button) (interactive) + (info + "(elisp) Key Binding Conventions") + (message "Type C-x 0 to close the new window")) + 'follow-link t) + (insert ".)\n\n") + (print-help-return-message))))) + +(defun tutorial--find-changed-keys (default-keys) + "Find the key bindings that have changed. +Check if the default Emacs key bindings that the tutorial depends +on have been changed. + +Return a list with the keys that have been changed. The element +of this list have the following format: + + \(list KEY DEF-FUN DEF-FUN-TXT WHERE REMARK) + +Where + KEY is a key sequence whose standard binding has been changed + DEF-FUN is the standard binding of KEY + DEF-FUN-TXT is a short descriptive text for DEF-FUN + WHERE is a text describing the key sequences to which DEF-FUN is + bound now (or, if it is remapped, a key sequence + for the function it is remapped to) + REMARK is a list with info about rebinding. It has either of these + formats: + + \(TEXT cua-mode) + \(TEXT current-binding KEY-FUN DEF-FUN KEY WHERE) + + Here TEXT is a link text to show to the user. The + rest of the list is used to show information when + the user clicks the link. + + KEY-FUN is the actual binding for KEY." + (let (changed-keys remark) + ;; (default-keys tutorial--default-keys)) + (dolist (kdf default-keys) + ;; The variables below corresponds to those with the same names + ;; described in the doc string. + (let* ((key (nth 1 kdf)) + (def-fun (nth 0 kdf)) + (def-fun-txt (format "%s" def-fun)) + (rem-fun (command-remapping def-fun)) + (key-fun (key-binding key)) + (where (where-is-internal (if rem-fun rem-fun def-fun)))) + (when (eq key-fun 'ESC-prefix) + (message "ESC-prefix!!!!")) + (if where + (progn + (setq where (key-description (car where))) + (when (and (< 10 (length where)) + (string= (substring where 0 (length "<menu-bar>")) + "<menu-bar>")) + (setq where "The menus"))) + (setq where "")) + (setq remark nil) + (unless + (cond ((eq key-fun def-fun) + ;; No rebinding, return t + t) + ((eq key-fun (command-remapping def-fun)) + ;; Just a remapping, return t + t) + ;; cua-mode specials: + ((and cua-mode + (or (and + (equal key [?\C-v]) + (eq key-fun 'cua-paste)) + (and + (equal key [?\C-z]) + (eq key-fun 'undo)))) + (setq remark (list "cua-mode, more info" 'cua-mode)) + nil) + ((and cua-mode + (or + (and (eq def-fun 'ESC-prefix) + (equal key-fun + `(keymap + (118 . cua-repeat-replace-region)))) + (and (eq def-fun 'mode-specific-command-prefix) + (equal key-fun + '(keymap + (timeout . copy-region-as-kill)))) + (and (eq def-fun 'Control-X-prefix) + (equal key-fun + '(keymap (timeout . kill-region)))))) + (setq remark (list "cua-mode replacement" 'cua-mode)) + (cond + ((eq def-fun 'mode-specific-command-prefix) + (setq def-fun-txt "\"C-c prefix\"")) + ((eq def-fun 'Control-X-prefix) + (setq def-fun-txt "\"C-x prefix\"")) + ((eq def-fun 'ESC-prefix) + (setq def-fun-txt "\"ESC prefix\""))) + (setq where "Same key") + nil) + ;; viper-mode specials: + ((and (boundp 'viper-mode-string) + (boundp 'viper-current-state) + (eq viper-current-state 'vi-state) + (or (and (eq def-fun 'isearch-forward) + (eq key-fun 'viper-isearch-forward)) + (and (eq def-fun 'isearch-backward) + (eq key-fun 'viper-isearch-backward)))) + ;; These bindings works as the default bindings, + ;; return t + t) + ((when normal-erase-is-backspace + (or (and (equal key [C-delete]) + (equal key-fun 'kill-word)) + (and (equal key [C-backspace]) + (equal key-fun 'backward-kill-word)))) + ;; This is the strange handling of C-delete and + ;; C-backspace, return t + t) + (t + ;; This key has indeed been rebound. Put information + ;; in `remark' and return nil + (setq remark + (list "more info" 'current-binding + key-fun def-fun key where)) + nil)) + (add-to-list 'changed-keys + (list key def-fun def-fun-txt where remark))))) + changed-keys)) + +(defvar tutorial--tab-map + (let ((map (make-sparse-keymap))) + (define-key map [tab] 'forward-button) + (define-key map [(shift tab)] 'backward-button) + (define-key map [(meta tab)] 'backward-button) + map) + "Keymap that allows tabbing between buttons.") + +(defun tutorial--display-changes (changed-keys) + "Display changes to some default key bindings. +If some of the default key bindings that the tutorial depends on +have been changed then display the changes in the tutorial buffer +with some explanatory links. + +CHANGED-KEYS should be a list in the format returned by +`tutorial--find-changed-keys'." + (when (or changed-keys + (boundp 'viper-mode-string)) + ;; Need the custom button face for viper buttons: + (when (boundp 'viper-mode-string) + (require 'cus-edit)) + (let ((start (point)) + end + (head (get-lang-string tutorial--lang 'tut-chgdhead)) + (head2 (get-lang-string tutorial--lang 'tut-chgdhead2))) + (when (and head head2) + (goto-char tutorial--point-before-chkeys) + (insert head) + (insert-button head2 + 'tutorial-buffer + (current-buffer) + ;;'tutorial-arg arg + 'action + 'tutorial--detailed-help + 'follow-link t + 'face '(:inherit link :background "yellow")) + (insert "]\n\n" ) + (when changed-keys + (dolist (tk changed-keys) + (let* ((def-fun (nth 1 tk)) + (key (nth 0 tk)) + (def-fun-txt (nth 2 tk)) + (where (nth 3 tk)) + (remark (nth 4 tk)) + (rem-fun (command-remapping def-fun)) + (key-txt (key-description key)) + (key-fun (key-binding key)) + tot-len) + (unless (eq def-fun key-fun) + ;; Mark the key in the tutorial text + (unless (string= "Same key" where) + (let ((here (point)) + (key-desc (key-description key))) + (while (search-forward key-desc nil t) + (put-text-property (match-beginning 0) + (match-end 0) + 'tutorial-remark 'only-colored) + (put-text-property (match-beginning 0) + (match-end 0) + 'face '(:background "yellow")) + (forward-line) + (let ((s (get-lang-string tutorial--lang 'tut-chgdkey)) + (s2 (get-lang-string tutorial--lang 'tut-chgdkey2)) + (start (point)) + end) + ;;(concat "** The key " key-desc " has been rebound, but you can use " where " instead [")) + (when (and s s2) + (setq s (format s key-desc where s2)) + (insert s) + (insert-button s2 + 'tutorial-buffer + (current-buffer) + ;;'tutorial-arg arg + 'action + 'tutorial--detailed-help + 'explain-key-desc key-desc + 'follow-link t + 'face '(:inherit link :background "yellow")) + (insert "] **") + (insert "\n") + (setq end (point)) + (put-text-property start end 'local-map tutorial--tab-map) + ;; Add a property so we can remove the remark: + (put-text-property start end 'tutorial-remark t) + (put-text-property start end + 'face '(:background "yellow" :foreground "#c00")) + (put-text-property start end 'read-only t)))) + (goto-char here))))))) + + + (setq end (point)) + ;; Make the area with information about change key + ;; bindings stand out: + (put-text-property start end 'tutorial-remark t) + (put-text-property start end + 'face + ;; The default warning face does not + ;;look good in this situation. Instead + ;;try something that could be + ;;recognized from warnings in normal + ;;life: + ;; 'font-lock-warning-face + (list :background "yellow" :foreground "#c00")) + ;; Make it possible to use Tab/S-Tab between fields in + ;; this area: + (put-text-property start end 'local-map tutorial--tab-map) + (setq tutorial--point-after-chkeys (point-marker)) + ;; Make this area read-only: + (put-text-property start end 'read-only t))))) + +(defun tutorial--saved-dir () + "Directory where to save tutorials." + (expand-file-name ".emacstut" "~/")) + +(defun tutorial--saved-file () + "File name in which to save tutorials." + (let ((file-name tutorial--lang) + (ext (file-name-extension tutorial--lang))) + (when (or (not ext) + (string= ext "")) + (setq file-name (concat file-name ".tut"))) + (expand-file-name file-name (tutorial--saved-dir)))) + +(defun tutorial--remove-remarks() + "Remove the remark lines that was added to the tutorial buffer." + (save-excursion + (goto-char (point-min)) + (let (prop-start + prop-end + prop-val) + ;; Catch the case when we already are on a remark line + (while (if (get-text-property (point) 'tutorial-remark) + (setq prop-start (point)) + (setq prop-start (next-single-property-change (point) 'tutorial-remark))) + (setq prop-end (next-single-property-change prop-start 'tutorial-remark)) + (setq prop-val (get-text-property prop-start 'tutorial-remark)) + (unless prop-end + (setq prop-end (point-max))) + (goto-char prop-end) + (if (eq prop-val 'only-colored) + (put-text-property prop-start prop-end 'face '(:background nil)) + (let ((orig-text (get-text-property prop-start 'tutorial-orig))) + (delete-region prop-start prop-end) + (when orig-text (insert orig-text)))))))) + +(defun tutorial--save-tutorial () + "Save the tutorial buffer. +This saves the part of the tutorial before and after the area +showing changed keys. It also saves the point position and the +position where the display of changed bindings was inserted." + ;; This runs in a hook so protect it: + (condition-case err + (tutorial--save-tutorial-to (tutorial--saved-file)) + (error (message "Error saving tutorial state: %s" (error-message-string err)) + (sit-for 4)))) + +(defun tutorial--save-tutorial-to (saved-file) + "Save the tutorial buffer to SAVED-FILE. +See `tutorial--save-tutorial' for more information." + ;; Anything to save? + (when (or (buffer-modified-p) + (< 1 (point))) + (let ((tutorial-dir (tutorial--saved-dir)) + save-err) + ;; The tutorial is saved in a subdirectory in the user home + ;; directory. Create this subdirectory first. + (unless (file-directory-p tutorial-dir) + (condition-case err + (make-directory tutorial-dir nil) + (error (setq save-err t) + (warn "Could not create directory %s: %s" tutorial-dir + (error-message-string err))))) + ;; Make sure we have that directory. + (if (file-directory-p tutorial-dir) + (let ((tut-point (if (= 0 tutorial--point-after-chkeys) + ;; No info about changed keys is + ;; displayed. + (point) + (if (< (point) tutorial--point-after-chkeys) + (- (point)) + (- (point) tutorial--point-after-chkeys)))) + (old-point (point)) + ;; Use a special undo list so that we easily can undo + ;; the changes we make to the tutorial buffer. This is + ;; currently not needed since we now delete the buffer + ;; after saving, but kept for possible future use of + ;; this function. + buffer-undo-list + (inhibit-read-only t)) + ;; Delete the area displaying info about changed keys. + ;; (when (< 0 tutorial--point-after-chkeys) + ;; (delete-region tutorial--point-before-chkeys + ;; tutorial--point-after-chkeys)) + ;; Delete the remarks: + (tutorial--remove-remarks) + ;; Put the value of point first in the buffer so it will + ;; be saved with the tutorial. + (goto-char (point-min)) + (insert (number-to-string tut-point) + "\n" + (number-to-string (marker-position + tutorial--point-before-chkeys)) + "\n") + (condition-case err + (write-region nil nil saved-file) + (error (setq save-err t) + (warn "Could not save tutorial to %s: %s" + saved-file + (error-message-string err)))) + ;; An error is raised here?? Is this a bug? + (condition-case err + (undo-only) + (error nil)) + ;; Restore point + (goto-char old-point) + (if save-err + (message "Could not save tutorial state.") + (message "Saved tutorial state."))) + (message "Can't save tutorial: %s is not a directory" + tutorial-dir))))) + + +;;;###autoload +(defun help-with-tutorial (&optional arg dont-ask-for-revert) + "Select the Emacs learn-by-doing tutorial. +If there is a tutorial version written in the language +of the selected language environment, that version is used. +If there's no tutorial in that language, `TUTORIAL' is selected. +With ARG, you are asked to choose which language. +If DONT-ASK-FOR-REVERT is non-nil the buffer is reverted without +any question when restarting the tutorial. + +If any of the standard Emacs key bindings that are used in the +tutorial have been changed then an explanatory note about this is +shown in the beginning of the tutorial buffer. + +When the tutorial buffer is killed the content and the point +position in the buffer is saved so that the tutorial may be +resumed later." + (interactive "P") + (if (boundp 'viper-current-state) + (let ((prompt1 + "You can not run the Emacs tutorial directly because you have \ +enabled Viper.") + (prompt2 "\nThere is however a Viper tutorial you can run instead. +Run the Viper tutorial? ")) + (if (fboundp 'viper-tutorial) + (if (y-or-n-p (concat prompt1 prompt2)) + (progn (message "") + (funcall 'viper-tutorial 0)) + (message "Tutorial aborted by user")) + (message prompt1))) + (let* ((lang (if arg + (let ((minibuffer-setup-hook minibuffer-setup-hook)) + (add-hook 'minibuffer-setup-hook + 'minibuffer-completion-help) + (read-language-name 'tutorial "Language: " "English")) + (if (get-language-info current-language-environment 'tutorial) + current-language-environment + "English"))) + (filename (get-language-info lang 'tutorial)) + ;; Choose a buffer name including the language so that + ;; several languages can be tested simultaneously: + (tut-buf-name (concat "TUTORIAL (" lang ")")) + (old-tut-buf (get-buffer tut-buf-name)) + (old-tut-win (when old-tut-buf (get-buffer-window old-tut-buf t))) + (old-tut-is-ok (when old-tut-buf + (not (buffer-modified-p old-tut-buf)))) + old-tut-file + (old-tut-point 1)) + (setq tutorial--point-after-chkeys (point-min)) + ;; Try to display the tutorial buffer before asking to revert it. + ;; If the tutorial buffer is shown in some window make sure it is + ;; selected and displayed: + (if old-tut-win + (raise-frame + (window-frame + (select-window (get-buffer-window old-tut-buf t)))) + ;; Else, is there an old tutorial buffer? Then display it: + (when old-tut-buf + (switch-to-buffer old-tut-buf))) + ;; Use whole frame for tutorial + (delete-other-windows) + ;; If the tutorial buffer has been changed then ask if it should + ;; be reverted: + (when (and old-tut-buf + (not old-tut-is-ok)) + (setq old-tut-is-ok + (if dont-ask-for-revert + nil + (not (y-or-n-p + "You have changed the Tutorial buffer. Revert it? "))))) + ;; (Re)build the tutorial buffer if it is not ok + (unless old-tut-is-ok + (switch-to-buffer (get-buffer-create tut-buf-name)) + (unless old-tut-buf (text-mode)) + (unless lang (error "Variable lang is nil")) + (setq tutorial--lang lang) + (setq old-tut-file (file-exists-p (tutorial--saved-file))) + (let ((inhibit-read-only t)) + (erase-buffer)) + (message "Preparing tutorial ...") (sit-for 0) + + ;; Do not associate the tutorial buffer with a file. Instead use + ;; a hook to save it when the buffer is killed. + (setq buffer-auto-save-file-name nil) + (add-hook 'kill-buffer-hook 'tutorial--save-tutorial nil t) + + ;; Insert the tutorial. First offer to resume last tutorial + ;; editing session. + (when dont-ask-for-revert + (setq old-tut-file nil)) + (when old-tut-file + (setq old-tut-file + (y-or-n-p "Resume your last saved tutorial? "))) + (if old-tut-file + (progn + (insert-file-contents (tutorial--saved-file)) + (goto-char (point-min)) + (setq old-tut-point + (string-to-number + (buffer-substring-no-properties + (line-beginning-position) (line-end-position)))) + (forward-line) + (setq tutorial--point-before-chkeys + (string-to-number + (buffer-substring-no-properties + (line-beginning-position) (line-end-position)))) + (forward-line) + (delete-region (point-min) (point)) + (goto-char tutorial--point-before-chkeys) + (setq tutorial--point-before-chkeys (point-marker))) + (insert-file-contents (expand-file-name filename data-directory)) + (forward-line) + (setq tutorial--point-before-chkeys (point-marker))) + + + ;; Check if there are key bindings that may disturb the + ;; tutorial. If so tell the user. + (let ((changed-keys (tutorial--find-changed-keys tutorial--default-keys))) + (when changed-keys + (tutorial--display-changes changed-keys))) + + + ;; Clear message: + (unless dont-ask-for-revert + (message "") (sit-for 0)) + + + (if old-tut-file + ;; Just move to old point in saved tutorial. + (let ((old-point + (if (> 0 old-tut-point) + (- old-tut-point) + (+ old-tut-point tutorial--point-after-chkeys)))) + (when (< old-point 1) + (setq old-point 1)) + (goto-char old-point)) + (goto-char (point-min)) + (search-forward "\n<<") + (beginning-of-line) + ;; Convert the <<...>> line to the proper [...] line, + ;; or just delete the <<...>> line if a [...] line follows. + (cond ((save-excursion + (forward-line 1) + (looking-at "\\[")) + (delete-region (point) (progn (forward-line 1) (point)))) + ((looking-at "<<Blank lines inserted.*>>") + (replace-match "[Middle of page left blank for didactic purposes. Text continues below]")) + (t + (looking-at "<<") + (replace-match "[") + (search-forward ">>") + (replace-match "]"))) + (beginning-of-line) + (let ((n (- (window-height (selected-window)) + (count-lines (point-min) (point)) + 6))) + (if (< n 8) + (progn + ;; For a short gap, we don't need the [...] line, + ;; so delete it. + (delete-region (point) (progn (end-of-line) (point))) + (newline n)) + ;; Some people get confused by the large gap. + (newline (/ n 2)) + + ;; Skip the [...] line (don't delete it). + (forward-line 1) + (newline (- n (/ n 2))))) + (goto-char (point-min))) + (setq buffer-undo-list nil) + (set-buffer-modified-p nil))))) + + +;; Below is some attempt to handle language specific strings. These +;; are currently only used in the tutorial. + +(defconst lang-strings + '( + ("English" . + ( + (tut-chgdkey . "** The key %s has been rebound, but you can use %s instead [") + (tut-chgdkey2 . "More information") + (tut-chgdhead . " + NOTICE: The main purpose of the Emacs tutorial is to teach you + the most important standard Emacs commands (key bindings). + However, your Emacs has been customized by changing some of + these basic editing commands, so it doesn't correspond to the + tutorial. We have inserted colored notices where the altered + commands have been introduced. [") + (tut-chgdhead2 . "Details") + ) + ) + ) + "Language specific strings for Emacs. +This is an association list with the keys equal to the strings +that can be returned by `read-language-name'. The elements in +the list are themselves association lists with keys that are +string ids and values that are the language specific strings. + +See `get-lang-string' for more information.") + +(defun get-lang-string(lang stringid &optional no-eng-fallback) + "Get a language specific string for Emacs. +In certain places Emacs can replace a string showed to the user with a language specific string. +This function retrieves such strings. + +LANG is the language specification. It should be one of those +strings that can be returned by `read-language-name'. STRINGID +is a symbol that specifies the string to retrieve. + +If no string is found for STRINGID in the choosen language then +the English string is returned unless NO-ENG-FALLBACK is non-nil. + +See `lang-strings' for more information. + +Currently this feature is only used in `help-with-tutorial'." + (let ((my-lang-strings (assoc lang lang-strings)) + (found-string)) + (when my-lang-strings + (let ((entry (assoc stringid (cdr my-lang-strings)))) + (when entry + (setq found-string (cdr entry))))) + ;; Fallback to English strings + (unless (or found-string + no-eng-fallback) + (setq found-string (get-lang-string "English" stringid t))) + found-string)) + +;;(get-lang-string "English" 'tut-chgdkey) + +(provide 'tutorial) + +;; arch-tag: c8e80aef-c3bb-4ffb-8af6-22171bf0c100 +;;; tutorial.el ends here
--- a/lisp/url/ChangeLog Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/url/ChangeLog Tue Nov 07 23:22:48 2006 +0000 @@ -1,3 +1,14 @@ +2006-11-03 Shun-ichi GOTO <gotoh@taiyo.co.jp> (tiny change) + + * url-http.el (url-http-handle-authentication): If there are + several authentication headers, use the first with a supported + method. + +2006-11-01 Magnus Henoch <mange@freemail.hu> + + * url-http.el (url-http-create-request): Use buffer-local + equivalents of dynamically bound variables. + 2006-10-29 Magnus Henoch <mange@freemail.hu> * url-gw.el (url-open-stream): Really use asynchronous
--- a/lisp/url/url-http.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/url/url-http.el Tue Nov 07 23:22:48 2006 +0000 @@ -151,13 +151,15 @@ (defun url-http-create-request (url &optional ref-url) "Create an HTTP request for URL, referred to by REF-URL." - (declare (special proxy-object proxy-info)) + (declare (special proxy-object proxy-info + url-http-method url-http-data + url-http-extra-headers)) (let* ((extra-headers) (request nil) - (no-cache (cdr-safe (assoc "Pragma" url-request-extra-headers))) + (no-cache (cdr-safe (assoc "Pragma" url-http-extra-headers))) (proxy-obj (and (boundp 'proxy-object) proxy-object)) (proxy-auth (if (or (cdr-safe (assoc "Proxy-Authorization" - url-request-extra-headers)) + url-http-extra-headers)) (not proxy-obj)) nil (let ((url-basic-auth-storage @@ -166,7 +168,7 @@ (real-fname (concat (url-filename (or proxy-obj url)) (url-recreate-url-attributes (or proxy-obj url)))) (host (url-host (or proxy-obj url))) - (auth (if (cdr-safe (assoc "Authorization" url-request-extra-headers)) + (auth (if (cdr-safe (assoc "Authorization" url-http-extra-headers)) nil (url-get-authentication (or (and (boundp 'proxy-info) @@ -191,12 +193,12 @@ (memq 'lastloc url-privacy-level))) (setq ref-url nil)) - ;; url-request-extra-headers contains an assoc-list of + ;; url-http-extra-headers contains an assoc-list of ;; header/value pairs that we need to put into the request. (setq extra-headers (mapconcat (lambda (x) (concat (car x) ": " (cdr x))) - url-request-extra-headers "\r\n")) + url-http-extra-headers "\r\n")) (if (not (equal extra-headers "")) (setq extra-headers (concat extra-headers "\r\n"))) @@ -219,7 +221,7 @@ (delq nil (list ;; The request - (or url-request-method "GET") " " + (or url-http-method "GET") " " (if proxy-obj (url-recreate-url proxy-obj) real-fname) " HTTP/" url-http-version "\r\n" ;; Version of MIME we speak @@ -267,7 +269,7 @@ (equal "https" (url-type url))) ;; If-modified-since (if (and (not no-cache) - (member url-request-method '("GET" nil))) + (member url-http-method '("GET" nil))) (let ((tm (url-is-cached (or proxy-obj url)))) (if tm (concat "If-modified-since: " @@ -277,15 +279,15 @@ "Referer: " ref-url "\r\n")) extra-headers ;; Length of data - (if url-request-data + (if url-http-data (concat "Content-length: " (number-to-string - (length url-request-data)) + (length url-http-data)) "\r\n")) ;; End request "\r\n" ;; Any data - url-request-data)) + url-http-data)) "")) (url-http-debug "Request is: \n%s" request) request)) @@ -303,21 +305,29 @@ (declare (special status success url-http-method url-http-data url-callback-function url-callback-arguments)) (url-http-debug "Handling %s authentication" (if proxy "proxy" "normal")) - (let ((auth (or (mail-fetch-field (if proxy "proxy-authenticate" "www-authenticate")) - "basic")) + (let ((auths (or (nreverse + (mail-fetch-field + (if proxy "proxy-authenticate" "www-authenticate") + nil nil t)) + '("basic"))) (type nil) (url (url-recreate-url url-current-object)) (url-basic-auth-storage 'url-http-real-basic-auth-storage) - ) - + auth) ;; Cheating, but who cares? :) (if proxy (setq url-basic-auth-storage 'url-http-proxy-basic-auth-storage)) - (setq auth (url-eat-trailing-space (url-strip-leading-spaces auth))) - (if (string-match "[ \t]" auth) - (setq type (downcase (substring auth 0 (match-beginning 0)))) - (setq type (downcase auth))) + ;; find first supported auth + (while auths + (setq auth (url-eat-trailing-space (url-strip-leading-spaces (car auths)))) + (if (string-match "[ \t]" auth) + (setq type (downcase (substring auth 0 (match-beginning 0)))) + (setq type (downcase auth))) + (if (url-auth-registered type) + (setq auths nil) ; no more check + (setq auth nil + auths (cdr auths)))) (if (not (url-auth-registered type)) (progn
--- a/lisp/whitespace.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/whitespace.el Tue Nov 07 23:22:48 2006 +0000 @@ -194,7 +194,7 @@ :group 'whitespace) (defcustom whitespace-spacetab-regexp "[ ]+\t" - "Regexp to match a space followed by a TAB." + "Regexp to match one or more spaces followed by a TAB." :type 'regexp :group 'whitespace) @@ -205,8 +205,9 @@ :type 'boolean :group 'whitespace) -(defcustom whitespace-indent-regexp (concat "^\\(\t*\\) " " ") - "Regexp to match (any TABS followed by) 8/more whitespaces at start of line." +(defcustom whitespace-indent-regexp "^\t*\\( \\)+" + "Regexp to match multiples of eight spaces near line beginnings. +The default value ignores leading TABs." :type 'regexp :group 'whitespace) @@ -217,9 +218,8 @@ :type 'boolean :group 'whitespace) -;; (defcustom whitespace-ateol-regexp "[ \t]$" (defcustom whitespace-ateol-regexp "[ \t]+$" - "Regexp to match a TAB or a space at the EOL." + "Regexp to match one or more TABs or spaces at line ends." :type 'regexp :group 'whitespace) @@ -425,7 +425,8 @@ (progn (whitespace-check-buffer-list (buffer-name) buffer-file-name) (whitespace-tickle-timer) - (whitespace-unhighlight-the-space) + (overlay-recenter (point-max)) + (remove-overlays nil nil 'face 'whitespace-highlight) (if whitespace-auto-cleanup (if buffer-read-only (if (not quiet) @@ -591,74 +592,53 @@ (whitespace-buffer t))) (defun whitespace-buffer-leading () - "Check to see if there are any empty lines at the top of the file." + "Return t if the current buffer has leading newline characters. +If highlighting is enabled, highlight these characters." (save-excursion - (let ((pmin nil) - (pmax nil)) - (goto-char (point-min)) - (beginning-of-line) - (setq pmin (point)) - (end-of-line) - (setq pmax (point)) - (if (equal pmin pmax) - (progn - (whitespace-highlight-the-space pmin (1+ pmax)) - t) - nil)))) + (goto-char (point-min)) + (skip-chars-forward "\n") + (unless (bobp) + (whitespace-highlight-the-space (point-min) (point)) + t))) (defun whitespace-buffer-leading-cleanup () - "Remove any empty lines at the top of the file." + "Remove any leading newline characters from current buffer." (save-excursion (goto-char (point-min)) (skip-chars-forward "\n") (delete-region (point-min) (point)))) (defun whitespace-buffer-trailing () - "Check to see if are is more than one empty line at the bottom." + "Return t if the current buffer has extra trailing newline characters. +If highlighting is enabled, highlight these characters." (save-excursion - (let ((pmin nil) - (pmax nil)) - (goto-char (point-max)) - (beginning-of-line) - (setq pmin (point)) - (end-of-line) - (setq pmax (point)) - (if (equal pmin pmax) - (progn - (goto-char (- (point) 1)) - (beginning-of-line) - (setq pmin (point)) - (end-of-line) - (setq pmax (point)) - (if (equal pmin pmax) - (progn - (whitespace-highlight-the-space (- pmin 1) pmax) - t) - nil)) - nil)))) + (goto-char (point-max)) + (skip-chars-backward "\n") + (forward-line) + (unless (eobp) + (whitespace-highlight-the-space (point) (point-max)) + t))) (defun whitespace-buffer-trailing-cleanup () - "Delete all the empty lines at the bottom." + "Remove extra trailing newline characters from current buffer." (save-excursion (goto-char (point-max)) (skip-chars-backward "\n") - (if (not (bolp)) - (forward-char 1)) - (delete-region (point) (point-max)))) + (unless (eobp) + (forward-line) + (delete-region (point) (point-max))))) (defun whitespace-buffer-search (regexp) "Search for any given whitespace REGEXP." - (let ((whitespace-retval "")) - (save-excursion - (goto-char (point-min)) - (while (re-search-forward regexp nil t) - (progn - (setq whitespace-retval (format "%s %s" whitespace-retval - (match-beginning 0))) - (whitespace-highlight-the-space (match-beginning 0) (match-end 0)))) - (if (equal "" whitespace-retval) - nil - whitespace-retval)))) + (with-local-quit + (let (whitespace-retval) + (save-excursion + (goto-char (point-min)) + (while (re-search-forward regexp nil t) + (whitespace-highlight-the-space (match-beginning 0) (match-end 0)) + (push (match-beginning 0) whitespace-retval))) + (when whitespace-retval + (format " %s" (nreverse whitespace-retval)))))) (defun whitespace-buffer-cleanup (regexp newregexp) "Search for any given whitespace REGEXP and replace it with the NEWREGEXP." @@ -713,17 +693,14 @@ "Highlight the current line, unhighlighting a previously jumped to line." (if whitespace-display-spaces-in-color (let ((ol (whitespace-make-overlay b e))) - (push ol whitespace-highlighted-space) (whitespace-overlay-put ol 'face 'whitespace-highlight)))) -;; (add-hook 'pre-command-hook 'whitespace-unhighlight-the-space)) (defun whitespace-unhighlight-the-space() "Unhighlight the currently highlight line." (if (and whitespace-display-spaces-in-color whitespace-highlighted-space) (progn (mapc 'whitespace-delete-overlay whitespace-highlighted-space) - (setq whitespace-highlighted-space nil)) - (remove-hook 'pre-command-hook 'whitespace-unhighlight-the-space))) + (setq whitespace-highlighted-space nil)))) (defun whitespace-check-buffer-list (buf-name buf-file) "Add a buffer and its file to the whitespace monitor list. @@ -780,7 +757,7 @@ (whitespace-refresh-rescan-list buffile bufname)))))) (defun whitespace-refresh-rescan-list (buffile bufname) - "Refresh the list of files to be rescaned for whitespace creep." + "Refresh the list of files to be rescanned for whitespace creep." (if whitespace-all-buffer-files (setq whitespace-all-buffer-files (delete (list buffile bufname) whitespace-all-buffer-files))
--- a/lisp/wid-edit.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/wid-edit.el Tue Nov 07 23:22:48 2006 +0000 @@ -598,7 +598,7 @@ :type 'directory) (defcustom widget-image-enable t - "If non nil, use image buttons in widgets when available." + "If non-nil, use image buttons in widgets when available." :version "21.1" :group 'widgets :type 'boolean) @@ -1719,7 +1719,7 @@ ;;; The `push-button' Widget. ;; (defcustom widget-push-button-gui t -;; "If non nil, use GUI push buttons when available." +;; "If non-nil, use GUI push buttons when available." ;; :group 'widgets ;; :type 'boolean) @@ -2562,7 +2562,7 @@ ;;; The `editable-list' Widget. ;; (defcustom widget-editable-list-gui nil -;; "If non nil, use GUI push-buttons in editable list when available." +;; "If non-nil, use GUI push-buttons in editable list when available." ;; :type 'boolean ;; :group 'widgets)
--- a/lisp/window.el Tue Nov 07 02:37:49 2006 +0000 +++ b/lisp/window.el Tue Nov 07 23:22:48 2006 +0000 @@ -795,8 +795,11 @@ (defvar mouse-autoselect-window-window nil "Last window recorded by delayed window autoselection.") -(defvar mouse-autoselect-window-now nil - "When non-nil don't delay autoselection in `handle-select-window'.") +(defvar mouse-autoselect-window-state nil + "When non-nil, special state of delayed window autoselection. +Possible values are `suspend' \(suspend autoselection after a menu or +scrollbar interaction\) and `select' \(the next invocation of +'handle-select-window' shall select the window immediately\).") (defun mouse-autoselect-window-cancel (&optional force) "Cancel delayed window autoselection. @@ -806,32 +809,26 @@ (eq this-command 'scroll-bar-toolkit-scroll) (memq (nth 4 (event-end last-input-event)) '(handle end-scroll))) - (setq mouse-autoselect-window-now nil) + (setq mouse-autoselect-window-state nil) (when (timerp mouse-autoselect-window-timer) (cancel-timer mouse-autoselect-window-timer)) (remove-hook 'pre-command-hook 'mouse-autoselect-window-cancel))) -(defun mouse-autoselect-window-start (window) +(defun mouse-autoselect-window-start (mouse-position &optional window suspend) "Start delayed window autoselection. -Called when Emacs detects that the mouse has moved to the non-selected -window WINDOW and the variable `mouse-autoselect-window' has a numeric, -non-zero value. The return value is non-nil iff delayed autoselection -started successfully. Delayed window autoselection is canceled when the -mouse position has stabilized or a command is executed." - ;; Cancel any active window autoselection. - (mouse-autoselect-window-cancel t) - ;; Record current mouse position in `mouse-autoselect-window-position' and - ;; WINDOW in `mouse-autoselect-window-window'. - (setq mouse-autoselect-window-position (mouse-position)) - (setq mouse-autoselect-window-window window) - ;; Install timer which runs `mouse-autoselect-window-select' every +MOUSE-POSITION is the last position where the mouse was seen as returned +by `mouse-position'. Optional argument WINDOW non-nil denotes the +window where the mouse was seen. Optional argument SUSPEND non-nil +means suspend autoselection." + ;; Record values for MOUSE-POSITION, WINDOW, and SUSPEND. + (setq mouse-autoselect-window-position mouse-position) + (when window (setq mouse-autoselect-window-window window)) + (setq mouse-autoselect-window-state (when suspend 'suspend)) + ;; Install timer which runs `mouse-autoselect-window-select' after ;; `mouse-autoselect-window' seconds. (setq mouse-autoselect-window-timer (run-at-time - (abs mouse-autoselect-window) (abs mouse-autoselect-window) - 'mouse-autoselect-window-select)) - ;; Executing a command cancels window autoselection. - (add-hook 'pre-command-hook 'mouse-autoselect-window-cancel)) + (abs mouse-autoselect-window) nil 'mouse-autoselect-window-select))) (defun mouse-autoselect-window-select () "Select window with delayed window autoselection. @@ -840,9 +837,21 @@ active. This function is run by `mouse-autoselect-window-timer'." (condition-case nil (let* ((mouse-position (mouse-position)) - (window (window-at (cadr mouse-position) (cddr mouse-position) - (car mouse-position)))) + (window + (condition-case nil + (window-at (cadr mouse-position) (cddr mouse-position) + (car mouse-position)) + (error nil)))) (cond + ((or (menu-or-popup-active-p) + (and window + (not (coordinates-in-window-p (cdr mouse-position) window)))) + ;; A menu / popup dialog is active or the mouse is on the scroll-bar + ;; of WINDOW, temporarily suspend delayed autoselection. + (mouse-autoselect-window-start mouse-position nil t)) + ((eq mouse-autoselect-window-state 'suspend) + ;; Delayed autoselection was temporarily suspended, reenable it. + (mouse-autoselect-window-start mouse-position)) ((and window (not (eq window (selected-window))) (or (not (numberp mouse-autoselect-window)) (and (> mouse-autoselect-window 0) @@ -851,24 +860,23 @@ (eq window mouse-autoselect-window-window)) ;; Otherwise select window iff the mouse is at the same ;; position as before. Observe that the first test after - ;; `mouse-autoselect-window-start' usually fails since the - ;; value of `mouse-autoselect-window-position' recorded there - ;; is the position where the mouse has entered the new window - ;; and not necessarily where the mouse has stopped moving. + ;; starting autoselection usually fails since the value of + ;; `mouse-autoselect-window-position' recorded there is the + ;; position where the mouse has entered the new window and + ;; not necessarily where the mouse has stopped moving. (equal mouse-position mouse-autoselect-window-position)) ;; The minibuffer is a candidate window iff it's active. (or (not (window-minibuffer-p window)) (eq window (active-minibuffer-window)))) - ;; Mouse position has stabilized in non-selected window: Cancel window - ;; autoselection and try to select that window. + ;; Mouse position has stabilized in non-selected window: Cancel + ;; delayed autoselection and try to select that window. (mouse-autoselect-window-cancel t) ;; Select window where mouse appears unless the selected window is the ;; minibuffer. Use `unread-command-events' in order to execute pre- ;; and post-command hooks and trigger idle timers. To avoid delaying - ;; autoselection again, temporarily set `mouse-autoselect-window-now' - ;; to t. + ;; autoselection again, set `mouse-autoselect-window-state'." (unless (window-minibuffer-p (selected-window)) - (setq mouse-autoselect-window-now t) + (setq mouse-autoselect-window-state 'select) (setq unread-command-events (cons (list 'select-window (list window)) unread-command-events)))) @@ -876,14 +884,12 @@ (not (numberp mouse-autoselect-window)) (equal mouse-position mouse-autoselect-window-position)) ;; Mouse position has either stabilized in the selected window or at - ;; `mouse-autoselect-window-position': Cancel window autoselection. + ;; `mouse-autoselect-window-position': Cancel delayed autoselection. (mouse-autoselect-window-cancel t)) (t - ;; Mouse position has not stabilized yet, record new mouse position in - ;; `mouse-autoselect-window-position' and any window at that position - ;; in `mouse-autoselect-window-window'. - (setq mouse-autoselect-window-position mouse-position) - (setq mouse-autoselect-window-window window)))) + ;; Mouse position has not stabilized yet, resume delayed + ;; autoselection. + (mouse-autoselect-window-start mouse-position window)))) (error nil))) (defun handle-select-window (event) @@ -901,14 +907,18 @@ (minibuffer-window-active-p window))) (unless (and (numberp mouse-autoselect-window) (not (zerop mouse-autoselect-window)) - (not mouse-autoselect-window-now) - ;; When `mouse-autoselect-window' has a numeric, non-zero - ;; value, delay window autoselection by that value. - ;; `mouse-autoselect-window-start' returns non-nil iff it - ;; successfully installed a timer for this purpose. - (mouse-autoselect-window-start window)) - ;; Re-enable delayed window autoselection. - (setq mouse-autoselect-window-now nil) + (not (eq mouse-autoselect-window-state 'select)) + (progn + ;; Cancel any delayed autoselection. + (mouse-autoselect-window-cancel t) + ;; Start delayed autoselection from current mouse position + ;; and window. + (mouse-autoselect-window-start (mouse-position) window) + ;; Executing a command cancels delayed autoselection. + (add-hook + 'pre-command-hook 'mouse-autoselect-window-cancel))) + ;; Reset state of delayed autoselection. + (setq mouse-autoselect-window-state nil) (when mouse-autoselect-window ;; Run `mouse-leave-buffer-hook' when autoselecting window. (run-hooks 'mouse-leave-buffer-hook))
--- a/lispintro/ChangeLog Tue Nov 07 02:37:49 2006 +0000 +++ b/lispintro/ChangeLog Tue Nov 07 23:22:48 2006 +0000 @@ -1,18 +1,138 @@ +2006-11-06 Robert J. Chassell <bob@rattlesnake.com> + + * emacs-lisp-intro.texi: Finish minor changes seen from DVI output. + Replace 22.1.100 with 22.1.1. + (current-kill): Mention functions that directly or indirectly call + `kill-new', which sets `kill-ring-yank-pointer'. + (Understanding current-kill): Change `lasted' to `last'. Remove + extraneous parenthesis. Reword item about returning `car' of list. + (yank): Remove mention of `rotate-yank-pointer'. + (Y Axis Element): Add comment regarding replacement of blank space. + (print-Y-axis Penultimate): Explain that `print-graph' will pass + `height-of-top-line' so `print-Y-axis' does not have a bug. + +2006-11-05 Robert J. Chassell <bob@rattlesnake.com> + + * emacs-lisp-intro.texi: Yet more minor changes: + (defcustom): Said that `:options' is usually for a hook. Remove + extraneous space in parenthetical remark concerning + `text-mode-hook-identify'. At end, mention other defines, too. + (Beginning a .emacs File): Reverse words about comments so they + parallel numbers of listed semi-colons. + (Text and Auto-fill): Remove extraneous blank line in example. + (Mail Aliases): Remove extraneous blank line in example. + (Keybindings): Reformat as needed with `key' rather than `kbd'. + (Keybindings, Miscellaneous, Mode Line): For small book format, start + section name on top of new page. + (Simple Extension): Replace longer expression with + `emacs-major-version'. Remove comment about `number-to-string' + function. + (Miscellaneous): Add filename option, `-H', to `grep' example + (debug, debug-on-entry): Replace `GNU Emacs 22' with `a recent + GNU Emacs'. + (edebug): More properly state where to place point for 'M-x + edebug-defun'. + + * emacs-lisp-intro.texi: More minor changes. + Center images for TeX output. + (kill-new function): Remove indentation for sentence talking about + momentarily skipping code. + (cons & search-fwd Review): Document @code{funcall}. Document + @code{re-search-forward} with existing @code{search-forward}. + Reference chapter on regular expression searches. + (Recursion with list): Specify a more recent version as being Emacs. + (Recursion with list, Every, recursive-graph-body-print): Change + `if ... progn' expression to `when'. + (Recursive triangle function): For printing in small book, ensure + section name is not last on bottom of preceding page. + (Keep): Remove extraneous space in function definition example. + (sentence-end): Specify `in English' for glyphs that end a sentence. + Note that in GNU Emacs 22, the name refers to both a variable and a + function. + (fwd-sentence while loops): Write a function as one, not as a form + (fwd-para let): Add `which' to sentence with `parstart' and `parsep'. + (etags): Move sentences involving `find-tag' and sources. State + location of Emacs `src' directory. + (Design count-words-region): Better explain two backslashes in a row. + (Find a File): Fix grammar; add a `to' and write `to visit'. Change + `named' to `selected'. + (lengths-list-file): Remove extraneous parenthesis from reference. + (lengths-list-many-files): Explain `expand-file-name' better. + (Files List): Rephrase sentence regarding Lisp sources directory + +2006-11-04 Robert J. Chassell <bob@rattlesnake.com> + + * emacs-lisp-intro.texi: Replace 22.0.100 with 22.1.100. + (defcustom): Note that the value set by defconst is a variable. + (Buffer Size & Locations): Parenthetical remark about evaluation. + (Finding More): Change text to include C sources by inference. + + * emacs-lisp-intro.texi: Minor fixes. + Replace all tabs with eight spaces each so printed text looks correct. + Remove extraneous comma in a printed node name produced by `ref'. + (insert-buffer): Add a missing beginning parenthesis. + (beginning-of-buffer): Add `beginning of' to note about accessible + portion. + (narrow Exercise): Write closing parenthesis at end of correct + paragraph. + (zap-to-char): Remove extraneous `a' from first sentence. + (Complete zap-to-char): Remove two extraneous sentences. + (zap-to-char body): Move sentences on documentation two nodes earlier. + (Lisp macro): Add definition of `unless' macro. + (last-command & this-command): Remove comment that `we have not yet + seen' the @code{eq} function. + (kill-append function): Reformat `kill-append' function definition so + it prints well. + (kill-new function): Indent the sentence beginning `notice'. Replace + `the same as' with `similar to'. Repair typo. Remove obsolete + references to `yank' and `yank-pop. End section with a note that `we + will digress into C.' + +2006-11-02 Robert J. Chassell <bob@rattlesnake.com> + + * emacs-lisp-intro.texi (kill-ring-yank-pointer): Revert addition + of extraneous quotation mark to rotate-yank-pointer. + +2006-11-01 Juri Linkov <juri@jurta.org> + + * emacs-lisp-intro.texi: Fix unbalanced quotes. + +2006-10-31 Robert J. Chassell <bob@rattlesnake.com> + + * emacs-lisp-intro.texi: Revised text for kill-region, + copy-region-as-kill, kill-append, kill-new, forward-sentence, + forward-paragraph, find-file, current-kill, yank, and yank-pop. + Removed INSTALL MANIFEST from the directory since those files are + now irrelevant. Updated Info file in ../info. Changed numbering + so is now Revised Third Edition and this instance's edition-number + is 3.00. Did not update ISBN number. + + * emacs-lisp-intro.texi: Remove version reference for X colors. + Document `='. Remove mention that :eval was new in 21. Updated + instance's edition-number to 3.01. + +2006-10-30 Robert J. Chassell <bob@rattlesnake.com> + + * emacs-lisp-intro.texi: Many changes since it turned out that + many `simple' functions were rewritten. Changes to the text + regarding zap-to-char, mark-whole-buffer, append-to-buffer, + copy-to-buffer, beginning-of-buffer, what-line, and possibly + others. (I have not reviewed all yet.) This instance does build + for Info and TeX. + 2006-10-29 Chong Yidong <cyd@stupidchicken.com> * Makefile.in: Use relative paths to avoid advertising filesystem contents during compilation. - * makefile.w32-in: Likewise. - 2006-08-21 Robert J. Chassell <bob@rattlesnake.com> * emacs-lisp-intro.texi: deleted in directory copy of texinfo.tex - and pointed towards ../man/texinfo.tex so only one file - needs updating. Added comment of what to do when building on own. + and pointed towards ../man/texinfo.tex so only one file + needs updating. Added comment of what to do when building on own. * texinfo.tex: changed to version 2006-02-13.16 - to enable a DVI build using the more recent versions of TeX. + to enable a DVI build using the more recent versions of TeX. 2006-05-25 David Kastrup <dak@gnu.org>
--- a/lispintro/INSTALL Tue Nov 07 02:37:49 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -Basic Installation for An Introduction to Programming in Emacs Lisp version 2 -================== - - # To see the table of contents of the emacs-lisp-intro-2.00.tar.gz - # file, execute the following at your shell prompt: - - tar -tzvf emacs-lisp-intro-2.00.tar.gz - - # To uncompress and untar the file, execute the following: - - tar -xzvf emacs-lisp-intro-2.00.tar.gz - - # The file will untar into a subdirectory called emacs-lisp-intro-2.00 - # That directory will contain the Texinfo source for the book, the - # Info files and various other files. - - cd emacs-lisp-intro-2.00 - - # To create a DVI file that can be printed directly or converted - # to PostScript or PDF and then printed, execute the following: - - ./configure - make dvi - - # To create an HTML file, execute the following - # (presumably you have already executed the `./configure' command - # before running `make dvi'; if not execute `./configure' now); - # this will place HTML files into a emacs-lisp-intro/ subdirectory: - - makeinfo --html --verbose emacs-lisp-intro.texi - - # To create a single, large HTML file in the current directory, - # use the --no-split option, like this: - - makeinfo --html --no-split --verbose emacs-lisp-intro.texi - - # At the time of writing, `makeinfo' version 4.0b creates HTML - # files with %20 in addresses instead of a space. Some - # browsers have difficulty following such references. In - # GNU Emacs, you can replace the occurrences of %20 with a - # command such as - # (replace-string "%20" " ") - - # To create a single, large Info file in the current directory - # instead of the usual 16 smaller Info files, and also, to avoid - # indenting paragraphs, execute: - - makeinfo --no-split --paragraph-indent=0 --verbose emacs-lisp-intro.texi - - # To create a single, large Plain text file in the current - # directory, execute: - - makeinfo --fill-column=70 --no-split --paragraph-indent=0 \ - --verbose --no-headers --output=emacs-lisp-intro.txt emacs-lisp-intro.texi - -###
--- a/lispintro/MANIFEST Tue Nov 07 02:37:49 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -`emacs-lisp-intro-2.00.tar' contains: - - size filename - - 2102 INSTALL - 1482 MANIFEST - 10295 Makefile - 358 Makefile.am - 10215 Makefile.in - 5642 README - 3542 aclocal.m4 - 7129 drawers.eps - 36057 configure - 142 configure.in - 12136 cons-1.eps - 12523 cons-2.eps - 12420 cons-2a.eps - 12984 cons-3.eps - 13866 cons-4.eps - 12986 cons-5.eps - 772149 emacs-lisp-intro.texi - 5584 install-sh - 10252 lambda-1.eps - 10278 lambda-2.eps - 10275 lambda-3.eps - 4650 missing - 732 mkinstalldirs - 207383 texinfo.tex - -###
--- a/lispintro/README Tue Nov 07 02:37:49 2006 +0000 +++ b/lispintro/README Tue Nov 07 23:22:48 2006 +0000 @@ -1,16 +1,17 @@ -This directory contains the source of the "Introduction to programming +This directory contains the source of the "Introduction to Programming in Emacs Lisp" written by Robert J. Chassell, bob@gnu.org. This manual is an elementary introduction to programming in Emacs Lisp for people who are not programmers, and who are not necessarily interested in programming, but who do want to customize or extend their computing environment. -This second edition of 2001 Nov 20 updates the previous editions to -GNU Emacs 21. +This third edition of 2006 Oct 31 updates the previous editions to GNU +Emacs 22. The Texinfo source file `emacs-lisp-intro.texi', formats without -error using TeX version 3.14159, `kpathsea' version 3.3.1, -`texinfo.tex' version 2001-05-24.08, and `makeinfo' version 4.0b. +reported error using `pdfeTeXk', Version 3.141592-1.21a-2.2 (Web2C +7.5.4) and texinfo.tex version 2006-08-26.17 started by `texi2dvi' +version 4.8, and with `makeinfo' version 4.8. Also, this tar file contains the following optional Encapsulated Post Script figures. @@ -56,5 +57,5 @@ You will find additional instructions on formatting in the beginning of the Texinfo file 'emacs-lisp-intro.texi'. Best Wishes! -2001 Nov 20 +2006 Oct 31 Robert J. Chassell, bob@gnu.org
--- a/lispintro/emacs-lisp-intro.texi Tue Nov 07 02:37:49 2006 +0000 +++ b/lispintro/emacs-lisp-intro.texi Tue Nov 07 23:22:48 2006 +0000 @@ -1,5 +1,6 @@ \input ../man/texinfo @c -*-texinfo-*- -@c change above to \input texinfo if building on own. +@c \input texinfo @c -*-texinfo-*- +@c change to \input texinfo if building on own. @comment %**start of header @setfilename ../info/eintr @c setfilename emacs-lisp-intro.info @@ -23,20 +24,27 @@ @comment %**end of header -@set edition-number 2.14 -@set update-date 2004 Oct 12 +@set edition-number 3.06 +@set update-date 6 November 2006 @ignore ## Summary of shell commands to create various output formats: pushd /usr/local/src/emacs/lispintro/ + ## pushd /u/intro/ ## Info output - makeinfo --no-split --paragraph-indent=0 --verbose emacs-lisp-intro.texi + # makeinfo --no-split --paragraph-indent=0 --verbose emacs-lisp-intro.texi + makeinfo --paragraph-indent=0 --verbose emacs-lisp-intro.texi + + ## ;; (progn (when (bufferp (get-buffer "*info*")) (kill-buffer "*info*")) (info "../info/eintr")) ## DVI output texi2dvi emacs-lisp-intro.texi + ## View DVI output; see below also + # xdvi -margins 24pt -topmargin 4pt -offsets 24pt -geometry 760x1140 -s 5 -useTeXpages -mousemode 1 emacs-lisp-intro.dvi & + ## HTML output makeinfo --html --no-split --verbose emacs-lisp-intro.texi @@ -52,6 +60,8 @@ makeinfo --xml --no-split --paragraph-indent=0 \ --verbose emacs-lisp-intro.texi + popd + #### (You must be in the same directory as the viewed file.) ## View DVI output @@ -63,7 +73,15 @@ ## View Info output with standalone reader info emacs-lisp-intro.info - ## popd + ## popd + + +# as user `root' +# insert thumbdrive + mtusb # mount -v -t ext3 /dev/sda /mnt + cp -v /u/intro/emacs-lisp-intro.texi /mnt/backup/intro/emacs-lisp-intro.texi + umtusb # umount -v /mnt +# remove thumbdrive @end ignore @@ -75,7 +93,6 @@ @c Your site may require editing changes to print PostScript; in this @c case, search for `print-postscript-figures' and make appropriate changes. - @c ================ How to Create an Info file ================ @c If you have `makeinfo' installed, run the following command @@ -166,7 +183,12 @@ @c in the Texinfo version 4.6 of the 2003 Jun 13 distribution. @tex -\global\def\xrefprintnodename#1{``#1''} +\if \xrefprintnodename + \global\def\xrefprintnodename#1{\unskip, ``#1''} + \else + \global\def\xrefprintnodename#1{ ``#1''} +\fi +% \global\def\xrefprintnodename#1{, ``#1''} @end tex @c ---------------------------------------------------- @@ -174,7 +196,7 @@ @dircategory Emacs @direntry * Emacs Lisp Intro: (eintr). - A simple introduction to Emacs Lisp programming. + A simple introduction to Emacs Lisp programming. @end direntry @copying @@ -242,7 +264,7 @@ @sp 2 @center @titlefont{Programming in Emacs Lisp} @sp 2 -@center Revised Second Edition +@center Revised Third Edition @sp 4 @center by Robert J. Chassell @@ -280,6 +302,16 @@ every node in every chapter. @end ifnottex +@c >>>> Set pageno appropriately <<<< + +@c The first page of the Preface is a roman numeral; it is the first +@c right handed page after the Table of Contents; hence the following +@c setting must be for an odd negative number. + +@iftex +@global@pageno = -11 +@end iftex + @menu * Preface:: What to look for. * List Processing:: What is Lisp? @@ -339,7 +371,7 @@ * Numbers Lists:: List have numbers, other lists, in them. * Lisp Atoms:: Elemental entities. -* Whitespace in Lists:: Formating lists to be readable. +* Whitespace in Lists:: Formatting lists to be readable. * Typing Lists:: How GNU Emacs helps you type lists. The Lisp Interpreter @@ -371,34 +403,34 @@ Setting the Value of a Variable -* Using set:: Setting values. -* Using setq:: Setting a quoted value. -* Counting:: Using @code{setq} to count. +* Using set:: Setting values. +* Using setq:: Setting a quoted value. +* Counting:: Using @code{setq} to count. Practicing Evaluation -* How to Evaluate:: Typing editing commands or @kbd{C-x C-e} - causes evaluation. -* Buffer Names:: Buffers and files are different. -* Getting Buffers:: Getting a buffer itself, not merely its name. -* Switching Buffers:: How to change to another buffer. -* Buffer Size & Locations:: Where point is located and the size of - the buffer. +* How to Evaluate:: Typing editing commands or @kbd{C-x C-e} + causes evaluation. +* Buffer Names:: Buffers and files are different. +* Getting Buffers:: Getting a buffer itself, not merely its name. +* Switching Buffers:: How to change to another buffer. +* Buffer Size & Locations:: Where point is located and the size of + the buffer. * Evaluation Exercise:: How To Write Function Definitions * Primitive Functions:: -* defun:: The @code{defun} special form. -* Install:: Install a function definition. -* Interactive:: Making a function interactive. -* Interactive Options:: Different options for @code{interactive}. -* Permanent Installation:: Installing code permanently. -* let:: Creating and initializing local variables. -* if:: What if? -* else:: If--then--else expressions. -* Truth & Falsehood:: What Lisp considers false and true. -* save-excursion:: Keeping track of point, mark, and buffer. +* defun:: The @code{defun} special form. +* Install:: Install a function definition. +* Interactive:: Making a function interactive. +* Interactive Options:: Different options for @code{interactive}. +* Permanent Installation:: Installing code permanently. +* let:: Creating and initializing local variables. +* if:: What if? +* else:: If--then--else expressions. +* Truth & Falsehood:: What Lisp considers false and true. +* save-excursion:: Keeping track of point, mark, and buffer. * Review:: * defun Exercises:: @@ -473,6 +505,7 @@ * if & or:: Using an @code{if} instead of an @code{or}. * Insert or:: How the @code{or} expression works. * Insert let:: Two @code{save-excursion} expressions. +* New insert-buffer:: The Interactive Expression in @code{insert-buffer} @@ -519,9 +552,9 @@ * Storing Text:: Text is stored in a list. * zap-to-char:: Cutting out text up to a character. * kill-region:: Cutting text out of a region. +* copy-region-as-kill:: A definition for copying text. * Digression into C:: Minor note on C programming language macros. * defvar:: How to give a variable an initial value. -* copy-region-as-kill:: A definition for copying text. * cons & search-fwd Review:: * search Exercises:: @@ -538,12 +571,7 @@ * Complete kill-region:: The function definition. * condition-case:: Dealing with a problem. -* delete-and-extract-region:: Doing the work. - -Initializing a Variable with @code{defvar} - -* See variable current value:: -* defvar and asterisk:: An old-time convention. +* Lisp macro:: @code{copy-region-as-kill} @@ -556,6 +584,11 @@ * kill-append function:: * kill-new function:: +Initializing a Variable with @code{defvar} + +* See variable current value:: +* defvar and asterisk:: + How Lists are Implemented * Lists diagrammed:: @@ -564,9 +597,9 @@ Yanking Text Back -* Kill Ring Overview:: The kill ring is a list. -* kill-ring-yank-pointer:: The @code{kill-ring-yank-pointer} variable. -* yank nthcdr Exercises:: +* Kill Ring Overview:: +* kill-ring-yank-pointer:: The kill ring is a list. +* yank nthcdr Exercises:: The @code{kill-ring-yank-pointer} variable. Loops and Recursion @@ -643,11 +676,6 @@ * forward-paragraph in brief:: Key parts of the function definition. * fwd-para let:: The @code{let*} expression. * fwd-para while:: The forward motion @code{while} loop. -* fwd-para between paragraphs:: Movement between paragraphs. -* fwd-para within paragraph:: Movement within paragraphs. -* fwd-para no fill prefix:: When there is no fill prefix. -* fwd-para with fill prefix:: When there is a fill prefix. -* fwd-para summary:: Summary of @code{forward-paragraph} code. Counting: Repetition and Regexps @@ -707,7 +735,7 @@ * Loading Files:: Load (i.e., evaluate) files automatically. * Autoload:: Make functions available. * Simple Extension:: Define a function; bind it to a key. -* X11 Colors:: Colors in version 19 in X. +* X11 Colors:: Colors in X. * Miscellaneous:: * Mode Line:: How to customize your mode line. @@ -721,28 +749,19 @@ Handling the Kill Ring -* rotate-yank-pointer:: Move a pointer along a list and around. +* current-kill:: * yank:: Paste a copy of a clipped element. -* yank-pop:: Insert first element pointed to. +* yank-pop:: Insert element pointed to. * ring file:: -The @code{rotate-yank-pointer} Function - -* Understanding rotate-yk-ptr:: -* rotate-yk-ptr body:: The body of @code{rotate-yank-pointer}. - -The Body of @code{rotate-yank-pointer} +The @code{current-kill} Function + +* Understanding current-kill:: + +@code{current-kill} in Outline * Digression concerning error:: How to mislead humans, but not computers. -* rotate-yk-ptr else-part:: The else-part of the @code{if} expression. -* Remainder Function:: The remainder, @code{%}, function. -* rotate-yk-ptr remainder:: Using @code{%} in @code{rotate-yank-pointer}. -* kill-rng-yk-ptr last elt:: Pointing to the last element. - -@code{yank} - -* rotate-yk-ptr arg:: Pass the argument to @code{rotate-yank-pointer}. -* rotate-yk-ptr negative arg:: Pass a negative argument. +* Determining the Element:: A Graph with Labelled Axes @@ -778,16 +797,6 @@ @end detailmenu @end menu -@c >>>> Set pageno appropriately <<<< - -@c The first page of the Preface is a roman numeral; it is the first -@c right handed page after the Table of Contents; hence the following -@c setting must be for an odd negative number. - -@iftex -@global@pageno = -11 -@end iftex - @node Preface, List Processing, Top, Top @comment node-name, next, previous, up @unnumbered Preface @@ -809,11 +818,11 @@ editing in the most general sense of the word.) @menu -* Why:: Why learn Emacs Lisp? -* On Reading this Text:: Read, gain familiarity, pick up habits.... -* Who You Are:: For whom this is written. +* Why:: +* On Reading this Text:: +* Who You Are:: * Lisp History:: -* Note for Novices:: You can read this as a novice. +* Note for Novices:: * Thank You:: @end menu @@ -1066,16 +1075,16 @@ Errors, , Generate an Error Message}.} Lists are the basis of Lisp. @menu -* Lisp Lists:: What are lists? -* Run a Program:: Any list in Lisp is a program ready to run. -* Making Errors:: Generating an error message. -* Names & Definitions:: Names of symbols and function definitions. -* Lisp Interpreter:: What the Lisp interpreter does. -* Evaluation:: Running a program. -* Variables:: Returning a value from a variable. -* Arguments:: Passing information to a function. -* set & setq:: Setting the value of a variable. -* Summary:: The major points. +* Lisp Lists:: +* Run a Program:: +* Making Errors:: +* Names & Definitions:: +* Lisp Interpreter:: +* Evaluation:: +* Variables:: +* Arguments:: +* set & setq:: +* Summary:: * Error Message Exercises:: @end menu @@ -1105,10 +1114,10 @@ @cindex Flowers in a field @menu -* Numbers Lists:: List have numbers, other lists, in them. -* Lisp Atoms:: Elemental entities. -* Whitespace in Lists:: Formating lists to be readable. -* Typing Lists:: How GNU Emacs helps you type lists. +* Numbers Lists:: +* Lisp Atoms:: +* Whitespace in Lists:: +* Typing Lists:: @end menu @node Numbers Lists, Lisp Atoms, Lisp Lists, Lisp Lists @@ -1151,8 +1160,8 @@ using in the lists cannot be divided into any smaller parts and still mean the same thing as part of a program; likewise with numbers and single character symbols like @samp{+}. On the other hand, unlike an -atom, a list can be split into parts. (@xref{car cdr & cons, , -@code{car} @code{cdr} & @code{cons} Fundamental Functions}.) +ancient atom, a list can be split into parts. (@xref{car cdr & cons, +, @code{car} @code{cdr} & @code{cons} Fundamental Functions}.) In a list, atoms are separated from each other by whitespace. They can be right next to a parenthesis. @@ -1378,13 +1387,13 @@ @noindent What you see depends on which version of Emacs you are running. GNU -Emacs version 21 provides more information than version 20 and before. +Emacs version 22 provides more information than version 20 and before. First, the more recent result of generating an error; then the earlier, version 20 result. @need 1250 @noindent -In GNU Emacs version 21, a @file{*Backtrace*} window will open up and +In GNU Emacs version 22, a @file{*Backtrace*} window will open up and you will see the following in it: @smallexample @@ -1501,7 +1510,7 @@ of locating the definition or set of instructions. What we see is the name through which the instructions can be found. Names of people work the same way. I can be referred to as @samp{Bob}; however, I am -not the letters @samp{B}, @samp{o}, @samp{b} but am, or were, the +not the letters @samp{B}, @samp{o}, @samp{b} but am, or was, the consciousness consistently associated with a particular life-form. The name is not me, but it can be used to refer to me. @@ -1546,8 +1555,8 @@ yourself or the computer. @menu -* Complications:: Variables, Special forms, Lists within. -* Byte Compiling:: Specially processing code for speed. +* Complications:: +* Byte Compiling:: @end menu @node Complications, Byte Compiling, Lisp Interpreter, Lisp Interpreter @@ -1639,7 +1648,7 @@ or else produce an error. @menu -* Evaluating Inner Lists:: Lists within lists... +* Evaluating Inner Lists:: @end menu @node Evaluating Inner Lists, , Evaluation, Evaluation @@ -1737,13 +1746,12 @@ of drawers. The function definition is put in one drawer, the value in another, and so on. What is put in the drawer holding the value can be changed without affecting the contents of the drawer holding the -function definition, and vice-versa. +function definition, and vice-verse. @menu * fill-column Example:: -* Void Function:: The error message for a symbol - without a function. -* Void Variable:: The error message for a symbol without a value. +* Void Function:: +* Void Variable:: @end menu @node fill-column Example, Void Function, Variables, Variables @@ -1805,7 +1813,7 @@ @need 1250 @noindent -In GNU Emacs version 21, you will create a @file{*Backtrace*} buffer +In GNU Emacs version 22, you will create a @file{*Backtrace*} buffer that says: @smallexample @@ -1825,6 +1833,7 @@ (Remember, to quit the debugger and make the debugger window go away, type @kbd{q} in the @file{*Backtrace*} buffer.) +@ignore @need 800 In GNU Emacs 20 and before, you will produce an error message that says: @@ -1833,8 +1842,9 @@ @end smallexample @noindent -(The message will go away away as soon as you move the cursor or type +(The message will go away as soon as you move the cursor or type another key.) +@end ignore @node Void Variable, , Void Function, Variables @comment node-name, next, previous, up @@ -1854,7 +1864,7 @@ @need 1500 @noindent -In GNU Emacs 21, you will create a @file{*Backtrace*} buffer that +In GNU Emacs 22, you will create a @file{*Backtrace*} buffer that says: @smallexample @@ -1891,6 +1901,7 @@ definition, the error message reported that the symbol's value as a variable was void. +@ignore @need 800 In GNU Emacs version 20 and before, your error message will say: @@ -1899,7 +1910,8 @@ @end example @noindent -The meaning is the same as in GNU Emacs 21. +The meaning is the same as in GNU Emacs 22. +@end ignore @node Arguments, set & setq, Variables, List Processing @comment node-name, next, previous, up @@ -1945,14 +1957,11 @@ have two different function definitions at the same time.)} @menu -* Data types:: Types of data passed to a function. -* Args as Variable or List:: An argument can be the value - of a variable or list. -* Variable Number of Arguments:: Some functions may take a - variable number of arguments. -* Wrong Type of Argument:: Passing an argument of the wrong type - to a function. -* message:: A useful function for sending messages. +* Data types:: +* Args as Variable or List:: +* Variable Number of Arguments:: +* Wrong Type of Argument:: +* message:: @end menu @node Data types, Args as Variable or List, Arguments, Arguments @@ -2028,7 +2037,7 @@ @noindent The value will be a number two more than what you get by evaluating -@code{fill-column} alone. For me, this is 74, because the value of +@code{fill-column} alone. For me, this is 74, because my value of @code{fill-column} is 72. As we have just seen, an argument can be a symbol that returns a value @@ -2038,7 +2047,7 @@ @w{@code{"The "}} and @w{@code{" red foxes."}} and the list @code{(number-to-string (+ 2 fill-column))}. -@c For Emacs 21, need number-to-string +@c For GNU Emacs 22, need number-to-string @smallexample (concat "The " (number-to-string (+ 2 fill-column)) " red foxes.") @end smallexample @@ -2122,7 +2131,7 @@ could not carry out its addition. @need 1250 -In GNU Emacs version 21, you will create and enter a +In GNU Emacs version 22, you will create and enter a @file{*Backtrace*} buffer that says: @noindent @@ -2180,6 +2189,7 @@ would have been a number, such as 37, rather than a symbol like @code{hello}. But then you would not have got the error message. +@ignore @need 1250 In GNU Emacs version 20 and before, the echo area displays an error message that says: @@ -2190,6 +2200,7 @@ This says, in different words, the same as the top line of the @file{*Backtrace*} buffer. +@end ignore @node message, , Wrong Type of Argument, Arguments @comment node-name, next, previous, up @@ -2300,8 +2311,9 @@ in place of the @samp{%d}; and the value returned by the expression beginning with @code{concat} is inserted in place of the @samp{%s}. -When I evaluate the expression, the message @code{"He saw 38 red -foxes leaping."} appears in my echo area. +When your fill column is 70 and you evaluate the expression, the +message @code{"He saw 38 red foxes leaping."} appears in your echo +area. @node set & setq, Summary, Arguments, List Processing @comment node-name, next, previous, up @@ -2319,9 +2331,9 @@ work but also illustrate how arguments are passed. @menu -* Using set:: Setting values. -* Using setq:: Setting a quoted value. -* Counting:: Using @code{setq} to count. +* Using set:: +* Using setq:: +* Counting:: @end menu @node Using set, Using setq, set & setq, set & setq @@ -2340,7 +2352,7 @@ @noindent The list @code{(rose violet daisy buttercup)} will appear in the echo area. This is what is @emph{returned} by the @code{set} function. As a -side effect, the symbol @code{flowers} is bound to the list ; that is, +side effect, the symbol @code{flowers} is bound to the list; that is, the symbol @code{flowers}, which can be viewed as a variable, is given the list as its value. (This process, by the way, illustrates how a side effect to the Lisp interpreter, setting the value, can be the @@ -2529,7 +2541,14 @@ Then the instructions in the function definition are carried out. @item -A single-quote, @code{'}, tells the Lisp interpreter that it should +A single quotation mark, +@ifinfo +' +@end ifinfo +@ifnotinfo +@code{'} +@end ifnotinfo +, tells the Lisp interpreter that it should return the following expression as written, and not evaluate it as it would if the quote were not there. @@ -2584,13 +2603,11 @@ buffer-related functions, to see how they were written. @menu -* How to Evaluate:: Typing editing commands or @kbd{C-x C-e} - causes evaluation. -* Buffer Names:: Buffers and files are different. -* Getting Buffers:: Getting a buffer itself, not merely its name. -* Switching Buffers:: How to change to another buffer. -* Buffer Size & Locations:: Where point is located and the size of - the buffer. +* How to Evaluate:: +* Buffer Names:: +* Getting Buffers:: +* Switching Buffers:: +* Buffer Size & Locations:: * Evaluation Exercise:: @end menu @@ -2656,27 +2673,45 @@ each of the following expressions by positioning the cursor after it and typing @kbd{C-x C-e}. -@smallexample +@example @group (buffer-name) (buffer-file-name) @end group -@end smallexample - -@noindent -When I do this, @file{"introduction.texinfo"} is the value returned by -evaluating @code{(buffer-name)}, and -@file{"/gnu/work/intro/introduction.texinfo"} is the value returned by -evaluating @code{(buffer-file-name)}. The former is the name of the -buffer and the latter is the name of the file. (In the expressions, the -parentheses tell the Lisp interpreter to treat @code{buffer-name} and -@code{buffer-file-name} as functions; without the parentheses, the -interpreter would attempt to evaluate the symbols as variables. -@xref{Variables}.) +@end example + +@noindent +When I do this in Info, the value returned by evaluating +@code{(buffer-name)} is @file{"*info*"}, and the value returned by +evaluating @code{(buffer-file-name)} is @file{nil}. + +On the other hand, while I am writing this Introduction, the value +returned by evaluating @code{(buffer-name)} is +@file{"introduction.texinfo"}, and the value returned by evaluating +@code{(buffer-file-name)} is +@file{"/gnu/work/intro/introduction.texinfo"}. + +@cindex @code{nil}, history of word +The former is the name of the buffer and the latter is the name of the +file. In Info, the buffer name is @file{"*info*"}. Info does not +point to any file, so the result of evaluating +@code{(buffer-file-name)} is @file{nil}. The symbol @code{nil} is +from the Latin word for `nothing'; in this case, it means that the +buffer is not associated with any file. (In Lisp, @code{nil} is also +used to mean `false' and is a synonym for the empty list, @code{()}.) + +When I am writing, the name of my buffer is +@file{"introduction.texinfo"}. The name of the file to which it +points is @file{"/gnu/work/intro/introduction.texinfo"}. + +(In the expressions, the parentheses tell the Lisp interpreter to +treat @w{@code{buffer-name}} and @w{@code{buffer-file-name}} as +functions; without the parentheses, the interpreter would attempt to +evaluate the symbols as variables. @xref{Variables}.) In spite of the distinction between files and buffers, you will often -find that people refer to a file when they mean a buffer and vice-versa. +find that people refer to a file when they mean a buffer and vice-verse. Indeed, most people say, ``I am editing a file,'' rather than saying, ``I am editing a buffer which I will soon save to a file.'' It is almost always clear from context what people mean. When dealing with @@ -2698,23 +2733,25 @@ temporarily before being loaded onto ships; then it became a business and cultural center in its own right. -Not all buffers are associated with files. For example, when you start -an Emacs session by typing the command @code{emacs} alone, without -naming any files, Emacs will start with the @file{*scratch*} buffer on -the screen. This buffer is not visiting any file. Similarly, a +Not all buffers are associated with files. For example, a +@file{*scratch*} buffer does not visit any file. Similarly, a @file{*Help*} buffer is not associated with any file. -@cindex @code{nil}, history of word -If you switch to the @file{*scratch*} buffer, type @code{(buffer-name)}, -position the cursor after it, and type @kbd{C-x C-e} to evaluate the -expression, the name @code{"*scratch*"} is returned and will appear in -the echo area. @code{"*scratch*"} is the name of the buffer. However, -if you type @code{(buffer-file-name)} in the @file{*scratch*} buffer and -evaluate that, @code{nil} will appear in the echo area. @code{nil} is -from the Latin word for `nothing'; in this case, it means that the -@file{*scratch*} buffer is not associated with any file. (In Lisp, -@code{nil} is also used to mean `false' and is a synonym for the empty -list, @code{()}.) +In the old days, when you lacked a @file{~/.emacs} file and started an +Emacs session by typing the command @code{emacs} alone, without naming +any files, Emacs started with the @file{*scratch*} buffer visible. +Nowadays, you will see a splash screen. You can follow one of the +commands suggested on the splash screen, visit a file, or press the +spacebar to reach the @file{*scratch*} buffer. + +If you switch to the @file{*scratch*} buffer, type +@code{(buffer-name)}, position the cursor after it, and then type +@kbd{C-x C-e} to evaluate the expression. The name @code{"*scratch*"} +will be returned and will appear in the echo area. @code{"*scratch*"} +is the name of the buffer. When you type @code{(buffer-file-name)} in +the @file{*scratch*} buffer and evaluate that, @code{nil} will appear +in the echo area, just as it does when you evaluate +@code{(buffer-file-name)} in Info. Incidentally, if you are in the @file{*scratch*} buffer and want the value returned by an expression to appear in the @file{*scratch*} @@ -2771,18 +2808,20 @@ @end smallexample @noindent -If you evaluate the expression in the usual way, @file{#<buffer *info*>} -appears in the echo area. The special format indicates that the -buffer itself is being returned, rather than just its name. +If you evaluate this expression in Info in Emacs in the usual way, +@file{#<buffer *info*>} will appear in the echo area. The special +format indicates that the buffer itself is being returned, rather than +just its name. Incidentally, while you can type a number or symbol into a program, you cannot do that with the printed representation of a buffer: the only way to get a buffer itself is with a function such as @code{current-buffer}. A related function is @code{other-buffer}. This returns the most -recently selected buffer other than the one you are in currently. If -you have recently switched back and forth from the @file{*scratch*} -buffer, @code{other-buffer} will return that buffer. +recently selected buffer other than the one you are in currently, not +a printed representation of its name. If you have recently switched +back and forth from the @file{*scratch*} buffer, @code{other-buffer} +will return that buffer. @need 800 You can see this by evaluating the expression: @@ -2815,12 +2854,13 @@ function. When you switched back and forth from Info to the @file{*scratch*} buffer to evaluate @code{(buffer-name)}, you most likely typed @kbd{C-x b} and then typed @file{*scratch*}@footnote{Or -rather, to save typing, you probably typed just part of the name, such -as @code{*sc}, and then pressed your @kbd{TAB} key to cause it to -expand to the full name; and then typed your @kbd{RET} key.} when -prompted in the minibuffer for the name of the buffer to which you -wanted to switch. The keystrokes, @kbd{C-x b}, cause the Lisp -interpreter to evaluate the interactive function +rather, to save typing, you probably only typed @kbd{RET} if the +default buffer was @file{*scratch*}, or if it was different, then you +typed just part of the name, such as @code{*sc}, pressed your +@kbd{TAB} key to cause it to expand to the full name, and then typed +your @kbd{RET} key.} when prompted in the minibuffer for the name of +the buffer to which you wanted to switch. The keystrokes, @kbd{C-x +b}, cause the Lisp interpreter to evaluate the interactive function @code{switch-to-buffer}. As we said before, this is how Emacs works: different keystrokes call or run different functions. For example, @kbd{C-f} calls @code{forward-char}, @kbd{M-e} calls @@ -2945,7 +2985,9 @@ @noindent For me, the value of point in this location is 66043, which means that -there are 319 characters (including spaces) between the two expressions. +there are 319 characters (including spaces) between the two +expressions. (Doubtless, you will see different numbers, since I will +have edited this since I first evaluated point.) @cindex @samp{narrowing} defined The function @code{point-min} is somewhat similar to @code{point}, but @@ -2980,16 +3022,16 @@ @menu * Primitive Functions:: -* defun:: The @code{defun} special form. -* Install:: Install a function definition. -* Interactive:: Making a function interactive. -* Interactive Options:: Different options for @code{interactive}. -* Permanent Installation:: Installing code permanently. -* let:: Creating and initializing local variables. -* if:: What if? -* else:: If--then--else expressions. -* Truth & Falsehood:: What Lisp considers false and true. -* save-excursion:: Keeping track of point, mark, and buffer. +* defun:: +* Install:: +* Interactive:: +* Interactive Options:: +* Permanent Installation:: +* let:: +* if:: +* else:: +* Truth & Falsehood:: +* save-excursion:: * Review:: * defun Exercises:: @end menu @@ -3226,10 +3268,9 @@ Emacs. To reload code automatically whenever you start Emacs, see @ref{Permanent Installation, , Installing Code Permanently}.) - @menu * Effect of installation:: -* Change a defun:: How to change a function definition. +* Change a defun:: @end menu @node Effect of installation, Change a defun, Install, Install @@ -3237,7 +3278,6 @@ @unnumberedsubsec The effect of installation @end ifnottex - You can see the effect of installing @code{multiply-by-seven} by evaluating the following sample. Place the cursor after the following expression and type @kbd{C-x C-e}. The number 21 will appear in the @@ -3254,7 +3294,9 @@ @smallexample @group -multiply-by-seven: +multiply-by-seven is a Lisp function. +(multiply-by-seven NUMBER) + Multiply NUMBER by seven. @end group @end smallexample @@ -3329,8 +3371,8 @@ each time you typed a key, it would be very distracting. @menu -* Interactive multiply-by-seven:: An overview. -* multiply-by-seven in detail:: The interactive version. +* Interactive multiply-by-seven:: +* multiply-by-seven in detail:: @end menu @node Interactive multiply-by-seven, multiply-by-seven in detail, Interactive, Interactive @@ -3436,14 +3478,14 @@ subsequent elements of the list to the function @code{message}. As we have seen, @code{message} is an Emacs Lisp function especially -designed for sending a one line message to a user. (@xref{message, , The -@code{message} function}.) -In summary, the @code{message} function prints its first argument in the -echo area as is, except for occurrences of @samp{%d}, @samp{%s}, or -@samp{%c}. When it sees one of these control sequences, the function -looks to the second and subsequent arguments and prints the value of the -argument in the location in the string where the control sequence is -located. +designed for sending a one line message to a user. (@xref{message, , +The @code{message} function}.) In summary, the @code{message} +function prints its first argument in the echo area as is, except for +occurrences of @samp{%d} or @samp{%s} (and various other %-sequences +which we have not mentioned). When it sees a control sequence, the +function looks to the second or subsequent arguments and prints the +value of the argument in the location in the string where the control +sequence is located. In the interactive @code{multiply-by-seven} function, the control string is @samp{%d}, which requires a number, and the value returned by @@ -3476,62 +3518,67 @@ @code{interactive}, elisp, The GNU Emacs Lisp Reference Manual}.) @need 1250 -For example, the character @samp{r} causes Emacs to pass the beginning -and end of the region (the current values of point and mark) to the -function as two separate arguments. It is used as follows: - -@smallexample -(interactive "r") -@end smallexample - -On the other hand, a @samp{B} tells Emacs to ask for the name of a -buffer that will be passed to the function. When it sees a @samp{B}, -Emacs will ask for the name by prompting the user in the minibuffer, -using a string that follows the @samp{B}, as in @code{"BAppend to -buffer:@: "}. Not only will Emacs prompt for the name, but Emacs will -complete the name if you type enough of it and press @key{TAB}. - -A function with two or more arguments can have information passed to -each argument by adding parts to the string that follows -@code{interactive}. When you do this, the information is passed to -each argument in the same order it is specified in the +Consider the function @code{zap-to-char}. Its interactive expression +is + +@smallexample +(interactive "p\ncZap to char: ") +@end smallexample + +The first part of the argument to @code{interactive} is @samp{p}, with +which you are already familiar. This argument tells Emacs to +interpret a `prefix', as a number to be passed to the function. You +can specify a prefix either by typing @kbd{C-u} followed by a number +or by typing @key{META} followed by a number. The prefix is the +number of specified characters. Thus, if your prefix is three and the +specified character is @samp{x}, then you will delete all the text up +to and including the third next @samp{x}. If you do not set a prefix, +then you delete all the text up to and including the specified +character, but no more. + +The @samp{c} tells the function the name of the character to which to delete. + +More formally, a function with two or more arguments can have +information passed to each argument by adding parts to the string that +follows @code{interactive}. When you do this, the information is +passed to each argument in the same order it is specified in the @code{interactive} list. In the string, each part is separated from the next part by a @samp{\n}, which is a newline. For example, you -could follow @code{"BAppend to buffer:@: "} with a @samp{\n} and an -@samp{r}. This would cause Emacs to pass the values of point and mark -to the function as well as prompt you for the buffer---three arguments -in all. - -In this case, the function definition would look like the following, -where @code{buffer}, @code{start}, and @code{end} are the symbols to -which @code{interactive} binds the buffer and the current values of the -beginning and ending of the region: - -@smallexample -@group -(defun @var{name-of-function} (buffer start end) +can follow @samp{p} with a @samp{\n} and an @samp{cZap to char:@: }. +This causes Emacs to pass the value of the prefix argument (if there +is one) and the character. + +In this case, the function definition looks like the following, where +@code{arg} and @code{char} are the symbols to which @code{interactive} +binds the prefix argument and the specified character: + +@smallexample +@group +(defun @var{name-of-function} (arg char) "@var{documentation}@dots{}" - (interactive "BAppend to buffer:@: \nr") + (interactive "p\ncZap to char: ") @var{body-of-function}@dots{}) @end group @end smallexample @noindent (The space after the colon in the prompt makes it look better when you -are prompted. The @code{append-to-buffer} function looks exactly like -this. @xref{append-to-buffer, , The Definition of -@code{append-to-buffer}}.) - -If a function does not have arguments, then @code{interactive} does not +are prompted. @xref{copy-to-buffer, , The Definition of +@code{copy-to-buffer}}, for an example.) + +When a function does not take arguments, @code{interactive} does not require any. Such a function contains the simple expression @code{(interactive)}. The @code{mark-whole-buffer} function is like this. Alternatively, if the special letter-codes are not right for your application, you can pass your own arguments to @code{interactive} as -a list. @xref{Using Interactive, , Using @code{Interactive}, elisp, The -GNU Emacs Lisp Reference Manual}, for more information about this advanced -technique. +a list. + +@xref{append-to-buffer, , The Definition of @code{append-to-buffer}}, +for an example. @xref{Using Interactive, , Using @code{Interactive}, +elisp, The GNU Emacs Lisp Reference Manual}, for a more complete +explanation about this technique. @node Permanent Installation, let, Interactive Options, Writing Defuns @comment node-name, next, previous, up @@ -3565,11 +3612,11 @@ @xref{Loading Files, , Loading Files}. @item -On the other hand, if you have code that your whole site will use, it -is usual to put it in a file called @file{site-init.el} that is loaded -when Emacs is built. This makes the code available to everyone who -uses your machine. (See the @file{INSTALL} file that is part of the -Emacs distribution.) +Thirdly, if you have code that your whole site will use, it is usual +to put it in a file called @file{site-init.el} that is loaded when +Emacs is built. This makes the code available to everyone who uses +your machine. (See the @file{INSTALL} file that is part of the Emacs +distribution.) @end itemize Finally, if you have code that everyone who uses Emacs may want, you @@ -3621,6 +3668,7 @@ @end ifnottex @cindex @samp{local variable} defined +@cindex @samp{variable, local}, defined The @code{let} special form prevents confusion. @code{let} creates a name for a @dfn{local variable} that overshadows any use of the same name outside the @code{let} expression. This is like understanding @@ -3726,13 +3774,17 @@ The two variables are @code{zebra} and @code{tiger}. Each variable is the first element of a two-element list and each value is the second element of its two-element list. In the varlist, Emacs binds the -variable @code{zebra} to the value @code{stripes}, and binds the +variable @code{zebra} to the value @code{stripes}@footnote{According +to Jared Diamond in @cite{Guns, Germs, and Steel}, ``@dots{} zebras +become impossibly dangerous as they grow older'' but the claim here is +that they do not become fierce like a tiger. (1997, W. W. Norton and +Co., ISBN 0-393-03894-2, page 171)}, and binds the variable @code{tiger} to the value @code{fierce}. In this example, both values are symbols preceded by a quote. The values could just as well have been another list or a string. The body of the @code{let} -follows after the list holding the variables. In this example, the body -is a list that uses the @code{message} function to print a string in -the echo area. +follows after the list holding the variables. In this example, the +body is a list that uses the @code{message} function to print a string +in the echo area. @need 1500 You may evaluate the example in the usual fashion, by placing the @@ -3818,7 +3870,7 @@ @menu * if in more detail:: -* type-of-animal in detail:: An example of an @code{if} expression. +* type-of-animal in detail:: @end menu @node if in more detail, type-of-animal in detail, if, if @@ -4086,8 +4138,8 @@ (Of course, if the @var{characteristic} were @code{ferocious}, the message @code{"It's not fierce!"} would be printed; and it would be misleading! When you write code, you need to take into account the -possibility that some such argument will be tested by the @code{if} and -write your program accordingly.) +possibility that some such argument will be tested by the @code{if} +and write your program accordingly.) @node Truth & Falsehood, save-excursion, else, Writing Defuns @comment node-name, next, previous, up @@ -4106,11 +4158,11 @@ if the result of evaluating it is a value that is not @code{nil}. In other words, the result of the test is considered true if the value returned is a number such as 47, a string such as @code{"hello"}, or a -symbol (other than @code{nil}) such as @code{flowers}, or a list, or -even a buffer! - -@menu -* nil explained:: @code{nil} has two meanings. +symbol (other than @code{nil}) such as @code{flowers}, or a list (so +long as it is not empty), or even a buffer! + +@menu +* nil explained:: @end menu @node nil explained, , Truth & Falsehood, Truth & Falsehood @@ -4198,7 +4250,7 @@ unexpected movement of point or mark. @menu -* Point and mark:: A review of various locations. +* Point and mark:: * Template for save-excursion:: @end menu @@ -4256,8 +4308,8 @@ In addition to recording the values of point and mark, @code{save-excursion} keeps track of the current buffer, and restores it, too. This means you can write code that will change the buffer and -have @code{save-excursion} switch you back to the original buffer. This -is how @code{save-excursion} is used in @code{append-to-buffer}. +have @code{save-excursion} switch you back to the original buffer. +This is how @code{save-excursion} is used in @code{append-to-buffer}. (@xref{append-to-buffer, , The Definition of @code{append-to-buffer}}.) @node Template for save-excursion, , Point and mark, save-excursion @@ -4334,7 +4386,9 @@ definition. @need 1250 -For example: +For example, in an early version of Emacs, the function definition was +as follows. (It is slightly more complex now that it seeks the first +non-whitespace character rather than the first visible character.) @smallexample @group @@ -4346,6 +4400,24 @@ @end group @end smallexample +@ignore +In GNU Emacs 22, + +(defun backward-to-indentation (&optional arg) + "Move backward ARG lines and position at first nonblank character." + (interactive "p") + (forward-line (- (or arg 1))) + (skip-chars-forward " \t")) + +(defun back-to-indentation () + "Move point to the first non-whitespace character on this line." + (interactive) + (beginning-of-line 1) + (skip-syntax-forward " " (line-end-position)) + ;; Move back over chars that have whitespace syntax but have the p flag. + (backward-prefix-chars)) +@end ignore + @item interactive Declare to the interpreter that the function can be used interactively. This special form may be followed by a string with one @@ -4430,10 +4502,10 @@ @smallexample @group (if (string-equal - (number-to-string 21) + (number-to-string 22) (substring (emacs-version) 10 12)) - (message "This is version 21 Emacs") - (message "This is not version 21 Emacs")) + (message "This is version 22 Emacs") + (message "This is not version 22 Emacs")) @end group @end smallexample @@ -4460,6 +4532,11 @@ the second. In all cases, both arguments must be numbers or markers (markers indicate positions in buffers). +@need 800 +@item = +The @code{=} function tests whether two arguments, both numbers or +markers, are equal. + @item string< @itemx string-lessp @itemx string= @@ -4487,6 +4564,7 @@ be a string or a symbol; the argument used by @samp{%d} must be a number. The argument used by @samp{%c} must be an @sc{ascii} code number; it will be printed as the character with that @sc{ascii} code. +(Various other %-sequences have not been mentioned.) @item setq @itemx set @@ -4567,13 +4645,11 @@ buffers. Later, we will study other functions. @menu -* Finding More:: How to find more information. -* simplified-beginning-of-buffer:: Shows @code{goto-char}, - @code{point-min}, and @code{push-mark}. -* mark-whole-buffer:: Almost the same as @code{beginning-of-buffer}. -* append-to-buffer:: Uses @code{save-excursion} and - @code{insert-buffer-substring}. -* Buffer Related Review:: Review. +* Finding More:: +* simplified-beginning-of-buffer:: +* mark-whole-buffer:: +* append-to-buffer:: +* Buffer Related Review:: * Buffer Exercises:: @end menu @@ -4591,12 +4667,23 @@ then @key{RET}). @cindex Find source of function -In versions 20 and higher, when a function is written in Emacs Lisp, -@code{describe-function} will also tell you the location of the -function definition. If you move point over the file name and press +@c In version 22, tells location both of C and of Emacs Lisp +Also, @code{describe-function} will tell you the location of the +function definition. + +Put point into the name of the file that contains the function and +press the @key{RET} key. In this case, @key{RET} means +@code{push-button} rather than `return' or `enter'. Emacs will take +you directly to the function definition. + +@ignore +Not In version 22 + +If you move point over the file name and press the @key{RET} key, which in this case means @code{help-follow} rather than `return' or `enter', Emacs will take you directly to the function definition. +@end ignore More generally, if you want to see a function in its original source file, you can use the @code{find-tags} function to jump to it. @@ -4604,7 +4691,6 @@ Lisp, and C, and it works with non-programming text as well. For example, @code{find-tags} will jump to the various nodes in the Texinfo source file of this document. - The @code{find-tags} function depends on `tags tables' that record the locations of the functions, variables, and other items to which @code{find-tags} jumps. @@ -4619,7 +4705,7 @@ @key{RET}}. (On some keyboards, the @key{META} key is labelled @key{ALT}.) -@c !!! 21.0.100 tags table location in this paragraph +@c !!! 22.1.1 tags table location in this paragraph @cindex TAGS table, specifying @findex find-tags Depending on how the initial default values of your copy of Emacs are @@ -4629,15 +4715,15 @@ if it has already been created for you, will be in a subdirectory of the @file{/usr/local/share/emacs/} directory; thus you would use the @code{M-x visit-tags-table} command and specify a pathname such as -@file{/usr/local/share/emacs/21.0.100/lisp/TAGS} or -@file{/usr/local/src/emacs/src/TAGS}. If the tags table has -not already been created, you will have to create it yourself. +@file{/usr/local/share/emacs/22.1.1/lisp/TAGS}. If the tags table +has not already been created, you will have to create it yourself. It +will in a file such as @file{/usr/local/src/emacs/src/TAGS}. @need 1250 To create a @file{TAGS} file in a specific directory, switch to that directory in Emacs using @kbd{M-x cd} command, or list the directory with @kbd{C-x d} (@code{dired}). Then run the compile command, with -@w{@code{etags *.el}} as the command to execute +@w{@code{etags *.el}} as the command to execute: @smallexample M-x compile RET etags *.el RET @@ -4773,11 +4859,13 @@ @smallexample @group -One arg, a number. Set point to that number. -Beginning of buffer is position (point-min), -end is (point-max). -@end group -@end smallexample +Set point to POSITION, a number or marker. +Beginning of buffer is position (point-min), end is (point-max). +@end group +@end smallexample + +@noindent +The function's one argument is the desired position. @noindent (The prompt for @code{describe-function} will offer you the symbol @@ -4805,12 +4893,10 @@ a mark at the end of the buffer. It is generally bound to @kbd{C-x h}. - @menu * mark-whole-buffer overview:: -* Body of mark-whole-buffer:: Only three lines of code. -@end menu - +* Body of mark-whole-buffer:: +@end menu @node mark-whole-buffer overview, Body of mark-whole-buffer, mark-whole-buffer, mark-whole-buffer @ifnottex @@ -4818,15 +4904,18 @@ @end ifnottex @need 1250 -In GNU Emacs 20, the code for the complete function looks like this: +In GNU Emacs 22, the code for the complete function looks like this: @smallexample @group (defun mark-whole-buffer () - "Put point at beginning and mark at end of buffer." + "Put point at beginning and mark at end of buffer. +You probably should not use this function in Lisp programs; +it is usually a mistake for a Lisp function to use any subroutine +that uses or sets the mark." (interactive) (push-mark (point)) - (push-mark (point-max)) + (push-mark (point-max) nil t) (goto-char (point-min))) @end group @end smallexample @@ -4863,10 +4952,11 @@ The body of the @code{mark-whole-buffer} function consists of three lines of code: +@c GNU Emacs 22 @smallexample @group (push-mark (point)) -(push-mark (point-max)) +(push-mark (point-max) nil t) (goto-char (point-min)) @end group @end smallexample @@ -4889,34 +4979,36 @@ line causes Emacs to determine the position of point and set a mark there. -The next line of @code{mark-whole-buffer} is @code{(push-mark (point-max)}. -This expression sets a mark at the point in the buffer -that has the highest number. This will be the end of the buffer (or, -if the buffer is narrowed, the end of the accessible portion of the -buffer. @xref{Narrowing & Widening, , Narrowing and Widening}, for -more about narrowing.) After this mark has been set, the previous -mark, the one set at point, is no longer set, but Emacs remembers its -position, just as all other recent marks are always remembered. This -means that you can, if you wish, go back to that position by typing -@kbd{C-u C-@key{SPC}} twice. - -(In GNU Emacs 21, the @code{(push-mark (point-max)} is slightly more -complicated than shown here. The line reads +In earlier versions of GNU Emacs, the next line of +@code{mark-whole-buffer} was @code{(push-mark (point-max))}. This +expression sets a mark at the point in the buffer that has the highest +number. This will be the end of the buffer (or, if the buffer is +narrowed, the end of the accessible portion of the buffer. +@xref{Narrowing & Widening, , Narrowing and Widening}, for more about +narrowing.) After this mark has been set, the previous mark, the one +set at point, is no longer set, but Emacs remembers its position, just +as all other recent marks are always remembered. This means that you +can, if you wish, go back to that position by typing @kbd{C-u +C-@key{SPC}} twice. + +@need 1250 +In GNU Emacs 22, the @code{(point-max)} is slightly more complicated. +The line reads @smallexample (push-mark (point-max) nil t) @end smallexample @noindent -(The expression works nearly the same as before. It sets a mark at -the highest numbered place in the buffer that it can. However, in -this version, @code{push-mark} has two additional arguments. The -second argument to @code{push-mark} is @code{nil}. This tells the -function it @emph{should} display a message that says `Mark set' when -it pushes the mark. The third argument is @code{t}. This tells +The expression works nearly the same as before. It sets a mark at the +highest numbered place in the buffer that it can. However, in this +version, @code{push-mark} has two additional arguments. The second +argument to @code{push-mark} is @code{nil}. This tells the function +it @emph{should} display a message that says `Mark set' when it pushes +the mark. The third argument is @code{t}. This tells @code{push-mark} to activate the mark when Transient Mark mode is turned on. Transient Mark mode highlights the currently active -region. It is usually turned off.) +region. It is often turned off. Finally, the last line of the function is @code{(goto-char (point-min)))}. This is written exactly the same way as it is written @@ -4932,16 +5024,16 @@ @section The Definition of @code{append-to-buffer} @findex append-to-buffer -The @code{append-to-buffer} command is very nearly as simple as the -@code{mark-whole-buffer} command. What it does is copy the region (that -is, the part of the buffer between point and mark) from the current -buffer to a specified buffer. +The @code{append-to-buffer} command is more complex than the +@code{mark-whole-buffer} command. What it does is copy the region +(that is, the part of the buffer between point and mark) from the +current buffer to a specified buffer. @menu * append-to-buffer overview:: -* append interactive:: A two part interactive expression. -* append-to-buffer body:: Incorporates a @code{let} expression. -* append save-excursion:: How the @code{save-excursion} works. +* append interactive:: +* append-to-buffer body:: +* append save-excursion:: @end menu @node append-to-buffer overview, append interactive, append-to-buffer, append-to-buffer @@ -4954,10 +5046,15 @@ @code{insert-buffer-substring} function to copy the region. @code{insert-buffer-substring} is described by its name: it takes a string of characters from part of a buffer, a ``substring'', and -inserts them into another buffer. Most of @code{append-to-buffer} is +inserts them into another buffer. + +Most of @code{append-to-buffer} is concerned with setting up the conditions for @code{insert-buffer-substring} to work: the code must specify both the -buffer to which the text will go and the region that will be copied. +buffer to which the text will go, the window it comes from and goes +to, and the region that will be copied. + +@need 1250 Here is the complete text of the function: @smallexample @@ -4969,13 +5066,26 @@ @group When calling from a program, give three arguments: -a buffer or the name of one, and two character numbers -specifying the portion of the current buffer to be copied." - (interactive "BAppend to buffer:@: \nr") +BUFFER (or buffer name), START and END. +START and END specify the portion of the current buffer to be copied." + (interactive + (list (read-buffer "Append to buffer: " (other-buffer + (current-buffer) t)) + (region-beginning) (region-end))) +@end group +@group (let ((oldbuf (current-buffer))) (save-excursion - (set-buffer (get-buffer-create buffer)) - (insert-buffer-substring oldbuf start end)))) + (let* ((append-to (get-buffer-create buffer)) + (windows (get-buffer-window-list append-to t t)) + point) + (set-buffer append-to) + (setq point (point)) + (barf-if-buffer-read-only) + (insert-buffer-substring oldbuf start end) + (dolist (window windows) + (when (= (window-point window) point) + (set-window-point window (point)))))))) @end group @end smallexample @@ -4989,7 +5099,7 @@ @group (defun append-to-buffer (buffer start end) "@var{documentation}@dots{}" - (interactive "BAppend to buffer:@: \nr") + (interactive @dots{}) @var{body}@dots{}) @end group @end smallexample @@ -5000,7 +5110,12 @@ will be copied. The next part of the function is the documentation, which is clear and -complete. +complete. As is conventional, the three arguments are written in +upper case so you will notice them easily. Even better, they are +described in the same order as in the argument list. + +Note that the documentation distinguishes between a buffer and its +name. (The function can handle either.) @node append interactive, append-to-buffer body, append-to-buffer overview, append-to-buffer @comment node-name, next, previous, up @@ -5012,30 +5127,96 @@ Function Interactive}.) The expression reads as follows: @smallexample +@group +(interactive + (list (read-buffer + "Append to buffer: " + (other-buffer (current-buffer) t)) + (region-beginning) + (region-end))) +@end group +@end smallexample + +@noindent +This expression is not one with letters standing for parts, as +described earlier. Instead, it starts a list with thee parts. + +The first part of the list is an expression to read the name of a +buffer and return it as a string. That is @code{read-buffer}. The +function requires a prompt as its first argument, @samp{"Append to +buffer: "}. Its second argument tells the command what value to +provide if you don't specify anything. + +In this case that second argument is an expression containing the +function @code{other-buffer}, an exception, and a @samp{t}, standing +for true. + +The first argument to @code{other-buffer}, the exception, is yet +another function, @code{current-buffer}. That is not going to be +returned. The second argument is the symbol for true, @code{t}. that +tells @code{other-buffer} that it may show visible buffers (except in +this case, it will not show the current buffer, which makes sense). + +@need 1250 +The expression looks like this: + +@smallexample +(other-buffer (current-buffer) t) +@end smallexample + +The second and third arguments to the @code{list} expression are +@code{(region-beginning)} and @code{(region-end)}. These two +functions specify the beginning and end of the text to be appended. + +@need 1250 +Originally, the command used the letters @samp{B} and @samp{r}. +The whole @code{interactive} expression looked like this: + +@smallexample (interactive "BAppend to buffer:@: \nr") @end smallexample @noindent -This expression has an argument inside of quotation marks and that -argument has two parts, separated by @samp{\n}. - -The first part is @samp{BAppend to buffer:@: }. Here, the @samp{B} -tells Emacs to ask for the name of the buffer that will be passed to the -function. Emacs will ask for the name by prompting the user in the -minibuffer, using the string following the @samp{B}, which is the string -@samp{Append to buffer:@: }. Emacs then binds the variable @code{buffer} -in the function's argument list to the specified buffer. - -The newline, @samp{\n}, separates the first part of the argument from -the second part. It is followed by an @samp{r} that tells Emacs to bind -the two arguments that follow the symbol @code{buffer} in the function's +But when that was done, the default value of the buffer switched to +was invisible. That was not wanted. + +(The prompt was separated from the second argument with a newline, +@samp{\n}. It was followed by an @samp{r} that told Emacs to bind the +two arguments that follow the symbol @code{buffer} in the function's argument list (that is, @code{start} and @code{end}) to the values of -point and mark. +point and mark. That argument worked fine.) @node append-to-buffer body, append save-excursion, append interactive, append-to-buffer @comment node-name, next, previous, up @subsection The Body of @code{append-to-buffer} +@ignore +in GNU Emacs 22 in /usr/local/src/emacs/lisp/simple.el + +(defun append-to-buffer (buffer start end) + "Append to specified buffer the text of the region. +It is inserted into that buffer before its point. + +When calling from a program, give three arguments: +BUFFER (or buffer name), START and END. +START and END specify the portion of the current buffer to be copied." + (interactive + (list (read-buffer "Append to buffer: " (other-buffer (current-buffer) t)) + (region-beginning) (region-end))) + (let ((oldbuf (current-buffer))) + (save-excursion + (let* ((append-to (get-buffer-create buffer)) + (windows (get-buffer-window-list append-to t t)) + point) + (set-buffer append-to) + (setq point (point)) + (barf-if-buffer-read-only) + (insert-buffer-substring oldbuf start end) + (dolist (window windows) + (when (= (window-point window) point) + (set-window-point window (point)))))))) +@end ignore + The body of the @code{append-to-buffer} function begins with @code{let}. As we have seen before (@pxref{let, , @code{let}}), the purpose of a @@ -5052,7 +5233,7 @@ @group (defun append-to-buffer (buffer start end) "@var{documentation}@dots{}" - (interactive "BAppend to buffer:@: \nr") + (interactive @dots{}) (let ((@var{variable} @var{value})) @var{body}@dots{}) @end group @@ -5142,7 +5323,7 @@ @need 1500 @noindent -This formatting convention makes it easy to see that the two lines in +This formatting convention makes it easy to see that the lines in the body of the @code{save-excursion} are enclosed by the parentheses associated with @code{save-excursion}, just as the @code{save-excursion} itself is enclosed by the parentheses associated @@ -5152,8 +5333,10 @@ @group (let ((oldbuf (current-buffer))) (save-excursion - (set-buffer (get-buffer-create buffer)) - (insert-buffer-substring oldbuf start end)))) + @dots{} + (set-buffer @dots{}) + (insert-buffer-substring oldbuf start end) + @dots{})) @end group @end smallexample @@ -5174,70 +5357,84 @@ @need 1200 @noindent In this function, the body of the @code{save-excursion} contains only -two expressions. The body looks like this: - -@smallexample -@group -(set-buffer (get-buffer-create buffer)) -(insert-buffer-substring oldbuf start end) -@end group -@end smallexample - -When the @code{append-to-buffer} function is evaluated, the two -expressions in the body of the @code{save-excursion} are evaluated in -sequence. The value of the last expression is returned as the value of -the @code{save-excursion} function; the other expression is evaluated -only for its side effects. - -The first line in the body of the @code{save-excursion} uses the -@code{set-buffer} function to change the current buffer to the one -specified in the first argument to @code{append-to-buffer}. (Changing -the buffer is the side effect; as we have said before, in Lisp, a side -effect is often the primary thing we want.) The second line does the -primary work of the function. - -The @code{set-buffer} function changes Emacs' attention to the buffer to -which the text will be copied and from which @code{save-excursion} will -return. - -@need 800 -The line looks like this: +one expression, the @code{let*} expression. You know about a +@code{let} function. The @code{let*} function is different. It has a +@samp{*} in its name. It enables Emacs to set each variable in its +varlist in sequence, one after another. + +Its critical feature is that variables later in the varlist can make +use of the values to which Emacs set variables earlier in the varlist. +@xref{fwd-para let, , The @code{let*} expression}. + +We will skip functions like @code{let*} and focus on two: the +@code{set-buffer} function and the @code{insert-buffer-substring} +function. + +@need 1250 +In the old days, the @code{set-buffer} expression was simply @smallexample (set-buffer (get-buffer-create buffer)) @end smallexample -The innermost expression of this list is @code{(get-buffer-create -buffer)}. This expression uses the @code{get-buffer-create} function, -which either gets the named buffer, or if it does not exist, creates one -with the given name. This means you can use @code{append-to-buffer} to -put text into a buffer that did not previously exist. - -@code{get-buffer-create} also keeps @code{set-buffer} from getting an -unnecessary error: @code{set-buffer} needs a buffer to go to; if you -were to specify a buffer that does not exist, Emacs would baulk. -Since @code{get-buffer-create} will create a buffer if none exists, -@code{set-buffer} is always provided with a buffer. - -@need 1250 -The last line of @code{append-to-buffer} does the work of appending -the text: +@need 1250 +@noindent +but now it is + +@smallexample +(set-buffer append-to) +@end smallexample + +@noindent +@code{append-to} is bound to @code{(get-buffer-create buffer)} earlier +on in the @code{let*} expression. That extra binding would not be +necessary except for that @code{append-to} is used later in the +varlist as an argument to @code{get-buffer-window-list}. + +@ignore +in GNU Emacs 22 + + (let ((oldbuf (current-buffer))) + (save-excursion + (let* ((append-to (get-buffer-create buffer)) + (windows (get-buffer-window-list append-to t t)) + point) + (set-buffer append-to) + (setq point (point)) + (barf-if-buffer-read-only) + (insert-buffer-substring oldbuf start end) + (dolist (window windows) + (when (= (window-point window) point) + (set-window-point window (point)))))))) +@end ignore + +The @code{append-to-buffer} function definition inserts text from the +buffer in which you are currently to a named buffer. It happens that +@code{insert-buffer-substring} copies text from another buffer to the +current buffer, just the reverse---that is why the +@code{append-to-buffer} definition starts out with a @code{let} that +binds the local symbol @code{oldbuf} to the value returned by +@code{current-buffer}. + +@need 1250 +The @code{insert-buffer-substring} expression looks like this: @smallexample (insert-buffer-substring oldbuf start end) @end smallexample @noindent -The @code{insert-buffer-substring} function copies a string @emph{from} -the buffer specified as its first argument and inserts the string into -the present buffer. In this case, the argument to -@code{insert-buffer-substring} is the value of the variable created and -bound by the @code{let}, namely the value of @code{oldbuf}, which was -the current buffer when you gave the @code{append-to-buffer} command. +The @code{insert-buffer-substring} function copies a string +@emph{from} the buffer specified as its first argument and inserts the +string into the present buffer. In this case, the argument to +@code{insert-buffer-substring} is the value of the variable created +and bound by the @code{let}, namely the value of @code{oldbuf}, which +was the current buffer when you gave the @code{append-to-buffer} +command. After @code{insert-buffer-substring} has done its work, -@code{save-excursion} will restore the action to the original buffer and -@code{append-to-buffer} will have done its job. +@code{save-excursion} will restore the action to the original buffer +and @code{append-to-buffer} will have done its job. @need 800 Written in skeletal form, the workings of the body look like this: @@ -5251,16 +5448,15 @@ @var{change-back-to-original-buffer-when-finished} @var{let-the-local-meaning-of-}@code{oldbuf}@var{-disappear-when-finished} - -@end group -@end smallexample - -In summary, @code{append-to-buffer} works as follows: it saves the value -of the current buffer in the variable called @code{oldbuf}. It gets the -new buffer, creating one if need be, and switches Emacs to it. Using -the value of @code{oldbuf}, it inserts the region of text from the old -buffer into the new buffer; and then using @code{save-excursion}, it -brings you back to your original buffer. +@end group +@end smallexample + +In summary, @code{append-to-buffer} works as follows: it saves the +value of the current buffer in the variable called @code{oldbuf}. It +gets the new buffer (creating one if need be) and switches Emacs' +attention to it. Using the value of @code{oldbuf}, it inserts the +region of text from the old buffer into the new buffer; and then using +@code{save-excursion}, it brings you back to your original buffer. In looking at @code{append-to-buffer}, you have explored a fairly complex function. It shows how to use @code{let} and @@ -5351,10 +5547,9 @@ to which the name refers. @menu -* copy-to-buffer:: With @code{set-buffer}, @code{get-buffer-create}. -* insert-buffer:: Read-only, and with @code{or}. -* beginning-of-buffer:: Shows @code{goto-char}, - @code{point-min}, and @code{push-mark}. +* copy-to-buffer:: +* insert-buffer:: +* beginning-of-buffer:: * Second Buffer Related Review:: * optional Exercise:: @end menu @@ -5366,42 +5561,63 @@ After understanding how @code{append-to-buffer} works, it is easy to understand @code{copy-to-buffer}. This function copies text into a -buffer, but instead of adding to the second buffer, it replaces the -previous text in the second buffer. The code for the -@code{copy-to-buffer} function is almost the same as the code for -@code{append-to-buffer}, except that @code{erase-buffer} and a second -@code{save-excursion} are used. (@xref{append-to-buffer, , The -Definition of @code{append-to-buffer}}, for the description of -@code{append-to-buffer}.) - -@need 800 -The body of @code{copy-to-buffer} looks like this +buffer, but instead of adding to the second buffer, it replaces all the +previous text in the second buffer. + +@need 800 +The body of @code{copy-to-buffer} looks like this, @smallexample @group @dots{} -(interactive "BCopy to buffer:@: \nr") - (let ((oldbuf (current-buffer))) +(interactive "BCopy to buffer: \nr") +(let ((oldbuf (current-buffer))) + (with-current-buffer (get-buffer-create buffer) + (barf-if-buffer-read-only) + (erase-buffer) (save-excursion - (set-buffer (get-buffer-create buffer)) - (erase-buffer) - (save-excursion - (insert-buffer-substring oldbuf start end))))) -@end group -@end smallexample - -This code is similar to the code in @code{append-to-buffer}: it is -only after changing to the buffer to which the text will be copied -that the definition for this function diverges from the definition for -@code{append-to-buffer}: the @code{copy-to-buffer} function erases the -buffer's former contents. (This is what is meant by `replacement'; to -replace text, Emacs erases the previous text and then inserts new -text.) After erasing the previous contents of the buffer, -@code{save-excursion} is used for a second time and the new text is -inserted. - -Why is @code{save-excursion} used twice? Consider again what the -function does. + (insert-buffer-substring oldbuf start end))))) +@end group +@end smallexample + +The @code{copy-to-buffer} function has a simpler @code{interactive} +expression than @code{append-to-buffer}. + +@need 800 +The definition then says + +@smallexample +(with-current-buffer (get-buffer-create buffer) @dots{} +@end smallexample + +First, look at the earliest inner expression; that is evaluated first. +That expression starts with @code{get-buffer-create buffer}. The +function tells the computer to use the buffer with the name specified +as the one to which you are copying, or if such a buffer does not +exist, to create it. Then, the @code{with-current-buffer} function +evaluates its body with that buffer temporarily current. + +(This demonstrates another way to shift the computer's attention but +not the user's. The @code{append-to-buffer} function showed how to do +the same with @code{save-excursion} and @code{set-buffer}. +@code{with-current-buffer} is a newer, and arguably easier, +mechanism.) + +The @code{barf-if-buffer-read-only} function sends you an error +message saying the buffer is read-only if you cannot modify it. + +The next line has the @code{erase-buffer} function as its sole +contents. That function erases the buffer. + +Finally, the last two lines contain the @code{save-excursion} +expression with @code{insert-buffer-substring} as its body. +The @code{insert-buffer-substring} expression copies the text from +the buffer you are in (and you have not seen the computer shift its +attention, so you don't know that that buffer is now called +@code{oldbuf}). + +Incidentally, this is what is meant by `replacement'. To replace text, +Emacs erases the previous text and then inserts new text. @need 1250 In outline, the body of @code{copy-to-buffer} looks like this: @@ -5409,27 +5625,14 @@ @smallexample @group (let (@var{bind-}@code{oldbuf}@var{-to-value-of-}@code{current-buffer}) - (save-excursion ; @r{First use of @code{save-excursion}.} - @var{change-buffer} + (@var{with-the-buffer-you-are-copying-to} + (@var{but-do-not-erase-or-copy-to-a-read-only-buffer}) (erase-buffer) - (save-excursion ; @r{Second use of @code{save-excursion}.} + (save-excursion @var{insert-substring-from-}@code{oldbuf}@var{-into-buffer}))) @end group @end smallexample -The first use of @code{save-excursion} returns Emacs to the buffer from -which the text is being copied. That is clear, and is just like its use -in @code{append-to-buffer}. Why the second use? The reason is that -@code{insert-buffer-substring} always leaves point at the @emph{end} of -the region being inserted. The second @code{save-excursion} causes -Emacs to leave point at the beginning of the text being inserted. In -most circumstances, users prefer to find point at the beginning of -inserted text. (Of course, the @code{copy-to-buffer} function returns -the user to the original buffer when done---but if the user @emph{then} -switches to the copied-to buffer, point will go to the beginning of the -text. Thus, this use of a second @code{save-excursion} is a little -nicety.) - @node insert-buffer, beginning-of-buffer, copy-to-buffer, More Complex @comment node-name, next, previous, up @section The Definition of @code{insert-buffer} @@ -5443,17 +5646,21 @@ Here is a discussion based on the original code. The code was simplified in 2003 and is harder to understand. +(@xref{New insert-buffer, , New Body for @code{insert-buffer}}, to see +a discussion of the new body.) + In addition, this code illustrates the use of @code{interactive} with a buffer that might be @dfn{read-only} and the important distinction between the name of an object and the object actually referred to. @menu * insert-buffer code:: -* insert-buffer interactive:: When you can read, but not write. -* insert-buffer body:: The body has an @code{or} and a @code{let}. -* if & or:: Using an @code{if} instead of an @code{or}. -* Insert or:: How the @code{or} expression works. -* Insert let:: Two @code{save-excursion} expressions. +* insert-buffer interactive:: +* insert-buffer body:: +* if & or:: +* Insert or:: +* Insert let:: +* New insert-buffer :: @end menu @node insert-buffer code, insert-buffer interactive, insert-buffer, insert-buffer @@ -5462,7 +5669,7 @@ @end ifnottex @need 800 -Here is the code: +Here is the earlier code: @smallexample @group @@ -5511,8 +5718,8 @@ buffer:@: }. @menu -* Read-only buffer:: When a buffer cannot be modified. -* b for interactive:: An existing buffer or else its name. +* Read-only buffer:: +* b for interactive:: @end menu @node Read-only buffer, b for interactive, insert-buffer interactive, insert-buffer interactive @@ -5546,6 +5753,11 @@ enabled. If the buffer does not exist, you receive a message that says ``No match''; your terminal may beep at you as well. +The new and simplified code generates a list for @code{interactive}. +It uses the @code{barf-if-buffer-read-only} and @code{read-buffer} +functions with which we are already familiar and the @code{progn} +special form with which we are not. (It will be described later.) + @node insert-buffer body, if & or, insert-buffer interactive, insert-buffer @comment node-name, next, previous, up @subsection The Body of the @code{insert-buffer} Function @@ -5644,7 +5856,7 @@ @noindent @code{not} is a function that returns true if its argument is false and false if its argument is true. So if @code{(bufferp buffer)} -returns true, the @code{not} expression returns false and vice-versa: +returns true, the @code{not} expression returns false and vice-verse: what is ``not true'' is false and what is ``not false'' is true. Using this test, the @code{if} expression works as follows: when the @@ -5722,7 +5934,7 @@ (or (holding-on-to-guest) (find-and-take-arm-of-guest)) @end smallexample -@node Insert let, , Insert or, insert-buffer +@node Insert let, New insert-buffer , Insert or, insert-buffer @comment node-name, next, previous, up @subsection The @code{let} Expression in @code{insert-buffer} @@ -5821,6 +6033,45 @@ use @code{or}. All these functions are building blocks that we will find and use again and again. +@node New insert-buffer , , Insert let, insert-buffer +@comment node-name, next, previous, up +@subsection New Body for @code{insert-buffer} +@findex insert-buffer, new version body +@findex new version body for insert-buffer + +The body in the GNU Emacs 22 version is more confusing than the original. + +@need 1250 +It consists of two expressions, + +@smallexample +@group + (push-mark + (save-excursion + (insert-buffer-substring (get-buffer buffer)) + (point))) + + nil +@end group +@end smallexample + +@noindent +except, and this is what confuses novices, very important work is done +inside the @code{push-mark} expression. + +The @code{get-buffer} function returns a buffer with the name +provided. You will note that the function is @emph{not} called +@code{get-buffer-create}; it does not create a buffer if one does not +already exist. The buffer returned by @code{get-buffer}, an existing +buffer, is passed to @code{insert-buffer-substring}, which inserts the +whole of the buffer (since you did not specify anything else). + +The location into which the buffer is inserted is recorded by +@code{push-mark}. Then the function returns @code{nil}, the value of +its last command. Put another way, the @code{insert-buffer} function +exists only to produce a side effect, inserting another buffer, not to +return any value. + @node beginning-of-buffer, Second Buffer Related Review, insert-buffer, More Complex @comment node-name, next, previous, up @section Complete Definition of @code{beginning-of-buffer} @@ -5833,23 +6084,24 @@ As previously described, when invoked without an argument, @code{beginning-of-buffer} moves the cursor to the beginning of the -buffer, leaving the mark at the previous position. However, when the +buffer (in truth, the beginning of the accessible portion of the +buffer), leaving the mark at the previous position. However, when the command is invoked with a number between one and ten, the function considers that number to be a fraction of the length of the buffer, -measured in tenths, and Emacs moves the cursor that fraction of the way -from the beginning of the buffer. Thus, you can either call this +measured in tenths, and Emacs moves the cursor that fraction of the +way from the beginning of the buffer. Thus, you can either call this function with the key command @kbd{M-<}, which will move the cursor to the beginning of the buffer, or with a key command such as @kbd{C-u 7 M-<} which will move the cursor to a point 70% of the way through the -buffer. If a number bigger than ten is used for the argument, it moves -to the end of the buffer. +buffer. If a number bigger than ten is used for the argument, it +moves to the end of the buffer. The @code{beginning-of-buffer} function can be called with or without an argument. The use of the argument is optional. @menu * Optional Arguments:: -* beginning-of-buffer opt arg:: Example with optional argument. +* beginning-of-buffer opt arg:: * beginning-of-buffer complete:: @end menu @@ -5864,12 +6116,12 @@ @cindex Optional arguments @cindex Keyword @findex optional -However, optional arguments are a feature of Lisp: a @dfn{keyword} may -be used to tell the Lisp interpreter that an argument is optional. -The keyword is @code{&optional}. (The @samp{&} in front of +However, optional arguments are a feature of Lisp: a particular +@dfn{keyword} is used to tell the Lisp interpreter that an argument is +optional. The keyword is @code{&optional}. (The @samp{&} in front of @samp{optional} is part of the keyword.) In a function definition, if -an argument follows the keyword @code{&optional}, a value does not -need to be passed to that argument when the function is called. +an argument follows the keyword @code{&optional}, no value need be +passed to that argument when the function is called. @need 1200 The first line of the function definition of @code{beginning-of-buffer} @@ -5887,12 +6139,16 @@ (defun beginning-of-buffer (&optional arg) "@var{documentation}@dots{}" (interactive "P") - (push-mark) + (or (@var{is-the-argument-a-cons-cell} arg) + (and @var{are-both-transient-mark-mode-and-mark-active-true}) + (push-mark)) + (let (@var{determine-size-and-set-it}) (goto-char (@var{if-there-is-an-argument} @var{figure-out-where-to-go} @var{else-go-to} (point-min)))) + @var{do-nicety} @end group @end smallexample @@ -5900,26 +6156,37 @@ function except that the @code{interactive} expression has @code{"P"} as an argument and the @code{goto-char} function is followed by an if-then-else expression that figures out where to put the cursor if -there is an argument. - -The @code{"P"} in the @code{interactive} expression tells Emacs to pass -a prefix argument, if there is one, to the function. A prefix argument -is made by typing the @key{META} key followed by a number, or by typing -@kbd{C-u} and then a number (if you don't type a number, @kbd{C-u} -defaults to 4). - -The true-or-false-test of the @code{if} expression is simple: it is -simply the argument @code{arg}. If @code{arg} has a value that is not -@code{nil}, which will be the case if @code{beginning-of-buffer} is -called with an argument, then this true-or-false-test will return true -and the then-part of the @code{if} expression will be evaluated. On the +there is an argument that is not a cons cell. + +(Since I do not explain a cons cell for many more chapters, please +consider ignoring the function @code{consp}. @xref{List +Implementation, , How Lists are Implemented}, and @ref{Cons Cell Type, +, Cons Cell and List Types, elisp, The GNU Emacs Lisp Reference +Manual}.) + +The @code{"P"} in the @code{interactive} expression tells Emacs to +pass a prefix argument, if there is one, to the function in raw form. +A prefix argument is made by typing the @key{META} key followed by a +number, or by typing @kbd{C-u} and then a number. (If you don't type +a number, @kbd{C-u} defaults to a cons cell with a 4. A lowercase +@code{"p"} in the @code{interactive} expression causes the function to +convert a prefix arg to a number.) + +The true-or-false-test of the @code{if} expression looks complex, but +it is not: it checks whether @code{arg} has a value that is not +@code{nil} and whether it is a cons cell. (That is what @code{consp} +does; it checks whether its argument is a cons cell.) If @code{arg} +has a value that is not @code{nil} (and is not a cons cell), which +will be the case if @code{beginning-of-buffer} is called with a +numeric argument, then this true-or-false-test will return true and +the then-part of the @code{if} expression will be evaluated. On the other hand, if @code{beginning-of-buffer} is not called with an argument, the value of @code{arg} will be @code{nil} and the else-part -of the @code{if} expression will be evaluated. The else-part is simply -@code{point-min}, and when this is the outcome, the whole -@code{goto-char} expression is @code{(goto-char (point-min))}, which is -how we saw the @code{beginning-of-buffer} function in its simplified -form. +of the @code{if} expression will be evaluated. The else-part is +simply @code{point-min}, and when this is the outcome, the whole +@code{goto-char} expression is @code{(goto-char (point-min))}, which +is how we saw the @code{beginning-of-buffer} function in its +simplified form. @node beginning-of-buffer opt arg, beginning-of-buffer complete, Optional Arguments, beginning-of-buffer @subsection @code{beginning-of-buffer} with an Argument @@ -5934,11 +6201,12 @@ @group (if (> (buffer-size) 10000) ;; @r{Avoid overflow for large buffer sizes!} - (* (prefix-numeric-value arg) (/ (buffer-size) 10)) + (* (prefix-numeric-value arg) + (/ size 10)) (/ (+ 10 (* - (buffer-size) (prefix-numeric-value arg))) 10)) + size (prefix-numeric-value arg))) 10))) @end group @end smallexample @@ -5984,13 +6252,21 @@ In @code{beginning-of-buffer}, the inner @code{if} expression tests whether the size of the buffer is greater than 10,000 characters. To do -this, it uses the @code{>} function and the @code{buffer-size} function. +this, it uses the @code{>} function and the computation of @code{size} +that comes from the let expression. + +In the old days, the function @code{buffer-size} was used. Not only +was that function called several times, it gave the size of the whole +buffer, not the accessible part. The computation makes much more +sense when it handles just the accessible part. (@xref{Narrowing & +Widening, , Narrowing and Widening}, for more information on focusing +attention to an `accessible' part.) @need 800 The line looks like this: @smallexample -(if (> (buffer-size) 10000) +(if (> size 10000) @end smallexample @need 1200 @@ -6002,7 +6278,7 @@ @group (* (prefix-numeric-value arg) - (/ (buffer-size) 10)) + (/ size 10)) @end group @end smallexample @@ -6019,11 +6295,12 @@ @findex / @r{(division)} @cindex Division -The second argument is @code{(/ (buffer-size) 10)}. This expression -divides the numeric value of the buffer by ten. This produces a number -that tells how many characters make up one tenth of the buffer size. -(In Lisp, @code{/} is used for division, just as @code{*} is -used for multiplication.) +The second argument is @code{(/ size 10)}. This expression divides +the numeric value by ten --- the numeric value of the size of the +accessible portion of the buffer. This produces a number that tells +how many characters make up one tenth of the buffer size. (In Lisp, +@code{/} is used for division, just as @code{*} is used for +multiplication.) @need 1200 In the multiplication expression as a whole, this amount is multiplied @@ -6032,23 +6309,22 @@ @smallexample @group (* @var{numeric-value-of-prefix-arg} - @var{number-of-characters-in-one-tenth-of-the-buffer}) + @var{number-of-characters-in-one-tenth-of-the-accessible-buffer}) @end group @end smallexample @noindent If, for example, the prefix argument is @samp{7}, the one-tenth value -will be multiplied by 7 to give a position 70% of the way through the -buffer. - -@need 1200 -The result of all this is that if the buffer is large, the -@code{goto-char} expression reads like this: +will be multiplied by 7 to give a position 70% of the way through. + +@need 1200 +The result of all this is that if the accessible portion of the buffer +is large, the @code{goto-char} expression reads like this: @smallexample @group (goto-char (* (prefix-numeric-value arg) - (/ (buffer-size) 10))) + (/ size 10))) @end group @end smallexample @@ -6069,7 +6345,7 @@ @c Keep this on one line. @smallexample -(/ (+ 10 (* (buffer-size) (prefix-numeric-value arg))) 10)) +(/ (+ 10 (* size (prefix-numeric-value arg))) 10)) @end smallexample @need 1200 @@ -6084,7 +6360,7 @@ (/ (+ 10 (* - (buffer-size) + size (prefix-numeric-value arg))) 10)) @end group @@ -6093,12 +6369,12 @@ @need 1200 @noindent Looking at parentheses, we see that the innermost operation is -@code{(prefix-numeric-value arg)}, which converts the raw argument to a -number. This number is multiplied by the buffer size in the following -expression: - -@smallexample -(* (buffer-size) (prefix-numeric-value arg)) +@code{(prefix-numeric-value arg)}, which converts the raw argument to +a number. In the following expression, this number is multiplied by +the size of the accessible portion of the buffer: + +@smallexample +(* size (prefix-numeric-value arg)) @end smallexample @noindent @@ -6120,6 +6396,47 @@ Here is the complete text of the @code{beginning-of-buffer} function: @sp 1 +@c In GNU Emacs 22 +@smallexample +@group +(defun beginning-of-buffer (&optional arg) + "Move point to the beginning of the buffer; +leave mark at previous position. +With \\[universal-argument] prefix, +do not set mark at previous position. +With numeric arg N, +put point N/10 of the way from the beginning. + +If the buffer is narrowed, +this command uses the beginning and size +of the accessible part of the buffer. +@end group + +@group +Don't use this command in Lisp programs! +\(goto-char (point-min)) is faster +and avoids clobbering the mark." + (interactive "P") + (or (consp arg) + (and transient-mark-mode mark-active) + (push-mark)) +@end group +@group + (let ((size (- (point-max) (point-min)))) + (goto-char (if (and arg (not (consp arg))) + (+ (point-min) + (if (> size 10000) + ;; Avoid overflow for large buffer sizes! + (* (prefix-numeric-value arg) + (/ size 10)) + (/ (+ 10 (* size (prefix-numeric-value arg))) 10))) + (point-min)))) + (if arg (forward-line 1))) +@end group +@end smallexample + +@ignore +From before GNU Emacs 22 @smallexample @group (defun beginning-of-buffer (&optional arg) @@ -6151,6 +6468,7 @@ (if arg (forward-line 1))) @end group @end smallexample +@end ignore @noindent Except for two small points, the previous discussion shows how this @@ -6162,18 +6480,21 @@ In the documentation string, there is reference to an expression: @smallexample -\(goto-char (point-min)) -@end smallexample - -@noindent -A @samp{\} is used before the first parenthesis of this expression. -This @samp{\} tells the Lisp interpreter that the expression should be -printed as shown in the documentation rather than evaluated as a -symbolic expression, which is what it looks like. - -@need 1200 -Finally, the last line of the @code{beginning-of-buffer} command says to -move point to the beginning of the next line if the command is +\\[universal-argument] +@end smallexample + +@noindent +A @samp{\\} is used before the first square bracket of this +expression. This @samp{\\} tells the Lisp interpreter to substitute +whatever key is currently bound to the @samp{[@dots{}]}. In the case +of @code{universal-argument}, that is usually @kbd{C-u}, but it might +be different. (@xref{Documentation Tips, , Tips for Documentation +Strings, elisp, The GNU Emacs Lisp Reference Manual}, for more +information.) + +@need 1200 +Finally, the last line of the @code{beginning-of-buffer} command says +to move point to the beginning of the next line if the command is invoked with an argument: @smallexample @@ -6185,8 +6506,15 @@ appropriate tenths position in the buffer. This is a flourish that means that the cursor is always located @emph{at least} the requested tenths of the way through the buffer, which is a nicety that is, -perhaps, not necessary, but which, if it did not occur, would be sure to -draw complaints. +perhaps, not necessary, but which, if it did not occur, would be sure +to draw complaints. + +On the other hand, it also means that if you specify the command with +a @kbd{C-u}, but without a number, that is to say, if the `raw prefix +argument' is simply a cons cell, then the command puts you at the +beginning of the second line @dots{} I don't know whether this is +intended or whether no one has dealt with the code to avoid this +happening. @node Second Buffer Related Review, optional Exercise, beginning-of-buffer, More Complex @comment node-name, next, previous, up @@ -6200,7 +6528,7 @@ argument that is not @code{nil}; if none return a value that is not @code{nil}, return @code{nil}. In brief, return the first true value of the arguments; return a true value if one @emph{or} any of the -other are true. +others are true. @item and Evaluate each argument in sequence, and if any are @code{nil}, return @@ -6254,9 +6582,9 @@ novices. @menu -* Narrowing advantages:: The advantages of narrowing -* save-restriction:: The @code{save-restriction} special form. -* what-line:: The number of the line that point is on. +* Narrowing advantages:: +* save-restriction:: +* what-line:: * narrow Exercise:: @end menu @@ -6359,6 +6687,60 @@ @end group @end smallexample +@ignore +Emacs 22 +/usr/local/src/emacs/lisp/simple.el + +(defun what-line () + "Print the current buffer line number and narrowed line number of point." + (interactive) + (let ((start (point-min)) + (n (line-number-at-pos))) + (if (= start 1) + (message "Line %d" n) + (save-excursion + (save-restriction + (widen) + (message "line %d (narrowed line %d)" + (+ n (line-number-at-pos start) -1) n)))))) + +(defun line-number-at-pos (&optional pos) + "Return (narrowed) buffer line number at position POS. +If POS is nil, use current buffer location. +Counting starts at (point-min), so the value refers +to the contents of the accessible portion of the buffer." + (let ((opoint (or pos (point))) start) + (save-excursion + (goto-char (point-min)) + (setq start (point)) + (goto-char opoint) + (forward-line 0) + (1+ (count-lines start (point)))))) + +(defun count-lines (start end) + "Return number of lines between START and END. +This is usually the number of newlines between them, +but can be one more if START is not equal to END +and the greater of them is not at the start of a line." + (save-excursion + (save-restriction + (narrow-to-region start end) + (goto-char (point-min)) + (if (eq selective-display t) + (save-match-data + (let ((done 0)) + (while (re-search-forward "[\n\C-m]" nil t 40) + (setq done (+ 40 done))) + (while (re-search-forward "[\n\C-m]" nil t 1) + (setq done (+ 1 done))) + (goto-char (point-max)) + (if (and (/= start end) + (not (bolp))) + (1+ done) + done))) + (- (buffer-size) (forward-line (buffer-size))))))) +@end ignore + @node what-line, narrow Exercise, save-restriction, Narrowing & Widening @comment node-name, next, previous, up @section @code{what-line} @@ -6389,13 +6771,17 @@ well as your line number in a widened buffer. The recent version is more complex than the version shown here. If you feel adventurous, you might want to look at it after figuring out how this version -works. The newer version uses a conditional to determine whether the -buffer has been narrowed, and rather than use @code{beginning-of-line} -to move point to the beginning of the current line, if need be, the -function uses @code{(forward-line 0)}.) - -The function as shown here has a documentation line and is -interactive, as you would expect. The next two lines use the +works. You will probably need to use @kbd{C-h f} +(@code{describe-function}). The newer version uses a conditional to +determine whether the buffer has been narrowed. + +(Also, it uses @code{line-number-at-pos}, which among other simple +expressions, such as @code{(goto-char (point-min))}, moves point to +the beginning of the current line with @code{(forward-line 0)} rather +than @code{beginning-of-line}.) + +The @code{what-line} function as shown here has a documentation line +and is interactive, as you would expect. The next two lines use the functions @code{save-restriction} and @code{widen}. The @code{save-restriction} special form notes whatever narrowing is in @@ -6434,15 +6820,14 @@ @end group @end smallexample -The @code{message} function prints a one-line message at the bottom of the -Emacs screen. The first argument is inside of quotation marks and is -printed as a string of characters. However, it may contain @samp{%d}, -@samp{%s}, or @samp{%c} to print arguments that follow the string. -@samp{%d} prints the argument as a decimal, so the message will say -something such as @samp{Line 243}. - -@need 1200 - +The @code{message} function prints a one-line message at the bottom of +the Emacs screen. The first argument is inside of quotation marks and +is printed as a string of characters. However, it may contain a +@samp{%d} expression to print a following argument. @samp{%d} prints +the argument as a decimal, so the message will say something such as +@samp{Line 243}. + +@need 1200 The number that is printed in place of the @samp{%d} is computed by the last line of the function: @@ -6450,6 +6835,33 @@ (1+ (count-lines 1 (point))) @end smallexample +@ignore +GNU Emacs 22 + +(defun count-lines (start end) + "Return number of lines between START and END. +This is usually the number of newlines between them, +but can be one more if START is not equal to END +and the greater of them is not at the start of a line." + (save-excursion + (save-restriction + (narrow-to-region start end) + (goto-char (point-min)) + (if (eq selective-display t) + (save-match-data + (let ((done 0)) + (while (re-search-forward "[\n\C-m]" nil t 40) + (setq done (+ 40 done))) + (while (re-search-forward "[\n\C-m]" nil t 1) + (setq done (+ 1 done))) + (goto-char (point-max)) + (if (and (/= start end) + (not (bolp))) + (1+ done) + done))) + (- (buffer-size) (forward-line (buffer-size))))))) +@end ignore + @noindent What this does is count the lines from the first position of the buffer, indicated by the @code{1}, up to @code{(point)}, and then add @@ -6477,12 +6889,14 @@ @cindex Properties, mention of @code{buffer-substring-no-properties} (@code{buffer-substring} is a previously unmentioned function you will have to investigate yourself; or perhaps you will have to use -@code{buffer-substring-no-properties} @dots{}, yet another function -and one that introduces text properties, a feature otherwise not -discussed here. @xref{Text Properties, , Text Properties, elisp, The -GNU Emacs Lisp Reference Manual}. Additionally, do you really need -@code{goto-char} or @code{point-min}? Or can you write the function -without them?) +@code{buffer-substring-no-properties} or +@code{filter-buffer-substring} @dots{}, yet other functions. Text +properties are a feature otherwise not discussed here. @xref{Text +Properties, , Text Properties, elisp, The GNU Emacs Lisp Reference +Manual}.) + +Additionally, do you really need @code{goto-char} or @code{point-min}? +Or can you write the function without them? @node car cdr & cons, Cutting & Storing Text, Narrowing & Widening, Top @comment node-name, next, previous, up @@ -6499,13 +6913,13 @@ namely, @code{setcdr} and @code{nthcdr}. (@xref{copy-region-as-kill}.) @menu -* Strange Names:: An historical aside: why the strange names? -* car & cdr:: Functions for extracting part of a list. -* cons:: Constructing a list. -* nthcdr:: Calling @code{cdr} repeatedly. +* Strange Names:: +* car & cdr:: +* cons:: +* nthcdr:: * nth:: -* setcar:: Changing the first element of a list. -* setcdr:: Changing the rest of a list. +* setcar:: +* setcdr:: * cons Exercise:: @end menu @@ -6687,7 +7101,7 @@ @menu * Build a list:: -* length:: How to find the length of a list. +* length:: @end menu @node Build a list, length, cons, cons @@ -6798,7 +7212,7 @@ What you see, if you evaluate this, is the error message @smallexample -Wrong number of arguments: #<subr length>, 0 +Lisp error: (wrong-number-of-arguments length 0) @end smallexample @noindent @@ -6808,13 +7222,20 @@ length the function is measuring. (Note that @emph{one} list is @emph{one} argument, even if the list has many elements inside it.) -The part of the error message that says @samp{#<subr length>} is the -name of the function. This is written with a special notation, -@samp{#<subr}, that indicates that the function @code{length} is one -of the primitive functions written in C rather than in Emacs Lisp. -(@samp{subr} is an abbreviation for `subroutine'.) @xref{What Is a -Function, , What Is a Function?, elisp , The GNU Emacs Lisp Reference -Manual}, for more about subroutines. +The part of the error message that says @samp{length} is the name of +the function. + +@ignore +@code{length} is still a subroutine, but you need C-h f to discover that. + +In an earlier version: + This is written with a special notation, @samp{#<subr}, + that indicates that the function @code{length} is one of the primitive + functions written in C rather than in Emacs Lisp. (@samp{subr} is an + abbreviation for `subroutine'.) @xref{What Is a Function, , What Is a + Function?, elisp , The GNU Emacs Lisp Reference Manual}, for more + about subroutines. +@end ignore @node nthcdr, nth, cons, car cdr & cons @comment node-name, next, previous, up @@ -7016,9 +7437,14 @@ @noindent If you are reading this in Info inside of GNU Emacs, you can evaluate this expression in the usual fashion, by positioning the cursor after -the expression and typing @kbd{C-x C-e}. (I'm doing this right here as -I write this. This is one of the advantages of having the interpreter -built into the computing environment.) +the expression and typing @kbd{C-x C-e}. (I'm doing this right here +as I write this. This is one of the advantages of having the +interpreter built into the computing environment. Incidentally, when +there is nothing on the line after the final parentheses, such as a +comment, point can be on the next line. Thus, if your cursor is in +the first column of the next line, you do not need to move it. +Indeed, Emacs permits any amount of white space after the final +parenthesis.) @need 1200 When we evaluate the variable @code{animals}, we see that it is bound to @@ -7156,12 +7582,12 @@ sources with `clip' and all occurrences of `killed' with `clipped'.) @menu -* Storing Text:: Text is stored in a list. -* zap-to-char:: Cutting out text up to a character. -* kill-region:: Cutting text out of a region. -* Digression into C:: Minor note on C programming language macros. -* defvar:: How to give a variable an initial value. -* copy-region-as-kill:: A definition for copying text. +* Storing Text:: +* zap-to-char:: +* kill-region:: +* copy-region-as-kill:: +* Digression into C:: +* defvar:: * cons & search-fwd Review:: * search Exercises:: @end menu @@ -7181,9 +7607,9 @@ @need 1200 @noindent -The function @code{cons} can be used to to create a new list from a -piece of text (an `atom', to use the jargon) and an existing list, -like this: +The function @code{cons} can be used to create a new list from a piece +of text (an `atom', to use the jargon) and an existing list, like +this: @smallexample @group @@ -7238,27 +7664,27 @@ @section @code{zap-to-char} @findex zap-to-char -The @code{zap-to-char} function barely changed between GNU Emacs -version 19 and GNU Emacs version 21. However, @code{zap-to-char} -calls another function, @code{kill-region}, which enjoyed a major rewrite -on the way to version 21. +The @code{zap-to-char} function changed little between GNU Emacs +version 19 and GNU Emacs version 22. However, @code{zap-to-char} +calls another function, @code{kill-region}, which enjoyed a major +rewrite. The @code{kill-region} function in Emacs 19 is complex, but does not use code that is important at this time. We will skip it. -The @code{kill-region} function in Emacs 21 is easier to read than the +The @code{kill-region} function in Emacs 22 is easier to read than the same function in Emacs 19 and introduces a very important concept, that of error handling. We will walk through the function. But first, let us look at the interactive @code{zap-to-char} function. @menu -* Complete zap-to-char:: The complete implementation. -* zap-to-char interactive:: A three part interactive expression. -* zap-to-char body:: A short overview. -* search-forward:: How to search for a string. -* progn:: The @code{progn} special form. -* Summing up zap-to-char:: Using @code{point} and @code{search-forward}. +* Complete zap-to-char:: +* zap-to-char interactive:: +* zap-to-char body:: +* search-forward:: +* progn:: +* Summing up zap-to-char:: @end menu @node Complete zap-to-char, zap-to-char interactive, zap-to-char, zap-to-char @@ -7266,18 +7692,16 @@ @unnumberedsubsec The Complete @code{zap-to-char} Implementation @end ifnottex -The GNU Emacs version 19 and version 21 implementations of the -@code{zap-to-char} function are nearly identical in form, and they -work alike. The function removes the text in the region between the -location of the cursor (i.e., of point) up to and including the next -occurrence of a specified character. The text that @code{zap-to-char} -removes is put in the kill ring; and it can be retrieved from the kill -ring by typing @kbd{C-y} (@code{yank}). If the command is given an -argument, it removes text through that number of occurrences. Thus, -if the cursor were at the beginning of this sentence and the character -were @samp{s}, @samp{Thus} would be removed. If the argument were -two, @samp{Thus, if the curs} would be removed, up to and including -the @samp{s} in @samp{cursor}. +The @code{zap-to-char} function removes the text in the region between +the location of the cursor (i.e., of point) up to and including the +next occurrence of a specified character. The text that +@code{zap-to-char} removes is put in the kill ring; and it can be +retrieved from the kill ring by typing @kbd{C-y} (@code{yank}). If +the command is given an argument, it removes text through that number +of occurrences. Thus, if the cursor were at the beginning of this +sentence and the character were @samp{s}, @samp{Thus} would be +removed. If the argument were two, @samp{Thus, if the curs} would be +removed, up to and including the @samp{s} in @samp{cursor}. If the specified character is not found, @code{zap-to-char} will say ``Search failed'', tell you the character you typed, and not remove @@ -7288,12 +7712,8 @@ manipulates text, and we will focus attention on them as well as on the deletion command. -@need 800 -Here is the complete text of the version 19 implementation of the function: - -@c v 19 -@smallexample -@group +@ignore +@c GNU Emacs version 19 (defun zap-to-char (arg char) ; version 19 implementation "Kill up to and including ARG'th occurrence of CHAR. Goes backward if ARG is negative; error if CHAR not found." @@ -7303,8 +7723,29 @@ (search-forward (char-to-string char) nil nil arg) (point)))) -@end group -@end smallexample +@end ignore + +@need 1250 +Here is the complete text of the version 22 implementation of the function: + +@c GNU Emacs 22 +@smallexample +@group +(defun zap-to-char (arg char) + "Kill up to and including ARG'th occurrence of CHAR. +Case is ignored if `case-fold-search' is non-nil in the current buffer. +Goes backward if ARG is negative; error if CHAR not found." + (interactive "p\ncZap to char: ") + (if (char-table-p translation-table-for-input) + (setq char (or (aref translation-table-for-input char) char))) + (kill-region (point) (progn + (search-forward (char-to-string char) nil nil arg) + (point)))) +@end group +@end smallexample + +The documentation is thorough. You do need to know the jargon meaning +of the word `kill'. @node zap-to-char interactive, zap-to-char body, Complete zap-to-char, zap-to-char @comment node-name, next, previous, up @@ -7315,44 +7756,11 @@ this: @smallexample -(interactive "*p\ncZap to char: ") -@end smallexample - -The part within quotation marks, @code{"*p\ncZap to char:@: "}, specifies -three different things. First, and most simply, the asterisk, @samp{*}, -causes an error to be signaled if the buffer is read-only. This means that -if you try @code{zap-to-char} in a read-only buffer you will not be able to -remove text, and you will receive a message that says ``Buffer is -read-only''; your terminal may beep at you as well. - -The version 21 implementation does not have the asterisk, @samp{*}. The -function works the same as in version 19: in both cases, it cannot -remove text from a read-only buffer but the function does copy the -text that would have been removed to the kill ring. Also, in both -cases, you see an error message. - -However, the version 19 implementation copies text from a read-only -buffer only because of a mistake in the implementation of -@code{interactive}. According to the documentation for -@code{interactive}, the asterisk, @samp{*}, should prevent the -@code{zap-to-char} function from doing anything at all when the buffer -is read only. In version 19, the function should not copy the text to -the kill ring. It is a bug that it does. - -In version 21, the function is designed to copy the text to the kill -ring; moreover, @code{interactive} is implemented correctly. So the -asterisk, @samp{*}, had to be removed from the interactive -specification. However, if you insert an @samp{*} yourself and -evaluate the function definition, then the next time you run the -@code{zap-to-char} function on a read-only buffer, you will not copy -any text. - -That change aside, and a change to the documentation, the two versions -of the @code{zap-to-char} function are identical. - -Let us continue with the interactive specification. - -The second part of @code{"*p\ncZap to char:@: "} is the @samp{p}. +(interactive "p\ncZap to char: ") +@end smallexample + +The part within quotation marks, @code{"p\ncZap to char:@: "}, specifies +two different things. First, and most simply, is the @samp{p}. This part is separated from the next part by a newline, @samp{\n}. The @samp{p} means that the first argument to the function will be passed the value of a `processed prefix'. The prefix argument is @@ -7360,15 +7768,21 @@ the function is called interactively without a prefix, 1 is passed to this argument. -The third part of @code{"*p\ncZap to char:@: "} is @samp{cZap to char:@: -}. In this part, the lower case @samp{c} indicates that -@code{interactive} expects a prompt and that the argument will be a -character. The prompt follows the @samp{c} and is the string @samp{Zap -to char:@: } (with a space after the colon to make it look good). +The second part of @code{"p\ncZap to char:@: "} is +@samp{cZap to char:@: }. In this part, the lower case @samp{c} +indicates that @code{interactive} expects a prompt and that the +argument will be a character. The prompt follows the @samp{c} and is +the string @samp{Zap to char:@: } (with a space after the colon to +make it look good). What all this does is prepare the arguments to @code{zap-to-char} so they are of the right type, and give the user a prompt. +In a read-only buffer, the @code{zap-to-char} function copies the text +to the kill ring, but does not remove it. The echo area displays a +message saying that the buffer is read-only. Also, the terminal may +beep or blink at you. + @node zap-to-char body, search-forward, zap-to-char interactive, zap-to-char @comment node-name, next, previous, up @subsection The Body of @code{zap-to-char} @@ -7376,11 +7790,26 @@ The body of the @code{zap-to-char} function contains the code that kills (that is, removes) the text in the region from the current position of the cursor up to and including the specified character. + The first part of the code looks like this: @smallexample -(kill-region (point) @dots{} -@end smallexample +(if (char-table-p translation-table-for-input) + (setq char (or (aref translation-table-for-input char) char))) +(kill-region (point) (progn + (search-forward (char-to-string char) nil nil arg) + (point))) +@end smallexample + +@noindent +@code{char-table-p} is an hitherto unseen function. It determines +whether its argument is a character table. When it is, it sets the +character passed to @code{zap-to-char} to one of them, if that +character exists, or to the character itself. (This becomes important +for certain characters in non-European languages. The @code{aref} +function extracts an element from an array. It is an array-specific +function that is not described in this document. @xref{Arrays, , +Arrays, elisp, The GNU Emacs Lisp Reference Manual}.) @noindent @code{(point)} is the current position of the cursor. @@ -7402,10 +7831,12 @@ zapped-for-character in @code{zap-to-char}. If the search is successful, @code{search-forward} leaves point immediately after the last character in the target string. (In @code{zap-to-char}, the -target string is just one character long.) If the search is -backwards, @code{search-forward} leaves point just before the first -character in the target. Also, @code{search-forward} returns @code{t} -for true. (Moving point is therefore a `side effect'.) +target string is just one character long. @code{zap-to-char} uses the +function @code{char-to-string} to ensure that the computer treats that +character as a string.) If the search is backwards, +@code{search-forward} leaves point just before the first character in +the target. Also, @code{search-forward} returns @code{t} for true. +(Moving point is therefore a `side effect'.) @need 1250 In @code{zap-to-char}, the @code{search-forward} function looks like this: @@ -7501,9 +7932,12 @@ The second and last argument to @code{progn} is the expression @code{(point)}. This expression returns the value of point, which in this case will be the location to which it has been moved by -@code{search-forward}. This value is returned by the @code{progn} -expression and is passed to @code{kill-region} as @code{kill-region}'s -second argument. +@code{search-forward}. (In the source, a line that tells the function +to go to the previous character, if it is going forward, was commented +out in 1999; I don't remember whether that feature or mis-feature was +ever a part of the distributed source.) The value of @code{point} is +returned by the @code{progn} expression and is passed to +@code{kill-region} as @code{kill-region}'s second argument. @node Summing up zap-to-char, , progn, zap-to-char @comment node-name, next, previous, up @@ -7520,14 +7954,14 @@ these two values of point, the first one as the beginning of the region and the second one as the end of the region, and removes the region. -The @code{progn} special form is necessary because the @code{kill-region} -command takes two arguments; and it would fail if @code{search-forward} -and @code{point} expressions were written in sequence as two -additional arguments. The @code{progn} expression is a single argument -to @code{kill-region} and returns the one value that @code{kill-region} -needs for its second argument. - -@node kill-region, Digression into C, zap-to-char, Cutting & Storing Text +The @code{progn} special form is necessary because the +@code{kill-region} command takes two arguments; and it would fail if +@code{search-forward} and @code{point} expressions were written in +sequence as two additional arguments. The @code{progn} expression is +a single argument to @code{kill-region} and returns the one value that +@code{kill-region} needs for its second argument. + +@node kill-region, copy-region-as-kill, zap-to-char, Cutting & Storing Text @comment node-name, next, previous, up @section @code{kill-region} @findex kill-region @@ -7536,7 +7970,67 @@ This function clips text from a region and copies that text to the kill ring, from which it may be retrieved. -The Emacs 21 version of that function uses @code{condition-case} and +@ignore +GNU Emacs 22: + +(defun kill-region (beg end &optional yank-handler) + "Kill (\"cut\") text between point and mark. +This deletes the text from the buffer and saves it in the kill ring. +The command \\[yank] can retrieve it from there. +\(If you want to kill and then yank immediately, use \\[kill-ring-save].) + +If you want to append the killed region to the last killed text, +use \\[append-next-kill] before \\[kill-region]. + +If the buffer is read-only, Emacs will beep and refrain from deleting +the text, but put the text in the kill ring anyway. This means that +you can use the killing commands to copy text from a read-only buffer. + +This is the primitive for programs to kill text (as opposed to deleting it). +Supply two arguments, character positions indicating the stretch of text + to be killed. +Any command that calls this function is a \"kill command\". +If the previous command was also a kill command, +the text killed this time appends to the text killed last time +to make one entry in the kill ring. + +In Lisp code, optional third arg YANK-HANDLER, if non-nil, +specifies the yank-handler text property to be set on the killed +text. See `insert-for-yank'." + ;; Pass point first, then mark, because the order matters + ;; when calling kill-append. + (interactive (list (point) (mark))) + (unless (and beg end) + (error "The mark is not set now, so there is no region")) + (condition-case nil + (let ((string (filter-buffer-substring beg end t))) + (when string ;STRING is nil if BEG = END + ;; Add that string to the kill ring, one way or another. + (if (eq last-command 'kill-region) + (kill-append string (< end beg) yank-handler) + (kill-new string nil yank-handler))) + (when (or string (eq last-command 'kill-region)) + (setq this-command 'kill-region)) + nil) + ((buffer-read-only text-read-only) + ;; The code above failed because the buffer, or some of the characters + ;; in the region, are read-only. + ;; We should beep, in case the user just isn't aware of this. + ;; However, there's no harm in putting + ;; the region's text in the kill ring, anyway. + (copy-region-as-kill beg end) + ;; Set this-command now, so it will be set even if we get an error. + (setq this-command 'kill-region) + ;; This should barf, if appropriate, and give us the correct error. + (if kill-read-only-ok + (progn (message "Read only text copied to kill ring") nil) + ;; Signal an error if the buffer is read-only. + (barf-if-buffer-read-only) + ;; If the buffer isn't read-only, the text is. + (signal 'text-read-only (list (current-buffer))))))) +@end ignore + +The Emacs 22 version of that function uses @code{condition-case} and @code{copy-region-as-kill}, both of which we will explain. @code{condition-case} is an important special form. @@ -7547,9 +8041,9 @@ contains the code that is called in the event of an error. @menu -* Complete kill-region:: The function definition. -* condition-case:: Dealing with a problem. -* delete-and-extract-region:: Doing the work. +* Complete kill-region:: +* condition-case:: +* Lisp macro:: @end menu @node Complete kill-region, condition-case, kill-region, kill-region @@ -7559,10 +8053,116 @@ @need 1200 We will go through the @code{condition-case} code in a moment. First, -let us look at the original definition of @code{kill-region}, with -comments added (the newer definition has an optional third argument -and is more complex): - +let us look at the definition of @code{kill-region}, with comments +added: + +@c GNU Emacs 22: +@smallexample +@group +(defun kill-region (beg end) + "Kill (\"cut\") text between point and mark. +This deletes the text from the buffer and saves it in the kill ring. +The command \\[yank] can retrieve it from there. @dots{} " +@end group + +@group + ;; @bullet{} Since order matters, pass point first. + (interactive (list (point) (mark))) + ;; @bullet{} And tell us if we cannot cut the text. + ;; `unless' is an `if' without a then-part. + (unless (and beg end) + (error "The mark is not set now, so there is no region")) +@end group + +@group + ;; @bullet{} `condition-case' takes three arguments. + ;; If the first argument is nil, as it is here, + ;; information about the error signal is not + ;; stored for use by another function. + (condition-case nil +@end group + +@group + ;; @bullet{} The second argument to `condition-case' tells the + ;; Lisp interpreter what to do when all goes well. +@end group + +@group + ;; It starts with a `let' function that extracts the string + ;; and tests whether it exists. If so (that is what the + ;; `when' checks), it calls an `if' function that determines + ;; whether the previous command was another call to + ;; `kill-region'; if it was, then the new text is appended to + ;; the previous text; if not, then a different function, + ;; `kill-new', is called. +@end group + +@group + ;; The `kill-append' function concatenates the new string and + ;; the old. The `kill-new' function inserts text into a new + ;; item in the kill ring. +@end group + +@group + ;; `when' is an `if' without an else-part. The second `when' + ;; again checks whether the current string exists; in + ;; addition, it checks whether the previous command was + ;; another call to `kill-region'. If one or the other + ;; condition is true, then it sets the current command to + ;; be `kill-region'. +@end group +@group + (let ((string (filter-buffer-substring beg end t))) + (when string ;STRING is nil if BEG = END + ;; Add that string to the kill ring, one way or another. + (if (eq last-command 'kill-region) +@end group +@group + ;; @minus{} `yank-handler' is an optional argument to + ;; `kill-region' that tells the `kill-append' and + ;; `kill-new' functions how deal with properties + ;; added to the text, such as `bold' or `italics'. + (kill-append string (< end beg) yank-handler) + (kill-new string nil yank-handler))) + (when (or string (eq last-command 'kill-region)) + (setq this-command 'kill-region)) + nil) +@end group + +@group + ;; @bullet{} The third argument to `condition-case' tells the interpreter + ;; what to do with an error. +@end group +@group + ;; The third argument has a conditions part and a body part. + ;; If the conditions are met (in this case, + ;; if text or buffer are read-only) + ;; then the body is executed. +@end group +@group + ;; The first part of the third argument is the following: + ((buffer-read-only text-read-only) ;; the if-part + ;; @dots{} the then-part + (copy-region-as-kill beg end) +@end group +@group + ;; Next, also as part of the then-part, set this-command, so + ;; it will be set in an error + (setq this-command 'kill-region) + ;; Finally, in the then-part, send a message if you may copy + ;; the text to the kill ring without signally an error, but + ;; don't if you may not. +@end group +@group + (if kill-read-only-ok + (progn (message "Read only text copied to kill ring") nil) + (barf-if-buffer-read-only) + ;; If the buffer isn't read-only, the text is. + (signal 'text-read-only (list (current-buffer))))) +@end group +@end smallexample + +@ignore @c v 21 @smallexample @group @@ -7615,7 +8215,7 @@ @group ;; The third argument has a conditions part and a body part. ;; If the conditions are met (in this case, - ;; if text or buffer is read-only) + ;; if text or buffer are read-only) ;; then the body is executed. @end group @group @@ -7632,8 +8232,9 @@ (signal 'text-read-only (list (current-buffer))))))) @end group @end smallexample - -@node condition-case, delete-and-extract-region, Complete kill-region, kill-region +@end ignore + +@node condition-case, Lisp macro, Complete kill-region, kill-region @comment node-name, next, previous, up @subsection @code{condition-case} @findex condition-case @@ -7707,87 +8308,75 @@ @end group @end smallexample -@node delete-and-extract-region, , condition-case, kill-region -@comment node-name, next, previous, up -@subsection @code{delete-and-extract-region} -@findex delete-and-extract-region - -A @code{condition-case} expression has two parts, a part that is -evaluated in the expectation that all will go well, but which may -generate an error; and a part that is evaluated when there is an -error. - -First, let us look at the code in @code{kill-region} that is run in -the expectation that all goes well. This is the core of the function. -The code looks like this: - -@smallexample -@group -(let ((string (delete-and-extract-region beg end))) - (when string - (if (eq last-command 'kill-region) - (kill-append string (< end beg)) - (kill-new string))) - (setq this-command 'kill-region)) -@end group -@end smallexample - -It looks complicated because we have the new functions -@code{delete-and-extract-region}, @code{kill-append}, and -@code{kill-new} as well as the new variables, -@code{last-command} and @code{this-command}. - -The @code{delete-and-extract-region} function is straightforward. It -is a built-in function that deletes the text in a region (a side -effect) and also returns that text. This is the function that -actually removes the text. (And if it cannot do that, it signals the -error.) - -In this @code{let} expression, the text that -@code{delete-and-extract-region} returns is placed in the local -variable called @samp{string}. This is the text that is removed from -the buffer. (To be more precise, the variable is set to point to the -address of the extracted text; to say it is `placed in' the variable -is simply a shorthand.) - -If the variable @samp{string} does point to text, that text is added -to the kill ring. The variable will have a @code{nil} value if no -text was removed. - -The code uses @code{when} to determine whether the variable -@samp{string} points to text. A @code{when} statement is simply a -programmers' convenience. A @code{when} statement is an @code{if} -statement without the possibility of an else clause. In your mind, you -can replace @code{when} with @code{if} and understand what goes on. -That is what the Lisp interpreter does. - +@ignore +2006 Oct 24 +In Emacs 22, +copy-region-as-kill is short, 12 lines, and uses +filter-buffer-substring, which is longer, 39 lines +and has delete-and-extract-region in it. +delete-and-extract-region is written in C. + +see Initializing a Variable with @code{defvar} +this is line 8054 +Initializing a Variable with @code{defvar} includes line 8350 +@end ignore + +@node Lisp macro, , condition-case, kill-region +@comment node-name, next, previous, up +@subsection Lisp macro @cindex Macro, lisp @cindex Lisp macro + +The part of the @code{condition-case} expression that is evaluated in +the expectation that all goes well has a @code{when}. The code uses +@code{when} to determine whether the @code{string} variable points to +text that exists. + +A @code{when} expression is simply a programmers' convenience. It is +an @code{if} without the possibility of an else clause. In your mind, +you can replace @code{when} with @code{if} and understand what goes +on. That is what the Lisp interpreter does. + Technically speaking, @code{when} is a Lisp macro. A Lisp @dfn{macro} enables you to define new control constructs and other language features. It tells the interpreter how to compute another Lisp expression which will in turn compute the value. In this case, the -`other expression' is an @code{if} expression. For more about Lisp -macros, see @ref{Macros, , Macros, elisp, The GNU Emacs Lisp Reference -Manual}. The C programming language also provides macros. These are -different, but also useful. We will briefly look at C macros in +`other expression' is an @code{if} expression. + +The @code{kill-region} function definition also has an @code{unless} +macro; it is the converse of @code{when}. The @code{unless} macro is +an @code{if} without a then clause + +For more about Lisp macros, see @ref{Macros, , Macros, elisp, The GNU +Emacs Lisp Reference Manual}. The C programming language also +provides macros. These are different, but also useful. + +@ignore +We will briefly look at C macros in @ref{Digression into C}. - -@need 1200 -If the string has content, then another conditional expression is -executed. This is an @code{if} with both a then-part and an else-part. +@end ignore + +@need 1200 +Regarding the @code{when} macro, in the @code{condition-case} +expression, when the string has content, then another conditional +expression is executed. This is an @code{if} with both a then-part +and an else-part. @smallexample @group (if (eq last-command 'kill-region) - (kill-append string (< end beg)) - (kill-new string))) + (kill-append string (< end beg) yank-handler) + (kill-new string nil yank-handler)) @end group @end smallexample The then-part is evaluated if the previous command was another call to @code{kill-region}; if not, the else-part is evaluated. +@code{yank-handler} is an optional argument to @code{kill-region} that +tells the @code{kill-append} and @code{kill-new} functions how deal +with properties added to the text, such as `bold' or `italics'. + @code{last-command} is a variable that comes with Emacs that we have not seen before. Normally, whenever a function is executed, Emacs sets the value of @code{last-command} to the previous command. @@ -7797,12 +8386,722 @@ whether the previous command was @code{kill-region}. If it was, @smallexample -(kill-append string (< end beg)) +(kill-append string (< end beg) yank-handler) @end smallexample @noindent concatenates a copy of the newly clipped text to the just previously -clipped text in the kill ring. (If the @w{@code{(< end beg))}} +clipped text in the kill ring. + +@node copy-region-as-kill, Digression into C, kill-region, Cutting & Storing Text +@comment node-name, next, previous, up +@section @code{copy-region-as-kill} +@findex copy-region-as-kill +@findex nthcdr + +The @code{copy-region-as-kill} function copies a region of text from a +buffer and (via either @code{kill-append} or @code{kill-new}) saves it +in the @code{kill-ring}. + +If you call @code{copy-region-as-kill} immediately after a +@code{kill-region} command, Emacs appends the newly copied text to the +previously copied text. This means that if you yank back the text, you +get it all, from both this and the previous operation. On the other +hand, if some other command precedes the @code{copy-region-as-kill}, +the function copies the text into a separate entry in the kill ring. + +@menu +* Complete copy-region-as-kill:: +* copy-region-as-kill body:: +@end menu + +@node Complete copy-region-as-kill, copy-region-as-kill body, copy-region-as-kill, copy-region-as-kill +@ifnottex +@unnumberedsubsec The complete @code{copy-region-as-kill} function definition +@end ifnottex + +@need 1200 +Here is the complete text of the version 22 @code{copy-region-as-kill} +function: + +@smallexample +@group +(defun copy-region-as-kill (beg end) + "Save the region as if killed, but don't kill it. +In Transient Mark mode, deactivate the mark. +If `interprogram-cut-function' is non-nil, also save the text for a window +system cut and paste." + (interactive "r") +@end group +@group + (if (eq last-command 'kill-region) + (kill-append (filter-buffer-substring beg end) (< end beg)) + (kill-new (filter-buffer-substring beg end))) +@end group +@group + (if transient-mark-mode + (setq deactivate-mark t)) + nil) +@end group +@end smallexample + +@need 800 +As usual, this function can be divided into its component parts: + +@smallexample +@group +(defun copy-region-as-kill (@var{argument-list}) + "@var{documentation}@dots{}" + (interactive "r") + @var{body}@dots{}) +@end group +@end smallexample + +The arguments are @code{beg} and @code{end} and the function is +interactive with @code{"r"}, so the two arguments must refer to the +beginning and end of the region. If you have been reading though this +document from the beginning, understanding these parts of a function is +almost becoming routine. + +The documentation is somewhat confusing unless you remember that the +word `kill' has a meaning different from usual. The `Transient Mark' +and @code{interprogram-cut-function} comments explain certain +side-effects. + +After you once set a mark, a buffer always contains a region. If you +wish, you can use Transient Mark mode to highlight the region +temporarily. (No one wants to highlight the region all the time, so +Transient Mark mode highlights it only at appropriate times. Many +people turn off Transient Mark mode, so the region is never +highlighted.) + +Also, a windowing system allows you to copy, cut, and paste among +different programs. In the X windowing system, for example, the +@code{interprogram-cut-function} function is @code{x-select-text}, +which works with the windowing system's equivalent of the Emacs kill +ring. + +The body of the @code{copy-region-as-kill} function starts with an +@code{if} clause. What this clause does is distinguish between two +different situations: whether or not this command is executed +immediately after a previous @code{kill-region} command. In the first +case, the new region is appended to the previously copied text. +Otherwise, it is inserted into the beginning of the kill ring as a +separate piece of text from the previous piece. + +The last two lines of the function prevent the region from lighting up +if Transient Mark mode is turned on. + +The body of @code{copy-region-as-kill} merits discussion in detail. + +@node copy-region-as-kill body, , Complete copy-region-as-kill, copy-region-as-kill +@comment node-name, next, previous, up +@subsection The Body of @code{copy-region-as-kill} + +The @code{copy-region-as-kill} function works in much the same way as +the @code{kill-region} function. Both are written so that two or more +kills in a row combine their text into a single entry. If you yank +back the text from the kill ring, you get it all in one piece. +Moreover, kills that kill forward from the current position of the +cursor are added to the end of the previously copied text and commands +that copy text backwards add it to the beginning of the previously +copied text. This way, the words in the text stay in the proper +order. + +Like @code{kill-region}, the @code{copy-region-as-kill} function makes +use of the @code{last-command} variable that keeps track of the +previous Emacs command. + +@menu +* last-command & this-command:: +* kill-append function:: +* kill-new function:: +@end menu + +@node last-command & this-command, kill-append function, copy-region-as-kill body, copy-region-as-kill body +@ifnottex +@unnumberedsubsubsec @code{last-command} and @code{this-command} +@end ifnottex + +Normally, whenever a function is executed, Emacs sets the value of +@code{this-command} to the function being executed (which in this case +would be @code{copy-region-as-kill}). At the same time, Emacs sets +the value of @code{last-command} to the previous value of +@code{this-command}. + +In the first part of the body of the @code{copy-region-as-kill} +function, an @code{if} expression determines whether the value of +@code{last-command} is @code{kill-region}. If so, the then-part of +the @code{if} expression is evaluated; it uses the @code{kill-append} +function to concatenate the text copied at this call to the function +with the text already in the first element (the @sc{car}) of the kill +ring. On the other hand, if the value of @code{last-command} is not +@code{kill-region}, then the @code{copy-region-as-kill} function +attaches a new element to the kill ring using the @code{kill-new} +function. + +@need 1250 +The @code{if} expression reads as follows; it uses @code{eq}: + +@smallexample +@group + (if (eq last-command 'kill-region) + ;; @r{then-part} + (kill-append (filter-buffer-substring beg end) (< end beg)) + ;; @r{else-part} + (kill-new (filter-buffer-substring beg end))) +@end group +@end smallexample + +@findex filter-buffer-substring +(The @code{filter-buffer-substring} function returns a filtered +substring of the buffer, if any. Optionally---the arguments are not +here, so neither is done---the function may delete the initial text or +return the text without its properties; this function is a replacement +for the older @code{buffer-substring} function, which came before text +properties were implemented.) + +@findex eq @r{(example of use)} +@noindent +The @code{eq} function tests whether its first argument is the same Lisp +object as its second argument. The @code{eq} function is similar to the +@code{equal} function in that it is used to test for equality, but +differs in that it determines whether two representations are actually +the same object inside the computer, but with different names. +@code{equal} determines whether the structure and contents of two +expressions are the same. + +If the previous command was @code{kill-region}, then the Emacs Lisp +interpreter calls the @code{kill-append} function + +@node kill-append function, kill-new function, last-command & this-command, copy-region-as-kill body +@unnumberedsubsubsec The @code{kill-append} function +@findex kill-append + +@need 800 +The @code{kill-append} function looks like this: + +@c in GNU Emacs 22 +@smallexample +@group +(defun kill-append (string before-p &optional yank-handler) + "Append STRING to the end of the latest kill in the kill ring. +If BEFORE-P is non-nil, prepend STRING to the kill. +@dots{} " + (let* ((cur (car kill-ring))) + (kill-new (if before-p (concat string cur) (concat cur string)) + (or (= (length cur) 0) + (equal yank-handler + (get-text-property 0 'yank-handler cur))) + yank-handler))) +@end group +@end smallexample + +@ignore +was: +(defun kill-append (string before-p) + "Append STRING to the end of the latest kill in the kill ring. +If BEFORE-P is non-nil, prepend STRING to the kill. +If `interprogram-cut-function' is set, pass the resulting kill to +it." + (kill-new (if before-p + (concat string (car kill-ring)) + (concat (car kill-ring) string)) + t)) +@end ignore + +@noindent +The @code{kill-append} function is fairly straightforward. It uses +the @code{kill-new} function, which we will discuss in more detail in +a moment. + +(Also, the function provides an optional argument called +@code{yank-handler}; when invoked, this argument tells the function +how to deal with properties added to the text, such as `bold' or +`italics'.) + +@c !!! bug in GNU Emacs 22 version of kill-append ? +It has a @code{let*} function to set the value of the first element of +the kill ring to @code{cur}. (I do not know why the function does not +use @code{let} instead; only one value is set in the expression. +Perhaps this is a bug that produces no problems?) + +Consider the conditional that is one of the two arguments to +@code{kill-new}. It uses @code{concat} to concatenate the new text to +the @sc{car} of the kill ring. Whether it prepends or appends the +text depends on the results of an @code{if} expression: + +@smallexample +@group +(if before-p ; @r{if-part} + (concat string cur) ; @r{then-part} + (concat cur string)) ; @r{else-part} +@end group +@end smallexample + +@noindent +If the region being killed is before the region that was killed in the +last command, then it should be prepended before the material that was +saved in the previous kill; and conversely, if the killed text follows +what was just killed, it should be appended after the previous text. +The @code{if} expression depends on the predicate @code{before-p} to +decide whether the newly saved text should be put before or after the +previously saved text. + +The symbol @code{before-p} is the name of one of the arguments to +@code{kill-append}. When the @code{kill-append} function is +evaluated, it is bound to the value returned by evaluating the actual +argument. In this case, this is the expression @code{(< end beg)}. +This expression does not directly determine whether the killed text in +this command is located before or after the kill text of the last +command; what it does is determine whether the value of the variable +@code{end} is less than the value of the variable @code{beg}. If it +is, it means that the user is most likely heading towards the +beginning of the buffer. Also, the result of evaluating the predicate +expression, @code{(< end beg)}, will be true and the text will be +prepended before the previous text. On the other hand, if the value of +the variable @code{end} is greater than the value of the variable +@code{beg}, the text will be appended after the previous text. + +@need 800 +When the newly saved text will be prepended, then the string with the new +text will be concatenated before the old text: + +@smallexample +(concat string cur) +@end smallexample + +@need 1200 +@noindent +But if the text will be appended, it will be concatenated +after the old text: + +@smallexample +(concat cur string)) +@end smallexample + +To understand how this works, we first need to review the +@code{concat} function. The @code{concat} function links together or +unites two strings of text. The result is a string. For example: + +@smallexample +@group +(concat "abc" "def") + @result{} "abcdef" +@end group + +@group +(concat "new " + (car '("first element" "second element"))) + @result{} "new first element" + +(concat (car + '("first element" "second element")) " modified") + @result{} "first element modified" +@end group +@end smallexample + +We can now make sense of @code{kill-append}: it modifies the contents +of the kill ring. The kill ring is a list, each element of which is +saved text. The @code{kill-append} function uses the @code{kill-new} +function which in turn uses the @code{setcar} function. + +@node kill-new function, , kill-append function, copy-region-as-kill body +@unnumberedsubsubsec The @code{kill-new} function +@findex kill-new + +@c in GNU Emacs 22, additional documentation to kill-new: +@ignore +Optional third arguments YANK-HANDLER controls how the STRING is later +inserted into a buffer; see `insert-for-yank' for details. +When a yank handler is specified, STRING must be non-empty (the yank +handler, if non-nil, is stored as a `yank-handler' text property on STRING). + +When the yank handler has a non-nil PARAM element, the original STRING +argument is not used by `insert-for-yank'. However, since Lisp code +may access and use elements from the kill ring directly, the STRING +argument should still be a \"useful\" string for such uses." +@end ignore +@need 1200 +The @code{kill-new} function looks like this: + +@smallexample +@group +(defun kill-new (string &optional replace yank-handler) + "Make STRING the latest kill in the kill ring. +Set `kill-ring-yank-pointer' to point to it. + +If `interprogram-cut-function' is non-nil, apply it to STRING. +Optional second argument REPLACE non-nil means that STRING will replace +the front of the kill ring, rather than being added to the list. +@dots{}" +@end group +@group + (if (> (length string) 0) + (if yank-handler + (put-text-property 0 (length string) + 'yank-handler yank-handler string)) + (if yank-handler + (signal 'args-out-of-range + (list string "yank-handler specified for empty string")))) +@end group +@group + (if (fboundp 'menu-bar-update-yank-menu) + (menu-bar-update-yank-menu string (and replace (car kill-ring)))) +@end group +@group + (if (and replace kill-ring) + (setcar kill-ring string) + (push string kill-ring) + (if (> (length kill-ring) kill-ring-max) + (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil))) +@end group +@group + (setq kill-ring-yank-pointer kill-ring) + (if interprogram-cut-function + (funcall interprogram-cut-function string (not replace)))) +@end group +@end smallexample +@ignore +was: +(defun kill-new (string &optional replace) + "Make STRING the latest kill in the kill ring. +Set the kill-ring-yank pointer to point to it. +If `interprogram-cut-function' is non-nil, apply it to STRING. +Optional second argument REPLACE non-nil means that STRING will replace +the front of the kill ring, rather than being added to the list." + (and (fboundp 'menu-bar-update-yank-menu) + (menu-bar-update-yank-menu string (and replace (car kill-ring)))) + (if (and replace kill-ring) + (setcar kill-ring string) + (setq kill-ring (cons string kill-ring)) + (if (> (length kill-ring) kill-ring-max) + (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil))) + (setq kill-ring-yank-pointer kill-ring) + (if interprogram-cut-function + (funcall interprogram-cut-function string (not replace)))) +@end ignore + +(Notice that the function is not interactive.) + +As usual, we can look at this function in parts. + +The function definition has an optional @code{yank-handler} argument, +which when invoked tells the function how to deal with properties +added to the text, such as `bold' or `italics'. We will skip that. + +@need 1200 +The first line of the documentation makes sense: + +@smallexample +Make STRING the latest kill in the kill ring. +@end smallexample + +@noindent +Let's skip over the rest of the documentation for the moment. + +@noindent +Also, let's skip over the initial @code{if} expression and those lines +of code involving @code{menu-bar-update-yank-menu}. We will explain +them below. + +@need 1200 +The critical lines are these: + +@smallexample +@group + (if (and replace kill-ring) + ;; @r{then} + (setcar kill-ring string) +@end group +@group + ;; @r{else} + (push string kill-ring) +@end group +@group + (setq kill-ring (cons string kill-ring)) + (if (> (length kill-ring) kill-ring-max) + ;; @r{avoid overly long kill ring} + (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil))) +@end group +@group + (setq kill-ring-yank-pointer kill-ring) + (if interprogram-cut-function + (funcall interprogram-cut-function string (not replace)))) +@end group +@end smallexample + +The conditional test is @w{@code{(and replace kill-ring)}}. +This will be true when two conditions are met: the kill ring has +something in it, and the @code{replace} variable is true. + +@need 1250 +When the @code{kill-append} function sets @code{replace} to be true +and when the kill ring has at least one item in it, the @code{setcar} +expression is executed: + +@smallexample +(setcar kill-ring string) +@end smallexample + +The @code{setcar} function actually changes the first element of the +@code{kill-ring} list to the value of @code{string}. It replaces the +first element. + +@need 1250 +On the other hand, if the kill ring is empty, or replace is false, the +else-part of the condition is executed: + +@smallexample +(push string kill-ring) +@end smallexample + +@noindent +@need 1250 +@code{push} puts its first argument onto the second. It is similar to +the older + +@smallexample +(setq kill-ring (cons string kill-ring)) +@end smallexample + +@noindent +@need 1250 +or the newer + +@smallexample +(add-to-list kill-ring string) +@end smallexample + +@noindent +When it is false, the expression first constructs a new version of the +kill ring by prepending @code{string} to the existing kill ring as a +new element (that is what the @code{push} does). Then it executes a +second @code{if} clause. This second @code{if} clause keeps the kill +ring from growing too long. + +Let's look at these two expressions in order. + +The @code{push} line of the else-part sets the new value of the kill +ring to what results from adding the string being killed to the old +kill ring. + +We can see how this works with an example. + +@need 800 +First, + +@smallexample +(setq example-list '("here is a clause" "another clause")) +@end smallexample + +@need 1200 +@noindent +After evaluating this expression with @kbd{C-x C-e}, you can evaluate +@code{example-list} and see what it returns: + +@smallexample +@group +example-list + @result{} ("here is a clause" "another clause") +@end group +@end smallexample + +@need 1200 +@noindent +Now, we can add a new element on to this list by evaluating the +following expression: +@findex push, @r{example} + +@smallexample +(push "a third clause" example-list) +@end smallexample + +@need 800 +@noindent +When we evaluate @code{example-list}, we find its value is: + +@smallexample +@group +example-list + @result{} ("a third clause" "here is a clause" "another clause") +@end group +@end smallexample + +@noindent +Thus, the third clause is added to the list by @code{push}. + +@need 1200 +Now for the second part of the @code{if} clause. This expression +keeps the kill ring from growing too long. It looks like this: + +@smallexample +@group +(if (> (length kill-ring) kill-ring-max) + (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil)) +@end group +@end smallexample + +The code checks whether the length of the kill ring is greater than +the maximum permitted length. This is the value of +@code{kill-ring-max} (which is 60, by default). If the length of the +kill ring is too long, then this code sets the last element of the +kill ring to @code{nil}. It does this by using two functions, +@code{nthcdr} and @code{setcdr}. + +We looked at @code{setcdr} earlier (@pxref{setcdr, , @code{setcdr}}). +It sets the @sc{cdr} of a list, just as @code{setcar} sets the +@sc{car} of a list. In this case, however, @code{setcdr} will not be +setting the @sc{cdr} of the whole kill ring; the @code{nthcdr} +function is used to cause it to set the @sc{cdr} of the next to last +element of the kill ring---this means that since the @sc{cdr} of the +next to last element is the last element of the kill ring, it will set +the last element of the kill ring. + +@findex nthcdr, @r{example} +The @code{nthcdr} function works by repeatedly taking the @sc{cdr} of a +list---it takes the @sc{cdr} of the @sc{cdr} of the @sc{cdr} +@dots{} It does this @var{N} times and returns the results. +(@xref{nthcdr, , @code{nthcdr}}.) + +@findex setcdr, @r{example} +Thus, if we had a four element list that was supposed to be three +elements long, we could set the @sc{cdr} of the next to last element +to @code{nil}, and thereby shorten the list. (If you set the last +element to some other value than @code{nil}, which you could do, then +you would not have shortened the list. @xref{setcdr, , +@code{setcdr}}.) + +You can see shortening by evaluating the following three expressions +in turn. First set the value of @code{trees} to @code{(maple oak pine +birch)}, then set the @sc{cdr} of its second @sc{cdr} to @code{nil} +and then find the value of @code{trees}: + +@smallexample +@group +(setq trees '(maple oak pine birch)) + @result{} (maple oak pine birch) +@end group + +@group +(setcdr (nthcdr 2 trees) nil) + @result{} nil + +trees + @result{} (maple oak pine) +@end group +@end smallexample + +@noindent +(The value returned by the @code{setcdr} expression is @code{nil} since +that is what the @sc{cdr} is set to.) + +To repeat, in @code{kill-new}, the @code{nthcdr} function takes the +@sc{cdr} a number of times that is one less than the maximum permitted +size of the kill ring and @code{setcdr} sets the @sc{cdr} of that +element (which will be the rest of the elements in the kill ring) to +@code{nil}. This prevents the kill ring from growing too long. + +@need 800 +The next to last expression in the @code{kill-new} function is + +@smallexample +(setq kill-ring-yank-pointer kill-ring) +@end smallexample + +The @code{kill-ring-yank-pointer} is a global variable that is set to be +the @code{kill-ring}. + +Even though the @code{kill-ring-yank-pointer} is called a +@samp{pointer}, it is a variable just like the kill ring. However, the +name has been chosen to help humans understand how the variable is used. + +@need 1200 +Now, to return to an early expression in the body of the function: + +@smallexample +@group + (if (fboundp 'menu-bar-update-yank-menu) + (menu-bar-update-yank-menu string (and replace (car kill-ring)))) +@end group +@end smallexample + +@noindent +It starts with an @code{if} expression + +In this case, the expression tests first to see whether +@code{menu-bar-update-yank-menu} exists as a function, and if so, +calls it. The @code{fboundp} function returns true if the symbol it +is testing has a function definition that `is not void'. If the +symbol's function definition were void, we would receive an error +message, as we did when we created errors intentionally (@pxref{Making +Errors, , Generate an Error Message}). + +@noindent +The then-part contains an expression whose first element is the +function @code{and}. + +@findex and +The @code{and} special form evaluates each of its arguments until one +of the arguments returns a value of @code{nil}, in which case the +@code{and} expression returns @code{nil}; however, if none of the +arguments returns a value of @code{nil}, the value resulting from +evaluating the last argument is returned. (Since such a value is not +@code{nil}, it is considered true in Emacs Lisp.) In other words, an +@code{and} expression returns a true value only if all its arguments +are true. (@xref{Second Buffer Related Review}.) + +The expression determines whether the second argument to +@code{menu-bar-update-yank-menu} is true or not. +@ignore + ;; If we're supposed to be extending an existing string, and that + ;; string really is at the front of the menu, then update it in place. +@end ignore + +@code{menu-bar-update-yank-menu} is one of the functions that make it +possible to use the `Select and Paste' menu in the Edit item of a menu +bar; using a mouse, you can look at the various pieces of text you +have saved and select one piece to paste. + +The last expression in the @code{kill-new} function adds the newly +copied string to whatever facility exists for copying and pasting +among different programs running in a windowing system. In the X +Windowing system, for example, the @code{x-select-text} function takes +the string and stores it in memory operated by X. You can paste the +string in another program, such as an Xterm. + +@need 1200 +The expression looks like this: + +@smallexample +@group + (if interprogram-cut-function + (funcall interprogram-cut-function string (not replace)))) +@end group +@end smallexample + +If an @code{interprogram-cut-function} exists, then Emacs executes +@code{funcall}, which in turn calls its first argument as a function +and passes the remaining arguments to it. (Incidentally, as far as I +can see, this @code{if} expression could be replaced by an @code{and} +expression similar to the one in the first part of the function.) + +We are not going to discuss windowing systems and other programs +further, but merely note that this is a mechanism that enables GNU +Emacs to work easily and well with other programs. + +This code for placing text in the kill ring, either concatenated with +an existing element or as a new element, leads us to the code for +bringing back text that has been cut out of the buffer---the yank +commands. However, before discussing the yank commands, it is better +to learn how lists are implemented in a computer. This will make +clear such mysteries as the use of the term `pointer'. But before +that, we will digress into C. + +@ignore +@c is this true in Emacs 22? Does not seems to be + + (If the @w{@code{(< end beg))}} expression is true, @code{kill-append} prepends the string to the just previously clipped text. For a detailed discussion, see @ref{kill-append function, , The @code{kill-append} function}.) @@ -7817,29 +9116,46 @@ then the @code{kill-new} function is called, which adds the text to the kill ring as the latest item, and sets the @code{kill-ring-yank-pointer} variable to point to it. - -@node Digression into C, defvar, kill-region, Cutting & Storing Text +@end ignore +@ignore + +@c Evidently, changed for Emacs 22. The zap-to-char command does not +@c use the delete-and-extract-region function + +2006 Oct 26, the Digression into C is now OK but should come after +copy-region-as-kill and filter-buffer-substring + +2006 Oct 24 +In Emacs 22, +copy-region-as-kill is short, 12 lines, and uses +filter-buffer-substring, which is longer, 39 lines +and has delete-and-extract-region in it. +delete-and-extract-region is written in C. + +see Initializing a Variable with @code{defvar} +@end ignore + +@node Digression into C, defvar, copy-region-as-kill, Cutting & Storing Text @comment node-name, next, previous, up @section Digression into C @findex delete-and-extract-region @cindex C, a digression into @cindex Digression into C -The @code{zap-to-char} command uses the -@code{delete-and-extract-region} function, which in turn uses two -other functions, @code{copy-region-as-kill} and -@code{del_range_1}. The @code{copy-region-as-kill} function will be -described in a following section; it puts a copy of the region in the -kill ring so it can be yanked back. (@xref{copy-region-as-kill, , -@code{copy-region-as-kill}}.) - -The @code{delete-and-extract-region} function removes the contents of -a region and you cannot get them back. - -Unlike the other code discussed here, @code{delete-and-extract-region} -is not written in Emacs Lisp; it is written in C and is one of the -primitives of the GNU Emacs system. Since it is very simple, I will -digress briefly from Lisp and describe it here. +The @code{copy-region-as-kill} function (@pxref{copy-region-as-kill, , +@code{copy-region-as-kill}}) uses the @code{filter-buffer-substring} +function, which in turn uses the @code{delete-and-extract-region} +function. It removes the contents of a region and you cannot get them +back. + +Unlike the other code discussed here, the +@code{delete-and-extract-region} function is not written in Emacs +Lisp; it is written in C and is one of the primitives of the GNU Emacs +system. Since it is very simple, I will digress briefly from Lisp and +describe it here. + +@c GNU Emacs 22 in /usr/local/src/emacs/src/editfns.c +@c the DEFUN for buffer-substring-no-properties @need 1500 Like many of the other Emacs primitives, @@ -7847,17 +9163,24 @@ macro, a macro being a template for code. The complete macro looks like this: -@c /usr/local/src/emacs/src/editfns.c -@smallexample -@group -DEFUN ("delete-and-extract-region", Fdelete_and_extract_region, - Sdelete_and_extract_region, 2, 2, 0, - "Delete the text between START and END and return it.") - (start, end) +@smallexample +@group +DEFUN ("buffer-substring-no-properties", Fbuffer_substring_no_properties, + Sbuffer_substring_no_properties, 2, 2, 0, + doc: /* Return the characters of part of the buffer, +without the text properties. +The two arguments START and END are character positions; +they can be in either order. */) + (start, end) Lisp_Object start, end; @{ + register int b, e; + validate_region (&start, &end); - return del_range_1 (XINT (start), XINT (end), 1, 1); + b = XINT (start); + e = XINT (end); + + return make_buffer_string (b, e, 0); @} @end group @end smallexample @@ -7865,8 +9188,11 @@ Without going into the details of the macro writing process, let me point out that this macro starts with the word @code{DEFUN}. The word @code{DEFUN} was chosen since the code serves the same purpose as -@code{defun} does in Lisp. The word @code{DEFUN} is followed by seven -parts inside of parentheses: +@code{defun} does in Lisp. (The @code{DEFUN} C macro is defined in +@file{emacs/src/lisp.h}.) + +The word @code{DEFUN} is followed by seven parts inside of +parentheses: @itemize @bullet @item @@ -7915,7 +9241,7 @@ @smallexample @group "Set point to POSITION, a number or marker.\n\ -Beginning of buffer is position (point-min), end is (point-max). +Beginning of buffer is position (point-min), end is (point-max)." @end group @end smallexample @end itemize @@ -7924,26 +9250,27 @@ In a C macro, the formal parameters come next, with a statement of what kind of object they are, followed by what might be called the `body' of the macro. For @code{delete-and-extract-region} the `body' -consists of the following two lines: +consists of the following four lines: @smallexample @group validate_region (&start, &end); +if (XINT (start) == XINT (end)) + return build_string (""); return del_range_1 (XINT (start), XINT (end), 1, 1); @end group @end smallexample -The first function, @code{validate_region} checks whether the values +The @code{validate_region} function checks whether the values passed as the beginning and end of the region are the proper type and -are within range. The second function, @code{del_range_1}, actually -deletes the text. - -@code{del_range_1} is a complex function we will not look into. It -updates the buffer and does other things. - -However, it is worth looking at the two arguments passed to -@code{del_range}. These are @w{@code{XINT (start)}} and @w{@code{XINT -(end)}}. +are within range. If the beginning and end positions are the same, +then return and empty string. + +The @code{del_range_1} function actually deletes the text. It is a +complex function we will not look into. It updates the buffer and +does other things. However, it is worth looking at the two arguments +passed to @code{del_range}. These are @w{@code{XINT (start)}} and +@w{@code{XINT (end)}}. As far as the C language is concerned, @code{start} and @code{end} are two integers that mark the beginning and end of the region to be @@ -7954,11 +9281,10 @@ In early versions of Emacs, these two numbers were thirty-two bits long, but the code is slowly being generalized to handle other lengths. Three of the available bits are used to specify the type of -information and a fourth bit is used for handling the computer's -memory; the remaining bits are used as `content'. +information; the remaining bits are used as `content'. @samp{XINT} is a C macro that extracts the relevant number from the -longer collection of bits; the four other bits are discarded. +longer collection of bits; the three other bits are discarded. @need 800 The command in @code{delete-and-extract-region} looks like this: @@ -7975,15 +9301,26 @@ simple; but hidden underneath is a great deal of complexity to make it all work. -@node defvar, copy-region-as-kill, Digression into C, Cutting & Storing Text +@node defvar, cons & search-fwd Review, Digression into C, Cutting & Storing Text @comment node-name, next, previous, up @section Initializing a Variable with @code{defvar} @findex defvar @cindex Initializing a variable @cindex Variable initialization -Unlike the @code{delete-and-extract-region} function, the -@code{copy-region-as-kill} function is written in Emacs Lisp. Two +@ignore +2006 Oct 24 +In Emacs 22, +copy-region-as-kill is short, 12 lines, and uses +filter-buffer-substring, which is longer, 39 lines +and has delete-and-extract-region in it. +delete-and-extract-region is written in C. + +see Initializing a Variable with @code{defvar} + +@end ignore + +The @code{copy-region-as-kill} function is written in Emacs Lisp. Two functions within it, @code{kill-append} and @code{kill-new}, copy a region in a buffer and save it in a variable called the @code{kill-ring}. This section describes how the @code{kill-ring} @@ -8011,7 +9348,7 @@ @menu * See variable current value:: -* defvar and asterisk:: An old-time convention. +* defvar and asterisk:: @end menu @node See variable current value, defvar and asterisk, defvar, defvar @@ -8111,620 +9448,8 @@ (@xref{Examining, , Examining and Setting Variables, emacs, The GNU Emacs Manual}.) -@node copy-region-as-kill, cons & search-fwd Review, defvar, Cutting & Storing Text -@comment node-name, next, previous, up -@section @code{copy-region-as-kill} -@findex copy-region-as-kill -@findex nthcdr - -The @code{copy-region-as-kill} function copies a region of text from a -buffer and (via either @code{kill-append} or @code{kill-new}) saves it -in the @code{kill-ring}. - -If you call @code{copy-region-as-kill} immediately after a -@code{kill-region} command, Emacs appends the newly copied text to the -previously copied text. This means that if you yank back the text, you -get it all, from both this and the previous operation. On the other -hand, if some other command precedes the @code{copy-region-as-kill}, -the function copies the text into a separate entry in the kill ring. - -@menu -* Complete copy-region-as-kill:: The complete function definition. -* copy-region-as-kill body:: The body of @code{copy-region-as-kill}. -@end menu - -@node Complete copy-region-as-kill, copy-region-as-kill body, copy-region-as-kill, copy-region-as-kill -@ifnottex -@unnumberedsubsec The complete @code{copy-region-as-kill} function definition -@end ifnottex - -@need 1200 -Here is the complete text of the version 21 @code{copy-region-as-kill} -function: - -@c !!! for no text properties, use buffer-substring-no-properties - -@smallexample -@group -(defun copy-region-as-kill (beg end) - "Save the region as if killed, but don't kill it. -In Transient Mark mode, deactivate the mark. -If `interprogram-cut-function' is non-nil, also save -the text for a window system cut and paste." - (interactive "r") -@end group -@group - (if (eq last-command 'kill-region) - (kill-append (buffer-substring beg end) (< end beg)) - (kill-new (buffer-substring beg end))) -@end group -@group - (if transient-mark-mode - (setq deactivate-mark t)) - nil) -@end group -@end smallexample - -@need 800 -As usual, this function can be divided into its component parts: - -@smallexample -@group -(defun copy-region-as-kill (@var{argument-list}) - "@var{documentation}@dots{}" - (interactive "r") - @var{body}@dots{}) -@end group -@end smallexample - -The arguments are @code{beg} and @code{end} and the function is -interactive with @code{"r"}, so the two arguments must refer to the -beginning and end of the region. If you have been reading though this -document from the beginning, understanding these parts of a function is -almost becoming routine. - -The documentation is somewhat confusing unless you remember that the -word `kill' has a meaning different from its usual meaning. The -`Transient Mark' and @code{interprogram-cut-function} comments explain -certain side-effects. - -After you once set a mark, a buffer always contains a region. If you -wish, you can use Transient Mark mode to highlight the region -temporarily. (No one wants to highlight the region all the time, so -Transient Mark mode highlights it only at appropriate times. Many -people turn off Transient Mark mode, so the region is never -highlighted.) - -Also, a windowing system allows you to copy, cut, and paste among -different programs. In the X windowing system, for example, the -@code{interprogram-cut-function} function is @code{x-select-text}, -which works with the windowing system's equivalent of the Emacs kill -ring. - -The body of the @code{copy-region-as-kill} function starts with an -@code{if} clause. What this clause does is distinguish between two -different situations: whether or not this command is executed -immediately after a previous @code{kill-region} command. In the first -case, the new region is appended to the previously copied text. -Otherwise, it is inserted into the beginning of the kill ring as a -separate piece of text from the previous piece. - -The last two lines of the function prevent the region from lighting up -if Transient Mark mode is turned on. - -The body of @code{copy-region-as-kill} merits discussion in detail. - -@node copy-region-as-kill body, , Complete copy-region-as-kill, copy-region-as-kill -@comment node-name, next, previous, up -@subsection The Body of @code{copy-region-as-kill} - -The @code{copy-region-as-kill} function works in much the same way as -the @code{kill-region} function (@pxref{kill-region, -,@code{kill-region}}). Both are written so that two or more kills in -a row combine their text into a single entry. If you yank back the -text from the kill ring, you get it all in one piece. Moreover, kills -that kill forward from the current position of the cursor are added to -the end of the previously copied text and commands that copy text -backwards add it to the beginning of the previously copied text. This -way, the words in the text stay in the proper order. - -Like @code{kill-region}, the @code{copy-region-as-kill} function makes -use of the @code{last-command} variable that keeps track of the -previous Emacs command. - -@menu -* last-command & this-command:: -* kill-append function:: -* kill-new function:: -@end menu - -@node last-command & this-command, kill-append function, copy-region-as-kill body, copy-region-as-kill body -@ifnottex -@unnumberedsubsubsec @code{last-command} and @code{this-command} -@end ifnottex - -Normally, whenever a function is executed, Emacs sets the value of -@code{this-command} to the function being executed (which in this case -would be @code{copy-region-as-kill}). At the same time, Emacs sets -the value of @code{last-command} to the previous value of -@code{this-command}. - -In the first part of the body of the @code{copy-region-as-kill} -function, an @code{if} expression determines whether the value of -@code{last-command} is @code{kill-region}. If so, the then-part of -the @code{if} expression is evaluated; it uses the @code{kill-append} -function to concatenate the text copied at this call to the function -with the text already in the first element (the @sc{car}) of the kill -ring. On the other hand, if the value of @code{last-command} is not -@code{kill-region}, then the @code{copy-region-as-kill} function -attaches a new element to the kill ring using the @code{kill-new} -function. - -@need 1250 -The @code{if} expression reads as follows; it uses @code{eq}, which is -a function we have not yet seen: - -@smallexample -@group - (if (eq last-command 'kill-region) - ;; @r{then-part} - (kill-append (buffer-substring beg end) (< end beg)) - ;; @r{else-part} - (kill-new (buffer-substring beg end))) -@end group -@end smallexample - -@findex eq @r{(example of use)} -@noindent -The @code{eq} function tests whether its first argument is the same Lisp -object as its second argument. The @code{eq} function is similar to the -@code{equal} function in that it is used to test for equality, but -differs in that it determines whether two representations are actually -the same object inside the computer, but with different names. -@code{equal} determines whether the structure and contents of two -expressions are the same. - -If the previous command was @code{kill-region}, then the Emacs Lisp -interpreter calls the @code{kill-append} function - -@node kill-append function, kill-new function, last-command & this-command, copy-region-as-kill body -@unnumberedsubsubsec The @code{kill-append} function -@findex kill-append - -@need 800 -The @code{kill-append} function looks like this: - -@smallexample -@group -(defun kill-append (string before-p) - "Append STRING to the end of the latest kill in the kill ring. -If BEFORE-P is non-nil, prepend STRING to the kill. -If `interprogram-cut-function' is set, pass the resulting kill to -it." - (kill-new (if before-p - (concat string (car kill-ring)) - (concat (car kill-ring) string)) - t)) -@end group -@end smallexample - -@noindent -The @code{kill-append} function is fairly straightforward. It uses -the @code{kill-new} function, which we will discuss in more detail in -a moment. - -First, let us look at the conditional that is one of the two arguments -to @code{kill-new}. It uses @code{concat} to concatenate the new text -to the @sc{car} of the kill ring. Whether it prepends or appends the -text depends on the results of an @code{if} expression: - -@smallexample -@group -(if before-p ; @r{if-part} - (concat string (car kill-ring)) ; @r{then-part} - (concat (car kill-ring) string)) ; @r{else-part} -@end group -@end smallexample - -@noindent -If the region being killed is before the region that was killed in the -last command, then it should be prepended before the material that was -saved in the previous kill; and conversely, if the killed text follows -what was just killed, it should be appended after the previous text. -The @code{if} expression depends on the predicate @code{before-p} to -decide whether the newly saved text should be put before or after the -previously saved text. - -The symbol @code{before-p} is the name of one of the arguments to -@code{kill-append}. When the @code{kill-append} function is -evaluated, it is bound to the value returned by evaluating the actual -argument. In this case, this is the expression @code{(< end beg)}. -This expression does not directly determine whether the killed text in -this command is located before or after the kill text of the last -command; what it does is determine whether the value of the variable -@code{end} is less than the value of the variable @code{beg}. If it -is, it means that the user is most likely heading towards the -beginning of the buffer. Also, the result of evaluating the predicate -expression, @code{(< end beg)}, will be true and the text will be -prepended before the previous text. On the other hand, if the value of -the variable @code{end} is greater than the value of the variable -@code{beg}, the text will be appended after the previous text. - -@need 800 -When the newly saved text will be prepended, then the string with the new -text will be concatenated before the old text: - -@smallexample -(concat string (car kill-ring)) -@end smallexample - -@need 1200 -@noindent -But if the text will be appended, it will be concatenated -after the old text: - -@smallexample -(concat (car kill-ring) string)) -@end smallexample - -To understand how this works, we first need to review the -@code{concat} function. The @code{concat} function links together or -unites two strings of text. The result is a string. For example: - -@smallexample -@group -(concat "abc" "def") - @result{} "abcdef" -@end group - -@group -(concat "new " - (car '("first element" "second element"))) - @result{} "new first element" - -(concat (car - '("first element" "second element")) " modified") - @result{} "first element modified" -@end group -@end smallexample - -We can now make sense of @code{kill-append}: it modifies the contents -of the kill ring. The kill ring is a list, each element of which is -saved text. The @code{kill-append} function uses the @code{kill-new} -function which in turn uses the @code{setcar} function. - -@node kill-new function, , kill-append function, copy-region-as-kill body -@unnumberedsubsubsec The @code{kill-new} function -@findex kill-new - -@need 1200 -The @code{kill-new} function looks like this: - -@smallexample -@group -(defun kill-new (string &optional replace) - "Make STRING the latest kill in the kill ring. -Set the kill-ring-yank pointer to point to it. -If `interprogram-cut-function' is non-nil, apply it to STRING. -Optional second argument REPLACE non-nil means that STRING will replace -the front of the kill ring, rather than being added to the list." -@end group -@group - (and (fboundp 'menu-bar-update-yank-menu) - (menu-bar-update-yank-menu string (and replace (car kill-ring)))) -@end group -@group - (if (and replace kill-ring) - (setcar kill-ring string) - (setq kill-ring (cons string kill-ring)) - (if (> (length kill-ring) kill-ring-max) - (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil))) -@end group -@group - (setq kill-ring-yank-pointer kill-ring) - (if interprogram-cut-function - (funcall interprogram-cut-function string (not replace)))) -@end group -@end smallexample - -As usual, we can look at this function in parts. - -@need 1200 -The first line of the documentation makes sense: - -@smallexample -Make STRING the latest kill in the kill ring. -@end smallexample - -@noindent -Let's skip over the rest of the documentation for the moment. - -Also, let's skip over the first two lines of code, those involving -@code{menu-bar-update-yank-menu}. We will explain them below. - -@need 1200 -The critical lines are these: - -@smallexample -@group - (if (and replace kill-ring) - ;; @r{then} - (setcar kill-ring string) -@end group -@group - ;; @r{else} - (setq kill-ring (cons string kill-ring)) - (if (> (length kill-ring) kill-ring-max) - ;; @r{avoid overly long kill ring} - (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil))) -@end group -@group - (setq kill-ring-yank-pointer kill-ring) - (if interprogram-cut-function - (funcall interprogram-cut-function string (not replace)))) -@end group -@end smallexample - -The conditional test is @w{@code{(and replace kill-ring)}}. -This will be true when two conditions are met: the kill ring has -something in it, and the @code{replace} variable is true. - -@need 1250 -The @code{kill-append} function sets @code{replace} to be true; then, -when the kill ring has at least one item in it, the @code{setcar} -expression is executed: - -@smallexample -(setcar kill-ring string) -@end smallexample - -The @code{setcar} function actually changes the first element of the -@code{kill-ring} list to the value of @code{string}. It replaces the -first element. - -On the other hand, if the kill ring is empty, or replace is false, the -else-part of the condition is executed: - -@smallexample -@group -(setq kill-ring (cons string kill-ring)) -(if (> (length kill-ring) kill-ring-max) - (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil)) -@end group -@end smallexample - -@noindent -This expression first constructs a new version of the kill ring by -prepending @code{string} to the existing kill ring as a new element. -Then it executes a second @code{if} clause. This second @code{if} -clause keeps the kill ring from growing too long. - -Let's look at these two expressions in order. - -The @code{setq} line of the else-part sets the new value of the kill -ring to what results from adding the string being killed to the old kill -ring. - -@need 800 -We can see how this works with an example: - -@smallexample -(setq example-list '("here is a clause" "another clause")) -@end smallexample - -@need 1200 -@noindent -After evaluating this expression with @kbd{C-x C-e}, you can evaluate -@code{example-list} and see what it returns: - -@smallexample -@group -example-list - @result{} ("here is a clause" "another clause") -@end group -@end smallexample - -@need 1200 -@noindent -Now, we can add a new element on to this list by evaluating the -following expression: -@findex cons, @r{example} - -@smallexample -(setq example-list (cons "a third clause" example-list)) -@end smallexample - -@need 800 -@noindent -When we evaluate @code{example-list}, we find its value is: - -@smallexample -@group -example-list - @result{} ("a third clause" "here is a clause" "another clause") -@end group -@end smallexample - -@noindent -Thus, the third clause was added to the list by @code{cons}. - -@need 1200 -This is exactly similar to what the @code{setq} and @code{cons} do in -the function. Here is the line again: - -@smallexample -(setq kill-ring (cons string kill-ring)) -@end smallexample - -@need 1200 -Now for the second part of the @code{if} clause. This expression -keeps the kill ring from growing too long. It looks like this: - -@smallexample -@group -(if (> (length kill-ring) kill-ring-max) - (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil)) -@end group -@end smallexample - -The code checks whether the length of the kill ring is greater than -the maximum permitted length. This is the value of -@code{kill-ring-max} (which is 60, by default). If the length of the -kill ring is too long, then this code sets the last element of the -kill ring to @code{nil}. It does this by using two functions, -@code{nthcdr} and @code{setcdr}. - -We looked at @code{setcdr} earlier (@pxref{setcdr, , @code{setcdr}}). -It sets the @sc{cdr} of a list, just as @code{setcar} sets the -@sc{car} of a list. In this case, however, @code{setcdr} will not be -setting the @sc{cdr} of the whole kill ring; the @code{nthcdr} -function is used to cause it to set the @sc{cdr} of the next to last -element of the kill ring---this means that since the @sc{cdr} of the -next to last element is the last element of the kill ring, it will set -the last element of the kill ring. - -@findex nthcdr, @r{example} -The @code{nthcdr} function works by repeatedly taking the @sc{cdr} of a -list---it takes the @sc{cdr} of the @sc{cdr} of the @sc{cdr} -@dots{} It does this @var{N} times and returns the results. - -@findex setcdr, @r{example} -Thus, if we had a four element list that was supposed to be three -elements long, we could set the @sc{cdr} of the next to last element -to @code{nil}, and thereby shorten the list. (If you sent the last -element to some other value than @code{nil}, which you could do, then -you would not have shortened the list.) - -You can see shortening by evaluating the following three expressions -in turn. First set the value of @code{trees} to @code{(maple oak pine -birch)}, then set the @sc{cdr} of its second @sc{cdr} to @code{nil} -and then find the value of @code{trees}: - -@smallexample -@group -(setq trees '(maple oak pine birch)) - @result{} (maple oak pine birch) -@end group - -@group -(setcdr (nthcdr 2 trees) nil) - @result{} nil - -trees - @result{} (maple oak pine) -@end group -@end smallexample - -@noindent -(The value returned by the @code{setcdr} expression is @code{nil} since -that is what the @sc{cdr} is set to.) - -To repeat, in @code{kill-new}, the @code{nthcdr} function takes the -@sc{cdr} a number of times that is one less than the maximum permitted -size of the kill ring and sets the @sc{cdr} of that element (which -will be the rest of the elements in the kill ring) to @code{nil}. -This prevents the kill ring from growing too long. - -@need 800 -The next to last expression in the @code{kill-new} function is - -@smallexample -(setq kill-ring-yank-pointer kill-ring) -@end smallexample - -The @code{kill-ring-yank-pointer} is a global variable that is set to be -the @code{kill-ring}. - -Even though the @code{kill-ring-yank-pointer} is called a -@samp{pointer}, it is a variable just like the kill ring. However, the -name has been chosen to help humans understand how the variable is used. -The variable is used in functions such as @code{yank} and -@code{yank-pop} (@pxref{Yanking, , Yanking Text Back}). - -@need 1200 -Now, to return to the first two lines in the body of the function: - -@smallexample -@group - (and (fboundp 'menu-bar-update-yank-menu) - (menu-bar-update-yank-menu string (and replace (car kill-ring)))) -@end group -@end smallexample - -@noindent -This is an expression whose first element is the function @code{and}. - -@findex and, @r{introduced} -The @code{and} special form evaluates each of its arguments until one of -the arguments returns a value of @code{nil}, in which case the -@code{and} expression returns @code{nil}; however, if none of the -arguments returns a value of @code{nil}, the value resulting from -evaluating the last argument is returned. (Since such a value is not -@code{nil}, it is considered true in Emacs Lisp.) In other words, an -@code{and} expression returns a true value only if all its arguments -are true. -@findex and - -In this case, the expression tests first to see whether -@code{menu-bar-update-yank-menu} exists as a function, and if so, -calls it. The @code{fboundp} function returns true if the symbol it -is testing has a function definition that `is not void'. If the -symbol's function definition were void, we would receive an error -message, as we did when we created errors intentionally (@pxref{Making -Errors, , Generate an Error Message}). - -@need 1200 -Essentially, the @code{and} is an @code{if} expression that reads like -this: - -@smallexample -@group -if @var{the-menu-bar-function-exists} - then @var{execute-it} -@end group -@end smallexample - -@code{menu-bar-update-yank-menu} is one of the functions that make it -possible to use the `Select and Paste' menu in the Edit item of a menu -bar; using a mouse, you can look at the various pieces of text you -have saved and select one piece to paste. - -Finally, the last expression in the @code{kill-new} function adds the -newly copied string to whatever facility exists for copying and -pasting among different programs running in a windowing system. In -the X Windowing system, for example, the @code{x-select-text} function -takes the string and stores it in memory operated by X. You can paste -the string in another program, such as an Xterm. - -@need 1200 -The expression looks like this: - -@smallexample -@group - (if interprogram-cut-function - (funcall interprogram-cut-function string (not replace)))) -@end group -@end smallexample - -If an @code{interprogram-cut-function} exists, then Emacs executes -@code{funcall}, which in turn calls its first argument as a function -and passes the remaining arguments to it. (Incidentally, as far as I -can see, this @code{if} expression could be replaced by an @code{and} -expression similar to the one in the first part of the function.) - -We are not going to discuss windowing systems and other programs -further, but merely note that this is a mechanism that enables GNU -Emacs to work easily and well with other programs. - -This code for placing text in the kill ring, either concatenated with -an existing element or as a new element, leads us to the code for -bringing back text that has been cut out of the buffer---the yank -commands. However, before discussing the yank commands, it is better -to learn how lists are implemented in a computer. This will make -clear such mysteries as the use of the term `pointer'. - -@need 1250 -@node cons & search-fwd Review, search Exercises, copy-region-as-kill, Cutting & Storing Text +@need 1250 +@node cons & search-fwd Review, search Exercises, defvar, Cutting & Storing Text @comment node-name, next, previous, up @section Review @@ -8762,6 +9487,10 @@ @end group @end smallexample +@item funcall +@code{funcall} evaluates its first argument as a function. It passes +its remaining arguments to its first argument. + @item nthcdr Return the result of taking @sc{cdr} `n' times on a list. @iftex @@ -8826,15 +9555,19 @@ and restore that narrowing after evaluating the arguments. @item search-forward -Search for a string, and if the string is found, move point. - -@need 1250 -@noindent -Takes four arguments: +Search for a string, and if the string is found, move point. With a +regular expression, use the similar @code{re-search-forward}. +(@xref{Regexp Search, , Regular Expression Searches}, for an +explanation of regular expression patterns and searches.) + +@need 1250 +@noindent +@code{search-forward} and @code{re-search-forward} take four +arguments: @enumerate @item -The string to search for. +The string or regular expression to search for. @item Optionally, the limit of the search. @@ -8856,14 +9589,15 @@ buffer and stores that text in the kill ring, so you can get it back by yanking. -@code{delete-and-extract-region} removes the text between point and -mark from the buffer and throws it away. You cannot get it back. - @code{copy-region-as-kill} copies the text between point and mark into the kill ring, from which you can get it by yanking. The function does not cut or remove the text from the buffer. @end table +@code{delete-and-extract-region} removes the text between point and +mark from the buffer and throws it away. You cannot get it back. +(This is not an interactive command.) + @need 1500 @node search Exercises, , cons & search-fwd Review, Cutting & Storing Text @section Searching Exercises @@ -8904,7 +9638,7 @@ @menu * Lists diagrammed:: -* Symbols as Chest:: Exploring a powerful metaphor. +* Symbols as Chest:: * List Exercise:: @end menu @@ -8940,7 +9674,7 @@ @ifset print-postscript-figures @sp 1 @tex -@image{cons-1} +@center @image{cons-1} %%%% old method of including an image % \input /usr/local/lib/tex/inputs/psfig.tex % \centerline{\psfig{figure=/usr/local/lib/emacs/man/cons-1.eps}} @@ -9003,7 +9737,7 @@ @ifset print-postscript-figures @sp 1 @tex -@image{cons-2} +@center @image{cons-2} %%%% old method of including an image % \input /usr/local/lib/tex/inputs/psfig.tex % \centerline{\psfig{figure=/usr/local/lib/emacs/man/cons-2.eps}} @@ -9052,7 +9786,7 @@ @ifset print-postscript-figures @sp 1 @tex -@image{cons-2a} +@center @image{cons-2a} %%%% old method of including an image % \input /usr/local/lib/tex/inputs/psfig.tex % \centerline{\psfig{figure=/usr/local/lib/emacs/man/cons-2a.eps}} @@ -9119,7 +9853,7 @@ @ifset print-postscript-figures @sp 1 @tex -@image{cons-3} +@center @image{cons-3} %%%% old method of including an image % \input /usr/local/lib/tex/inputs/psfig.tex % \centerline{\psfig{figure=/usr/local/lib/emacs/man/cons-3.eps}} @@ -9191,7 +9925,7 @@ @ifset print-postscript-figures @sp 1 @tex -@image{cons-4} +@center @image{cons-4} %%%% old method of including an image % \input /usr/local/lib/tex/inputs/psfig.tex % \centerline{\psfig{figure=/usr/local/lib/emacs/man/cons-4.eps}} @@ -9258,7 +9992,7 @@ being a chest of drawers. The function definition is put in one drawer, the value in another, and so on. What is put in the drawer holding the value can be changed without affecting the contents of the -drawer holding the function definition, and vice-versa. +drawer holding the function definition, and vice-verse. Actually, what is put in each drawer is the address of the value or function definition. It is as if you found an old chest in the attic, @@ -9308,7 +10042,7 @@ @ifset print-postscript-figures @sp 1 @tex -@image{drawers} +@center @image{drawers} %%%% old method of including an image % \input /usr/local/lib/tex/inputs/psfig.tex % \centerline{\psfig{figure=/usr/local/lib/emacs/man/drawers.eps}} @@ -9361,7 +10095,6 @@ @comment node-name, next, previous, up @chapter Yanking Text Back @findex yank -@findex rotate-yank-pointer @cindex Text retrieval @cindex Retrieving text @cindex Pasting text @@ -9385,8 +10118,8 @@ list is handled as a ring.) @menu -* Kill Ring Overview:: The kill ring is a list. -* kill-ring-yank-pointer:: The @code{kill-ring-yank-pointer} variable. +* Kill Ring Overview:: +* kill-ring-yank-pointer:: * yank nthcdr Exercises:: @end menu @@ -9422,9 +10155,17 @@ (insert (car kill-ring-yank-pointer)) @end smallexample +@noindent +(Well, no more. In GNU Emacs 22, the function has been replaced by +@code{insert-for-yank} which calls @code{insert-for-yank-1} +repetitively for each @code{yank-handler} segment. In turn, +@code{insert-for-yank-1} strips text properties from the inserted text +according to @code{yank-excluded-properties}. Otherwise, it is just +like @code{insert}. We will stick with plain @code{insert} since it +is easier to understand.) + To begin to understand how @code{yank} and @code{yank-pop} work, it is -first necessary to look at the @code{kill-ring-yank-pointer} variable -and the @code{rotate-yank-pointer} function. +first necessary to look at the @code{kill-ring-yank-pointer} variable. @node kill-ring-yank-pointer, yank nthcdr Exercises, Kill Ring Overview, Yanking @comment node-name, next, previous, up @@ -9470,7 +10211,7 @@ | | | | | --> "yet more text" | | - | --> "a different piece of text + | --> "a different piece of text" | --> "some text" @end group @@ -9480,7 +10221,7 @@ @ifset print-postscript-figures @sp 1 @tex -@image{cons-5} +@center @image{cons-5} %%%% old method of including an image % \input /usr/local/lib/tex/inputs/psfig.tex % \centerline{\psfig{figure=/usr/local/lib/emacs/man/cons-5.eps}} @@ -9525,15 +10266,45 @@ of the kill ring of which the first element (the @sc{car}) will be inserted. -The @code{rotate-yank-pointer} function changes the element in the -kill ring to which the @code{kill-ring-yank-pointer} points; when the -pointer is set to point to the next element beyond the end of the kill -ring, it automatically sets it to point to the first element of the -kill ring. This is how the list is transformed into a ring. The -@code{rotate-yank-pointer} function itself is not difficult, but -contains many details. It and the much simpler @code{yank} and -@code{yank-pop} functions are described in an appendix. -@xref{Kill Ring, , Handling the Kill Ring}. +@ignore +In GNU Emacs 22, the @code{kill-new} function calls + +@code{(setq kill-ring-yank-pointer kill-ring)} + +(defun rotate-yank-pointer (arg) + "Rotate the yanking point in the kill ring. +With argument, rotate that many kills forward (or backward, if negative)." + (interactive "p") + (current-kill arg)) + +(defun current-kill (n &optional do-not-move) + "Rotate the yanking point by N places, and then return that kill. +If N is zero, `interprogram-paste-function' is set, and calling it +returns a string, then that string is added to the front of the +kill ring and returned as the latest kill. +If optional arg DO-NOT-MOVE is non-nil, then don't actually move the +yanking point; just return the Nth kill forward." + (let ((interprogram-paste (and (= n 0) + interprogram-paste-function + (funcall interprogram-paste-function)))) + (if interprogram-paste + (progn + ;; Disable the interprogram cut function when we add the new + ;; text to the kill ring, so Emacs doesn't try to own the + ;; selection, with identical text. + (let ((interprogram-cut-function nil)) + (kill-new interprogram-paste)) + interprogram-paste) + (or kill-ring (error "Kill ring is empty")) + (let ((ARGth-kill-element + (nthcdr (mod (- n (length kill-ring-yank-pointer)) + (length kill-ring)) + kill-ring))) + (or do-not-move + (setq kill-ring-yank-pointer ARGth-kill-element)) + (car ARGth-kill-element))))) + +@end ignore @need 1500 @node yank nthcdr Exercises, , kill-ring-yank-pointer, Yanking @@ -9584,9 +10355,9 @@ 15 and 30 times their default value.}. @menu -* while:: Causing a stretch of code to repeat. +* while:: * dolist dotimes:: -* Recursion:: Causing a function to call itself. +* Recursion:: * Looping exercise:: @end menu @@ -9621,11 +10392,11 @@ @end smallexample @menu -* Looping with while:: Repeat so long as test returns true. -* Loop Example:: A @code{while} loop that uses a list. -* print-elements-of-list:: Uses @code{while}, @code{car}, @code{cdr}. -* Incrementing Loop:: A loop with an incrementing counter. -* Decrementing Loop:: A loop with a decrementing counter. +* Looping with while:: +* Loop Example:: +* print-elements-of-list:: +* Incrementing Loop:: +* Decrementing Loop:: @end menu @node Looping with while, Loop Example, while, while @@ -9776,8 +10547,9 @@ @cindex @file{*scratch*} buffer The function requires several lines for its output. If you are -reading this in Emacs 21 or a later version, you can evaluate the -following expression inside of Info, as usual. +reading this in a recent instance of GNU Emacs, +@c GNU Emacs 21, GNU Emacs 22, or a later version, +you can evaluate the following expression inside of Info, as usual. If you are using an earlier version of Emacs, you need to copy the necessary expressions to your @file{*scratch*} buffer and evaluate @@ -9787,8 +10559,10 @@ You can copy the expressions by marking the beginning of the region with @kbd{C-@key{SPC}} (@code{set-mark-command}), moving the cursor to the end of the region and then copying the region using @kbd{M-w} -(@code{copy-region-as-kill}). In the @file{*scratch*} buffer, you can -yank the expressions back by typing @kbd{C-y} (@code{yank}). +(@code{kill-ring-save}, which calls @code{copy-region-as-kill} and +then provides visual feedback). In the @file{*scratch*} +buffer, you can yank the expressions back by typing @kbd{C-y} +(@code{yank}). After you have copied the expressions to the @file{*scratch*} buffer, evaluate each expression in turn. Be sure to evaluate the last @@ -9801,7 +10575,7 @@ each @samp{^J} stands for a `newline'.) @need 1500 -If you are using Emacs 21 or later, you can evaluate these expressions +In a recent instance of GNU Emacs, you can evaluate these expressions directly in the Info buffer, and the echo area will grow to show the results. @@ -9882,9 +10656,9 @@ is set to 1. @menu -* Incrementing Example:: Counting pebbles in a triangle. -* Inc Example parts:: The parts of the function definition. -* Inc Example altogether:: Putting the function definition together. +* Incrementing Example:: +* Inc Example parts:: +* Inc Example altogether:: @end menu @node Incrementing Example, Inc Example parts, Incrementing Loop, Incrementing Loop @@ -9967,9 +10741,9 @@ called @code{number-of-rows}. Finally, we need a variable to use as a counter. We could call this -variable @code{counter}, but a better name is @code{row-number}. -That is because what the counter does is count rows, and a program -should be written to be as understandable as possible. +variable @code{counter}, but a better name is @code{row-number}. That +is because what the counter does in this function is count rows, and a +program should be written to be as understandable as possible. When the Lisp interpreter first starts evaluating the expressions in the function, the value of @code{total} should be set to zero, since we have @@ -10092,7 +10866,7 @@ (let (@var{varlist}) (while (@var{true-or-false-test}) @var{body-of-while}@dots{} ) - @dots{} ) ; @r{Need final expression here.} + @dots{} )) ; @r{Need final expression here.} @end group @end smallexample @@ -10190,9 +10964,9 @@ @end smallexample @menu -* Decrementing Example:: More pebbles on the beach. -* Dec Example parts:: The parts of the function definition. -* Dec Example altogether:: Putting the function definition together. +* Decrementing Example:: +* Dec Example parts:: +* Dec Example altogether:: @end menu @node Decrementing Example, Dec Example parts, Decrementing Loop, Decrementing Loop @@ -10547,13 +11321,13 @@ arguments that the final instance will stop. @menu -* Building Robots:: Same model, different serial number ... -* Recursive Definition Parts:: Walk until you stop ... -* Recursion with list:: Using a list as the test whether to recurse. +* Building Robots:: +* Recursive Definition Parts:: +* Recursion with list:: * Recursive triangle function:: * Recursion with cond:: -* Recursive Patterns:: Often used templates. -* No Deferment:: Don't store up work ... +* Recursive Patterns:: +* No Deferment:: * No deferment solution:: @end menu @@ -10668,8 +11442,8 @@ of numbers can be written recursively. Here is the code, including an expression to set the value of the variable @code{animals} to a list. -If you are using Emacs 20 or before, this example must be copied to -the @file{*scratch*} buffer and each expression must be evaluated +If you are using GNU Emacs 20 or before, this example must be copied +to the @file{*scratch*} buffer and each expression must be evaluated there. Use @kbd{C-u C-x C-e} to evaluate the @code{(print-elements-recursively animals)} expression so that the results are printed in the buffer; otherwise the Lisp interpreter will @@ -10679,8 +11453,8 @@ of the @code{print-elements-recursively} function, before the comment. Otherwise, the Lisp interpreter will try to evaluate the comment. -If you are using Emacs 21 or later, you can evaluate this expression -directly in Info. +If you are using a more recent version of Emacs, you can evaluate this +expression directly in Info. @findex print-elements-recursively @smallexample @@ -10690,11 +11464,10 @@ (defun print-elements-recursively (list) "Print each element of LIST on a line of its own. Uses recursion." - (if list ; @r{do-again-test} - (progn + (when list ; @r{do-again-test} (print (car list)) ; @r{body} (print-elements-recursively ; @r{recursive call} - (cdr list))))) ; @r{next-step-expression} + (cdr list)))) ; @r{next-step-expression} (print-elements-recursively animals) @end group @@ -10716,7 +11489,7 @@ assemblies a second robot and tells it what to do; the second robot is a different individual from the first, but is the same model. -When the second evaluation occurs, the @code{if} expression is +When the second evaluation occurs, the @code{when} expression is evaluated and if true, prints the first element of the list it receives as its argument (which is the second element of the original list). Then the function `calls itself' with the @sc{cdr} of the list @@ -10735,7 +11508,7 @@ Eventually, the function invokes itself on an empty list. It creates a new instance whose argument is @code{nil}. The conditional expression tests the value of @code{list}. Since the value of @code{list} is -@code{nil}, the @code{if} expression tests false so the then-part is +@code{nil}, the @code{when} expression tests false so the then-part is not evaluated. The function as a whole then returns @code{nil}. @need 1200 @@ -10755,6 +11528,7 @@ @end group @end smallexample +@need 2000 @node Recursive triangle function, Recursion with cond, Recursion with list, Recursion @comment node-name, next, previous, up @subsection Recursion in Place of a Counter @@ -11114,11 +11888,10 @@ (defun print-elements-recursively (list) "Print each element of LIST on a line of its own. Uses recursion." - (if list ; @r{do-again-test} - (progn + (when list ; @r{do-again-test} (print (car list)) ; @r{body} (print-elements-recursively ; @r{recursive call} - (cdr list))))) ; @r{next-step-expression} + (cdr list)))) ; @r{next-step-expression} (print-elements-recursively animals) @end group @@ -11129,9 +11902,9 @@ @itemize @bullet @item -If the list be empty, do nothing. -@item -But if the list has at least one element, +When the list is empty, do nothing. +@item +But when the list has at least one element, @itemize @minus @item act on the beginning of the list (the @sc{car} of the list), @@ -11250,7 +12023,7 @@ ;; Third do-again-test: when to skip element; ;; recursively call shorter list with next-step expression - (t (keep-three-letter-words (cdr word-list))))) + (t (keep-three-letter-words (cdr word-list))))) @end group @group @@ -11432,7 +12205,7 @@ @need 1200 @noindent and find that the result is false, so it will invoke -the then-part of the @code{if} clause: +the else-part of the @code{if} clause: @smallexample @group @@ -11548,7 +12321,7 @@ @ref{Indicating, , Indicating, texinfo, Texinfo Manual}, which goes to a Texinfo manual in the current directory. Or, if you are on the Internet, see -@uref{http://www.gnu.org/manual/texinfo-4.6/html_node/Indicating.html} +@uref{http://www.gnu.org/software/texinfo/manual/texinfo/} @end ifhtml @iftex ``Indicating Definitions, Commands, etc.'' in @cite{Texinfo, The GNU @@ -11594,11 +12367,11 @@ introduces several new features. @menu -* sentence-end:: The regular expression for @code{sentence-end}. -* re-search-forward:: Very similar to @code{search-forward}. -* forward-sentence:: A straightforward example of regexp search. -* forward-paragraph:: A somewhat complex example. -* etags:: How to create your own @file{TAGS} table. +* sentence-end:: +* re-search-forward:: +* forward-sentence:: +* forward-paragraph:: +* etags:: * Regexp Review:: * re-search Exercises:: @end menu @@ -11612,9 +12385,9 @@ end of a sentence. What should this regular expression be? Clearly, a sentence may be ended by a period, a question mark, or an -exclamation mark. Indeed, only clauses that end with one of those three -characters should be considered the end of a sentence. This means that -the pattern should include the character set: +exclamation mark. Indeed, in English, only clauses that end with one +of those three characters should be considered the end of a sentence. +This means that the pattern should include the character set: @smallexample [.?!] @@ -11697,13 +12470,27 @@ @end group @end smallexample +@noindent +(Well, not in GNU Emacs 22; that is because of an effort to make the +process simpler and to handle more glyphs and languages. When the +value of @code{sentence-end} is @code{nil}, then use the value defined +by the function @code{sentence-end}. (Here is a use of the difference +between a value and a function in Emacs Lisp.) The function returns a +value constructed from the variables @code{sentence-end-base}, +@code{sentence-end-double-space}, @code{sentence-end-without-period}, +and @code{sentence-end-without-space}. The critical variable is +@code{sentence-end-base}; its global value is similar to the one +described above but it also contains two additional quotation marks. +These have differing degrees of curliness. The +@code{sentence-end-without-period} variable, when true, tells Emacs +that a sentence may end without a period, such as text in Thai.) + @ignore - @noindent (Note that here the @key{TAB}, two spaces, and @key{RET} are shown literally in the pattern.) -This regular expression can be decyphered as follows: +This regular expression can be deciphered as follows: @table @code @item [.?!] @@ -11739,7 +12526,6 @@ the pattern, the carriage return is inserted as an actual carriage return between square brackets but here it is shown as @key{RET}. @end table - @end ignore @node re-search-forward, forward-sentence, sentence-end, Regexp Search @@ -11802,7 +12588,7 @@ @need 1200 In the @code{forward-sentence} function, the regular expression will be -the value of the variable @code{sentence-end}, namely: +the value of the variable @code{sentence-end}. In simple form, that is: @smallexample @group @@ -11831,8 +12617,8 @@ @menu * Complete forward-sentence:: -* fwd-sentence while loops:: Two @code{while} loops. -* fwd-sentence re-search:: A regular expression search. +* fwd-sentence while loops:: +* fwd-sentence re-search:: @end menu @node Complete forward-sentence, fwd-sentence while loops, forward-sentence, forward-sentence @@ -11843,6 +12629,44 @@ @need 1250 Here is the code for @code{forward-sentence}: +@c in GNU Emacs 22 +@smallexample +@group +(defun forward-sentence (&optional arg) + "Move forward to next `sentence-end'. With argument, repeat. +With negative argument, move backward repeatedly to `sentence-beginning'. + +The variable `sentence-end' is a regular expression that matches ends of +sentences. Also, every paragraph boundary terminates sentences as well." +@end group +@group + (interactive "p") + (or arg (setq arg 1)) + (let ((opoint (point)) + (sentence-end (sentence-end))) + (while (< arg 0) + (let ((pos (point)) + (par-beg (save-excursion (start-of-paragraph-text) (point)))) + (if (and (re-search-backward sentence-end par-beg t) + (or (< (match-end 0) pos) + (re-search-backward sentence-end par-beg t))) + (goto-char (match-end 0)) + (goto-char par-beg))) + (setq arg (1+ arg))) +@end group +@group + (while (> arg 0) + (let ((par-end (save-excursion (end-of-paragraph-text) (point)))) + (if (re-search-forward sentence-end par-end t) + (skip-chars-backward " \t\n") + (goto-char par-end))) + (setq arg (1- arg))) + (constrain-to-field nil opoint t))) +@end group +@end smallexample + +@ignore +GNU Emacs 21 @smallexample @group (defun forward-sentence (&optional arg) @@ -11872,6 +12696,7 @@ (setq arg (1- arg)))) @end group @end smallexample +@end ignore The function looks long at first sight and it is best to look at its skeleton first, and then its muscle. The way to see the skeleton is to @@ -11883,16 +12708,21 @@ "@var{documentation}@dots{}" (interactive "p") (or arg (setq arg 1)) - (while (< arg 0) - @var{body-of-while-loop} - (while (> arg 0) - @var{body-of-while-loop} + (let ((opoint (point)) (sentence-end (sentence-end))) + (while (< arg 0) + (let ((pos (point)) + (par-beg (save-excursion (start-of-paragraph-text) (point)))) + @var{rest-of-body-of-while-loop-when-going-backwards} + (while (> arg 0) + (let ((par-end (save-excursion (end-of-paragraph-text) (point)))) + @var{rest-of-body-of-while-loop-when-going-forwards} + @var{handle-forms-and-equivalent} @end group @end smallexample This looks much simpler! The function definition consists of documentation, an @code{interactive} expression, an @code{or} -expression, and @code{while} loops. +expression, a @code{let} expression, and @code{while} loops. Let's look at each of these parts in turn. @@ -11902,24 +12732,31 @@ that the processed prefix argument, if any, is passed to the function as its argument. (This will be a number.) If the function is not passed an argument (it is optional) then the argument -@code{arg} will be bound to 1. When @code{forward-sentence} is called -non-interactively without an argument, @code{arg} is bound to +@code{arg} will be bound to 1. + +When @code{forward-sentence} is called non-interactively without an +argument, @code{arg} is bound to @code{nil}. The @code{or} expression +handles this. What it does is either leave the value of @code{arg} as +it is, but only if @code{arg} is bound to a value; or it sets the +value of @code{arg} to 1, in the case when @code{arg} is bound to @code{nil}. -The @code{or} expression handles the prefix argument. What it does is -either leave the value of @code{arg} as it is, but only if @code{arg} -is bound to a value; or it sets the value of @code{arg} to 1, in the -case when @code{arg} is bound to @code{nil}. +Next is a @code{let}. That specifies the values of two local +variables, @code{point} and @code{sentence-end}. The local value of +point, from before the search, is used in the +@code{constrain-to-field} function which handles forms and +equivalents. The @code{sentence-end} variable is set by the +@code{sentence-end} function. @node fwd-sentence while loops, fwd-sentence re-search, Complete forward-sentence, forward-sentence @unnumberedsubsec The @code{while} loops -Two @code{while} loops follow the @code{or} expression. The first -@code{while} has a true-or-false-test that tests true if the prefix -argument for @code{forward-sentence} is a negative number. This is for -going backwards. The body of this loop is similar to the body of the -second @code{while} clause, but it is not exactly the same. We will -skip this @code{while} loop and concentrate on the second @code{while} +Two @code{while} loops follow. The first @code{while} has a +true-or-false-test that tests true if the prefix argument for +@code{forward-sentence} is a negative number. This is for going +backwards. The body of this loop is similar to the body of the second +@code{while} clause, but it is not exactly the same. We will skip +this @code{while} loop and concentrate on the second @code{while} loop. @need 1500 @@ -11988,7 +12825,7 @@ @code{save-excursion} restores point to its original position. Thus, the @code{let} binds @code{par-end} to the value returned by the @code{save-excursion} expression, which is the position of the end of -the paragraph. (The @code{(end-of-paragraph-text)} function uses +the paragraph. (The @code{end-of-paragraph-text} function uses @code{forward-paragraph}, which we will discuss shortly.) @need 1200 @@ -12052,6 +12889,9 @@ argument, which is @code{(goto-char par-end)}: it moves point to the end of the paragraph. +(And if the text is in a form or equivalent, and point may not move +fully, then the @code{constrain-to-field} function comes into play.) + Regular expression searches are exceptionally useful and the pattern illustrated by @code{re-search-forward}, in which the search is the test of an @code{if} expression, is handy. You will see or write code @@ -12062,6 +12902,151 @@ @section @code{forward-paragraph}: a Goldmine of Functions @findex forward-paragraph +@ignore +@c in GNU Emacs 22 +(defun forward-paragraph (&optional arg) + "Move forward to end of paragraph. +With argument ARG, do it ARG times; +a negative argument ARG = -N means move backward N paragraphs. + +A line which `paragraph-start' matches either separates paragraphs +\(if `paragraph-separate' matches it also) or is the first line of a paragraph. +A paragraph end is the beginning of a line which is not part of the paragraph +to which the end of the previous line belongs, or the end of the buffer. +Returns the count of paragraphs left to move." + (interactive "p") + (or arg (setq arg 1)) + (let* ((opoint (point)) + (fill-prefix-regexp + (and fill-prefix (not (equal fill-prefix "")) + (not paragraph-ignore-fill-prefix) + (regexp-quote fill-prefix))) + ;; Remove ^ from paragraph-start and paragraph-sep if they are there. + ;; These regexps shouldn't be anchored, because we look for them + ;; starting at the left-margin. This allows paragraph commands to + ;; work normally with indented text. + ;; This hack will not find problem cases like "whatever\\|^something". + (parstart (if (and (not (equal "" paragraph-start)) + (equal ?^ (aref paragraph-start 0))) + (substring paragraph-start 1) + paragraph-start)) + (parsep (if (and (not (equal "" paragraph-separate)) + (equal ?^ (aref paragraph-separate 0))) + (substring paragraph-separate 1) + paragraph-separate)) + (parsep + (if fill-prefix-regexp + (concat parsep "\\|" + fill-prefix-regexp "[ \t]*$") + parsep)) + ;; This is used for searching. + (sp-parstart (concat "^[ \t]*\\(?:" parstart "\\|" parsep "\\)")) + start found-start) + (while (and (< arg 0) (not (bobp))) + (if (and (not (looking-at parsep)) + (re-search-backward "^\n" (max (1- (point)) (point-min)) t) + (looking-at parsep)) + (setq arg (1+ arg)) + (setq start (point)) + ;; Move back over paragraph-separating lines. + (forward-char -1) (beginning-of-line) + (while (and (not (bobp)) + (progn (move-to-left-margin) + (looking-at parsep))) + (forward-line -1)) + (if (bobp) + nil + (setq arg (1+ arg)) + ;; Go to end of the previous (non-separating) line. + (end-of-line) + ;; Search back for line that starts or separates paragraphs. + (if (if fill-prefix-regexp + ;; There is a fill prefix; it overrides parstart. + (let (multiple-lines) + (while (and (progn (beginning-of-line) (not (bobp))) + (progn (move-to-left-margin) + (not (looking-at parsep))) + (looking-at fill-prefix-regexp)) + (unless (= (point) start) + (setq multiple-lines t)) + (forward-line -1)) + (move-to-left-margin) + ;; This deleted code caused a long hanging-indent line + ;; not to be filled together with the following lines. + ;; ;; Don't move back over a line before the paragraph + ;; ;; which doesn't start with fill-prefix + ;; ;; unless that is the only line we've moved over. + ;; (and (not (looking-at fill-prefix-regexp)) + ;; multiple-lines + ;; (forward-line 1)) + (not (bobp))) + (while (and (re-search-backward sp-parstart nil 1) + (setq found-start t) + ;; Found a candidate, but need to check if it is a + ;; REAL parstart. + (progn (setq start (point)) + (move-to-left-margin) + (not (looking-at parsep))) + (not (and (looking-at parstart) + (or (not use-hard-newlines) + (bobp) + (get-text-property + (1- start) 'hard))))) + (setq found-start nil) + (goto-char start)) + found-start) + ;; Found one. + (progn + ;; Move forward over paragraph separators. + ;; We know this cannot reach the place we started + ;; because we know we moved back over a non-separator. + (while (and (not (eobp)) + (progn (move-to-left-margin) + (looking-at parsep))) + (forward-line 1)) + ;; If line before paragraph is just margin, back up to there. + (end-of-line 0) + (if (> (current-column) (current-left-margin)) + (forward-char 1) + (skip-chars-backward " \t") + (if (not (bolp)) + (forward-line 1)))) + ;; No starter or separator line => use buffer beg. + (goto-char (point-min)))))) + + (while (and (> arg 0) (not (eobp))) + ;; Move forward over separator lines... + (while (and (not (eobp)) + (progn (move-to-left-margin) (not (eobp))) + (looking-at parsep)) + (forward-line 1)) + (unless (eobp) (setq arg (1- arg))) + ;; ... and one more line. + (forward-line 1) + (if fill-prefix-regexp + ;; There is a fill prefix; it overrides parstart. + (while (and (not (eobp)) + (progn (move-to-left-margin) (not (eobp))) + (not (looking-at parsep)) + (looking-at fill-prefix-regexp)) + (forward-line 1)) + (while (and (re-search-forward sp-parstart nil 1) + (progn (setq start (match-beginning 0)) + (goto-char start) + (not (eobp))) + (progn (move-to-left-margin) + (not (looking-at parsep))) + (or (not (looking-at parstart)) + (and use-hard-newlines + (not (get-text-property (1- start) 'hard))))) + (forward-char 1)) + (if (< (point) (point-max)) + (goto-char start)))) + (constrain-to-field nil opoint t) + ;; Return the number of steps that could not be done. + arg)) +@end ignore + The @code{forward-paragraph} function moves point forward to the end of the paragraph. It is usually bound to @kbd{M-@}} and makes use of a number of functions that are important in themselves, including @@ -12091,14 +13076,9 @@ This is an added complication. @menu -* forward-paragraph in brief:: Key parts of the function definition. -* fwd-para let:: The @code{let*} expression. -* fwd-para while:: The forward motion @code{while} loop. -* fwd-para between paragraphs:: Movement between paragraphs. -* fwd-para within paragraph:: Movement within paragraphs. -* fwd-para no fill prefix:: When there is no fill prefix. -* fwd-para with fill prefix:: When there is a fill prefix. -* fwd-para summary:: Summary of @code{forward-paragraph} code. +* forward-paragraph in brief:: +* fwd-para let:: +* fwd-para while:: @end menu @node forward-paragraph in brief, fwd-para let, forward-paragraph, forward-paragraph @@ -12121,12 +13101,10 @@ (or arg (setq arg 1)) (let* @var{varlist} - (while (< arg 0) ; @r{backward-moving-code} + (while (and (< arg 0) (not (bobp))) ; @r{backward-moving-code} @dots{} - (setq arg (1+ arg))) - (while (> arg 0) ; @r{forward-moving-code} + (while (and (> arg 0) (not (eobp))) ; @r{forward-moving-code} @dots{} - (setq arg (1- arg))))) @end group @end smallexample @@ -12147,22 +13125,34 @@ @unnumberedsubsec The @code{let*} expression The next line of the @code{forward-paragraph} function begins a -@code{let*} expression. This is a different kind of expression than -we have seen so far. The symbol is @code{let*} not @code{let}. +@code{let*} expression. This is a different than @code{let}. The +symbol is @code{let*} not @code{let}. The @code{let*} special form is like @code{let} except that Emacs sets each variable in sequence, one after another, and variables in the latter part of the varlist can make use of the values to which Emacs set variables in the earlier part of the varlist. -In the @code{let*} expression in this function, Emacs binds two -variables: @code{fill-prefix-regexp} and @code{paragraph-separate}. -The value to which @code{paragraph-separate} is bound depends on the -value of @code{fill-prefix-regexp}. - -@need 1200 -Let's look at each in turn. The symbol @code{fill-prefix-regexp} is -set to the value returned by evaluating the following list: +@ignore +( refappend save-excursion, , code save-excursion in code append-to-buffer .) +@end ignore + +(@ref{append save-excursion, , @code{save-excursion} in @code{append-to-buffer}}.) + +In the @code{let*} expression in this function, Emacs binds a total of +seven variables: @code{opoint}, @code{fill-prefix-regexp}, +@code{parstart}, @code{parsep}, @code{sp-parstart}, @code{start}, and +@code{found-start}. + +The variable @code{parsep} appears twice, first, to remove instances +of @samp{^}, and second, to handle fill prefixes. + +The variable @code{opoint} is just the value of @code{point}. As you +can guess, it is used in a @code{constrain-to-field} expression, just +as in @code{forward-sentence}. + +The variable @code{fill-prefix-regexp} is set to the value returned by +evaluating the following list: @smallexample @group @@ -12226,49 +13216,44 @@ will exactly match the fill prefix if the fill prefix exists. Otherwise, the variable will be set to @code{nil}. -The second local variable in the @code{let*} expression is -@code{paragraph-separate}. It is bound to the value returned by -evaluating the expression: - -@smallexample -@group -(if fill-prefix-regexp - (concat paragraph-separate - "\\|^" fill-prefix-regexp "[ \t]*$") - paragraph-separate))) -@end group -@end smallexample - -This expression shows why @code{let*} rather than @code{let} was used. -The true-or-false-test for the @code{if} depends on whether the variable -@code{fill-prefix-regexp} evaluates to @code{nil} or some other value. +The next two local variables in the @code{let*} expression are +designed to remove instances of @samp{^} from @code{parstart} and +@code{parsep}, the local variables which indicate the paragraph start +and the paragraph separator. The next expression sets @code{parsep} +again. That is to handle fill prefixes. + +This is the setting that requires the definition call @code{let*} +rather than @code{let}. The true-or-false-test for the @code{if} +depends on whether the variable @code{fill-prefix-regexp} evaluates to +@code{nil} or some other value. If @code{fill-prefix-regexp} does not have a value, Emacs evaluates -the else-part of the @code{if} expression and binds -@code{paragraph-separate} to its local value. -(@code{paragraph-separate} is a regular expression that matches what -separates paragraphs.) +the else-part of the @code{if} expression and binds @code{parsep} to +its local value. (@code{parsep} is a regular expression that matches +what separates paragraphs.) But if @code{fill-prefix-regexp} does have a value, Emacs evaluates -the then-part of the @code{if} expression and binds -@code{paragraph-separate} to a regular expression that includes the -@code{fill-prefix-regexp} as part of the pattern. - -Specifically, @code{paragraph-separate} is set to the original value -of the paragraph separate regular expression concatenated with an -alternative expression that consists of the @code{fill-prefix-regexp} -followed by a blank line. The @samp{^} indicates that the -@code{fill-prefix-regexp} must begin a line, and the optional -whitespace to the end of the line is defined by @w{@code{"[ \t]*$"}}.) -The @samp{\\|} defines this portion of the regexp as an alternative to -@code{paragraph-separate}. +the then-part of the @code{if} expression and binds @code{parsep} to a +regular expression that includes the @code{fill-prefix-regexp} as part +of the pattern. + +Specifically, @code{parsep} is set to the original value of the +paragraph separate regular expression concatenated with an alternative +expression that consists of the @code{fill-prefix-regexp} followed by +optional whitespace to the end of the line. The whitespace is defined +by @w{@code{"[ \t]*$"}}.) The @samp{\\|} defines this portion of the +regexp as an alternative to @code{parsep}. + +According to a comment in the code, the next local variable, +@code{sp-parstart}, is used for searching, and then the final two, +@code{start} and @code{found-start}, are set to @code{nil}. Now we get into the body of the @code{let*}. The first part of the body of the @code{let*} deals with the case when the function is given a negative argument and is therefore moving backwards. We will skip this section. -@node fwd-para while, fwd-para between paragraphs, fwd-para let, forward-paragraph +@node fwd-para while, , fwd-para let, forward-paragraph @unnumberedsubsec The forward motion @code{while} loop The second part of the body of the @code{let*} deals with forward @@ -12278,243 +13263,161 @@ @code{while} loop is evaluated exactly once, and the cursor moves forward one paragraph. +@ignore +(while (and (> arg 0) (not (eobp))) + + ;; Move forward over separator lines... + (while (and (not (eobp)) + (progn (move-to-left-margin) (not (eobp))) + (looking-at parsep)) + (forward-line 1)) + (unless (eobp) (setq arg (1- arg))) + ;; ... and one more line. + (forward-line 1) + + (if fill-prefix-regexp + ;; There is a fill prefix; it overrides parstart. + (while (and (not (eobp)) + (progn (move-to-left-margin) (not (eobp))) + (not (looking-at parsep)) + (looking-at fill-prefix-regexp)) + (forward-line 1)) + + (while (and (re-search-forward sp-parstart nil 1) + (progn (setq start (match-beginning 0)) + (goto-char start) + (not (eobp))) + (progn (move-to-left-margin) + (not (looking-at parsep))) + (or (not (looking-at parstart)) + (and use-hard-newlines + (not (get-text-property (1- start) 'hard))))) + (forward-char 1)) + + (if (< (point) (point-max)) + (goto-char start)))) +@end ignore + This part handles three situations: when point is between paragraphs, -when point is within a paragraph and there is a fill prefix, and -when point is within a paragraph and there is no fill prefix. +when there is a fill prefix and when there is no fill prefix. @need 800 The @code{while} loop looks like this: @smallexample @group -(while (> arg 0) - (beginning-of-line) +;; @r{going forwards and not at the end of the buffer} +(while (and (> arg 0) (not (eobp))) ;; @r{between paragraphs} - (while (prog1 (and (not (eobp)) - (looking-at paragraph-separate)) - (forward-line 1))) -@end group - -@group - ;; @r{within paragraphs, with a fill prefix} + ;; Move forward over separator lines... + (while (and (not (eobp)) + (progn (move-to-left-margin) (not (eobp))) + (looking-at parsep)) + (forward-line 1)) + ;; @r{This decrements the loop} + (unless (eobp) (setq arg (1- arg))) + ;; ... and one more line. + (forward-line 1) +@end group + +@group (if fill-prefix-regexp - ;; @r{There is a fill prefix; it overrides paragraph-start.} + ;; There is a fill prefix; it overrides parstart; + ;; we go forward line by line (while (and (not (eobp)) - (not (looking-at paragraph-separate)) + (progn (move-to-left-margin) (not (eobp))) + (not (looking-at parsep)) (looking-at fill-prefix-regexp)) (forward-line 1)) @end group @group - ;; @r{within paragraphs, no fill prefix} - (if (re-search-forward paragraph-start nil t) - (goto-char (match-beginning 0)) - (goto-char (point-max)))) - - (setq arg (1- arg))) -@end group -@end smallexample - -We can see immediately that this is a decrementing counter @code{while} -loop, using the expression @code{(setq arg (1- arg))} as the decrementer. - -@need 800 -The body of the loop consists of three expressions: - -@smallexample -@group -;; @r{between paragraphs} -(beginning-of-line) -(while - @var{body-of-while}) -@end group - -@group -;; @r{within paragraphs, with fill prefix} -(if @var{true-or-false-test} - @var{then-part} -@end group - -@group -;; @r{within paragraphs, no fill prefix} - @var{else-part} -@end group -@end smallexample - -@noindent -When the Emacs Lisp interpreter evaluates the body of the -@code{while} loop, the first thing it does is evaluate the -@code{(beginning-of-line)} expression and move point to the beginning -of the line. Then there is an inner @code{while} loop. This -@code{while} loop is designed to move the cursor out of the blank -space between paragraphs, if it should happen to be there. Finally, -there is an @code{if} expression that actually moves point to the end -of the paragraph. - -@node fwd-para between paragraphs, fwd-para within paragraph, fwd-para while, forward-paragraph -@unnumberedsubsec Between paragraphs - -First, let us look at the inner @code{while} loop. This loop handles -the case when point is between paragraphs; it uses three functions -that are new to us: @code{prog1}, @code{eobp} and @code{looking-at}. -@findex prog1 + ;; There is no fill prefix; + ;; we go forward character by character + (while (and (re-search-forward sp-parstart nil 1) + (progn (setq start (match-beginning 0)) + (goto-char start) + (not (eobp))) + (progn (move-to-left-margin) + (not (looking-at parsep))) + (or (not (looking-at parstart)) + (and use-hard-newlines + (not (get-text-property (1- start) 'hard))))) + (forward-char 1)) +@end group + +@group + ;; and if there is no fill prefix and if we are not at the end, + ;; go to whatever was found in the regular expression search + ;; for sp-parstart + (if (< (point) (point-max)) + (goto-char start)))) +@end group +@end smallexample + @findex eobp +We can see that this is a decrementing counter @code{while} loop, +using the expression @code{(setq arg (1- arg))} as the decrementer. +That expression is not far from the @code{while}, but is hidden in +another Lisp macro, an @code{unless} macro. Unless we are at the end +of the buffer --- that is what the @code{eobp} function determines; it +is an abbreviation of @samp{End Of Buffer P} --- we decrease the value +of @code{arg} by one. + +(If we are at the end of the buffer, we cannot go forward any more and +the next loop of the @code{while} expression will test false since the +test is an @code{and} with @code{(not (eobp))}. The @code{not} +function means exactly as you expect; it is another name for +@code{null}, a function that returns true when its argument is false.) + +Interestingly, the loop count is not decremented until we leave the +space between paragraphs, unless we come to the end of buffer or stop +seeing the local value of the paragraph separator. + +That second @code{while} also has a @code{(move-to-left-margin)} +expression. The function is self-explanatory. It is inside a +@code{progn} expression and not the last element of its body, so it is +only invoked for its side effect, which is to move point to the left +margin of the current line. + @findex looking-at - -@itemize @bullet -@item -@code{prog1} is similar to the @code{progn} special form, -except that @code{prog1} evaluates its arguments in sequence and then -returns the value of its first argument as the value of the whole -expression. (@code{progn} returns the value of its last argument as the -value of the expression.) The second and subsequent arguments to -@code{prog1} are evaluated only for their side effects. - -@item -@code{eobp} is an abbreviation of @samp{End Of Buffer P} and is a -function that returns true if point is at the end of the buffer. - -@item -@code{looking-at} is a function that returns true if the text following -point matches the regular expression passed @code{looking-at} as its -argument. -@end itemize - -@need 800 -The @code{while} loop we are studying looks like this: - -@smallexample -@group -(while (prog1 (and (not (eobp)) - (looking-at paragraph-separate)) - (forward-line 1))) -@end group -@end smallexample - -@need 1200 -@noindent -This is a @code{while} loop with no body! The true-or-false-test of the -loop is the expression: - -@smallexample -@group -(prog1 (and (not (eobp)) - (looking-at paragraph-separate)) - (forward-line 1)) -@end group -@end smallexample - -@noindent -The first argument to the @code{prog1} is the @code{and} expression. It -has within in it a test of whether point is at the end of the buffer and -also a test of whether the pattern following point matches the regular -expression for separating paragraphs. - -If the cursor is not at the end of the buffer and if the characters -following the cursor mark the separation between two paragraphs, then -the @code{and} expression is true. After evaluating the @code{and} -expression, the Lisp interpreter evaluates the second argument to -@code{prog1}, which is @code{forward-line}. This moves point forward -one line. The value returned by the @code{prog1} however, is the -value of its first argument, so the @code{while} loop continues so -long as point is not at the end of the buffer and is between -paragraphs. When, finally, point is moved to a paragraph, the -@code{and} expression tests false. Note however, that the -@code{forward-line} command is carried out anyhow. This means that -when point is moved from between paragraphs to a paragraph, it is left -at the beginning of the second line of the paragraph. - -@node fwd-para within paragraph, fwd-para no fill prefix, fwd-para between paragraphs, forward-paragraph -@unnumberedsubsec Within paragraphs - -The next expression in the outer @code{while} loop is an @code{if} -expression. The Lisp interpreter evaluates the then-part of the -@code{if} when the @code{fill-prefix-regexp} variable has a value other -than @code{nil}, and it evaluates the else-part when the value of -@code{if fill-prefix-regexp} is @code{nil}, that is, when there is no -fill prefix. - -@node fwd-para no fill prefix, fwd-para with fill prefix, fwd-para within paragraph, forward-paragraph -@unnumberedsubsec No fill prefix - -It is simplest to look at the code for the case when there is no fill -prefix first. This code consists of yet another inner @code{if} -expression, and reads as follows: - -@smallexample -@group -(if (re-search-forward paragraph-start nil t) - (goto-char (match-beginning 0)) - (goto-char (point-max))) -@end group -@end smallexample - -@noindent -This expression actually does the work that most people think of as -the primary purpose of the @code{forward-paragraph} command: it causes -a regular expression search to occur that searches forward to the -start of the next paragraph and if it is found, moves point there; but -if the start of another paragraph if not found, it moves point to the -end of the accessible region of the buffer. - -The only unfamiliar part of this is the use of @code{match-beginning}. -This is another function that is new to us. The -@code{match-beginning} function returns a number specifying the -location of the start of the text that was matched by the last regular -expression search. - -The @code{match-beginning} function is used here because of a -characteristic of a forward search: a successful forward search, -regardless of whether it is a plain search or a regular expression -search, will move point to the end of the text that is found. In this -case, a successful search will move point to the end of the pattern for -@code{paragraph-start}, which will be the beginning of the next -paragraph rather than the end of the current one. - -However, we want to put point at the end of the current paragraph, not at -the beginning of the next one. The two positions may be different, -because there may be several blank lines between paragraphs. - -@findex match-beginning -When given an argument of 0, @code{match-beginning} returns the position -that is the start of the text that the most recent regular -expression search matched. In this case, the most recent regular -expression search is the one looking for @code{paragraph-start}, so -@code{match-beginning} returns the beginning position of the pattern, -rather than the end of the pattern. The beginning position is the end -of the paragraph. - -(Incidentally, when passed a positive number as an argument, the -@code{match-beginning} function will place point at that parenthesized -expression in the last regular expression. It is a useful function.) - -@node fwd-para with fill prefix, fwd-para summary, fwd-para no fill prefix, forward-paragraph -@unnumberedsubsec With a fill prefix - -The inner @code{if} expression just discussed is the else-part of an enclosing -@code{if} expression which tests whether there is a fill prefix. If -there is a fill prefix, the then-part of this @code{if} is evaluated. -It looks like this: - -@smallexample -@group -(while (and (not (eobp)) - (not (looking-at paragraph-separate)) - (looking-at fill-prefix-regexp)) - (forward-line 1)) -@end group -@end smallexample - -@noindent -What this expression does is move point forward line by line so long -as three conditions are true: +The @code{looking-at} function is also self-explanatory; it returns +true if the text after point matches the regular expression given as +its argument. + +The rest of the body of the loop looks difficult at first, but makes +sense as you come to understand it. + +@need 800 +First consider what happens if there is a fill prefix: + +@smallexample +@group + (if fill-prefix-regexp + ;; There is a fill prefix; it overrides parstart; + ;; we go forward line by line + (while (and (not (eobp)) + (progn (move-to-left-margin) (not (eobp))) + (not (looking-at parsep)) + (looking-at fill-prefix-regexp)) + (forward-line 1)) +@end group +@end smallexample + +@noindent +This expression moves point forward line by line so long +as four conditions are true: @enumerate @item Point is not at the end of the buffer. @item +We can move to the left margin of the text and are +not at the end of the buffer. + +@item The text following point does not separate paragraphs. @item @@ -12526,101 +13429,93 @@ function. This means that if the text has a fill prefix, the @code{looking-at} function will see it. -@node fwd-para summary, , fwd-para with fill prefix, forward-paragraph -@unnumberedsubsec Summary - -In summary, when moving forward, the @code{forward-paragraph} function -does the following: - -@itemize @bullet -@item -Move point to the beginning of the line. - -@item -Skip over lines between paragraphs. - -@item -Check whether there is a fill prefix, and if there is: - -@itemize --- - -@item -Go forward line by line so long as the line is not a paragraph -separating line. -@end itemize - -@item -But if there is no fill prefix, - -@itemize --- - -@item -Search for the next paragraph start pattern. - -@item -Go to the beginning of the paragraph start pattern, which will be the -end of the previous paragraph. - -@item -Or else go to the end of the accessible portion of the buffer. -@end itemize -@end itemize - -@need 1200 -For review, here is the code we have just been discussing, formatted -for clarity: - -@smallexample -@group -(interactive "p") -(or arg (setq arg 1)) -(let* ( - (fill-prefix-regexp - (and fill-prefix (not (equal fill-prefix "")) - (not paragraph-ignore-fill-prefix) - (regexp-quote fill-prefix))) -@end group - -@group - (paragraph-separate - (if fill-prefix-regexp - (concat paragraph-separate - "\\|^" - fill-prefix-regexp - "[ \t]*$") - paragraph-separate))) - - @var{omitted-backward-moving-code} @dots{} -@end group - -@group - (while (> arg 0) ; @r{forward-moving-code} - (beginning-of-line) - - (while (prog1 (and (not (eobp)) - (looking-at paragraph-separate)) - (forward-line 1))) -@end group - -@group - (if fill-prefix-regexp - (while (and (not (eobp)) ; @r{then-part} - (not (looking-at paragraph-separate)) - (looking-at fill-prefix-regexp)) - (forward-line 1)) -@end group -@group - ; @r{else-part: the inner-if} - (if (re-search-forward paragraph-start nil t) - (goto-char (match-beginning 0)) - (goto-char (point-max)))) - - (setq arg (1- arg))))) ; @r{decrementer} -@end group -@end smallexample +@need 1250 +Consider what happens when there is no fill prefix. + +@smallexample +@group + (while (and (re-search-forward sp-parstart nil 1) + (progn (setq start (match-beginning 0)) + (goto-char start) + (not (eobp))) + (progn (move-to-left-margin) + (not (looking-at parsep))) + (or (not (looking-at parstart)) + (and use-hard-newlines + (not (get-text-property (1- start) 'hard))))) + (forward-char 1)) +@end group +@end smallexample + +@noindent +This @code{while} loop has us searching forward for +@code{sp-parstart}, which is the combination of possible whitespace +with a the local value of the start of a paragraph or of a paragraph +separator. (The latter two are within an expression starting +@code{\(?:} so that they are not referenced by the +@code{match-beginning} function.) + +@need 800 +The two expressions, + +@smallexample +@group +(setq start (match-beginning 0)) +(goto-char start) +@end group +@end smallexample + +@noindent +mean go to the start of the text matched by the regular expression +search. + +The @code{(match-beginning 0)} expression is new. It returns a number +specifying the location of the start of the text that was matched by +the last search. + +The @code{match-beginning} function is used here because of a +characteristic of a forward search: a successful forward search, +regardless of whether it is a plain search or a regular expression +search, moves point to the end of the text that is found. In this +case, a successful search moves point to the end of the pattern for +@code{sp-parstart}. + +However, we want to put point at the end of the current paragraph, not +somewhere else. Indeed, since the search possibly includes the +paragraph separator, point may end up at the beginning of the next one +unless we use an expression that includes @code{match-beginning}. + +@findex match-beginning +When given an argument of 0, @code{match-beginning} returns the +position that is the start of the text matched by the most recent +search. In this case, the most recent search looks for +@code{sp-parstart}. The @code{(match-beginning 0)} expression returns +the beginning position of that pattern, rather than the end position +of that pattern. + +(Incidentally, when passed a positive number as an argument, the +@code{match-beginning} function returns the location of point at that +parenthesized expression in the last search unless that parenthesized +expression begins with @code{\(?:}. I don't know why @code{\(?:} +appears here since the argument is 0.) + +@need 1250 +The last expression when there is no fill prefix is + +@smallexample +@group +(if (< (point) (point-max)) + (goto-char start)))) +@end group +@end smallexample + +@noindent +This says that if there is no fill prefix and if we are not at the +end, point should move to the beginning of whatever was found by the +regular expression search for @code{sp-parstart}. The full definition for the @code{forward-paragraph} function not only -includes this code for going forwards, but also code for going backwards. +includes code for going forwards, but also code for going backwards. If you are reading this inside of GNU Emacs and you want to see the whole function, you can type @kbd{C-h f} (@code{describe-function}) @@ -12631,29 +13526,27 @@ your sources! Without them, you are like a person who tries to drive a car with his eyes shut!) -@c !!! again, 21.0.100 tags table location in this paragraph -Or -- a good habit to get into -- you can type @kbd{M-.} -(@code{find-tag}) and the name of the function when prompted for it. -This will take you directly to the source. If the @code{find-tag} -function first asks you for the name of a @file{TAGS} table, give it -the name of the @file{TAGS} file such as -@file{/usr/local/share/emacs/21.0.100/lisp/TAGS}. (The exact path to your -@file{TAGS} file depends on how your copy of Emacs was installed.) - -You can also create your own @file{TAGS} file for directories that -lack one. -@ifnottex -@xref{etags, , Create Your Own @file{TAGS} File}. -@end ifnottex - @node etags, Regexp Review, forward-paragraph, Regexp Search @section Create Your Own @file{TAGS} File @findex etags @cindex @file{TAGS} file, create own -The @kbd{M-.} (@code{find-tag}) command takes you directly to the -source for a function, variable, node, or other source. The function -depends on tags tables to tell it where to go. +Besides @kbd{C-h f} (@code{describe-function}), another way to see the +source of a function is to type @kbd{M-.} (@code{find-tag}) and the +name of the function when prompted for it. This is a good habit to +get into. The @kbd{M-.} (@code{find-tag}) command takes you directly +to the source for a function, variable, or node. The function depends +on tags tables to tell it where to go. + +If the @code{find-tag} function first asks you for the name of a +@file{TAGS} table, give it the name of a @file{TAGS} file such as +@file{/usr/local/src/emacs/src/TAGS}. (The exact path to your +@file{TAGS} file depends on how your copy of Emacs was installed. I +just told you the location that provides both my C and my Emacs Lisp +sources.) + +You can also create your own @file{TAGS} file for directories that +lack one. You often need to build and install tags tables yourself. They are not built automatically. A tags table is called a @file{TAGS} file; @@ -12676,7 +13569,7 @@ @end smallexample @noindent -to create a @file{TAGS} file. +to create a @file{TAGS} file for Emacs Lisp. For example, if you have a large number of files in your @file{~/emacs} directory, as I do---I have 137 @file{.el} files in it, @@ -12684,11 +13577,10 @@ Lisp files in that directory. @need 1250 -The @code{etags} program takes all the -usual shell `wildcards'. For example, if you have two directories for -which you want a single @file{TAGS file}, type -@w{@code{etags *.el ../elisp/*.el}}, -where @file{../elisp/} is the second directory: +The @code{etags} program takes all the usual shell `wildcards'. For +example, if you have two directories for which you want a single +@file{TAGS} file, type @w{@code{etags *.el ../elisp/*.el}}, where +@file{../elisp/} is the second directory: @smallexample M-x compile RET etags *.el ../elisp/*.el RET @@ -12706,10 +13598,11 @@ list of supported languages. The @code{etags} program handles more than 20 languages, including -Emacs Lisp, Common Lisp, Scheme, C, C++, Ada, Fortran, Java, LaTeX, -Pascal, Perl, Python, Texinfo, makefiles, and most assemblers. The -program has no switches for specifying the language; it recognizes the -language in an input file according to its file name and contents. +Emacs Lisp, Common Lisp, Scheme, C, C++, Ada, Fortran, HTML, Java, +LaTeX, Pascal, Perl, Postscript, Python, TeX, Texinfo, makefiles, and +most assemblers. The program has no switches for specifying the +language; it recognizes the language in an input file according to its +file name and contents. @file{etags} is very helpful when you are writing code yourself and want to refer back to functions you have already written. Just run @@ -12720,11 +13613,11 @@ you want, but do not know where it is, you can use the @code{locate} program to attempt to find it. -Type @w{@kbd{M-x locate RET TAGS RET}} and Emacs will list for you the -full path names of all your @file{TAGS} files. On my system, this -command lists 34 @file{TAGS} files. On the other hand, a `plain -vanilla' system I recently installed did not contain any @file{TAGS} -files. +Type @w{@kbd{M-x locate @key{RET} TAGS @key{RET}}} and Emacs will list +for you the full path names of all your @file{TAGS} files. On my +system, this command lists 34 @file{TAGS} files. On the other hand, a +`plain vanilla' system I recently installed did not contain any +@file{TAGS} files. If the tags table you want has been created, you can use the @code{M-x visit-tags-table} command to specify it. Otherwise, you will need to @@ -12739,8 +13632,8 @@ The GNU Emacs sources come with a @file{Makefile} that contains a sophisticated @code{etags} command that creates, collects, and merges tags tables from all over the Emacs sources and puts the information -into one @file{TAGS} file in the @file{src/} directory below the top -level of your Emacs source directory. +into one @file{TAGS} file in the @file{src/} directory. (The +@file{src/} directory is below the top level of your Emacs directory.) @need 1250 To build this @file{TAGS} file, go to the top level of your Emacs @@ -12784,6 +13677,7 @@ nil @end group @end smallexample + @noindent (The @code{insert} function inserts its arguments at point; the @code{format} function returns a string formatted from its arguments @@ -12800,6 +13694,7 @@ @enumerate @item A regular expression that specifies the pattern to search for. +(Remember to put quotation marks around this argument!) @item Optionally, the limit of the search. @@ -12844,20 +13739,6 @@ of a buffer. The end of the accessible part is the end of the buffer if the buffer is not narrowed; it is the end of the narrowed part if the buffer is narrowed. - -@item prog1 -Evaluate each argument in sequence and then return the value of the -@emph{first}. - -@need 1250 -For example: - -@smallexample -@group -(prog1 1 2 3 4) - @result{} 1 -@end group -@end smallexample @end table @need 1500 @@ -12891,8 +13772,8 @@ @menu * Why Count Words:: -* count-words-region:: Use a regexp, but find a problem. -* recursive-count-words:: Start with case of no words in region. +* count-words-region:: +* recursive-count-words:: * Counting Exercise:: @end menu @@ -12928,8 +13809,8 @@ words in just a section, rather than all of a buffer. So it makes more sense to design the command to count the number of words in a region. Once you have a @code{count-words-region} command, you can, -if you wish, count words in a whole buffer by marking it with @kbd{C-x -h} (@code{mark-whole-buffer}). +if you wish, count words in a whole buffer by marking it with +@w{@kbd{C-x h}} (@code{mark-whole-buffer}). Clearly, counting words is a repetitive act: starting from the beginning of the region, you count the first word, then the second @@ -12938,8 +13819,8 @@ or to a @code{while} loop. @menu -* Design count-words-region:: The definition using a @code{while} loop. -* Whitespace Bug:: The Whitespace Bug in @code{count-words-region}. +* Design count-words-region:: +* Whitespace Bug:: @end menu @node Design count-words-region, Whitespace Bug, count-words-region, count-words-region @@ -13043,11 +13924,13 @@ @noindent (Note that paired backslashes precede the @samp{w} and @samp{W}. A -single backslash has special meaning to the Emacs Lisp interpreter. It -indicates that the following character is interpreted differently than -usual. For example, the two characters, @samp{\n}, stand for +single backslash has special meaning to the Emacs Lisp interpreter. +It indicates that the following character is interpreted differently +than usual. For example, the two characters, @samp{\n}, stand for @samp{newline}, rather than for a backslash followed by @samp{n}. Two -backslashes in a row stand for an ordinary, `unspecial' backslash.) +backslashes in a row stand for an ordinary, `unspecial' backslash, so +Emacs Lisp interpreter ends of seeing a single backslash followed by a +letter. So it discovers the letter is special.) We need a counter to count how many words there are; this variable must first be set to 0 and then incremented each time Emacs goes @@ -13312,21 +14195,21 @@ @iftex @noindent (For information about @code{and}, see -@ref{forward-paragraph, , @code{forward-paragraph}: a Goldmine of -Functions}.) +@ref{kill-new function, , The @code{kill-new} function}.) @end iftex @ifinfo @noindent -(@xref{forward-paragraph}, for information about @code{and}.) +(@xref{kill-new function, , The @code{kill-new} function}, for +information about @code{and}.) @end ifinfo The @code{re-search-forward} expression returns @code{t} if the search succeeds and as a side effect moves point. Consequently, as words are -found, point is moved through the region. When the search -expression fails to find another word, or when point reaches the end -of the region, the true-or-false-test tests false, the @code{while} -loop exists, and the @code{count-words-region} function displays one -or other of its messages. +found, point is moved through the region. When the search expression +fails to find another word, or when point reaches the end of the +region, the true-or-false-test tests false, the @code{while} loop +exits, and the @code{count-words-region} function displays one or +other of its messages. After incorporating these final changes, the @code{count-words-region} works without bugs (or at least, without bugs that I have found!). @@ -13590,6 +14473,7 @@ each word, the counting mechanism must be an expression that adds one to the value returned by a call to @code{recursive-count-words}. +@need 800 Consider several cases: @itemize @bullet @@ -13776,15 +14660,15 @@ @menu * Divide and Conquer:: -* Words and Symbols:: What to count? -* Syntax:: What constitutes a word or symbol? -* count-words-in-defun:: Very like @code{count-words}. -* Several defuns:: Counting several defuns in a file. -* Find a File:: Do you want to look at a file? -* lengths-list-file:: A list of the lengths of many definitions. -* Several files:: Counting in definitions in different files. -* Several files recursively:: Recursively counting in different files. -* Prepare the data:: Prepare the data for display in a graph. +* Words and Symbols:: +* Syntax:: +* count-words-in-defun:: +* Several defuns:: +* Find a File:: +* lengths-list-file:: +* Several files:: +* Several files recursively:: +* Prepare the data:: @end menu @node Divide and Conquer, Words and Symbols, Words in a defun, Words in a defun @@ -14161,7 +15045,7 @@ @node Several defuns, Find a File, count-words-in-defun, Words in a defun @section Count Several @code{defuns} Within a File -A file such as @file{simple.el} may have 80 or more function +A file such as @file{simple.el} may have a hundred or more function definitions within it. Our long term goal is to collect statistics on many files, but as a first step, our immediate goal is to collect statistics on one file. @@ -14223,9 +15107,7 @@ problem. @need 1200 -Let's look at the source for @code{find-file} (you can use the -@code{find-tag} command or @kbd{C-h f} (@code{describe-function}) to -find the source of a function): +Let's look at the source for @code{find-file}: @smallexample @group @@ -14238,18 +15120,54 @@ @end group @end smallexample -The definition possesses short but complete documentation and an -interactive specification that prompts you for a file name when you -use the command interactively. The body of the definition contains -two functions, @code{find-file-noselect} and @code{switch-to-buffer}. +@noindent +(The most recent version of the @code{find-file} function definition +permits you to specify optional wildcards to visit multiple files; that +makes the definition more complex and we will not discuss it here, +since it is not relevant. You can see its source using either +@kbd{M-.} (@code{find-tag}) or @kbd{C-h f} (@code{describe-function}).) + +@ignore +In Emacs 22 +(defun find-file (filename &optional wildcards) + "Edit file FILENAME. +Switch to a buffer visiting file FILENAME, +creating one if none already exists. +Interactively, the default if you just type RET is the current directory, +but the visited file name is available through the minibuffer history: +type M-n to pull it into the minibuffer. + +Interactively, or if WILDCARDS is non-nil in a call from Lisp, +expand wildcards (if any) and visit multiple files. You can +suppress wildcard expansion by setting `find-file-wildcards' to nil. + +To visit a file without any kind of conversion and without +automatically choosing a major mode, use \\[find-file-literally]." + (interactive (find-file-read-args "Find file: " nil)) + (let ((value (find-file-noselect filename nil nil wildcards))) + (if (listp value) + (mapcar 'switch-to-buffer (nreverse value)) + (switch-to-buffer value)))) +@end ignore + +The definition I am showing possesses short but complete documentation +and an interactive specification that prompts you for a file name when +you use the command interactively. The body of the definition +contains two functions, @code{find-file-noselect} and +@code{switch-to-buffer}. According to its documentation as shown by @kbd{C-h f} (the @code{describe-function} command), the @code{find-file-noselect} function reads the named file into a buffer and returns the buffer. -However, the buffer is not selected. Emacs does not switch its -attention (or yours if you are using @code{find-file-noselect}) to the -named buffer. That is what @code{switch-to-buffer} does: it switches -the buffer to which Emacs attention is directed; and it switches the +(Its most recent version includes an optional wildcards argument, +too, as well as another to read a file literally and an other you +suppress warning messages. These optional arguments are irrelevant.) + +However, the @code{find-file-noselect} function does not select the +buffer in which it puts the file. Emacs does not switch its attention +(or yours if you are using @code{find-file-noselect}) to the selected +buffer. That is what @code{switch-to-buffer} does: it switches the +buffer to which Emacs attention is directed; and it switches the buffer displayed in the window to the new buffer. We have discussed buffer switching elsewhere. (@xref{Switching Buffers}.) @@ -14261,7 +15179,7 @@ So instead of calling on @code{find-file} to do the job, we must write our own expression. -The task is easy: use @code{find-file-noselect} and @code{set-buffer}. +The task is easy: use @code{find-file-noselect} and @code{set-buffer}. @node lengths-list-file, Several files, Find a File, Words in a defun @section @code{lengths-list-file} in Detail @@ -14324,10 +15242,10 @@ Besides, the buffer is not going to be saved, even if it were changed. This line is entirely the consequence of great, perhaps excessive, caution. The reason for the caution is that this function and those -it calls work on the sources for Emacs and it is very inconvenient if -they are inadvertently modified. It goes without saying that I did -not realize a need for this line until an experiment went awry and -started to modify my Emacs source files @dots{} +it calls work on the sources for Emacs and it is inconvenient if they +are inadvertently modified. It goes without saying that I did not +realize a need for this line until an experiment went awry and started +to modify my Emacs source files @dots{} Next comes a call to widen the buffer if it is narrowed. This function is usually not needed---Emacs creates a fresh buffer if none @@ -14345,10 +15263,10 @@ definition and constructs a lengths' list containing the information. Emacs kills the buffer after working through it. This is to save -space inside of Emacs. My version of Emacs 19 contained over 300 -source files of interest; Emacs 21 contains over 800 source files. -Another function will apply @code{lengths-list-file} to each of the -files. +space inside of Emacs. My version of GNU Emacs 19 contained over 300 +source files of interest; GNU Emacs 22 contains over a thousand source +files. Another function will apply @code{lengths-list-file} to each +of the files. Finally, the last expression within the @code{let} expression is the @code{lengths-list} variable; its value is returned as the value of @@ -14358,20 +15276,15 @@ place your cursor after the following expression and type @kbd{C-x C-e} (@code{eval-last-sexp}). -@c !!! 21.0.100 lisp sources location here +@c !!! 22.1.1 lisp sources location here @smallexample (lengths-list-file - "/usr/local/share/emacs/21.0.100/lisp/emacs-lisp/debug.el") -@end smallexample - -@c was: (lengths-list-file "../lisp/debug.el") -@c !!! as of 21, Info file is in -@c /usr/share/info/emacs-lisp-intro.info.gz -@c but debug.el is in /usr/local/share/emacs/21.0.100/lisp/emacs-lisp/debug.el - -@noindent -(You may need to change the pathname of the file; the one here worked -with GNU Emacs version 21.0.100. To change the expression, copy it to + "/usr/local/share/emacs/22.1.1/lisp/emacs-lisp/debug.el") +@end smallexample + +@noindent +(You may need to change the pathname of the file; the one here is for +GNU Emacs version 22.1.1. To change the expression, copy it to the @file{*scratch*} buffer and edit it. @need 1200 @@ -14384,15 +15297,15 @@ @end smallexample @noindent -(@xref{defcustom, , Specifying Variables using @code{defcustom}}.) +(@xref{defcustom, , Specifying Variables using @code{defcustom}}. Then evaluate the @code{lengths-list-file} expression.) @need 1200 The lengths' list for @file{debug.el} takes less than a second to -produce and looks like this: - -@smallexample -(77 95 85 87 131 89 50 25 44 44 68 35 64 45 17 34 167 457) +produce and looks like this in GNU Emacs 22: + +@smallexample +(83 113 105 144 289 22 30 97 48 89 25 52 52 88 28 29 77 49 43 290 232 587) @end smallexample @need 1500 @@ -14403,7 +15316,7 @@ (75 41 80 62 20 45 44 68 45 12 34 235) @end smallexample -(The newer version of @file{debug.el} contains more defuns than the +(The newer version of @file{debug.el} contains more defuns than the earlier one; and my new machine is much faster than the old one.) Note that the length of the last definition in the file is first in @@ -14421,8 +15334,8 @@ either a @code{while} loop or recursion. @menu -* lengths-list-many-files:: Return a list of the lengths of defuns. -* append:: Attach one list to another. +* lengths-list-many-files:: +* append:: @end menu @node lengths-list-many-files, append, Several files, Several files @@ -14496,14 +15409,14 @@ @end smallexample @code{expand-file-name} is a built-in function that converts a file -name to the absolute, long, path name form of the directory in which -the function is called. - -@c !!! 21.0.100 lisp sources location here +name to the absolute, long, path name form. The function employs the +name of the directory in which the function is called. + +@c !!! 22.1.1 lisp sources location here @need 1500 Thus, if @code{expand-file-name} is called on @code{debug.el} when Emacs is visiting the -@file{/usr/local/share/emacs/21.0.100/lisp/emacs-lisp/} directory, +@file{/usr/local/share/emacs/22.1.1/lisp/emacs-lisp/} directory, @smallexample debug.el @@ -14513,9 +15426,9 @@ @noindent becomes -@c !!! 21.0.100 lisp sources location here -@smallexample -/usr/local/share/emacs/21.0.100/lisp/emacs-lisp/debug.el +@c !!! 22.1.1 lisp sources location here +@smallexample +/usr/local/share/emacs/22.1.1/lisp/emacs-lisp/debug.el @end smallexample The only other new element of this function definition is the as yet @@ -14604,21 +15517,21 @@ the @file{*scratch*} buffer, edit them, and then evaluate them. The results are shown after the @samp{@result{}}. (These results are -for files from Emacs Version 21.0.100; files from other versions of +for files from Emacs Version 22.1.1; files from other versions of Emacs may produce different results.) -@c !!! 21.0.100 lisp sources location here -@smallexample -@group -(cd "/usr/local/share/emacs/21.0.100/") +@c !!! 22.1.1 lisp sources location here +@smallexample +@group +(cd "/usr/local/share/emacs/22.1.1/") (lengths-list-file "./lisp/macros.el") - @result{} (273 263 456 90) + @result{} (283 263 480 90) @end group @group (lengths-list-file "./lisp/mail/mailalias.el") - @result{} (38 32 26 77 174 180 321 198 324) + @result{} (38 32 29 95 178 180 321 218 324) @end group @group @@ -14627,11 +15540,11 @@ @end group @group -(recursive-lengths-list-many-files - '("./lisp/macros.el" - "./lisp/mail/mailalias.el" - "./lisp/makesum.el")) - @result{} (273 263 456 90 38 32 26 77 174 180 321 198 324 85 181) + (recursive-lengths-list-many-files + '("./lisp/macros.el" + "./lisp/mail/mailalias.el" + "./lisp/makesum.el")) + @result{} (283 263 480 90 38 32 29 95 178 180 321 218 324 85 181) @end group @end smallexample @@ -14671,8 +15584,8 @@ that we will need. @menu -* Sorting:: Sorting lists. -* Files List:: Making a list of files. +* Sorting:: +* Files List:: * Counting function definitions:: @end menu @@ -14717,13 +15630,27 @@ @code{recursive-lengths-list-many-files} function is straightforward; it uses the @code{<} function: +@ignore +2006 Oct 29 +In GNU Emacs 22, eval +(progn + (cd "/usr/local/share/emacs/22.0.50/") + (sort + (recursive-lengths-list-many-files + '("./lisp/macros.el" + "./lisp/mail/mailalias.el" + "./lisp/makesum.el")) + '<)) + +@end ignore + @smallexample @group (sort (recursive-lengths-list-many-files - '("../lisp/macros.el" - "../lisp/mailalias.el" - "../lisp/makesum.el")) + '("./lisp/macros.el" + "./lisp/mailalias.el" + "./lisp/makesum.el")) '<) @end group @end smallexample @@ -14733,7 +15660,7 @@ which produces: @smallexample -(85 86 116 122 154 176 179 265) +(29 32 38 85 90 95 178 180 181 218 263 283 321 324 480) @end smallexample @noindent @@ -14779,9 +15706,9 @@ @smallexample @group -("../lisp/macros.el" - "../lisp/mail/rmail.el" - "../lisp/makesum.el") +("./lisp/macros.el" + "./lisp/mail/rmail.el" + "./lisp/makesum.el") @end group @end smallexample @@ -14795,7 +15722,7 @@ For example, the first @samp{.el} file in the @file{lisp/} directory is @file{abbrev.el}. Its name is -@file{/usr/local/share/emacs/21.0.100/lisp/abbrev.el} and it is not a +@file{/usr/local/share/emacs/22.1.1/lisp/abbrev.el} and it is not a directory or a symbolic link. @need 1000 @@ -14804,23 +15731,23 @@ @smallexample @group -("/usr/local/share/emacs/21.0.100/lisp/abbrev.el" +("abbrev.el" nil 1 1000 100 @end group @group -(15019 32380) -(14883 48041) -(15214 49336) -11583 +(17733 259) +(17491 28834) +(17596 62124) +13157 "-rw-rw-r--" @end group @group -t -341385 -776) +nil +2971624 +773) @end group @end smallexample @@ -14830,18 +15757,17 @@ @smallexample @group -("/usr/local/share/emacs/21.0.100/lisp/mail" +("mail" t @dots{} ) @end group @end smallexample -(Look at the documentation of @code{file-attributes} to learn about -the different attributes. Bear in mind that the -@code{file-attributes} function does not list the filename, so its -first element is @code{directory-files-and-attributes}'s second -element.) +(To learn about the different attributes, look at the documentation of +@code{file-attributes}. Bear in mind that the @code{file-attributes} +function does not list the filename, so its first element is +@code{directory-files-and-attributes}'s second element.) We will want our new function, @code{files-in-below-directory}, to list the @samp{.el} files in the directory it is told to check, and in @@ -14893,11 +15819,14 @@ using @code{append} as the combiner. @ignore -(directory-files "/usr/local/share/emacs/21.0.100/lisp/" t "\\.el$") -(shell-command "find /usr/local/share/emacs/21.0.100/lisp/ -name '*.el'") +(directory-files "/usr/local/src/emacs/lisp/" t "\\.el$") +(shell-command "find /usr/local/src/emacs/lisp/ -name '*.el'") + +(directory-files "/usr/local/share/emacs/22.1.1/lisp/" t "\\.el$") +(shell-command "find /usr/local/share/emacs/22.1.1/lisp/ -name '*.el'") @end ignore -@c /usr/local/share/emacs/21.0.100/lisp/ +@c /usr/local/share/emacs/22.1.1/lisp/ @need 800 Here is the function: @@ -14909,7 +15838,7 @@ ;; Although the function will be used non-interactively, ;; it will be easier to test if we make it interactive. ;; The directory will have a name such as - ;; "/usr/local/share/emacs/21.0.100/lisp/" + ;; "/usr/local/share/emacs/22.1.1/lisp/" (interactive "DDirectory name: ") @end group @group @@ -14953,7 +15882,8 @@ @end group @end smallexample -@c (files-in-below-directory "/usr/local/share/emacs/21.0.100/lisp/") +@c (files-in-below-directory "/usr/local/src/emacs/lisp/") +@c (files-in-below-directory "/usr/local/share/emacs/22.1.1/lisp/") The @code{files-in-below-directory} @code{directory-files} function takes one argument, the name of a directory. @@ -14961,16 +15891,18 @@ @need 1250 Thus, on my system, -@c !!! 21.0.100 lisp sources location here +@c (length (files-in-below-directory "/usr/local/src/emacs/lisp/")) + +@c !!! 22.1.1 lisp sources location here @smallexample @group (length - (files-in-below-directory "/usr/local/share/emacs/21.0.100/lisp/")) -@end group -@end smallexample - -@noindent -tells me that my version 21.0.100 Lisp sources directory contains 754 + (files-in-below-directory "/usr/local/share/emacs/22.1.1/lisp/")) +@end group +@end smallexample + +@noindent +tells me that in and below my Lisp sources directory are 1031 @samp{.el} files. @code{files-in-below-directory} returns a list in reverse alphabetical @@ -14980,24 +15912,21 @@ @smallexample @group (sort - (files-in-below-directory "/usr/local/share/emacs/21.0.100/lisp/") + (files-in-below-directory "/usr/local/share/emacs/22.1.1/lisp/") 'string-lessp) @end group @end smallexample @ignore (defun test () - "Test how long it takes to find lengths of all elisp defuns." + "Test how long it takes to find lengths of all sorted elisp defuns." (insert "\n" (current-time-string) "\n") (sit-for 0) (sort (recursive-lengths-list-many-files - '("../lisp/macros.el" - "../lisp/mailalias.el" - "../lisp/makesum.el")) + (files-in-below-directory "/usr/local/src/emacs/lisp/")) '<) (insert (format "%s" (current-time-string)))) - @end ignore @node Counting function definitions, , Files List, Prepare the data @@ -15259,11 +16188,14 @@ @c colon in printed section title causes problem in Info cross reference This way, we avoid an error. @iftex -@xref{forward-paragraph, , @code{forward-paragraph}: a Goldmine of -Functions}, for more information about @code{and}. +@noindent +(For information about @code{and}, see +@ref{kill-new function, , The @code{kill-new} function}.) @end iftex @ifinfo -@xref{forward-paragraph}, for more information about @code{and}. +@noindent +(@xref{kill-new function, , The @code{kill-new} function}, for +information about @code{and}.) @end ifinfo Here is a short test of the @code{defuns-per-range} function. First, @@ -15301,7 +16233,6 @@ of 200 or larger. @c The next step is to turn this numbers' list into a graph. - @node Readying a Graph, Emacs Initialization, Words in a defun, Top @chapter Readying a Graph @cindex Readying a graph @@ -15328,7 +16259,7 @@ @menu * Columns of a graph:: -* graph-body-print:: How to print the body of a graph. +* graph-body-print:: * recursive-graph-body-print:: * Printed Axes:: * Line Graph Exercise:: @@ -15363,7 +16294,7 @@ own column-insertion function or discover whether one exists in Emacs. To see whether there is one in Emacs, we can use the @kbd{M-x apropos} -command. This command is like the @kbd{C-h a} (command-apropos) +command. This command is like the @kbd{C-h a} (@code{command-apropos}) command, except that the latter finds only those functions that are commands. The @kbd{M-x apropos} command lists all symbols that match a regular expression, including functions that are not interactive. @@ -15374,9 +16305,11 @@ the word `print' or the word `insert' or the word `column'. Therefore, we can simply type @kbd{M-x apropos RET print\|insert\|column RET} and look at the result. On my system, this -command takes quite some time, and then produces a list of 79 -functions and variables. Scanning down the list, the only function -that looks as if it might do the job is @code{insert-rectangle}. +command once too takes quite some time, and then produced a list of 79 +functions and variables. Now it does not take much time at all and +produces a list of 211 functions and variables. Scanning down the +list, the only function that looks as if it might do the job is +@code{insert-rectangle}. @need 1200 Indeed, this is the function we want; its documentation says: @@ -15388,6 +16321,8 @@ RECTANGLE's first line is inserted at point, its second line is inserted at a point vertically under point, etc. RECTANGLE should be a list of strings. +After this command, the mark is at the upper left corner +and point is at the lower right corner. @end group @end smallexample @@ -15403,8 +16338,7 @@ @group (insert-rectangle '("first" "second" "third"))first second - third -nil + thirdnil @end group @end smallexample @@ -15418,12 +16352,14 @@ If you are reading this in Info, you can see how this works by switching to another buffer, such as the @file{*scratch*} buffer, -placing point somewhere in the buffer, typing @kbd{M-:}, -typing the @code{insert-rectangle} expression into the minibuffer at -the prompt, and then typing @key{RET}. This causes Emacs to evaluate -the expression in the minibuffer, but to use as the value of point the -position of point in the @file{*scratch*} buffer. (@kbd{M-:} -is the keybinding for @code{eval-expression}.) +placing point somewhere in the buffer, typing @kbd{M-:}, typing the +@code{insert-rectangle} expression into the minibuffer at the prompt, +and then typing @key{RET}. This causes Emacs to evaluate the +expression in the minibuffer, but to use as the value of point the +position of point in the @file{*scratch*} buffer. (@kbd{M-:} is the +keybinding for @code{eval-expression}. Also, @code{nil} does not +appear in the @file{*scratch*} buffer since the expression is +evaluated in the minibuffer.) We find when we do this that point ends up at the end of the last inserted line---that is to say, this function moves point as a @@ -15892,7 +16828,7 @@ The recursive function is a little more difficult. It has four parts: the `do-again-test', the printing code, the recursive call, and the -`next-step-expression'. The `do-again-test' is an @code{if} +`next-step-expression'. The `do-again-test' is a @code{when} expression that determines whether the @code{numbers-list} contains any remaining elements; if it does, the function prints one column of the graph using the printing code and calls itself again. The @@ -15909,8 +16845,7 @@ @end group @group - (if numbers-list - (progn + (when numbers-list (setq from-position (point)) (insert-rectangle (column-of-graph height (car numbers-list))) @@ -15920,7 +16855,7 @@ (forward-char symbol-width) (sit-for 0) ; @r{Draw graph column by column.} (recursive-graph-body-print-internal - (cdr numbers-list) height symbol-width)))) + (cdr numbers-list) height symbol-width))) @end group @end smallexample @@ -15983,20 +16918,20 @@ @menu * Default Configuration:: -* Site-wide Init:: You can write site-wide init files. -* defcustom:: Emacs will write code for you. -* Beginning a .emacs File:: How to write a @code{.emacs file}. -* Text and Auto-fill:: Automatically wrap lines. -* Mail Aliases:: Use abbreviations for email addresses. -* Indent Tabs Mode:: Don't use tabs with @TeX{} -* Keybindings:: Create some personal keybindings. -* Keymaps:: More about key binding. -* Loading Files:: Load (i.e., evaluate) files automatically. -* Autoload:: Make functions available. -* Simple Extension:: Define a function; bind it to a key. -* X11 Colors:: Colors in version 19 in X. +* Site-wide Init:: +* defcustom:: +* Beginning a .emacs File:: +* Text and Auto-fill:: +* Mail Aliases:: +* Indent Tabs Mode:: +* Keybindings:: +* Keymaps:: +* Loading Files:: +* Autoload:: +* Simple Extension:: +* X11 Colors:: * Miscellaneous:: -* Mode Line:: How to customize your mode line. +* Mode Line:: @end menu @node Default Configuration, Site-wide Init, Emacs Initialization, Emacs Initialization @@ -16011,7 +16946,11 @@ sense, if you do not know who is going to use Emacs. Who knows what a person hopes to do with an unadorned file? Fundamental mode is the right default for such a file, just as C mode is the right default for -editing C code. But when you do know who is going to use Emacs---you, +editing C code. (Enough programming languages have syntaxes +that enable them to share or nearly share features, so C mode is +now provided by by CC mode, the `C Collection'.) + +But when you do know who is going to use Emacs---you, yourself---then it makes sense to customize Emacs. For example, I seldom want Fundamental mode when I edit an @@ -16141,7 +17080,7 @@ Customization buffer. The @code{:options} keyword specifies a suggested list of values for -the variable. Currently, you can use @code{:options} only for a hook. +the variable. Usually, @code{:options} applies to a hook. The list is only a suggestion; it is not exclusive; a person who sets the variable may set it to other values; the list shown following the @code{:options} keyword is intended to offer convenient choices to a @@ -16151,6 +17090,7 @@ command in which group the variable is located. This tells where to find it. +The @code{defcustom} function recognizes more than a dozen keywords. For more information, see @ref{Customization, , Writing Customization Definitions, elisp, The GNU Emacs Lisp Reference Manual}. @@ -16169,8 +17109,8 @@ @noindent and find that the group for editing files of data is called `data'. Enter that group. Text Mode Hook is the first member. You can click -on its various options to set the values. After you click on the -button to +on its various options, such as @code{turn-on-auto-fill}, to set the +values. After you click on the button to @smallexample Save for Future Sessions @@ -16183,24 +17123,21 @@ @smallexample @group (custom-set-variables - ;; custom-set-variables was added by Custom -- - ;; don't edit or cut/paste it! + ;; custom-set-variables was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. '(text-mode-hook (quote (turn-on-auto-fill text-mode-hook-identify)))) @end group @end smallexample @noindent (The @code{text-mode-hook-identify} function tells -@code{toggle-text-mode-auto-fill} which buffers are in Text mode.) - -In spite of the warning, you certainly may edit, cut, and paste the -expression! I do all time. The purpose of the warning is to scare -those who do not know what they are doing, so they do not -inadvertently generate an error. +@code{toggle-text-mode-auto-fill} which buffers are in Text mode. +It comes on automatically.) The @code{custom-set-variables} function works somewhat differently -than a @code{setq}. While I have never learned the differences, I do +than a @code{setq}. While I have never learned the differences, I modify the @code{custom-set-variables} expressions in my @file{.emacs} file by hand: I make the changes in what appears to me to be a reasonable manner and have not had any problems. Others prefer to use @@ -16221,7 +17158,7 @@ message that says @smallexample -this option has been changed outside the customize buffer. +CHANGED outside Customize; operating on it here may be unreliable. @end smallexample @need 800 @@ -16246,6 +17183,15 @@ I myself use @code{customize} for hardly anything. Mostly, I write expressions myself. +@findex defsubst +@findex defconst +Incidentally, to be more complete concerning defines: @code{defsubst} +defines an inline function. The syntax is just like that of +@code{defun}. @code{defconst} defines a symbol as a constant. The +intent is that neither programs nor users should ever change a value +set by @code{defconst}. (You can change it; the value set is a +variable; but please do not.) + @node Beginning a .emacs File, Text and Auto-fill, defcustom, Emacs Initialization @section Beginning a @file{.emacs} File @cindex @file{.emacs} file, beginning of @@ -16293,9 +17239,9 @@ @noindent This describes the usual conventions for comments in Emacs Lisp. Everything on a line that follows a semicolon is a comment. Two, -three, and four semicolons are used as section and subsection -markers. (@xref{Comments, ,, elisp, The GNU Emacs Lisp Reference -Manual}, for more about comments.) +three, and four semicolons are used as subsection and section markers. +(@xref{Comments, ,, elisp, The GNU Emacs Lisp Reference Manual}, for +more about comments.) @smallexample @group @@ -16338,12 +17284,10 @@ @smallexample @group ;;; Text mode and Auto Fill mode -; The next three lines put Emacs into Text mode +; The next two lines put Emacs into Text mode ; and Auto Fill mode, and are for writers who ; want to start writing prose rather than code. - (setq default-major-mode 'text-mode) -(add-hook 'text-mode-hook 'text-mode-hook-identify) (add-hook 'text-mode-hook 'turn-on-auto-fill) @end group @end smallexample @@ -16404,33 +17348,28 @@ else in Emacs. @need 800 -Here are the next two lines: +Here is the next line: @cindex Auto Fill mode turned on @findex add-hook @smallexample -(add-hook 'text-mode-hook 'text-mode-hook-identify) (add-hook 'text-mode-hook 'turn-on-auto-fill) @end smallexample @noindent -In these two lines, the @code{add-hook} command first adds -@code{text-mode-hook-identify} to the variable called -@code{text-mode-hook} and then adds @code{turn-on-auto-fill} to the -variable. +In this line, the @code{add-hook} command adds +@code{turn-on-auto-fill} to the variable. @code{turn-on-auto-fill} is the name of a program, that, you guessed -it!, turns on Auto Fill mode. @code{text-mode-hook-identify} is a -function that tells @code{toggle-text-mode-auto-fill} which buffers -are in Text mode. +it!, turns on Auto Fill mode. Every time Emacs turns on Text mode, Emacs runs the commands `hooked' onto Text mode. So every time Emacs turns on Text mode, Emacs also turns on Auto Fill mode. -In brief, the first line causes Emacs to enter Text mode when you edit -a file, unless the file name extension, first non-blank line, or local -variables tell Emacs otherwise. +In brief, the first line causes Emacs to enter Text mode when you edit a +file, unless the file name extension, a first non-blank line, or local +variables to tell Emacs otherwise. Text mode among other actions, sets the syntax table to work conveniently for writers. In Text mode, Emacs considers an apostrophe @@ -16439,11 +17378,10 @@ @samp{it's}. On the other hand, in C mode, @kbd{M-f} stops just after the @samp{t} of @samp{it's}. -The second and third lines causes Emacs to turn on Auto Fill mode when -it turns on Text mode. In Auto Fill mode, Emacs automatically breaks -a line that is too wide and brings the excessively wide part of the -line down to the next line. Emacs breaks lines between words, not -within them. +The second line causes Emacs to turn on Auto Fill mode when it turns +on Text mode. In Auto Fill mode, Emacs automatically breaks a line +that is too wide and brings the excessively wide part of the line down +to the next line. Emacs breaks lines between words, not within them. When Auto Fill mode is turned off, lines continue to the right as you type them. Depending on how you set the value of @@ -16471,7 +17409,6 @@ ; To enter mail mode, type `C-x m' ; To enter RMAIL (for reading mail), ; type `M-x rmail' - (setq mail-aliases t) @end group @end smallexample @@ -16531,6 +17468,7 @@ Files'' in @cite{The GNU Emacs Manual}. @end iftex +@need 1700 @node Keybindings, Keymaps, Indent Tabs Mode, Emacs Initialization @section Some Keybindings @@ -16558,13 +17496,14 @@ The command is @code{global-set-key}. It is followed by the keybinding. In a @file{.emacs} file, the keybinding is written as shown: @code{\C-c} stands for `control-c', which means `press the -control key and the @kbd{c} key at the same time'. The @code{w} means -`press the @kbd{w} key'. The keybinding is surrounded by double -quotation marks. In documentation, you would write this as @kbd{C-c -w}. (If you were binding a @key{META} key, such as @kbd{M-c}, rather -than a @key{CTL} key, you would write @code{\M-c}. @xref{Init -Rebinding, , Rebinding Keys in Your Init File, emacs, The GNU Emacs -Manual}, for details.) +control key and the @key{c} key at the same time'. The @code{w} means +`press the @key{w} key'. The keybinding is surrounded by double +quotation marks. In documentation, you would write this as +@w{@kbd{C-c w}}. (If you were binding a @key{META} key, such as +@kbd{M-c}, rather than a @key{CTRL} key, you would write +@w{@code{\M-c}} in your @file{.emacs} file. @xref{Init Rebinding, , +Rebinding Keys in Your Init File, emacs, The GNU Emacs Manual}, for +details.) The command invoked by the keys is @code{compare-windows}. Note that @code{compare-windows} is preceded by a single quote; otherwise, Emacs @@ -16785,7 +17724,10 @@ (defun load-library (library) "Load the library named LIBRARY. This is an interface to the function `load'." - (interactive "sLoad library: ") + (interactive + (list (completing-read "Load library: " + 'locate-file-completion + (cons load-path (get-load-suffixes))))) (load library)) @end group @end smallexample @@ -16822,12 +17764,12 @@ load that function's file with a @code{load} expression in your @file{.emacs} file. -In my @file{.emacs} file for Emacs version 21, I load 12 libraries +In my @file{.emacs} file for Emacs version 22, I load 14 libraries that contain functions that would otherwise be autoloaded. (Actually, -it would have been better to include these files in my `dumped' Emacs -when I built it, but I forgot. @xref{Building Emacs, , Building -Emacs, elisp, The GNU Emacs Lisp Reference Manual}, and the @file{INSTALL} -file for more about dumping.) +it would have been better to include these files in my `dumped' Emacs, +but I forgot. @xref{Building Emacs, , Building Emacs, elisp, The GNU +Emacs Lisp Reference Manual}, and the @file{INSTALL} file for more +about dumping.) You may also want to include autoloaded expressions in your @file{.emacs} file. @code{autoload} is a built-in function that takes up to five @@ -16850,8 +17792,8 @@ @end smallexample @noindent -(@code{html-helper-mode} is an alternative to @code{html-mode}, which -is a standard part of the distribution). +(@code{html-helper-mode} is an older alternative to @code{html-mode}, +which is a standard part of the distribution.) @noindent This expression autoloads the @code{html-helper-mode} function. It @@ -16916,37 +17858,41 @@ @cindex Conditional 'twixt two versions of Emacs @cindex Version of Emacs, choosing @cindex Emacs version, choosing -If you run two versions of GNU Emacs, such as versions 20 and 21, and +If you run two versions of GNU Emacs, such as versions 21 and 22, and use one @file{.emacs} file, you can select which code to evaluate with the following conditional: @smallexample @group (cond - ((string-equal (number-to-string 20) (substring (emacs-version) 10 12)) - ;; evaluate version 20 code + (= 21 emacs-major-version) + ;; evaluate version 21 code ( @dots{} )) - ((string-equal (number-to-string 21) (substring (emacs-version) 10 12)) - ;; evaluate version 21 code + (= 22 emacs-major-version) + ;; evaluate version 22 code ( @dots{} ))) @end group @end smallexample -For example, in contrast to version 20, version 21 blinks its cursor -by default. I hate such blinking, as well as some other features in -version 21, so I placed the following in my @file{.emacs} +For example, in contrast to version 20, more recent versions blink +their cursors by default. I hate such blinking, as well as other +features, so I placed the following in my @file{.emacs} file@footnote{When I start instances of Emacs that do not load my @file{.emacs} file or any site file, I also turn off blinking: @smallexample emacs -q --no-site-file -eval '(blink-cursor-mode nil)' + +@exdent Or nowadays, using an even more sophisticated set of options, + +emacs -Q - D @end smallexample }: @smallexample @group -(if (string-equal "21" (substring (emacs-version) 10 12)) - (progn +(when (or (= 21 emacs-major-version) + (= 22 emacs-major-version)) (blink-cursor-mode 0) ;; Insert newline when you press `C-n' (next-line) ;; at the end of the buffer @@ -16972,19 +17918,10 @@ ;; (Use numeric argument to turn on) (tooltip-mode nil) ;; If tooltips turned on, make tips appear promptly - (setq tooltip-delay 0.1) ; default is one second - )) -@end group -@end smallexample - -@noindent -(You will note that instead of typing @code{(number-to-string 21)}, I -decided to save typing and wrote `21' as a string, @code{"21"}, rather -than convert it from an integer to a string. In this instance, this -expression is better than the longer, but more general -@code{(number-to-string 21)}. However, if you do not know ahead of -time what type of information will be returned, then the -@code{number-to-string} function will be needed.) + (setq tooltip-delay 0.1) ; default is 0.7 second + ) +@end group +@end smallexample @node X11 Colors, Miscellaneous, Simple Extension, Emacs Initialization @section X11 Colors @@ -17055,27 +17992,26 @@ @end smallexample In any event, since it is not part of Emacs, I set the root color of -my X window in my @file{~/.xinitrc} file, like this@footnote{I -occasionally run more modern window managers, such as Sawfish with -GNOME, Enlightenment, SCWM, or KDE; in those cases, I often specify an -image rather than a plain color.}: - -@smallexample -@group -# I use TWM for window manager. +my X window in my @file{~/.xinitrc} file, like this@footnote{I also +run more modern window managers, such as Enlightenment, Gnome, or KDE; +in those cases, I often specify an image rather than a plain color.}: + +@smallexample xsetroot -solid Navy -fg white & -@end group -@end smallexample - +@end smallexample + +@need 1700 @node Miscellaneous, Mode Line, X11 Colors, Emacs Initialization @section Miscellaneous Settings for a @file{.emacs} File +@need 1250 Here are a few miscellaneous settings: @sp 1 @itemize @minus @item Set the shape and color of the mouse cursor: + @smallexample @group ; Cursor shapes are defined in @@ -17099,8 +18035,34 @@ @end smallexample @item -Convert @kbd{@key{CTL}-h} into @key{DEL} and @key{DEL} -into @kbd{@key{CTL}-h}.@* +Or you can set the values of a variety of features in an alist, like +this: + +@smallexample +@group +(setq-default + default-frame-alist + '((cursor-color . "white") + (mouse-color . "white") + (foreground-color . "white") + (background-color . "DodgerBlue4") + ;; (cursor-type . bar) + (cursor-type . box) +@end group +@group + (tool-bar-lines . 0) + (menu-bar-lines . 1) + (width . 80) + (height . 58) + (font . + "-Misc-Fixed-Medium-R-Normal--20-200-75-75-C-100-ISO8859-1") + )) +@end group +@end smallexample + +@item +Convert @kbd{@key{CTRL}-h} into @key{DEL} and @key{DEL} +into @kbd{@key{CTRL}-h}.@* (Some older keyboards needed this, although I have not seen the problem recently.) @@ -17123,20 +18085,30 @@ @end group @end smallexample -@item Ignore case when using `grep'@* +@noindent +or start GNU Emacs with the command @code{emacs -nbc}. + +@need 1250 +@item When using `grep'@* +@samp{-i}@w{ } Ignore case distinctions@* @samp{-n}@w{ } Prefix each line of output with line number@* -@samp{-i}@w{ } Ignore case distinctions@* +@samp{-H}@w{ } Print the filename for each match.@* @samp{-e}@w{ } Protect patterns beginning with a hyphen character, @samp{-} @smallexample -(setq grep-command "grep -n -i -e ") -@end smallexample - -@item Automatically uncompress compressed files when visiting them - -@smallexample +(setq grep-command "grep -i -nH -e ") +@end smallexample + +@ignore +@c Evidently, no longer needed in GNU Emacs 22 + +item Automatically uncompress compressed files when visiting them + +smallexample (load "uncompress") -@end smallexample +end smallexample + +@end ignore @item Find an existing buffer, even if it has a different name@* This avoids problems with symbolic links. @@ -17171,7 +18143,7 @@ @cindex Bindings, key, fixing unpleasant Some systems bind keys unpleasantly. Sometimes, for example, the -@key{CTL} key appears in an awkward spot rather than at the far left +@key{CTRL} key appears in an awkward spot rather than at the far left of the home row. Usually, when people fix these sorts of keybindings, they do not @@ -17187,9 +18159,7 @@ @smallexample @group loadkeys /usr/share/keymaps/i386/qwerty/emacs2.kmap.gz - @exdent or - install-keymap emacs2 @end group @end smallexample @@ -17222,6 +18192,7 @@ @end group @end smallexample +@need 1700 @node Mode Line, , Miscellaneous, Emacs Initialization @section A Modified Mode Line @vindex default-mode-line-format @@ -17305,8 +18276,8 @@ nowadays, Emacs can add properties to a string, such as highlighting or, as in this case, a help feature. If you place your mouse cursor over the hyphen, some help information appears (By default, you must -wait one second before the information appears. You can change that -timing by changing the value of @code{tooltip-delay}.) +wait seven-tenths of a second before the information appears. You can +change that timing by changing the value of @code{tooltip-delay}.) @need 1000 The new string format has a special syntax: @@ -17344,13 +18315,12 @@ characters; this length works well in a typical 80 column wide window.) -@code{:eval} is a new feature in GNU Emacs version 21. It says to -evaluate the following form and use the result as a string to display. -In this case, the expression displays the first component of the full -system name. The end of the first component is a @samp{.} (`period'), -so I use the @code{string-match} function to tell me the length of the -first component. The substring from the zeroth character to that -length is the name of the machine. +@code{:eval} says to evaluate the following form and use the result as +a string to display. In this case, the expression displays the first +component of the full system name. The end of the first component is +a @samp{.} (`period'), so I use the @code{string-match} function to +tell me the length of the first component. The substring from the +zeroth character to that length is the name of the machine. @need 1250 This is the expression: @@ -17399,10 +18369,10 @@ In this chapter, I will walk through a short example of each. @menu -* debug:: How to use the built-in debugger. -* debug-on-entry:: Start debugging when you call a function. -* debug-on-quit:: Start debugging when you quit with @kbd{C-g}. -* edebug:: How to use Edebug, a source level debugger. +* debug:: +* debug-on-entry:: +* debug-on-quit:: +* edebug:: * Debugging Exercises:: @end menu @@ -17445,8 +18415,8 @@ @end smallexample @noindent -In GNU Emacs version 21, you will create and enter a -@file{*Backtrace*} buffer that says: +In a recent GNU Emacs, you will create and enter a @file{*Backtrace*} +buffer that says: @noindent @smallexample @@ -17479,6 +18449,7 @@ tell you what you need to know to correct the definition. The function @code{1=} is `void'. +@ignore @need 800 In GNU Emacs 20 and before, you will see: @@ -17489,13 +18460,14 @@ @noindent which has the same meaning as the @file{*Backtrace*} buffer line in version 21. +@end ignore However, suppose you are not quite certain what is going on? You can read the complete backtrace. -In this case, you need to run GNU Emacs 21, which automatically starts -the debugger that puts you in the @file{*Backtrace*} buffer; or else, -you need to start the debugger manually as described below. +In this case, you need to run a recent GNU Emacs, which automatically +starts the debugger that puts you in the @file{*Backtrace*} buffer; or +else, you need to start the debugger manually as described below. Read the @file{*Backtrace*} buffer from the bottom up; it tells you what Emacs did that led to the error. Emacs made an interactive call @@ -17535,14 +18507,18 @@ @section @code{debug-on-entry} @findex debug-on-entry -GNU Emacs 21 starts the debugger automatically when your function has -an error. GNU Emacs version 20 and before did not; it simply +A recent GNU Emacs starts the debugger automatically when your +function has an error. + +@ignore +GNU Emacs version 20 and before did not; it simply presented you with an error message. You had to start the debugger manually. - -You can start the debugger manually for all versions of Emacs; the -advantage is that the debugger runs even if you do not have a bug in -your code. Sometimes your code will be free of bugs! +@end ignore + +Incidentally, you can start the debugger manually for all versions of +Emacs; the advantage is that the debugger runs even if you do not have +a bug in your code. Sometimes your code will be free of bugs! You can enter the debugger when you call the function by calling @code{debug-on-entry}. @@ -17742,7 +18718,8 @@ @need 1500 However, to prepare this function definition for Edebug, you must first @dfn{instrument} the code using a different command. You can do -this by positioning your cursor within the definition and typing +this by positioning your cursor within or just after the definition +and typing @smallexample M-x edebug-defun RET @@ -17796,13 +18773,13 @@ move point past @code{number}, you will see the following: @smallexample -Result: 3 = C-c -@end smallexample - -@noindent -This means the value of @code{number} is 3, which is @sc{ascii} -`control-c' (the third letter of the alphabet, in case you need to -know this information). +Result: 3 (#o3, #x3, ?\C-c) +@end smallexample + +@noindent +This means the value of @code{number} is 3, which is octal three, +hexadecimal three, and @sc{ascii} `control-c' (the third letter of the +alphabet, in case you need to know this information). You can continue moving through the code until you reach the line with the error. Before evaluation, that line looks like this: @@ -17863,7 +18840,7 @@ @item While running Edebug, type @kbd{?} to see a list of all the Edebug commands. (The @code{global-edebug-prefix} is usually @kbd{C-x X}, i.e.@: -@kbd{@key{CTL}-x} followed by an upper case @kbd{X}; use this prefix +@kbd{@key{CTRL}-x} followed by an upper case @kbd{X}; use this prefix for commands made outside of the Edebug debugging buffer.) @item @@ -17872,7 +18849,7 @@ @code{count-words-region} is working. @item -Move point to some spot further down function and then type the +Move point to some spot further down the function and then type the @kbd{h} (@code{edebug-goto-here}) command to jump to that location. @item @@ -17922,8 +18899,8 @@ on-line and as a typeset, printed book.) Go to the other on-line help that is part of GNU Emacs: the on-line -documentation for all functions, and @code{find-tags}, the program -that takes you to sources. +documentation for all functions and variables, and @code{find-tags}, +the program that takes you to sources. Here is an example of how I explore the sources. Because of its name, @file{simple.el} is the file I looked at first, a long time ago. As @@ -17932,21 +18909,16 @@ function, for example, looks complicated. You may want to walk through this function slowly, as we did with the -@code{forward-sentence} function. -@ifnottex -(@xref{forward-sentence}.) -@end ifnottex -@iftex -(@xref{forward-sentence, , @code{forward-sentence}}.) -@end iftex -Or you may want to skip that function and look at another, such as -@code{split-line}. You don't need to read all the functions. -According to @code{count-words-in-defun}, the @code{split-line} -function contains 27 words and symbols. - -Even though it is short, @code{split-line} contains four expressions +@code{forward-sentence} function. (@xref{forward-sentence, The +@code{forward-sentence} function}.) Or you may want to skip that +function and look at another, such as @code{split-line}. You don't +need to read all the functions. According to +@code{count-words-in-defun}, the @code{split-line} function contains +102 words and symbols. + +Even though it is short, @code{split-line} contains expressions we have not studied: @code{skip-chars-forward}, @code{indent-to}, -@code{current-column} and @samp{?\n}. +@code{current-column} and @code{insert-and-inherit}. Consider the @code{skip-chars-forward} function. (It is part of the function definition for @code{back-to-indentation}, which is shown in @@ -17974,25 +18946,17 @@ character codes; and it shows how to create a temporary buffer. (The @code{indent-to} function is written in C rather than Emacs Lisp; -it is a `built-in' function. @code{help-follow} only provides you -with the documentation of a built-in function; it does not take you to -the source. But @code{find-tag} will take you to the source, if -properly set up.) +it is a `built-in' function. @code{help-follow} takes you to its +source as does @code{find-tag}, when properly set up.) You can look at a function's source using @code{find-tag}, which is bound to @kbd{M-.} Finally, you can find out what the Reference Manual has to say by visiting the manual in Info, and typing @kbd{i} -(@code{Info-index}) and the name of the function, or by looking up -@code{skip-chars-forward} in the index to a printed copy of the -manual. - -Similarly, you can find out what is meant by @samp{?\n}. You can try -using @code{Info-index} with @samp{?\n}. It turns out that this -action won't help; but don't give up. If you search the index for -@samp{\n} without the @samp{?}, you will be taken directly to the -relevant section of the manual. (@xref{Character Type, , Character -Type, elisp, The GNU Emacs Lisp Reference Manual}. @samp{?\n} stands -for the newline character.) +(@code{Info-index}) and the name of the function, or by looking up the +function in the index to a printed copy of the manual. + +Similarly, you can find out what is meant by +@code{insert-and-inherit}. Other interesting source files include @file{paragraphs.el}, @file{loaddefs.el}, and @file{loadup.el}. The @file{paragraphs.el} @@ -18122,155 +19086,272 @@ @cindex Ring, making a list like a The kill ring is a list that is transformed into a ring by the -workings of the @code{rotate-yank-pointer} function. The @code{yank} -and @code{yank-pop} commands use the @code{rotate-yank-pointer} -function. This appendix describes the @code{rotate-yank-pointer} -function as well as both the @code{yank} and the @code{yank-pop} -commands. - -@menu -* rotate-yank-pointer:: Move a pointer along a list and around. -* yank:: Paste a copy of a clipped element. -* yank-pop:: Insert first element pointed to. +workings of the @code{current-kill} function. The @code{yank} and +@code{yank-pop} commands use the @code{current-kill} function. + +This appendix describes the @code{current-kill} function as well as +both the @code{yank} and the @code{yank-pop} commands, but first, +consider the workings of the kill ring. + +@need 1250 +The kill ring has a default maximum length of sixty items; this number +is too large for an explanation. Instead, set it to four. Please +evaluate the following: + +@smallexample +@group +(setq old-kill-ring-max kill-ring-max) +(setq kill-ring-max 4) +@end group +@end smallexample + +@noindent +Then, please copy each line of the following indented example into the +kill ring. You may kill each line with @kbd{C-k} or mark it and copy +it with @kbd{M-w}. + +@noindent +(In a read-only buffer, such as the @file{*info*} buffer, the kill +command, @kbd{C-k} (@code{kill-line}), will not remove the text, +merely copy it to the kill ring. However, your machine may beep at +you. Alternatively, for silence, you may copy the region of each line +with the @kbd{M-w} (@code{kill-ring-save}) command. You must mark +each line for this command to succeed, but it does not matter at which +end you put point or mark.) + +@need 1250 +@noindent +Please invoke the calls in order, so that five elements attempt to +fill the kill ring: + +@smallexample +@group +first some text +second piece of text +third line +fourth line of text +fifth bit of text +@end group +@end smallexample + +@need 1250 +@noindent +Then find the value of @code{kill-ring} by evaluating + +@smallexample +kill-ring +@end smallexample + +@need 800 +@noindent +It is: + +@smallexample +@group +("fifth bit of text" "fourth line of text" +"third line" "second piece of text") +@end group +@end smallexample + +@noindent +The first element, @samp{first some text}, was dropped. + +@need 1250 +To return to the old value for the length of the kill ring, evaluate: + +@smallexample +(setq kill-ring-max old-kill-ring-max) +@end smallexample + +@menu +* current-kill:: +* yank:: +* yank-pop:: * ring file:: @end menu -@node rotate-yank-pointer, yank, Kill Ring, Kill Ring -@comment node-name, next, previous, up -@appendixsec The @code{rotate-yank-pointer} Function -@findex rotate-yank-pointer - -The @code{rotate-yank-pointer} function changes the element in the kill -ring to which @code{kill-ring-yank-pointer} points. For example, it can -change @code{kill-ring-yank-pointer} from pointing to the second -element to point to the third element. - -@need 800 -Here is the code for @code{rotate-yank-pointer}: - -@smallexample -@group -(defun rotate-yank-pointer (arg) - "Rotate the yanking point in the kill ring." - (interactive "p") - (let ((length (length kill-ring))) -@end group -@group - (if (zerop length) - ;; @r{then-part} - (error "Kill ring is empty") -@end group -@group - ;; @r{else-part} - (setq kill-ring-yank-pointer - (nthcdr (% (+ arg - (- length - (length - kill-ring-yank-pointer))) - length) - kill-ring))))) -@end group -@end smallexample - -@menu -* Understanding rotate-yk-ptr:: -* rotate-yk-ptr body:: The body of @code{rotate-yank-pointer}. -@end menu - -@node Understanding rotate-yk-ptr, rotate-yk-ptr body, rotate-yank-pointer, rotate-yank-pointer -@ifnottex -@unnumberedsubsec @code{rotate-yank-pointer} in Outline -@end ifnottex - -The @code{rotate-yank-pointer} function looks complex, but as usual, -it can be understood by taking it apart piece by piece. First look at -it in skeletal form: - -@smallexample -@group -(defun rotate-yank-pointer (arg) - "Rotate the yanking point in the kill ring." - (interactive "p") +@node current-kill, yank, Kill Ring, Kill Ring +@comment node-name, next, previous, up +@appendixsec The @code{current-kill} Function +@findex current-kill + +The @code{current-kill} function changes the element in the kill ring +to which @code{kill-ring-yank-pointer} points. (Also, the +@code{kill-new} function sets @code{kill-ring-yank-pointer} to point +to the latest element of the the kill ring. The @code{kill-new} +function is used directly or indirectly by @code{kill-append}, +@code{copy-region-as-kill}, @code{kill-ring-save}, @code{kill-line}, +and @code{kill-region}.) + +@need 1500 +The @code{current-kill} function is used by @code{yank} and by +@code{yank-pop}. Here is the code for @code{current-kill}: + +@smallexample +@group +(defun current-kill (n &optional do-not-move) + "Rotate the yanking point by N places, and then return that kill. +If N is zero, `interprogram-paste-function' is set, and calling it +returns a string, then that string is added to the front of the +kill ring and returned as the latest kill. +@end group +@group +If optional arg DO-NOT-MOVE is non-nil, then don't actually move the +yanking point; just return the Nth kill forward." + (let ((interprogram-paste (and (= n 0) + interprogram-paste-function + (funcall interprogram-paste-function)))) +@end group +@group + (if interprogram-paste + (progn + ;; Disable the interprogram cut function when we add the new + ;; text to the kill ring, so Emacs doesn't try to own the + ;; selection, with identical text. + (let ((interprogram-cut-function nil)) + (kill-new interprogram-paste)) + interprogram-paste) +@end group +@group + (or kill-ring (error "Kill ring is empty")) + (let ((ARGth-kill-element + (nthcdr (mod (- n (length kill-ring-yank-pointer)) + (length kill-ring)) + kill-ring))) + (or do-not-move + (setq kill-ring-yank-pointer ARGth-kill-element)) + (car ARGth-kill-element))))) +@end group +@end smallexample + +Remember also that the @code{kill-new} function sets +@code{kill-ring-yank-pointer} to the latest element of the the kill +ring, which means that all the functions that call it set the value +indirectly: @code{kill-append}, @code{copy-region-as-kill}, +@code{kill-ring-save}, @code{kill-line}, and @code{kill-region}. + +@need 1500 +Here is the line in @code{kill-new}, which is explained in +@ref{kill-new function, , The @code{kill-new} function}. + +@smallexample +(setq kill-ring-yank-pointer kill-ring) +@end smallexample + +@menu +* Understanding current-kill:: +@end menu + +@node Understanding current-kill, , current-kill, current-kill +@ifnottex +@unnumberedsubsec @code{current-kill} in Outline +@end ifnottex + +The @code{current-kill} function looks complex, but as usual, it can +be understood by taking it apart piece by piece. First look at it in +skeletal form: + +@smallexample +@group +(defun current-kill (n &optional do-not-move) + "Rotate the yanking point by N places, and then return that kill." (let @var{varlist} @var{body}@dots{}) @end group @end smallexample -This function takes one argument, called @code{arg}. It has a brief -documentation string; and it is interactive with a small @samp{p}, which -means that the argument must be a processed prefix passed to the -function as a number. +This function takes two arguments, one of which is optional. It has a +documentation string. It is @emph{not} interactive. The body of the function definition is a @code{let} expression, which itself has a body as well as a @var{varlist}. The @code{let} expression declares a variable that will be only usable within the bounds of this function. This variable is called -@code{length} and is bound to a value that is equal to the number of -items in the kill ring. This is done by using the function called -@code{length}. (Note that this function has the same name as the -variable called @code{length}; but one use of the word is to name the -function and the other is to name the variable. The two are quite -distinct. Similarly, an English speaker will distinguish between the -meanings of the word @samp{ship} when he says: "I must ship this package -immediately." and "I must get aboard the ship immediately.") - -The function @code{length} tells the number of items there are in a list, -so @code{(length kill-ring)} returns the number of items there are in the -kill ring. - -@node rotate-yk-ptr body, , Understanding rotate-yk-ptr, rotate-yank-pointer -@comment node-name, next, previous, up -@appendixsubsec The Body of @code{rotate-yank-pointer} - -The body of @code{rotate-yank-pointer} is a @code{let} expression and -the body of the @code{let} expression is an @code{if} expression. - -The purpose of the @code{if} expression is to find out whether there is -anything in the kill ring. If the kill ring is empty, the @code{error} -function stops evaluation of the function and prints a message in the -echo area. On the other hand, if the kill ring has something in it, the -work of the function is done. - -Here is the if-part and then-part of the @code{if} expression: +@code{interprogram-paste} and is for copying to another program. It +is not for copying within this instance of GNU Emacs. Most window +systems provide a facility for interprogram pasting. Sadly, that +facility usually provides only for the last element. Most windowing +systems have not adopted a ring of many possibilities, even though +Emacs has provided it for decades. + +The @code{if} expression has two parts, one if there exists +@code{interprogram-paste} and one if not. + +@need 2000 +Let us consider the `if not' or else-part of the @code{current-kill} +function. (The then-part uses the the @code{kill-new} function, which +we have already described. @xref{kill-new function, , The +@code{kill-new} function}.) + +@smallexample +@group +(or kill-ring (error "Kill ring is empty")) +(let ((ARGth-kill-element + (nthcdr (mod (- n (length kill-ring-yank-pointer)) + (length kill-ring)) + kill-ring))) + (or do-not-move + (setq kill-ring-yank-pointer ARGth-kill-element)) + (car ARGth-kill-element)) +@end group +@end smallexample + +@noindent +The code first checks whether the kill ring has content; otherwise it +signals an error. + +@need 1000 +Note that the @code{or} expression is very similar to testing length +with an @code{if}: @findex zerop @findex error @smallexample @group -(if (zerop length) ; @r{if-part} - (error "Kill ring is empty") ; @r{then-part} - @dots{} +(if (zerop (length kill-ring)) ; @r{if-part} + (error "Kill ring is empty")) ; @r{then-part} + ;; No else-part @end group @end smallexample @noindent If there is not anything in the kill ring, its length must be zero and an error message sent to the user: @samp{Kill ring is empty}. The -@code{if} expression uses the function @code{zerop} which returns true -if the value it is testing is zero. When @code{zerop} tests true, the -then-part of the @code{if} is evaluated. The then-part is a list -starting with the function @code{error}, which is a function that is -similar to the @code{message} function (@pxref{message}), in that it -prints a one-line message in the echo area. However, in addition to -printing a message, @code{error} also stops evaluation of the function -within which it is embedded. This means that the rest of the function -will not be evaluated if the length of the kill ring is zero. - -@menu -* Digression concerning error:: How to mislead humans, but not computers. -* rotate-yk-ptr else-part:: The else-part of the @code{if} expression. -* Remainder Function:: The remainder, @code{%}, function. -* rotate-yk-ptr remainder:: Using @code{%} in @code{rotate-yank-pointer}. -* kill-rng-yk-ptr last elt:: Pointing to the last element. -@end menu - -@node Digression concerning error, rotate-yk-ptr else-part, rotate-yk-ptr body, rotate-yk-ptr body +@code{current-kill} function uses an @code{or} expression which is +simpler. But an @code{if} expression reminds us what goes on. + +This @code{if} expression uses the function @code{zerop} which returns +true if the value it is testing is zero. When @code{zerop} tests +true, the then-part of the @code{if} is evaluated. The then-part is a +list starting with the function @code{error}, which is a function that +is similar to the @code{message} function +(@pxref{message, , The @code{message} Function}) in that +it prints a one-line message in the echo area. However, in addition +to printing a message, @code{error} also stops evaluation of the +function within which it is embedded. This means that the rest of the +function will not be evaluated if the length of the kill ring is zero. + +Then the @code{current-kill} function selects the element to return. +The selection depends on the number of places that @code{current-kill} +rotates and on where @code{kill-ring-yank-pointer} points. + +Next, either the optional @code{do-not-move} argument is true or the +current value of @code{kill-ring-yank-pointer} is set to point to the +list. Finally, another expression returns the first element of the +list even if the @code{do-not-move} argument is true. + +@menu +* Digression concerning error:: +* Determining the Element :: +@end menu + +@node Digression concerning error, Determining the Element , Understanding current-kill, Understanding current-kill @ifnottex @unnumberedsubsubsec Digression about the word `error' @end ifnottex -(In my opinion, it is slightly misleading, at least to humans, to use +In my opinion, it is slightly misleading, at least to humans, to use the term `error' as the name of the @code{error} function. A better term would be `cancel'. Strictly speaking, of course, you cannot point to, much less rotate a pointer to a list that has no length, so @@ -18285,86 +19366,38 @@ that a human who is acting virtuously, by exploring his or her environment, is making an error. This is bad. Even though the computer takes the same steps as it does when there is an `error', a term such as -`cancel' would have a clearer connotation.) - -@node rotate-yk-ptr else-part, Remainder Function, Digression concerning error, rotate-yk-ptr body -@unnumberedsubsubsec The else-part of the @code{if} expression - -The else-part of the @code{if} expression is dedicated to setting the -value of @code{kill-ring-yank-pointer} when the kill ring has something -in it. The code looks like this: - -@smallexample -@group -(setq kill-ring-yank-pointer - (nthcdr (% (+ arg - (- length - (length kill-ring-yank-pointer))) - length) - kill-ring))))) -@end group -@end smallexample - -This needs some examination. Clearly, @code{kill-ring-yank-pointer} -is being set to be equal to some @sc{cdr} of the kill ring, using the +`cancel' would have a clearer connotation. + +@node Determining the Element , , Digression concerning error, Understanding current-kill +@ifnottex +@unnumberedsubsubsec Determining the Element +@end ifnottex + +Among other actions, the else-part of the @code{if} expression sets +the value of @code{kill-ring-yank-pointer} to +@code{ARGth-kill-element} when the kill ring has something in it and +the value of @code{do-not-move} is @code{nil}. + +@need 800 +The code looks like this: + +@smallexample +@group +(nthcdr (mod (- n (length kill-ring-yank-pointer)) + (length kill-ring)) + kill-ring))) +@end group +@end smallexample + +This needs some examination. Unless it is not supposed to move the +pointer, the @code{current-kill} function changes where +@code{kill-ring-yank-pointer} points. +That is what the +@w{@code{(setq kill-ring-yank-pointer ARGth-kill-element))}} +expression does. Also, clearly, @code{ARGth-kill-element} is being +set to be equal to some @sc{cdr} of the kill ring, using the @code{nthcdr} function that is described in an earlier section. -(@xref{copy-region-as-kill}.) But exactly how does it do this? - -Before looking at the details of the code let's first consider the -purpose of the @code{rotate-yank-pointer} function. - -The @code{rotate-yank-pointer} function changes what -@code{kill-ring-yank-pointer} points to. If -@code{kill-ring-yank-pointer} starts by pointing to the first element -of a list, a call to @code{rotate-yank-pointer} causes it to point to -the second element; and if @code{kill-ring-yank-pointer} points to the -second element, a call to @code{rotate-yank-pointer} causes it to -point to the third element. (And if @code{rotate-yank-pointer} is -given an argument greater than 1, it jumps the pointer that many -elements.) - -The @code{rotate-yank-pointer} function uses @code{setq} to reset what -the @code{kill-ring-yank-pointer} points to. If -@code{kill-ring-yank-pointer} points to the first element of the kill -ring, then, in the simplest case, the @code{rotate-yank-pointer} -function must cause it to point to the second element. Put another -way, @code{kill-ring-yank-pointer} must be reset to have a value equal -to the @sc{cdr} of the kill ring. - -@need 1250 -That is, under these circumstances, - -@smallexample -@group -(setq kill-ring-yank-pointer - ("some text" "a different piece of text" "yet more text")) - -(setq kill-ring - ("some text" "a different piece of text" "yet more text")) -@end group -@end smallexample - -@need 800 -@noindent -the code should do this: - -@smallexample -(setq kill-ring-yank-pointer (cdr kill-ring)) -@end smallexample - -@need 1000 -@noindent -As a result, the @code{kill-ring-yank-pointer} will look like this: - -@smallexample -@group -kill-ring-yank-pointer - @result{} ("a different piece of text" "yet more text")) -@end group -@end smallexample - -The actual @code{setq} expression uses the @code{nthcdr} function to do -the job. +(@xref{copy-region-as-kill}.) How does it do this? As we have seen before (@pxref{nthcdr}), the @code{nthcdr} function works by repeatedly taking the @sc{cdr} of a list---it takes the @@ -18381,498 +19414,254 @@ @end group @end smallexample -In the @code{rotate-yank-pointer} function, however, the first -argument to @code{nthcdr} is a rather complex looking expression with -lots of arithmetic inside of it: - -@smallexample -@group -(% (+ arg - (- length - (length kill-ring-yank-pointer))) - length) -@end group -@end smallexample - -As usual, we need to look at the most deeply embedded expression first -and then work our way towards the light. - -The most deeply embedded expression is @code{(length -kill-ring-yank-pointer)}. This finds the length of the current value of -the @code{kill-ring-yank-pointer}. (Remember that the -@code{kill-ring-yank-pointer} is the name of a variable whose value is a -list.) - -@need 800 -The measurement of the length is inside the expression: - -@smallexample -(- length (length kill-ring-yank-pointer)) -@end smallexample - -@noindent -In this expression, the first @code{length} is the variable that was -assigned the length of the kill ring in the @code{let} statement at the -beginning of the function. (One might think this function would be -clearer if the variable @code{length} were named -@code{length-of-kill-ring} instead; but if you look at the text of the -whole function, you will see that it is so short that naming this -variable @code{length} is not a bother, unless you are pulling the -function apart into very tiny pieces as we are doing here.) - -So the line @code{(- length (length kill-ring-yank-pointer))} tells the -difference between the length of the kill ring and the length of the list -whose name is @code{kill-ring-yank-pointer}. - -To see how all this fits into the @code{rotate-yank-pointer} -function, let's begin by analyzing the case where -@code{kill-ring-yank-pointer} points to the first element of the kill -ring, just as @code{kill-ring} does, and see what happens when -@code{rotate-yank-pointer} is called with an argument of 1. - -The variable @code{length} and the value of the expression -@code{(length kill-ring-yank-pointer)} will be the same since the -variable @code{length} is the length of the kill ring and the -@code{kill-ring-yank-pointer} is pointing to the whole kill ring. -Consequently, the value of - -@smallexample -(- length (length kill-ring-yank-pointer)) -@end smallexample - -@noindent -will be zero. Since the value of @code{arg} will be 1, this will mean -that the value of the whole expression - -@smallexample -(+ arg (- length (length kill-ring-yank-pointer))) -@end smallexample - -@noindent -will be 1. - -@need 1200 -Consequently, the argument to @code{nthcdr} will be found as the result of -the expression - -@smallexample -(% 1 length) -@end smallexample - -@node Remainder Function, rotate-yk-ptr remainder, rotate-yk-ptr else-part, rotate-yk-ptr body -@unnumberedsubsubsec The @code{%} remainder function - -To understand @code{(% 1 length)}, we need to understand @code{%}. -According to its documentation (which I just found by typing @kbd{C-h -f @kbd{%} @key{RET}}), the @code{%} function returns the remainder of -its first argument divided by its second argument. For example, the -remainder of 5 divided by 2 is 1. (2 goes into 5 twice with a -remainder of 1.) - -What surprises people who don't often do arithmetic is that a smaller -number can be divided by a larger number and have a remainder. In the -example we just used, 5 was divided by 2. We can reverse that and ask, -what is the result of dividing 2 by 5? If you can use fractions, the -answer is obviously 2/5 or .4; but if, as here, you can only use whole -numbers, the result has to be something different. Clearly, 5 can go into -2 zero times, but what of the remainder? To see what the answer is, -consider a case that has to be familiar from childhood: - -@itemize @bullet -@item -5 divided by 5 is 1 with a remainder of 0; - -@item -6 divided by 5 is 1 with a remainder of 1; - -@item -7 divided by 5 is 1 with a remainder of 2. - -@item -Similarly, 10 divided by 5 is 2 with a remainder of 0; - -@item -11 divided by 5 is 2 with a remainder of 1; - -@item -12 divided by 5 is 1 with a remainder of 2. -@end itemize - -@need 1250 -@noindent -By considering the cases as parallel, we can see that - -@itemize @bullet -@item -zero divided by 5 must be zero with a remainder of zero; - -@item -1 divided by 5 must be zero with a remainder of 1; - -@item -2 divided by 5 must be zero with a remainder of 2; -@end itemize - -@noindent -and so on. - -@need 1250 -So, in this code, if the value of @code{length} is 5, then the result of -evaluating - -@smallexample -(% 1 5) -@end smallexample - -@noindent -is 1. (I just checked this by placing the cursor after the expression -and typing @kbd{C-x C-e}. Indeed, 1 is printed in the echo area.) - -@need 2000 -@node rotate-yk-ptr remainder, kill-rng-yk-ptr last elt, Remainder Function, rotate-yk-ptr body -@unnumberedsubsubsec Using @code{%} in @code{rotate-yank-pointer} - -When the @code{kill-ring-yank-pointer} points to the -beginning of the kill ring, and the argument passed to -@code{rotate-yank-pointer} is 1, the @code{%} expression returns 1: - -@smallexample -@group -(- length (length kill-ring-yank-pointer)) - @result{} 0 -@end group -@end smallexample - -@need 1250 -@noindent -therefore, - -@smallexample -@group -(+ arg (- length (length kill-ring-yank-pointer))) - @result{} 1 -@end group -@end smallexample - -@need 1250 -@noindent -and consequently: - -@smallexample -@group -(% (+ arg (- length (length kill-ring-yank-pointer))) - length) - @result{} 1 -@end group -@end smallexample - -@noindent -regardless of the value of @code{length}. - -@need 1250 -@noindent -As a result of this, the @code{setq kill-ring-yank-pointer} expression -simplifies to: - -@smallexample -(setq kill-ring-yank-pointer (nthcdr 1 kill-ring)) -@end smallexample - -@noindent -What it does is now easy to understand. Instead of pointing as it did -to the first element of the kill ring, the -@code{kill-ring-yank-pointer} is set to point to the second element. - -Clearly, if the argument passed to @code{rotate-yank-pointer} is two, then -the @code{kill-ring-yank-pointer} is set to @code{(nthcdr 2 kill-ring)}; -and so on for different values of the argument. - -Similarly, if the @code{kill-ring-yank-pointer} starts out pointing to -the second element of the kill ring, its length is shorter than the -length of the kill ring by 1, so the computation of the remainder is -based on the expression @code{(% (+ arg 1) length)}. This means that -the @code{kill-ring-yank-pointer} is moved from the second element of -the kill ring to the third element if the argument passed to -@code{rotate-yank-pointer} is 1. - -@node kill-rng-yk-ptr last elt, , rotate-yk-ptr remainder, rotate-yk-ptr body -@unnumberedsubsubsec Pointing to the last element - -The final question is, what happens if the @code{kill-ring-yank-pointer} -is set to the @emph{last} element of the kill ring? Will a call to -@code{rotate-yank-pointer} mean that nothing more can be taken from the -kill ring? The answer is no. What happens is different and useful. -The @code{kill-ring-yank-pointer} is set to point to the beginning of -the kill ring instead. - -Let's see how this works by looking at the code, assuming the length of the -kill ring is 5 and the argument passed to @code{rotate-yank-pointer} is 1. -When the @code{kill-ring-yank-pointer} points to the last element of -the kill ring, its length is 1. The code looks like this: - -@smallexample -(% (+ arg (- length (length kill-ring-yank-pointer))) length) -@end smallexample - -@need 1250 -When the variables are replaced by their numeric values, the expression -looks like this: - -@smallexample -(% (+ 1 (- 5 1)) 5) -@end smallexample - -@noindent -This expression can be evaluated by looking at the most embedded inner -expression first and working outwards: The value of @code{(- 5 1)} is 4; -the sum of @code{(+ 1 4)} is 5; and the remainder of dividing 5 by 5 is -zero. So what @code{rotate-yank-pointer} will do is - -@smallexample -(setq kill-ring-yank-pointer (nthcdr 0 kill-ring)) -@end smallexample - -@noindent -which will set the @code{kill-ring-yank-pointer} to point to the beginning -of the kill ring. - -So what happens with successive calls to @code{rotate-yank-pointer} is that -it moves the @code{kill-ring-yank-pointer} from element to element in the -kill ring until it reaches the end; then it jumps back to the beginning. -And this is why the kill ring is called a ring, since by jumping back to -the beginning, it is as if the list has no end! (And what is a ring, but -an entity with no end?) - -@node yank, yank-pop, rotate-yank-pointer, Kill Ring +However, the @code{nthcdr} expression is more complicated. It uses +the @code{mod} function to determine which @sc{cdr} to select. + +(You will remember to look at inner functions first; indeed, we will +have to go inside the @code{mod}.) + +The @code{mod} function returns the value of its first argument modulo +the second; that is to say, it returns the remainder after dividing +the first argument by the second. The value returned has the same +sign as the second argument. + +@need 800 +Thus, + +@smallexample +@group +(mod 12 4) + @result{} 0 ;; @r{because there is no remainder} +(mod 13 4) + @result{} 1 +@end group +@end smallexample + +@need 1250 +In this case, the first argument is often smaller than the second. +That is fine. + +@smallexample +@group +(mod 0 4) + @result{} 0 +(mod 1 4) + @result{} 1 +@end group +@end smallexample + +We can guess what the @code{-} function does. It is like @code{+} but +subtracts instead of adds; the @code{-} function subtracts its second +argument from its first. Also, we already know what the @code{length} +function does (@pxref{length}). It returns the length of a list. + +And @code{n} is the name of the required argument to the +@code{current-kill} function. + +@need 1250 +So when the first argument to @code{nthcdr} is zero, the @code{nthcdr} +expression returns the whole list, as you can see by evaluating the +following: + +@smallexample +@group +;; kill-ring-yank-pointer @r{and} kill-ring @r{have a length of four} +;; @r{and} (mod (- 0 4) 4) @result{} 0 +(nthcdr (mod (- 0 4) 4) + '("fourth line of text" + "third line" + "second piece of text" + "first some text")) +@end group +@end smallexample + +@need 1250 +When the first argument to the @code{current-kill} function is one, +the @code{nthcdr} expression returns the list without its first +element. + +@smallexample +@group +(nthcdr (mod (- 1 4) 4) + '("fourth line of text" + "third line" + "second piece of text" + "first some text")) +@end group +@end smallexample + +@cindex @samp{global variable} defined +@cindex @samp{variable, global}, defined +Incidentally, both @code{kill-ring} and @code{kill-ring-yank-pointer} +are @dfn{global variables}. That means that any expression in Emacs +Lisp can access them. They are not like the local variables set by +@code{let} or like the symbols in an argument list. +Local variables can only be accessed +within the @code{let} that defines them or the function that specifies +them in an argument list (and within expressions called by them). + +@ignore +@c texi2dvi fails when the name of the section is within ifnottex ... +(@xref{Prevent confusion, , @code{let} Prevents Confusion}, and +@ref{defun, , The @code{defun} Special Form}.) +@end ignore + +@node yank, yank-pop, current-kill, Kill Ring @comment node-name, next, previous, up @appendixsec @code{yank} @findex yank -After learning about @code{rotate-yank-pointer}, the code for the -@code{yank} function is almost easy. It has only one tricky part, which is -the computation of the argument to be passed to @code{rotate-yank-pointer}. +After learning about @code{current-kill}, the code for the +@code{yank} function is almost easy. + +The @code{yank} function does not use the +@code{kill-ring-yank-pointer} variable directly. It calls +@code{insert-for-yank} which calls @code{current-kill} which sets the +@code{kill-ring-yank-pointer} variable. @need 1250 The code looks like this: +@c in GNU Emacs 22 @smallexample @group (defun yank (&optional arg) - "Reinsert the last stretch of killed text. -More precisely, reinsert the stretch of killed text most -recently killed OR yanked. -With just C-U as argument, same but put point in front -(and mark at end). With argument n, reinsert the nth -most recently killed stretch of killed text. + "Reinsert (\"paste\") the last stretch of killed text. +More precisely, reinsert the stretch of killed text most recently +killed OR yanked. Put point at end, and set mark at beginning. +With just \\[universal-argument] as argument, same but put point at +beginning (and mark at end). With argument N, reinsert the Nth most +recently killed stretch of killed text. + +When this command inserts killed text into the buffer, it honors +`yank-excluded-properties' and `yank-handler' as described in the +doc string for `insert-for-yank-1', which see. + See also the command \\[yank-pop]." @end group @group - (interactive "*P") - (rotate-yank-pointer (if (listp arg) 0 - (if (eq arg '-) -1 - (1- arg)))) + (setq yank-window-start (window-start)) + ;; If we don't get all the way thru, make last-command indicate that + ;; for the following command. + (setq this-command t) (push-mark (point)) - (insert (car kill-ring-yank-pointer)) +@end group +@group + (insert-for-yank (current-kill (cond + ((listp arg) 0) + ((eq arg '-) -2) + (t (1- arg))))) (if (consp arg) - (exchange-point-and-mark))) -@end group -@end smallexample - -Glancing over this code, we can understand the last few lines readily -enough. The mark is pushed, that is, remembered; then the first element -(the @sc{car}) of what the @code{kill-ring-yank-pointer} points to is -inserted; and then, if the argument passed the function is a -@code{cons}, point and mark are exchanged so the point is put in the -front of the inserted text rather than at the end. This option is -explained in the documentation. The function itself is interactive with -@code{"*P"}. This means it will not work on a read-only buffer, and that -the unprocessed prefix argument is passed to the function. - -@menu -* rotate-yk-ptr arg:: Pass the argument to @code{rotate-yank-pointer}. -* rotate-yk-ptr negative arg:: Pass a negative argument. -@end menu - -@node rotate-yk-ptr arg, rotate-yk-ptr negative arg, yank, yank -@unnumberedsubsubsec Passing the argument - -The hard part of @code{yank} is understanding the computation that -determines the value of the argument passed to -@code{rotate-yank-pointer}. Fortunately, it is not so difficult as it -looks at first sight. - -What happens is that the result of evaluating one or both of the -@code{if} expressions will be a number and that number will be the -argument passed to @code{rotate-yank-pointer}. - -@need 1250 -Laid out with comments, the code looks like this: - -@smallexample -@group -(if (listp arg) ; @r{if-part} - 0 ; @r{then-part} - (if (eq arg '-) ; @r{else-part, inner if} - -1 ; @r{inner if's then-part} - (1- arg)))) ; @r{inner if's else-part} -@end group -@end smallexample - -@noindent -This code consists of two @code{if} expression, one the else-part of -the other. - -The first or outer @code{if} expression tests whether the argument -passed to @code{yank} is a list. Oddly enough, this will be true if -@code{yank} is called without an argument---because then it will be -passed the value of @code{nil} for the optional argument and an -evaluation of @code{(listp nil)} returns true! So, if no argument is -passed to @code{yank}, the argument passed to -@code{rotate-yank-pointer} inside of @code{yank} is zero. This means -the pointer is not moved and the first element to which -@code{kill-ring-yank-pointer} points is inserted, as we expect. -Similarly, if the argument for @code{yank} is @kbd{C-u}, this will be -read as a list, so again, a zero will be passed to -@code{rotate-yank-pointer}. (@kbd{C-u} produces an unprocessed prefix -argument of @code{(4)}, which is a list of one element.) At the same -time, later in the function, this argument will be read as a -@code{cons} so point will be put in the front and mark at the end of -the insertion. (The @code{P} argument to @code{interactive} is -designed to provide these values for the case when an optional -argument is not provided or when it is @kbd{C-u}.) - -The then-part of the outer @code{if} expression handles the case when -there is no argument or when it is @kbd{C-u}. The else-part handles the -other situations. The else-part is itself another @code{if} expression. - -The inner @code{if} expression tests whether the argument is a minus -sign. (This is done by pressing the @key{META} and @kbd{-} keys at the -same time, or the @key{ESC} key and then the @kbd{-} key). In this -case, the @code{rotate-yank-pointer} function is passed @kbd{-1} as an -argument. This moves the @code{kill-ring-yank-pointer} backwards, which -is what is desired. - -If the true-or-false-test of the inner @code{if} expression is false -(that is, if the argument is not a minus sign), the else-part of the -expression is evaluated. This is the expression @code{(1- arg)}. -Because of the two @code{if} expressions, it will only occur when the -argument is a positive number or when it is a negative number (not -just a minus sign on its own). What @code{(1- arg)} does is decrement -the number and return it. (The @code{1-} function subtracts one from -its argument.) This means that if the argument to -@code{rotate-yank-pointer} is 1, it is reduced to zero, which means -the first element to which @code{kill-ring-yank-pointer} points is -yanked back, as you would expect. - -@node rotate-yk-ptr negative arg, , rotate-yk-ptr arg, yank -@unnumberedsubsubsec Passing a negative argument - -Finally, the question arises, what happens if either the remainder -function, @code{%}, or the @code{nthcdr} function is passed a negative -argument, as they quite well may? - -The answers can be found by a quick test. When @code{(% -1 5)} is -evaluated, a negative number is returned; and if @code{nthcdr} is -called with a negative number, it returns the same value as if it were -called with a first argument of zero. This can be seen by evaluating -the following code. - -Here the @samp{@result{}} points to the result of evaluating the code -preceding it. This was done by positioning the cursor after the code -and typing @kbd{C-x C-e} (@code{eval-last-sexp}) in the usual fashion. -You can do this if you are reading this in Info inside of GNU Emacs. - -@smallexample -@group -(% -1 5) - @result{} -1 -@end group - -@group -(setq animals '(cats dogs elephants)) - @result{} (cats dogs elephants) -@end group - -@group -(nthcdr 1 animals) - @result{} (dogs elephants) -@end group - -@group -(nthcdr 0 animals) - @result{} (cats dogs elephants) -@end group - -@group -(nthcdr -1 animals) - @result{} (cats dogs elephants) -@end group -@end smallexample - -So, if a minus sign or a negative number is passed to @code{yank}, the -@code{kill-ring-yank-point} is rotated backwards until it reaches the -beginning of the list. Then it stays there. Unlike the other case, -when it jumps from the end of the list to the beginning of the list, -making a ring, it stops. This makes sense. You often want to get back -to the most recently clipped out piece of text, but you don't usually -want to insert text from as many as thirty kill commands ago. So you -need to work through the ring to get to the end, but won't cycle around -it inadvertently if you are trying to come back to the beginning. - -Incidentally, any number passed to @code{yank} with a minus sign -preceding it will be treated as @minus{}1. This is evidently a -simplification for writing the program. You don't need to jump back -towards the beginning of the kill ring more than one place at a time -and doing this is easier than writing a function to determine the -magnitude of the number that follows the minus sign. + ;; This is like exchange-point-and-mark, + ;; but doesn't activate the mark. + ;; It is cleaner to avoid activation, even though the command + ;; loop would deactivate the mark because we inserted text. + (goto-char (prog1 (mark t) + (set-marker (mark-marker) (point) (current-buffer))))) +@end group +@group + ;; If we do get all the way thru, make this-command indicate that. + (if (eq this-command t) + (setq this-command 'yank)) + nil) +@end group +@end smallexample + +The key expression is @code{insert-for-yank}, which inserts the string +returned by @code{current-kill}, but removes some text properties from +it. + +However, before getting to that expression, the function sets the value +of @code{yank-window-start} to the position returned by the +@code{(window-start)} expression, the position at which the display +currently starts. The @code{yank} function also sets +@code{this-command} and pushes the mark. + +After it yanks the appropriate element, if the optional argument is a +@sc{cons} rather than a number or nothing, it puts point at beginning +of the yanked text and mark at its end. + +(The @code{prog1} function is like @code{progn} but returns the value +of its first argument rather than the value of its last argument. Its +first argument is forced to return the buffer's mark as an integer. +You can see the documentation for these functions by placing point +over them in this buffer and then typing @kbd{C-h f} +(@code{describe-function}) followed by a @kbd{RET}; the default is the +function.) + +The last part of the function tells what to do when it succeeds. @node yank-pop, ring file, yank, Kill Ring @comment node-name, next, previous, up @appendixsec @code{yank-pop} @findex yank-pop -After understanding @code{yank}, the @code{yank-pop} function is easy. -Leaving out the documentation to save space, it looks like this: - -@smallexample -@group -(defun yank-pop (arg) +After understanding @code{yank} and @code{current-kill}, you know how +to approach the @code{yank-pop} function. Leaving out the +documentation to save space, it looks like this: + +@c GNU Emacs 22 +@smallexample +@group +(defun yank-pop (&optional arg) + "@dots{}" (interactive "*p") (if (not (eq last-command 'yank)) (error "Previous command was not a yank")) @end group @group (setq this-command 'yank) - (let ((before (< (point) (mark)))) - (delete-region (point) (mark)) - (rotate-yank-pointer arg) -@end group -@group - (set-mark (point)) - (insert (car kill-ring-yank-pointer)) - (if before (exchange-point-and-mark)))) + (unless arg (setq arg 1)) + (let ((inhibit-read-only t) + (before (< (point) (mark t)))) +@end group +@group + (if before + (funcall (or yank-undo-function 'delete-region) (point) (mark t)) + (funcall (or yank-undo-function 'delete-region) (mark t) (point))) + (setq yank-undo-function nil) +@end group +@group + (set-marker (mark-marker) (point) (current-buffer)) + (insert-for-yank (current-kill arg)) + ;; Set the window start back where it was in the yank command, + ;; if possible. + (set-window-start (selected-window) yank-window-start t) +@end group +@group + (if before + ;; This is like exchange-point-and-mark, + ;; but doesn't activate the mark. + ;; It is cleaner to avoid activation, even though the command + ;; loop would deactivate the mark because we inserted text. + (goto-char (prog1 (mark t) + (set-marker (mark-marker) + (point) + (current-buffer)))))) + nil) @end group @end smallexample The function is interactive with a small @samp{p} so the prefix argument is processed and passed to the function. The command can only be used after a previous yank; otherwise an error message is -sent. This check uses the variable @code{last-command} which is -discussed elsewhere. (@xref{copy-region-as-kill}.) +sent. This check uses the variable @code{last-command} which is set +by @code{yank} and is discussed elsewhere. +(@xref{copy-region-as-kill}.) The @code{let} clause sets the variable @code{before} to true or false depending whether point is before or after mark and then the region between point and mark is deleted. This is the region that was just inserted by the previous yank and it is this text that will be -replaced. Next the @code{kill-ring-yank-pointer} is rotated so that -the previously inserted text is not reinserted yet again. Mark is set -at the beginning of the place the new text will be inserted and then -the first element to which @code{kill-ring-yank-pointer} points is -inserted. This leaves point after the new text. If in the previous -yank, point was left before the inserted text, point and mark are now -exchanged so point is again left in front of the newly inserted text. -That is all there is to it! +replaced. + +@code{funcall} calls its first argument as a function, passing +remaining arguments to it. The first argument is whatever the +@code{or} expression returns. The two remaining arguments are the +positions of point and mark set by the preceding @code{yank} command. + +There is more, but that is the hardest part. @node ring file, , yank-pop, Kill Ring @comment node-name, next, previous, up @@ -18895,10 +19684,10 @@ @menu * Labelled Example:: -* print-graph Varlist:: @code{let} expression in @code{print-graph}. -* print-Y-axis:: Print a label for the vertical axis. -* print-X-axis:: Print a horizontal label. -* Print Whole Graph:: The function to print a complete graph. +* print-graph Varlist:: +* print-Y-axis:: +* print-X-axis:: +* Print Whole Graph:: @end menu @node Labelled Example, print-graph Varlist, Full Graph, Full Graph @@ -19073,11 +19862,11 @@ five. @menu -* Height of label:: What height for the Y axis? -* Compute a Remainder:: How to compute the remainder of a division. -* Y Axis Element:: Construct a line for the Y axis. -* Y-axis-column:: Generate a list of Y axis labels. -* print-Y-axis Penultimate:: A not quite final version. +* Height of label:: +* Compute a Remainder:: +* Y Axis Element:: +* Y-axis-column:: +* print-Y-axis Penultimate:: @end menu @node Height of label, Compute a Remainder, print-Y-axis, print-Y-axis @@ -19129,10 +19918,7 @@ that you cannot discover using @code{apropos}: you find nothing if you type @kbd{M-x apropos @key{RET} remainder @key{RET}}. The only way to learn of the existence of @code{%} is to read about it in a book such -as this or in the Emacs Lisp sources. The @code{%} function is used -in the code for @code{rotate-yank-pointer}, which is described in an -appendix. (@xref{rotate-yk-ptr body, , The Body of -@code{rotate-yank-pointer}}.) +as this or in the Emacs Lisp sources. You can try the @code{%} function by evaluating the following two expressions: @@ -19354,7 +20140,8 @@ special format. The format is a question mark followed by a blank space, like this, @samp{? }. @xref{Character Type, , Character Type, elisp, The GNU Emacs Lisp Reference Manual}, for a description of the -syntax for characters. +syntax for characters. (Of course, you might want to replace the +blank space by some other character @dots{} You know what to do.) The @code{number-to-string} function is used in the concatenation expression, to convert the number to a string that is concatenated @@ -19477,10 +20264,10 @@ Press @key{RET} to evaluate the expression. @end enumerate -Emacs will print labels vertically, the top one being -@w{@samp{10 -@w{ }}}. (The @code{print-graph} function -will pass the value of @code{height-of-top-line}, which -in this case would end up as 15.) +Emacs will print labels vertically, the top one being @w{@samp{10 -@w{ +}}}. (The @code{print-graph} function will pass the value of +@code{height-of-top-line}, which in this case will end up as 15, +thereby getting rid of what might appear as a bug.) @need 2000 @node print-X-axis, Print Whole Graph, print-Y-axis, Full Graph @@ -19515,8 +20302,8 @@ graph without changing the ways the graph is labelled. @menu -* Similarities differences:: Much like @code{print-Y-axis}, but not exactly. -* X Axis Tic Marks:: Create tic marks for the horizontal axis. +* Similarities differences:: +* X Axis Tic Marks:: @end menu @node Similarities differences, X Axis Tic Marks, print-X-axis, print-X-axis @@ -19563,11 +20350,11 @@ @noindent (Note that the value of @code{graph-blank} is set by another @code{defvar}. The @code{boundp} predicate checks whether it has -already been set; @code{boundp} returns @code{nil} if it has not. -If @code{graph-blank} were unbound and we did not use this conditional -construction, in GNU Emacs 21, we would enter the debugger and see an -error message saying -@samp{@w{Debugger entered--Lisp error:} @w{(void-variable graph-blank)}}.) +already been set; @code{boundp} returns @code{nil} if it has not. If +@code{graph-blank} were unbound and we did not use this conditional +construction, in a recent GNU Emacs, we would enter the debugger and +see an error message saying @samp{@w{Debugger entered--Lisp error:} +@w{(void-variable graph-blank)}}.) @need 1200 Here is the @code{defvar} for @code{X-axis-tic-symbol}: @@ -19864,13 +20651,13 @@ @end smallexample @menu -* The final version:: A few changes. -* Test print-graph:: Run a short test. -* Graphing words in defuns:: Executing the final code. -* lambda:: How to write an anonymous function. -* mapcar:: Apply a function to elements of a list. -* Another Bug:: Yet another bug @dots{} most insidious. -* Final printed graph:: The graph itself! +* The final version:: +* Test print-graph:: +* Graphing words in defuns:: +* lambda:: +* mapcar:: +* Another Bug:: +* Final printed graph:: @end menu @node The final version, Test print-graph, Print Whole Graph, Print Whole Graph @@ -20259,7 +21046,7 @@ @ifset print-postscript-figures @sp 1 @tex -@image{lambda-1} +@center @image{lambda-1} %%%% old method of including an image % \input /usr/local/lib/tex/inputs/psfig.tex % \centerline{\psfig{figure=/usr/local/lib/emacs/man/lambda-1.eps}} @@ -20301,7 +21088,7 @@ @ifset print-postscript-figures @sp 1 @tex -@image{lambda-2} +@center @image{lambda-2} %%%% old method of including an image % \input /usr/local/lib/tex/inputs/psfig.tex % \centerline{\psfig{figure=/usr/local/lib/emacs/man/lambda-2.eps}} @@ -20340,7 +21127,7 @@ @ifset print-postscript-figures @sp 1 @tex -@image{lambda-3} +@center @image{lambda-3} %%%% old method of including an image % \input /usr/local/lib/tex/inputs/psfig.tex % \centerline{\psfig{figure=/usr/local/lib/emacs/man/lambda-3.eps}} @@ -21325,7 +22112,6 @@ that lists free books available from other publishers:@* @uref{http://www.gnu.org/doc/other-free-books.html} - @node GNU Free Documentation License, Index, Free Software and Free Manuals, Top @appendix GNU Free Documentation License
--- a/lispintro/makefile.w32-in Tue Nov 07 02:37:49 2006 +0000 +++ b/lispintro/makefile.w32-in Tue Nov 07 23:22:48 2006 +0000 @@ -21,7 +21,7 @@ srcdir = . -infodir = ../info +infodir = $(srcdir)/../info INFO_SOURCES = $(srcdir)/emacs-lisp-intro.texi # The file name eintr must fit within 5 characters, to allow for @@ -46,7 +46,7 @@ dvi: $(DVI_TARGETS) $(infodir)/eintr: $(INFO_SOURCES) - cd $(srcdir); $(MAKEINFO) emacs-lisp-intro.texi -o $(infodir)/eintr + $(MAKEINFO) -o $@ $(srcdir)/emacs-lisp-intro.texi emacs-lisp-intro.dvi: $(INFO_SOURCES) $(ENVADD) $(TEXI2DVI) $(srcdir)/emacs-lisp-intro.texi
--- a/lispref/ChangeLog Tue Nov 07 02:37:49 2006 +0000 +++ b/lispref/ChangeLog Tue Nov 07 23:22:48 2006 +0000 @@ -1,10 +1,20 @@ +2006-11-06 Richard Stallman <rms@gnu.org> + + * lists.texi (List Variables): Document COMPARE-FN. + + * keymaps.texi: Avoid use of "binding" to mean a relation; + use it only to refer to the meaning associated with a key. + (Keymaps): Change menu node description. + + * elisp.texi (Top): Change menu node description. + + * display.texi (Managing Overlays): Document overlay-recenter. + 2006-10-29 Chong Yidong <cyd@stupidchicken.com> * Makefile.in: Use relative paths to avoid advertising filesystem contents during compilation. - * makefile.w32-in: Likewise. - 2006-10-23 Kim F. Storm <storm@cua.dk> * commands.texi (Event Input Misc): Update unread-command-events.
--- a/lispref/display.texi Tue Nov 07 02:37:49 2006 +0000 +++ b/lispref/display.texi Tue Nov 07 23:22:48 2006 +0000 @@ -1259,6 +1259,21 @@ @result{} t @end example + Emacs stores the overlays of each buffer in two lists, divided +around an arbitrary ``center position.'' One list extends backwards +through the buffer from that center position, and the other extends +forwards from that center position. The center position can be anywhere +in the buffer. + +@defun overlay-recenter pos +This function recenters the overlays of the current buffer around +position @var{pos}. That makes overlay lookup faster for positions +near @var{pos}, but slower for positions far away from @var{pos}. +@end defun + + A loop that scans the buffer forwards, creating overlays, can run +faster if you do @code{(overlay-recenter (point-max))} first. + @node Overlay Properties @subsection Overlay Properties
--- a/lispref/elisp.texi Tue Nov 07 02:37:49 2006 +0000 +++ b/lispref/elisp.texi Tue Nov 07 23:22:48 2006 +0000 @@ -614,7 +614,7 @@ * Key Lookup:: How extracting elements from keymaps works. * Functions for Key Lookup:: How to request key lookup. * Changing Key Bindings:: Redefining a key in a keymap. -* Remapping Commands:: Bindings that translate one command to another. +* Remapping Commands:: A keymap can translate one command to another. * Key Binding Commands:: Interactive interfaces for redefining keys. * Scanning Keymaps:: Looking through all keymaps, for printing help. * Menu Keymaps:: A keymap can define a menu for X
--- a/lispref/keymaps.texi Tue Nov 07 02:37:49 2006 +0000 +++ b/lispref/keymaps.texi Tue Nov 07 23:22:48 2006 +0000 @@ -8,12 +8,12 @@ @chapter Keymaps @cindex keymap - The bindings between input events and commands are recorded in data -structures called @dfn{keymaps}. Each binding in a keymap associates -(or @dfn{binds}) an individual event type, either to another keymap or to -a command. When an event type is bound to a keymap, that keymap is used -to look up the next input event; this continues until a command is -found. The whole process is called @dfn{key lookup}. + The command bindings of input events are recorded in data structures +called @dfn{keymaps}. Each entry in a keymap associates (or +@dfn{binds}) an individual event type, either to another keymap or to +a command. When an event type is bound to a keymap, that keymap is +used to look up the next input event; this continues until a command +is found. The whole process is called @dfn{key lookup}. @menu * Key Sequences:: Key sequences as Lisp objects. @@ -32,7 +32,7 @@ * Key Lookup:: Finding a key's binding in one keymap. * Functions for Key Lookup:: How to request key lookup. * Changing Key Bindings:: Redefining a key in a keymap. -* Remapping Commands:: Bindings that translate one command to another. +* Remapping Commands:: A keymap can translate one command to another. * Translation Keymaps:: Keymaps for translating sequences of events. * Key Binding Commands:: Interactive interfaces for redefining keys. * Scanning Keymaps:: Looking through all keymaps, for printing help. @@ -382,19 +382,21 @@ @dfn{parent keymap}. Such a keymap looks like this: @example -(keymap @var{bindings}@dots{} . @var{parent-keymap}) +(keymap @var{elements}@dots{} . @var{parent-keymap}) @end example @noindent The effect is that this keymap inherits all the bindings of @var{parent-keymap}, whatever they may be at the time a key is looked up, -but can add to them or override them with @var{bindings}. - -If you change the bindings in @var{parent-keymap} using @code{define-key} -or other key-binding functions, these changes are visible in the -inheriting keymap unless shadowed by @var{bindings}. The converse is -not true: if you use @code{define-key} to change the inheriting keymap, -that affects @var{bindings}, but has no effect on @var{parent-keymap}. +but can add to them or override them with @var{elements}. + +If you change the bindings in @var{parent-keymap} using +@code{define-key} or other key-binding functions, these changed +bindings are visible in the inheriting keymap, unless shadowed by the +bindings made by @var{elements}. The converse is not true: if you use +@code{define-key} to change bindings in the inheriting keymap, these +changes are recorded in @var{elements}, but have no effect on +@var{parent-keymap}. The proper way to construct a keymap with a parent is to use @code{set-keymap-parent}; if you have code that directly constructs a
--- a/lispref/lists.texi Tue Nov 07 02:37:49 2006 +0000 +++ b/lispref/lists.texi Tue Nov 07 23:22:48 2006 +0000 @@ -713,12 +713,14 @@ Two functions modify lists that are the values of variables. -@defun add-to-list symbol element &optional append +@defun add-to-list symbol element &optional append compare-fn This function sets the variable @var{symbol} by consing @var{element} onto the old value, if @var{element} is not already a member of that value. It returns the resulting list, whether updated or not. The value of @var{symbol} had better be a list already before the call. -Membership is tested using @code{equal}. +@code{add-to-list} uses @var{compare-fn} to compare @var{element} +against existing list members; if @var{compare-fn} is @code{nil}, it +uses @code{equal}. Normally, if @var{element} is added, it is added to the front of @var{symbol}, but if the optional argument @var{append} is
--- a/lispref/makefile.w32-in Tue Nov 07 02:37:49 2006 +0000 +++ b/lispref/makefile.w32-in Tue Nov 07 23:22:48 2006 +0000 @@ -22,7 +22,7 @@ # Standard configure variables. srcdir = . -infodir = ../info +infodir = $(srcdir)/../info usermanualdir = $(srcdir)/../man # Redefine `TEX' if `tex' does not invoke plain TeX. For example: @@ -106,7 +106,7 @@ $(INSTALL_INFO) --info-dir=$(infodir) $(infodir)/elisp $(infodir)/elisp: $(srcs) - cd $(srcdir); $(MAKEINFO) -I. -I$(infodir) elisp.texi -o $(infodir)/elisp + $(MAKEINFO) -I. -I$(srcdir) -o $(infodir)/elisp $(srcdir)/elisp.texi elisp.dvi: $(srcs) $(texinputdir) $(TEX) -I $(usermanualdir) $(srcdir)/elisp.texi
--- a/lwlib/ChangeLog Tue Nov 07 02:37:49 2006 +0000 +++ b/lwlib/ChangeLog Tue Nov 07 23:22:48 2006 +0000 @@ -1,3 +1,7 @@ +2006-10-30 Chong Yidong <cyd@stupidchicken.com> + + * Makefile.in (lwlib-utils.o): Use CPPFLAGS. + 2006-09-15 Jay Belanger <belanger@truman.edu> * COPYING: Replace "Library Public License" by "Lesser Public
--- a/lwlib/Makefile.in Tue Nov 07 02:37:49 2006 +0000 +++ b/lwlib/Makefile.in Tue Nov 07 23:22:48 2006 +0000 @@ -47,7 +47,7 @@ # Depend on Makefile so that we recompile if TOOLKIT_DEFINES changes. lwlib.o: $(srcdir)/lwlib.c Makefile - $(CC) -c $(TOOLKIT_DEFINES) $(ALL_CFLAGS) $(srcdir)/lwlib.c + $(CC) -c $(CPPFLAGS) $(TOOLKIT_DEFINES) $(ALL_CFLAGS) $(srcdir)/lwlib.c lwlib-utils.o: lwlib-utils.c lwlib-utils.h lwlib.o: lwlib.c lwlib.h lwlib-int.h lwlib-Xaw.h lwlib-Xlw.h
--- a/make-dist Tue Nov 07 02:37:49 2006 +0000 +++ b/make-dist Tue Nov 07 23:22:48 2006 +0000 @@ -638,6 +638,7 @@ echo "Making links to \`man'" (cd man ln *.texi *.aux *.cps *.fns *.kys *.vrs ../${tempdir}/man + ln makefile.w32-in ../${tempdir}/man test -f README && ln README ../${tempdir}/man test -f Makefile.in && ln Makefile.in ../${tempdir}/man ln ChangeLog ../${tempdir}/man @@ -652,6 +653,7 @@ ln `ls -1 *.texi` ../${tempdir}/lispref ln *.aux *.cps *.fns *.kys *.vrs ../${tempdir}/lispref ln *.txt *.el spellfile tindex.pl ../${tempdir}/lispref + ln makefile.w32-in ../${tempdir}/lispref test -f README && ln README ../${tempdir}/lispref test -f Makefile.in && ln Makefile.in ../${tempdir}/lispref ln ChangeLog ../${tempdir}/lispref @@ -662,6 +664,7 @@ echo "Making links to \`lispintro'" (cd lispintro ln *.texi *.aux *.cps *.fns *.kys *.vrs *.eps ../${tempdir}/lispintro + ln makefile.w32-in ../${tempdir}/lispintro test -f texinfo.tex && ln texinfo.tex ../${tempdir}/lispintro test -f README && ln README ../${tempdir}/lispintro test -f Makefile.in && ln Makefile.in ../${tempdir}/lispintro
--- a/man/ChangeLog Tue Nov 07 02:37:49 2006 +0000 +++ b/man/ChangeLog Tue Nov 07 23:22:48 2006 +0000 @@ -1,3 +1,18 @@ +2006-11-07 Michael Albinus <michael.albinus@gmx.de> + + * tramp.texi (Configuration): scp is the default method. + (Default Method): Use ssh as example for another method. + +2006-11-06 Richard Stallman <rms@gnu.org> + + * emacs.texi (Acknowledgments): Fix name spelling, add Anna Bigatti. + + * ack.texi (Acknowledgments): Fix name spelling. + +2006-11-01 Juri Linkov <juri@jurta.org> + + * search.texi (Word Search): Document incremental word search. + 2006-10-28 Glenn Morris <rgm@gnu.org> * ack.texi (Acknowledgments): Add cal-html author.
--- a/man/ack.texi Tue Nov 07 02:37:49 2006 +0000 +++ b/man/ack.texi Tue Nov 07 23:22:48 2006 +0000 @@ -735,7 +735,7 @@ originally written by Olin Shivers. @item -Bengt Martensson, Mark Shapiro, Mike Newton, Aaron Larson, and Stefan +Bengt Martensson, Marc Shapiro, Mike Newton, Aaron Larson, and Stefan Schoef, wrote @file{bibtex.el}, a mode for editing Bib@TeX{} bibliography files.
--- a/man/emacs.texi Tue Nov 07 02:37:49 2006 +0000 +++ b/man/emacs.texi Tue Nov 07 23:22:48 2006 +0000 @@ -1027,7 +1027,7 @@ Abrahamsson, Jay K.@: Adams, Michael Albinus, Nagy Andras, Ralf Angeli, Joe Arceneaux, Miles Bader, David Bakhash, Juanma Barranquero, Eli Barzilay, Steven L.@: Baur, Jay Belanger, Alexander L.@: Belikoff, -Boaz Ben-Zvi, Karl Berry, Ray Blaak, Jim Blandy, Johan Bockg@aa{}rd, +Boaz Ben-Zvi, Karl Berry, Anna M.@: Bigatti, Ray Blaak, Jim Blandy, Johan Bockg@aa{}rd, Per Bothner, Terrence Brannon, Frank Bresz, Peter Breton, Emmanuel Briot, Kevin Broadey, Vincent Broman, David M.@: Brown, Georges Brun-Cottan, Joe Buehler, W@l{}odek Bzyl, Bill Carpenter, Per @@ -1082,7 +1082,7 @@ Schmid, Michael Schmidt, Ronald S. Schnell, Philippe Schnoebelen, Jan Schormann, Alex Schroeder, Stephen Schoef, Raymond Scholz, Randal Schwartz, Oliver Seidel, Manuel Serrano, Hovav Shacham, Stanislav -Shalunov, Mark Shapiro, Richard Sharman, Olin Shivers, Espen Skoglund, +Shalunov, Marc Shapiro, Richard Sharman, Olin Shivers, Espen Skoglund, Rick Sladkey, Lynn Slater, Chris Smith, David Smith, Paul D.@: Smith, Andre Spiegel, Michael Staats, William Sommerfeld, Michael Staats, Reiner Steib, Sam Steingold, Ake Stenhoff, Peter Stephenson, Ken
--- a/man/search.texi Tue Nov 07 02:37:49 2006 +0000 +++ b/man/search.texi Tue Nov 07 23:22:48 2006 +0000 @@ -417,7 +417,7 @@ Search backward for @var{words}, ignoring details of punctuation. @end table - Word search is a special case of nonincremental search and is invoked + Word search as a special case of nonincremental search is invoked with @kbd{C-s @key{RET} C-w}. This is followed by the search string, which must always be terminated with @key{RET}. Being nonincremental, this search does not start until the argument is terminated. It works @@ -426,6 +426,13 @@ Use @kbd{C-r @key{RET} C-w} to do backward word search. + You can also invoke word search with @kbd{C-s M-e C-w} or @kbd{C-r +M-e C-w} followed by the search string and terminated with @key{RET}, +@kbd{C-s} or @kbd{C-r}. This puts word search into incremental mode +where you can use all keys available for incremental search. However, +when you type more words in incremental word search, it will fail +until you type complete words. + @findex word-search-forward @findex word-search-backward Forward and backward word searches are implemented by the commands
--- a/man/tramp.texi Tue Nov 07 02:37:49 2006 +0000 +++ b/man/tramp.texi Tue Nov 07 23:22:48 2006 +0000 @@ -456,11 +456,10 @@ @cindex configuration @cindex default configuration -@value{tramp} is (normally) fully functional when it is initially installed. -It is initially configured to use the @command{ssh} program to connect -to the remote host and to use base64 or uu encoding to transfer the -files through that shell connection. So in the easiest case, you just -type @kbd{C-x C-f} and then enter the filename +@value{tramp} is (normally) fully functional when it is initially +installed. It is initially configured to use the @command{scp} +program to connect to the remote host. So in the easiest case, you +just type @kbd{C-x C-f} and then enter the filename @file{@value{prefix}@var{user}@@@var{machine}@value{postfix}@var{/path/to.file}}. On some hosts, there are problems with opening a connection. These are @@ -1036,7 +1035,7 @@ is not specified in the @value{tramp} file name. For example: @lisp -(setq tramp-default-method "scp") +(setq tramp-default-method "ssh") @end lisp @vindex tramp-default-method-alist
--- a/src/ChangeLog Tue Nov 07 02:37:49 2006 +0000 +++ b/src/ChangeLog Tue Nov 07 23:22:48 2006 +0000 @@ -1,4 +1,188 @@ -2006-10-29 Mark Davies <mark@mcs.vuw.ac.nz> (tiny change) +2006-11-06 Juanma Barranquero <lekktu@gmail.com> + + * lread.c (syms_of_lread): + * xsmfns.c (syms_of_xsmfns): Fix typo in docstring. + +2006-11-06 Martin Rudalics <rudalics@gmx.at> + + * macmenu.c (Fmenu_or_popup_active_p): Define outside HAVE_MENUS. + + * w32menu.c (Fmenu_or_popup_active_p): Define outside HAVE_MENUS. + Return nil if building without menus. + + * xmenu.c (Fmenu_or_popup_active_p): Define outside HAVE_MENUS. + Return nil if building without menus. + +2006-11-05 Mark Davies <mark@mcs.vuw.ac.nz> (tiny change) + + * s/netbsd.h (POSIX_SIGNALS): Defined. + +2006-11-05 Martin Rudalics <rudalics@gmx.at> + + * macmenu.c (Fmenu_or_popup_active_p): New function. + (syms_of_macmenu): Defsubr it. + + * w32menu.c (Fmenu_or_popup_active_p): New function. + (syms_of_w32menu): Defsubr it. + (popup_activated_flag, popup_activated): Remove. + + * xdisp.c (note_mouse_highlight) [HAVE_NTGUI]: Don't bother to + check popup_activated. + + * xmenu.c (Fmenu_or_popup_active_p): New function. + (syms_of_xmenu): Defsubr it. + +2006-11-05 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> + + * unexmacosx.c (malloc_cookie): Remove unused variable. + (region_list_head, region_list_tail, lca, nlc, infile_lc_highest_addr) + (text_seg_lowest_offset, mh, curr_header_offset, infd, outfd) + (emacs_zone, data_segment_old_fileoff, data_segment_scp) + (num_unexec_regions, unexec_regions): Make variables static. + (print_regions, find_emacs_zone_regions): Make static. + (unexec_region_info): New typedef. + (unexec_regions): Change type from vm_range_t[] to unexec_region_info[]. + All uses changed. + (unexec_regions_recorder): Subtract size of trailing null pages from + filesize. Show filesize. + (unexec_regions_merge): Don't merge if null pages of preceding region + is not too small. Use long format in printf. + (copy_segment, copy_data_segment): Show filesize. + (copy_data_segment): Write filesize bytes of region data. Adjust + filesize in segment command accordingly. + (dump_it): Use long format in printf. + +2006-11-05 Juanma Barranquero <lekktu@gmail.com> + + * dosfns.c (Finsert_startup_screen): + * fns.c (Ffeaturep, syms_of_fns): + * frame.c (syms_of_frame): Fix typos in docstrings. + + * unexcw.c (unexec): Fix typo in output message. + +2006-11-04 Ralf Angeli <angeli@caeruleus.net> + + * w32fns.c (w32_createwindow): Remove code for handling -geometry + command line option and `initial-frame-alist' which is superfluous + after the last change to `w32_createwindow'. + +2006-11-04 Slawomir Nowaczyk <slawek@cs.lth.se> (tiny change) + + * w32proc.c (sys_wait): Only wait for processes with fd<0. + Others should be handled by sys_select instead. Fixes problems + with (progn (start-process "" nil "ls") (call-process "ls")). + +2006-11-04 Giorgos Keramidas <keramida@ceid.upatras.gr> (tiny change) + + * xmenu.c (Fmenu_bar_open): Declare variable before BLOCK_INPUT to + avoid gcc 2.95 error. + +2006-11-04 Chong Yidong <cyd@stupidchicken.com> + + * gtkutil.c (update_frame_tool_bar): If icon image is invalid and + wicon is null, insert an empty button. + +2006-11-03 Jan Dj,Ad(Brv <jan.h.d@swipnet.se> + + * xterm.c (x_raise_frame): Send _NET_ACTIVE_WINDOW when raising the + window. + +2006-11-02 Juanma Barranquero <lekktu@gmail.com> + + * emacs.c (Fkill_emacs): Fix typo in docstring. + +2006-11-02 Nozomu Ando <nand@mac.com> + + * unexmacosx.c (mach_header, segment_command, vm_region, section) + [_LP64]: New defines. + (VM_REGION_BASIC_INFO_COUNT, VM_REGION_BASIC_INFO, LC_SEGMENT) + (MH_MAGIC) [_LP64]: Redefine. + (delta): Remove variable. + (curr_file_offset, pagesize): New variables. + (ROUNDUP_TO_PAGE_BOUNDARY): New macro. + (data_segment_old_fileoff): Initialize explicitly. + (print_region, unexec_regions_recorder, print_load_command_name) + (copy_segment, copy_data_segment): Use long format in printf. + (MAX_UNEXEC_REGIONS): Increase to 400. + (unexec_regions_recorder): Don't warn too many regions here. + (find_emacs_zone_regions): Warn too many regions here. + (print_load_command_name) [_LP64]: Show correct load command name. + (copy_segment, copy_data_segment): Use variable `curr_file_offset'. + Show starting virtual memory address. Don't show ending file offset. + (copy_symtab, copy_dysymtab, copy_twolevelhints): New argument DELTA. + (dump_it): Use new local variable `linkedit_delta' and pass to them. + Error if trying to handle multiple DATA segments. + (unexec): Initialize variable `pagesize'. + +2006-11-01 Juanma Barranquero <lekktu@gmail.com> + + * eval.c (Fcatch): Doc fix. + +2006-10-31 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> + + * image.c [MAC_OS] (image_load_qt_1, xpm_scan, xpm_make_color_table_v) + (xpm_put_color_table_v, xpm_get_color_table_v, xpm_make_color_table_h) + (xpm_put_color_table_h, xpm_get_color_table_h, xpm_str_to_color_key) + (xpm_load_image): Add const qualifier to arguments. + [MAC_OS] (xpm_color_key_strings): Make static const. + + * mac.c (create_apple_event_from_event_ref) + (create_apple_event_from_drag_ref, skip_white_space, parse_comment) + (parse_include_file, parse_binding, parse_component) + (parse_resource_name, parse_value, parse_resource_line) + (xrm_merge_string_database, xrm_get_resource) + (xrm_get_preference_database): Add const qualifier to arguments. + [MAC_OSX] (sys_select): Make variable `context' static const. + + * macfns.c (mac_color_map): Make static const. + (mac_color_map_lookup): Add const qualifier to arguments. + + * macmenu.c (install_menu_quit_handler): Make variable `typesList' + static const. + (name_is_separator): Add const qualifier to arguments. + + * macselect.c (init_service_handler): Make variable `specs' static + const. + + * macterm.c (mac_create_bitmap_from_bitmap_data): Make variable + `swap_nibbles' static const. + (atsu_get_text_layout_with_text_ptr): Make variables `lengths', + `tags', `sizes', `values' static const. + (mac_draw_string_common): Make variables `context' static. Make + variables `tags', `sizes', and `values' static const. + (pcm_get_status, x_detect_focus_change, x_scroll_bar_handle_click) + (xlfdpat_create, xlfdpat_block_match_1, xlfdpat_match) + (mac_to_x_fontname, parse_x_font_name, add_mac_font_name) + (mac_do_list_fonts, is_fully_specified_xlfd, do_grow_window) + (mac_store_event_ref_as_apple_event, mac_make_rdb): Add const + qualifier to arguments. + (xlfd_scalable_fields, keycode_to_xkeysym_table) + (fn_keycode_to_keycode_table): Make static const. + (mac_load_query_font): Make variables `tags', `sizes', `values', + `types', and `selectors' static const. + (mac_handle_command_event, mac_handle_window_event): Make + variables `names' and `types' static const. + (init_command_handler, install_window_handler): Make variables + `specs*' static const. + (mac_handle_font_event, mac_handle_text_input_event) + (mac_store_service_event): Make variables `names' and `types' + const. Make variables `names_*' and `types_*' static const. + + * macterm.h (create_apple_event_from_event_ref) + (create_apple_event_from_drag_ref, xrm_merge_string_database) + (xrm_get_resource, xrm_get_preference_database): Add const + qualifier to arguments in externs. + +2006-10-31 Kenichi Handa <handa@m17n.org> + + * xfns.c (xic_create_xfontset): Fix previous change. + +2006-10-30 Chong Yidong <cyd@stupidchicken.com> + + * s/openbsd.h (LD_SWITCH_SYSTEM): Add /usr/pkg/lib and + /usr/pkg/lib to library search path. + +2006-10-29 Mark Davies <mark@mcs.vuw.ac.nz> (tiny change) * ralloc.c (relinquish): Use a long for excess space counter to handle 64-bit case correctly.
--- a/src/dosfns.c Tue Nov 07 02:37:49 2006 +0000 +++ b/src/dosfns.c Tue Nov 07 23:22:48 2006 +0000 @@ -213,7 +213,7 @@ } DEFUN ("insert-startup-screen", Finsert_startup_screen, Sinsert_startup_screen, 0, 0, "", - doc: /* Insert copy of screen contents prior to starting emacs. + doc: /* Insert copy of screen contents prior to starting Emacs. Return nil if startup screen is not available. */) () {
--- a/src/emacs.c Tue Nov 07 02:37:49 2006 +0000 +++ b/src/emacs.c Tue Nov 07 23:22:48 2006 +0000 @@ -2072,7 +2072,7 @@ DEFUN ("kill-emacs", Fkill_emacs, Skill_emacs, 0, 1, "P", doc: /* Exit the Emacs job and kill it. If ARG is an integer, return ARG as the exit program code. -If ARG is a string, stuff it as keyboard input. +If ARG is a string, stuff it as keyboard input. The value of `kill-emacs-hook', if not void, is a list of functions (of no args),
--- a/src/eval.c Tue Nov 07 02:37:49 2006 +0000 +++ b/src/eval.c Tue Nov 07 23:22:48 2006 +0000 @@ -1174,7 +1174,7 @@ TAG is evalled to get the tag to use; it must not be nil. Then the BODY is executed. -Within BODY, (throw TAG) with same tag exits BODY and exits this `catch'. +Within BODY, a call to `throw' with the same TAG exits BODY and this `catch'. If no throw happens, `catch' returns the value of the last BODY form. If a throw happens, it specifies the value to return from `catch'. usage: (catch TAG BODY...) */)
--- a/src/fns.c Tue Nov 07 02:37:49 2006 +0000 +++ b/src/fns.c Tue Nov 07 23:22:48 2006 +0000 @@ -2828,7 +2828,7 @@ doc: /* Returns t if FEATURE is present in this Emacs. Use this to conditionalize execution of lisp code based on the -presence or absence of emacs or environment extensions. +presence or absence of Emacs or environment extensions. Use `provide' to declare that a feature is available. This function looks at the value of the variable `features'. The optional argument SUBFEATURE can be used to check a specific subfeature of FEATURE. */) @@ -5175,7 +5175,7 @@ Fset (Qyes_or_no_p_history, Qnil); DEFVAR_LISP ("features", &Vfeatures, - doc: /* A list of symbols which are the features of the executing emacs. + doc: /* A list of symbols which are the features of the executing Emacs. Used by `featurep' and `require', and altered by `provide'. */); Vfeatures = Fcons (intern ("emacs"), Qnil); Qsubfeatures = intern ("subfeatures");
--- a/src/frame.c Tue Nov 07 02:37:49 2006 +0000 +++ b/src/frame.c Tue Nov 07 23:22:48 2006 +0000 @@ -2611,7 +2611,7 @@ extern Lisp_Object Qtop; /* Calculate fullscreen size. Return in *TOP_POS and *LEFT_POS the - wanted positions of the WM window (not emacs window). + wanted positions of the WM window (not Emacs window). Return in *WIDTH and *HEIGHT the wanted width and height of Emacs window (FRAME_X_WINDOW). */ @@ -4215,7 +4215,7 @@ doc: /* The initial frame-object, which represents Emacs's stdout. */); DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified, - doc: /* Non-nil if all of emacs is iconified and frame updates are not needed. */); + doc: /* Non-nil if all of Emacs is iconified and frame updates are not needed. */); Vemacs_iconified = Qnil; DEFVAR_LISP ("mouse-position-function", &Vmouse_position_function,
--- a/src/gtkutil.c Tue Nov 07 02:37:49 2006 +0000 +++ b/src/gtkutil.c Tue Nov 07 23:22:48 2006 +0000 @@ -3720,7 +3720,12 @@ if (img->load_failed_p || img->pixmap == None) { - if (wicon) gtk_widget_hide (wicon); + if (wicon) + gtk_widget_hide (wicon); + else + gtk_toolbar_insert (GTK_TOOLBAR (x->toolbar_widget), + gtk_tool_button_new (NULL, ""), + i); continue; }
--- a/src/image.c Tue Nov 07 02:37:49 2006 +0000 +++ b/src/image.c Tue Nov 07 23:22:48 2006 +0000 @@ -2393,7 +2393,7 @@ struct frame *f; struct image *img; OSType type; - FSSpec *fss; + const FSSpec *fss; Handle dh; { ComponentResult err; @@ -2407,8 +2407,7 @@ XImagePtr ximg; RGBColor bg_color; - err = OpenADefaultComponent (GraphicsImporterComponentType, - type, &gi); + err = OpenADefaultComponent (GraphicsImporterComponentType, type, &gi); if (err != noErr) { image_error ("Cannot get importer component for `%s'", img->spec, Qnil); @@ -4110,25 +4109,25 @@ /* XPM support functions for Mac OS where libxpm is not available. Only XPM version 3 (without any extensions) is supported. */ -static int xpm_scan P_ ((unsigned char **, unsigned char *, - unsigned char **, int *)); +static int xpm_scan P_ ((const unsigned char **, const unsigned char *, + const unsigned char **, int *)); static Lisp_Object xpm_make_color_table_v - P_ ((void (**) (Lisp_Object, unsigned char *, int, Lisp_Object), - Lisp_Object (**) (Lisp_Object, unsigned char *, int))); -static void xpm_put_color_table_v P_ ((Lisp_Object, unsigned char *, + P_ ((void (**) (Lisp_Object, const unsigned char *, int, Lisp_Object), + Lisp_Object (**) (Lisp_Object, const unsigned char *, int))); +static void xpm_put_color_table_v P_ ((Lisp_Object, const unsigned char *, int, Lisp_Object)); static Lisp_Object xpm_get_color_table_v P_ ((Lisp_Object, - unsigned char *, int)); + const unsigned char *, int)); static Lisp_Object xpm_make_color_table_h - P_ ((void (**) (Lisp_Object, unsigned char *, int, Lisp_Object), - Lisp_Object (**) (Lisp_Object, unsigned char *, int))); -static void xpm_put_color_table_h P_ ((Lisp_Object, unsigned char *, + P_ ((void (**) (Lisp_Object, const unsigned char *, int, Lisp_Object), + Lisp_Object (**) (Lisp_Object, const unsigned char *, int))); +static void xpm_put_color_table_h P_ ((Lisp_Object, const unsigned char *, int, Lisp_Object)); static Lisp_Object xpm_get_color_table_h P_ ((Lisp_Object, - unsigned char *, int)); -static int xpm_str_to_color_key P_ ((char *)); + const unsigned char *, int)); +static int xpm_str_to_color_key P_ ((const char *)); static int xpm_load_image P_ ((struct frame *, struct image *, - unsigned char *, unsigned char *)); + const unsigned char *, const unsigned char *)); /* Tokens returned from xpm_scan. */ @@ -4148,7 +4147,7 @@ static int xpm_scan (s, end, beg, len) - unsigned char **s, *end, **beg; + const unsigned char **s, *end, **beg; int *len; { int c; @@ -4214,8 +4213,8 @@ static Lisp_Object xpm_make_color_table_v (put_func, get_func) - void (**put_func) (Lisp_Object, unsigned char *, int, Lisp_Object); - Lisp_Object (**get_func) (Lisp_Object, unsigned char *, int); + void (**put_func) (Lisp_Object, const unsigned char *, int, Lisp_Object); + Lisp_Object (**get_func) (Lisp_Object, const unsigned char *, int); { *put_func = xpm_put_color_table_v; *get_func = xpm_get_color_table_v; @@ -4225,7 +4224,7 @@ static void xpm_put_color_table_v (color_table, chars_start, chars_len, color) Lisp_Object color_table; - unsigned char *chars_start; + const unsigned char *chars_start; int chars_len; Lisp_Object color; { @@ -4235,7 +4234,7 @@ static Lisp_Object xpm_get_color_table_v (color_table, chars_start, chars_len) Lisp_Object color_table; - unsigned char *chars_start; + const unsigned char *chars_start; int chars_len; { return XVECTOR (color_table)->contents[*chars_start]; @@ -4243,8 +4242,8 @@ static Lisp_Object xpm_make_color_table_h (put_func, get_func) - void (**put_func) (Lisp_Object, unsigned char *, int, Lisp_Object); - Lisp_Object (**get_func) (Lisp_Object, unsigned char *, int); + void (**put_func) (Lisp_Object, const unsigned char *, int, Lisp_Object); + Lisp_Object (**get_func) (Lisp_Object, const unsigned char *, int); { *put_func = xpm_put_color_table_h; *get_func = xpm_get_color_table_h; @@ -4257,7 +4256,7 @@ static void xpm_put_color_table_h (color_table, chars_start, chars_len, color) Lisp_Object color_table; - unsigned char *chars_start; + const unsigned char *chars_start; int chars_len; Lisp_Object color; { @@ -4272,7 +4271,7 @@ static Lisp_Object xpm_get_color_table_h (color_table, chars_start, chars_len) Lisp_Object color_table; - unsigned char *chars_start; + const unsigned char *chars_start; int chars_len; { struct Lisp_Hash_Table *table = XHASH_TABLE (color_table); @@ -4290,11 +4289,11 @@ XPM_COLOR_KEY_C }; -static char xpm_color_key_strings[][4] = {"s", "m", "g4", "g", "c"}; +static const char xpm_color_key_strings[][4] = {"s", "m", "g4", "g", "c"}; static int xpm_str_to_color_key (s) - char *s; + const char *s; { int i; @@ -4310,15 +4309,15 @@ xpm_load_image (f, img, contents, end) struct frame *f; struct image *img; - unsigned char *contents, *end; -{ - unsigned char *s = contents, *beg, *str; + const unsigned char *contents, *end; +{ + const unsigned char *s = contents, *beg, *str; unsigned char buffer[BUFSIZ]; int width, height, x, y; int num_colors, chars_per_pixel; int len, LA1; - void (*put_color_table) (Lisp_Object, unsigned char *, int, Lisp_Object); - Lisp_Object (*get_color_table) (Lisp_Object, unsigned char *, int); + void (*put_color_table) (Lisp_Object, const unsigned char *, int, Lisp_Object); + Lisp_Object (*get_color_table) (Lisp_Object, const unsigned char *, int); Lisp_Object frame, color_symbols, color_table; int best_key, have_mask = 0; XImagePtr ximg = NULL, mask_img = NULL;
--- a/src/lread.c Tue Nov 07 02:37:49 2006 +0000 +++ b/src/lread.c Tue Nov 07 23:22:48 2006 +0000 @@ -145,7 +145,7 @@ This is set to 1 by read1 temporarily while handling #@NUMBER. */ static int load_each_byte; -/* Function to use for loading an Emacs lisp source file (not +/* Function to use for loading an Emacs Lisp source file (not compiled) instead of readevalloop. */ Lisp_Object Vload_source_file_function; @@ -4243,7 +4243,7 @@ Vload_read_function = Qnil; DEFVAR_LISP ("load-source-file-function", &Vload_source_file_function, - doc: /* Function called in `load' for loading an Emacs lisp source file. + doc: /* Function called in `load' for loading an Emacs Lisp source file. This function is for doing code conversion before reading the source file. If nil, loading is done without any code conversion. Arguments are FULLNAME, FILE, NOERROR, NOMESSAGE, where
--- a/src/mac.c Tue Nov 07 02:37:49 2006 +0000 +++ b/src/mac.c Tue Nov 07 23:22:48 2006 +0000 @@ -835,8 +835,8 @@ create_apple_event_from_event_ref (event, num_params, names, types, result) EventRef event; UInt32 num_params; - EventParamName *names; - EventParamType *types; + const EventParamName *names; + const EventParamType *types; AppleEvent *result; { OSStatus err; @@ -891,7 +891,7 @@ create_apple_event_from_drag_ref (drag, num_types, types, result) DragRef drag; UInt32 num_types; - FlavorType *types; + const FlavorType *types; AppleEvent *result; { OSErr err; @@ -1315,7 +1315,7 @@ static void skip_white_space (p) - char **p; + const char **p; { /* WhiteSpace = {<space> | <horizontal tab>} */ while (*P == ' ' || *P == '\t') @@ -1324,7 +1324,7 @@ static int parse_comment (p) - char **p; + const char **p; { /* Comment = "!" {<any character except null or newline>} */ if (*P == '!') @@ -1342,7 +1342,7 @@ /* Don't interpret filename. Just skip until the newline. */ static int parse_include_file (p) - char **p; + const char **p; { /* IncludeFile = "#" WhiteSpace "include" WhiteSpace FileName WhiteSpace */ if (*P == '#') @@ -1359,7 +1359,7 @@ static char parse_binding (p) - char **p; + const char **p; { /* Binding = "." | "*" */ if (*P == '.' || *P == '*') @@ -1377,7 +1377,7 @@ static Lisp_Object parse_component (p) - char **p; + const char **p; { /* Component = "?" | ComponentName ComponentName = NameChar {NameChar} @@ -1389,7 +1389,7 @@ } else if (isalnum (*P) || *P == '_' || *P == '-') { - char *start = P++; + const char *start = P++; while (isalnum (*P) || *P == '_' || *P == '-') P++; @@ -1402,7 +1402,7 @@ static Lisp_Object parse_resource_name (p) - char **p; + const char **p; { Lisp_Object result = Qnil, component; char binding; @@ -1436,7 +1436,7 @@ static Lisp_Object parse_value (p) - char **p; + const char **p; { char *q, *buf; Lisp_Object seq = Qnil, result; @@ -1526,7 +1526,7 @@ static Lisp_Object parse_resource_line (p) - char **p; + const char **p; { Lisp_Object quarks, value; @@ -1629,7 +1629,7 @@ void xrm_merge_string_database (database, data) XrmDatabase database; - char *data; + const char *data; { Lisp_Object quarks_value; @@ -1705,7 +1705,7 @@ Lisp_Object xrm_get_resource (database, name, class) XrmDatabase database; - char *name, *class; + const char *name, *class; { Lisp_Object key, query_cache, quark_name, quark_class, tmp; int i, nn, nc; @@ -1794,7 +1794,7 @@ XrmDatabase xrm_get_preference_database (application) - char *application; + const char *application; { #if TARGET_API_MAC_CARBON CFStringRef app_id, *keys, user_doms[2], host_doms[2]; @@ -5129,7 +5129,7 @@ int minfd, fd; CFRunLoopRef runloop = (CFRunLoopRef) GetCFRunLoopFromEventLoop (GetCurrentEventLoop ()); - static CFSocketContext context = {0, ofds, NULL, NULL, NULL}; + static const CFSocketContext context = {0, ofds, NULL, NULL, NULL}; static CFMutableDictionaryRef sources; if (sources == NULL)
--- a/src/macfns.c Tue Nov 07 02:37:49 2006 +0000 +++ b/src/macfns.c Tue Nov 07 23:22:48 2006 +0000 @@ -251,7 +251,7 @@ char *name; } colormap_t; -colormap_t mac_color_map[] = +static const colormap_t mac_color_map[] = { { RGB_TO_ULONG(255, 250, 250), "snow" }, { RGB_TO_ULONG(248, 248, 255), "ghost white" }, @@ -1009,7 +1009,7 @@ Lisp_Object mac_color_map_lookup (colorname) - char *colorname; + const char *colorname; { Lisp_Object ret = Qnil; int i;
--- a/src/macmenu.c Tue Nov 07 02:37:49 2006 +0000 +++ b/src/macmenu.c Tue Nov 07 23:22:48 2006 +0000 @@ -1500,7 +1500,8 @@ MenuHandle menu_handle; { #ifdef HAVE_CANCELMENUTRACKING - EventTypeSpec typesList[] = { { kEventClassKeyboard, kEventRawKeyDown } }; + static const EventTypeSpec typesList[] = + {{kEventClassKeyboard, kEventRawKeyDown}}; int id; for (id = min_menu_id[kind]; id < min_menu_id[kind + 1]; id++) @@ -2428,9 +2429,9 @@ /* Is this item a separator? */ static int name_is_separator (name) - char *name; + const char *name; { - char *start = name; + const char *start = name; /* Check if name string consists of only dashes ('-'). */ while (*name == '-') name++; @@ -2641,6 +2642,17 @@ } #endif /* HAVE_MENUS */ + +/* The following is used by delayed window autoselection. */ + +DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_p, 0, 0, 0, + doc: /* Return t if a menu or popup dialog is active. */) + () +{ + /* Always return Qnil since menu selection functions do not return + until a selection has been made or cancelled. */ + return Qnil; +} void syms_of_macmenu () @@ -2652,6 +2664,7 @@ staticpro (&Qdebug_on_next_call); defsubr (&Sx_popup_menu); + defsubr (&Smenu_or_popup_active_p); #ifdef HAVE_MENUS defsubr (&Sx_popup_dialog); #endif
--- a/src/macselect.c Tue Nov 07 02:37:49 2006 +0000 +++ b/src/macselect.c Tue Nov 07 23:22:48 2006 +0000 @@ -1616,10 +1616,11 @@ void init_service_handler () { - EventTypeSpec specs[] = {{kEventClassService, kEventServiceGetTypes}, - {kEventClassService, kEventServiceCopy}, - {kEventClassService, kEventServicePaste}, - {kEventClassService, kEventServicePerform}}; + static const EventTypeSpec specs[] = + {{kEventClassService, kEventServiceGetTypes}, + {kEventClassService, kEventServiceCopy}, + {kEventClassService, kEventServicePaste}, + {kEventClassService, kEventServicePerform}}; InstallApplicationEventHandler (NewEventHandlerUPP (mac_handle_service_event), GetEventTypeCount (specs), specs, NULL, NULL); }
--- a/src/macterm.c Tue Nov 07 02:37:49 2006 +0000 +++ b/src/macterm.c Tue Nov 07 23:22:48 2006 +0000 @@ -246,7 +246,8 @@ static void mac_focus_changed P_ ((int, struct mac_display_info *, struct frame *, struct input_event *)); static void x_detect_focus_change P_ ((struct mac_display_info *, - EventRecord *, struct input_event *)); + const EventRecord *, + struct input_event *)); static void XTframe_rehighlight P_ ((struct frame *)); static void x_frame_rehighlight P_ ((struct x_display_info *)); static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *)); @@ -642,7 +643,7 @@ char *bits; int w, h; { - static unsigned char swap_nibble[16] + static const unsigned char swap_nibble[16] = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */ 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */ 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */ @@ -828,9 +829,9 @@ if (saved_text_layout == NULL) { - UniCharCount lengths[] = {kATSUToTextEnd}; - ATSUAttributeTag tags[] = {kATSULineLayoutOptionsTag}; - ByteCount sizes[] = {sizeof (ATSLineLayoutOptions)}; + static const UniCharCount lengths[] = {kATSUToTextEnd}; + static const ATSUAttributeTag tags[] = {kATSULineLayoutOptionsTag}; + static const ByteCount sizes[] = {sizeof (ATSLineLayoutOptions)}; static ATSLineLayoutOptions line_layout = #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020 kATSLineDisableAllLayoutOperations | kATSLineUseDeviceMetrics @@ -839,7 +840,7 @@ kATSLineIsDisplayOnly | kATSLineFractDisable #endif ; - ATSUAttributeValuePtr values[] = {&line_layout}; + static const ATSUAttributeValuePtr values[] = {&line_layout}; err = ATSUCreateTextLayoutWithTextPtr (text, kATSUFromTextBeginning, @@ -962,11 +963,11 @@ else { CGrafPtr port; - CGContextRef context; + static CGContextRef context; float port_height = FRAME_PIXEL_HEIGHT (f); - ATSUAttributeTag tags[] = {kATSUCGContextTag}; - ByteCount sizes[] = {sizeof (CGContextRef)}; - ATSUAttributeValuePtr values[] = {&context}; + static const ATSUAttributeTag tags[] = {kATSUCGContextTag}; + static const ByteCount sizes[] = {sizeof (CGContextRef)}; + static const ATSUAttributeValuePtr values[] = {&context}; #if USE_CG_DRAWING context = mac_begin_cg_clip (f, gc); @@ -2199,7 +2200,7 @@ static enum pcm_status pcm_get_status (pcm) - XCharStruct *pcm; + const XCharStruct *pcm; { int height = pcm->ascent + pcm->descent; @@ -4221,7 +4222,7 @@ static void x_detect_focus_change (dpyinfo, event, bufp) struct mac_display_info *dpyinfo; - EventRecord *event; + const EventRecord *event; struct input_event *bufp; { struct frame *frame; @@ -5234,7 +5235,7 @@ x_scroll_bar_handle_click (bar, part_code, er, bufp) struct scroll_bar *bar; ControlPartCode part_code; - EventRecord *er; + const EventRecord *er; struct input_event *bufp; { int win_y, top_range; @@ -6714,11 +6715,12 @@ static struct xlfdpat * xlfdpat_create (pattern) - char *pattern; + const char *pattern; { struct xlfdpat *pat; int nblocks, i, skip; unsigned char last_char, *p, *q, *anychar_head; + const unsigned char *ptr; struct xlfdpat_block *blk; pat = xmalloc (sizeof (struct xlfdpat)); @@ -6729,9 +6731,9 @@ anychar_head = NULL; q = pat->buf; last_char = '\0'; - for (p = pattern; *p; p++) - { - unsigned char c = *p; + for (ptr = pattern; *ptr; ptr++) + { + unsigned char c = *ptr; if (c == '*') if (last_char == '*') @@ -6835,14 +6837,15 @@ that the pattern in *BLK matches with its prefix. Return NULL there is no such strings. STRING must be lowered in advance. */ -static char * +static const char * xlfdpat_block_match_1 (blk, string, start_max) struct xlfdpat_block *blk; - unsigned char *string; + const unsigned char *string; int start_max; { int start, infinity; - unsigned char *p, *s; + unsigned char *p; + const unsigned char *s; xassert (blk->len > 0); xassert (start_max + blk->len <= strlen (string)); @@ -6899,17 +6902,17 @@ ((b)->len == 1 ? memchr ((s), (b)->last_char, (m) + 1) \ : xlfdpat_block_match_1 (b, s, m)) -/* Check if XLFD pattern PAT, which is generated by `xfldpat_create', +/* Check if XLFD pattern PAT, which is generated by `xlfdpat_create', matches with STRING. STRING must be lowered in advance. */ static int xlfdpat_match (pat, string) struct xlfdpat *pat; - unsigned char *string; + const unsigned char *string; { int str_len, nblocks, i, start_max; struct xlfdpat_block *blk; - unsigned char *s; + const unsigned char *s; xassert (pat->nblocks > 0); @@ -7080,7 +7083,7 @@ static char * mac_to_x_fontname (name, size, style, charset) - char *name; + const char *name; int size; Style style; char *charset; @@ -7127,7 +7130,8 @@ static int parse_x_font_name (xf, family, size, style, charset) - char *xf, *family; + const char *xf; + char *family; int *size; Style *style; char *charset; @@ -7210,10 +7214,10 @@ static void add_mac_font_name (name, size, style, charset) - char *name; + const char *name; int size; Style style; - char *charset; + const char *charset; { if (size > 0) add_font_name_table_entry (mac_to_x_fontname (name, size, style, charset)); @@ -7515,7 +7519,7 @@ XLFD_SCL_LAST }; -static int xlfd_scalable_fields[] = +static const int xlfd_scalable_fields[] = { 6, /* PIXEL_SIZE */ 7, /* POINT_SIZE */ @@ -7525,14 +7529,16 @@ static Lisp_Object mac_do_list_fonts (pattern, maxnames) - char *pattern; + const char *pattern; int maxnames; { int i, n_fonts = 0; Lisp_Object font_list = Qnil; struct xlfdpat *pat; - char *scaled, *ptr; - int scl_val[XLFD_SCL_LAST], *field, *val; + char *scaled; + const char *ptr; + int scl_val[XLFD_SCL_LAST], *val; + const int *field; int exact; if (font_name_table == NULL) /* Initialize when first used. */ @@ -7782,7 +7788,8 @@ fields are present, none is '*'. */ static int -is_fully_specified_xlfd (char *p) +is_fully_specified_xlfd (p) + const char *p; { int i; char *q; @@ -7859,18 +7866,21 @@ if (strcmp (charset, "iso10646-1") == 0) /* XXX */ { OSStatus err; - ATSUAttributeTag tags[] = {kATSUFontTag, kATSUSizeTag, - kATSUQDBoldfaceTag, kATSUQDItalicTag}; - ByteCount sizes[] = {sizeof (ATSUFontID), sizeof (Fixed), - sizeof (Boolean), sizeof (Boolean)}; + static const ATSUAttributeTag tags[] = + {kATSUFontTag, kATSUSizeTag, + kATSUQDBoldfaceTag, kATSUQDItalicTag}; + static const ByteCount sizes[] = + {sizeof (ATSUFontID), sizeof (Fixed), + sizeof (Boolean), sizeof (Boolean)}; static Fixed size_fixed; static Boolean bold_p, italic_p; - ATSUAttributeValuePtr values[] = {&font_id, &size_fixed, - &bold_p, &italic_p}; - ATSUFontFeatureType types[] = {kAllTypographicFeaturesType, - kDiacriticsType}; - ATSUFontFeatureSelector selectors[] = {kAllTypeFeaturesOffSelector, - kDecomposeDiacriticsSelector}; + static const ATSUAttributeValuePtr values[] = + {&font_id, &size_fixed, + &bold_p, &italic_p}; + static const ATSUFontFeatureType types[] = + {kAllTypographicFeaturesType, kDiacriticsType}; + static const ATSUFontFeatureSelector selectors[] = + {kAllTypeFeaturesOffSelector, kDecomposeDiacriticsSelector}; Lisp_Object font_id_cons; FMFontStyle style; @@ -8663,7 +8673,7 @@ except `clear' (-> <clear>) on the KeyPad, `enter' (-> <kp-enter>) on the right of the Cmd key on laptops, and fn + `enter' (-> <linefeed>). */ -static unsigned char keycode_to_xkeysym_table[] = { +static const unsigned char keycode_to_xkeysym_table[] = { /*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*0x20*/ 0, 0, 0, 0, 0x0d /*return*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -8700,7 +8710,7 @@ keyboard, and they may not be the same on other types of keyboards. If the destination is identical to the source (f1 ... f12), it doesn't map `fn' key to a modifier. */ -static unsigned char fn_keycode_to_keycode_table[] = { +static const unsigned char fn_keycode_to_keycode_table[] = { /*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*0x20*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -9158,7 +9168,9 @@ Mesander and IM - Window Manager A. */ static void -do_grow_window (WindowPtr w, EventRecord *e) +do_grow_window (w, e) + WindowPtr w; + const EventRecord *e; { Rect limit_rect; int rows, columns, width, height; @@ -9342,8 +9354,8 @@ Lisp_Object class_key, id_key; EventRef event; UInt32 num_params; - EventParamName *names; - EventParamType *types; + const EventParamName *names; + const EventParamType *types; { OSStatus err = eventNotHandledErr; Lisp_Object binding; @@ -9404,10 +9416,10 @@ { OSStatus result, err; HICommand command; - static EventParamName names[] = {kEventParamDirectObject, - kEventParamKeyModifiers}; - static EventParamType types[] = {typeHICommand, - typeUInt32}; + static const EventParamName names[] = + {kEventParamDirectObject, kEventParamKeyModifiers}; + static const EventParamType types[] = + {typeHICommand, typeUInt32}; int num_params = sizeof (names) / sizeof (names[0]); result = CallNextEventHandler (next_handler, event); @@ -9431,7 +9443,8 @@ static OSStatus init_command_handler () { - EventTypeSpec specs[] = {{kEventClassCommand, kEventCommandProcess}}; + static const EventTypeSpec specs[] = + {{kEventClassCommand, kEventCommandProcess}}; static EventHandlerUPP handle_command_eventUPP = NULL; if (handle_command_eventUPP == NULL) @@ -9591,18 +9604,18 @@ case kEventWindowToolbarSwitchMode: result = CallNextEventHandler (next_handler, event); { - static EventParamName names[] = {kEventParamDirectObject, - kEventParamWindowMouseLocation, - kEventParamKeyModifiers, - kEventParamMouseButton, - kEventParamClickCount, - kEventParamMouseChord}; - static EventParamType types[] = {typeWindowRef, - typeQDPoint, - typeUInt32, - typeMouseButton, - typeUInt32, - typeUInt32}; + static const EventParamName names[] = {kEventParamDirectObject, + kEventParamWindowMouseLocation, + kEventParamKeyModifiers, + kEventParamMouseButton, + kEventParamClickCount, + kEventParamMouseChord}; + static const EventParamType types[] = {typeWindowRef, + typeQDPoint, + typeUInt32, + typeMouseButton, + typeUInt32, + typeUInt32}; int num_params = sizeof (names) / sizeof (names[0]); err = mac_store_event_ref_as_apple_event (0, 0, @@ -9709,18 +9722,18 @@ OSStatus result, err; Lisp_Object id_key; int num_params; - EventParamName *names; - EventParamType *types; - static EventParamName names_sel[] = {kEventParamATSUFontID, - kEventParamATSUFontSize, - kEventParamFMFontFamily, - kEventParamFMFontSize, - kEventParamFontColor}; - static EventParamType types_sel[] = {typeATSUFontID, - typeATSUSize, - typeFMFontFamily, - typeFMFontSize, - typeFontColor}; + const EventParamName *names; + const EventParamType *types; + static const EventParamName names_sel[] = {kEventParamATSUFontID, + kEventParamATSUFontSize, + kEventParamFMFontFamily, + kEventParamFMFontSize, + kEventParamFontColor}; + static const EventParamType types_sel[] = {typeATSUFontID, + typeATSUSize, + typeFMFontFamily, + typeFMFontSize, + typeFontColor}; result = CallNextEventHandler (next_handler, event); if (result != eventNotHandledErr) @@ -9761,10 +9774,10 @@ OSStatus result, err = noErr; Lisp_Object id_key = Qnil; int num_params; - EventParamName *names; - EventParamType *types; + const EventParamName *names; + const EventParamType *types; static UInt32 seqno_uaia = 0; - static EventParamName names_uaia[] = + static const EventParamName names_uaia[] = {kEventParamTextInputSendComponentInstance, kEventParamTextInputSendRefCon, kEventParamTextInputSendSLRec, @@ -9777,7 +9790,7 @@ kEventParamTextInputSendTextServiceEncoding, kEventParamTextInputSendTextServiceMacEncoding, EVENT_PARAM_TEXT_INPUT_SEQUENCE_NUMBER}; - static EventParamType types_uaia[] = + static const EventParamType types_uaia[] = {typeComponentInstance, typeLongInteger, typeIntlWritingCode, @@ -9794,12 +9807,12 @@ typeUInt32, typeUInt32, typeUInt32}; - static EventParamName names_ufke[] = + static const EventParamName names_ufke[] = {kEventParamTextInputSendComponentInstance, kEventParamTextInputSendRefCon, kEventParamTextInputSendSLRec, kEventParamTextInputSendText}; - static EventParamType types_ufke[] = + static const EventParamType types_ufke[] = {typeComponentInstance, typeLongInteger, typeIntlWritingCode, @@ -9952,12 +9965,12 @@ OSStatus err; Lisp_Object id_key; int num_params; - EventParamName *names; - EventParamType *types; - static EventParamName names_pfm[] = {kEventParamServiceMessageName, - kEventParamServiceUserData}; - static EventParamType types_pfm[] = {typeCFStringRef, - typeCFStringRef}; + const EventParamName *names; + const EventParamType *types; + static const EventParamName names_pfm[] = + {kEventParamServiceMessageName, kEventParamServiceUserData}; + static const EventParamType types_pfm[] = + {typeCFStringRef, typeCFStringRef}; switch (GetEventKind (event)) { @@ -9995,7 +10008,7 @@ { OSStatus err = noErr; #if USE_CARBON_EVENTS - EventTypeSpec specs_window[] = + static const EventTypeSpec specs_window[] = {{kEventClassWindow, kEventWindowUpdate}, {kEventClassWindow, kEventWindowGetIdealSize}, {kEventClassWindow, kEventWindowBoundsChanging}, @@ -10013,16 +10026,18 @@ {kEventClassWindow, kEventWindowFocusRelinquish}, #endif }; - EventTypeSpec specs_mouse[] = {{kEventClassMouse, kEventMouseWheelMoved}}; + static const EventTypeSpec specs_mouse[] = + {{kEventClassMouse, kEventMouseWheelMoved}}; static EventHandlerUPP handle_window_eventUPP = NULL; static EventHandlerUPP handle_mouse_eventUPP = NULL; #if USE_MAC_FONT_PANEL - EventTypeSpec specs_font[] = {{kEventClassFont, kEventFontPanelClosed}, - {kEventClassFont, kEventFontSelection}}; + static const EventTypeSpec specs_font[] = + {{kEventClassFont, kEventFontPanelClosed}, + {kEventClassFont, kEventFontSelection}}; static EventHandlerUPP handle_font_eventUPP = NULL; #endif #if USE_MAC_TSM - EventTypeSpec specs_text_input[] = + static const EventTypeSpec specs_text_input[] = {{kEventClassTextInput, kEventTextInputUpdateActiveInputArea}, {kEventClassTextInput, kEventTextInputUnicodeForKeyEvent}, {kEventClassTextInput, kEventTextInputOffsetToPos}}; @@ -11215,7 +11230,7 @@ static XrmDatabase mac_make_rdb (xrm_option) - char *xrm_option; + const char *xrm_option; { XrmDatabase database;
--- a/src/macterm.h Tue Nov 07 02:37:49 2006 +0000 +++ b/src/macterm.h Tue Nov 07 23:22:48 2006 +0000 @@ -669,11 +669,11 @@ extern OSErr mac_ae_put_lisp P_ ((AEDescList *, UInt32, Lisp_Object)); #if TARGET_API_MAC_CARBON extern OSStatus create_apple_event_from_event_ref P_ ((EventRef, UInt32, - EventParamName *, - EventParamType *, + const EventParamName *, + const EventParamType *, AppleEvent *)); extern OSErr create_apple_event_from_drag_ref P_ ((DragRef, UInt32, - FlavorType *, + const FlavorType *, AppleEvent *)); extern CFStringRef cfstring_create_with_utf8_cstring P_ ((const char *)); extern CFStringRef cfstring_create_with_string P_ ((Lisp_Object)); @@ -686,9 +686,10 @@ extern Lisp_Object cfobject_desc_to_lisp P_ ((CFTypeRef)); extern Lisp_Object cfproperty_list_to_lisp P_ ((CFPropertyListRef, int, int)); #endif -extern void xrm_merge_string_database P_ ((XrmDatabase, char *)); -extern Lisp_Object xrm_get_resource P_ ((XrmDatabase, char *, char *)); -extern XrmDatabase xrm_get_preference_database P_ ((char *)); +extern void xrm_merge_string_database P_ ((XrmDatabase, const char *)); +extern Lisp_Object xrm_get_resource P_ ((XrmDatabase, const char *, + const char *)); +extern XrmDatabase xrm_get_preference_database P_ ((const char *)); EXFUN (Fmac_get_preference, 4); /* arch-tag: 6b4ca125-5bef-476d-8ee8-31ed808b7e79
--- a/src/s/netbsd.h Tue Nov 07 02:37:49 2006 +0000 +++ b/src/s/netbsd.h Tue Nov 07 23:22:48 2006 +0000 @@ -138,5 +138,10 @@ #define GC_MARK_STACK GC_MAKE_GCPROS_NOOPS +/* Use sigprocmask and friends instead of sigblock; + sigblock is considered obsolete on NetBSD. */ + +#define POSIX_SIGNALS 1 + /* arch-tag: e80f364a-04e9-4faf-93cb-f36a0fe95c81 (do not change this comment) */
--- a/src/s/openbsd.h Tue Nov 07 02:37:49 2006 +0000 +++ b/src/s/openbsd.h Tue Nov 07 23:22:48 2006 +0000 @@ -23,11 +23,11 @@ /* Han Boetes <han@mijncomputer.nl> says this is necessary, otherwise Emacs dumps core on elf systems. */ -#define LD_SWITCH_SYSTEM LD_SWITCH_SYSTEM_tmp -Z +#define LD_SWITCH_SYSTEM LD_SWITCH_SYSTEM_tmp -Z -L/usr/pkg/lib -L/usr/local/lib #else -#define LD_SWITCH_SYSTEM LD_SWITCH_SYSTEM_tmp +#define LD_SWITCH_SYSTEM LD_SWITCH_SYSTEM_tmp -L/usr/pkg/lib -L/usr/local/lib #endif
--- a/src/unexcw.c Tue Nov 07 02:37:49 2006 +0000 +++ b/src/unexcw.c Tue Nov 07 23:22:48 2006 +0000 @@ -262,7 +262,7 @@ if (bss_sbrk_did_unexec) { /* can only dump once */ - printf ("You can only dump emacs once on this platform.\n"); + printf ("You can only dump Emacs once on this platform.\n"); return (1); }
--- a/src/unexmacosx.c Tue Nov 07 02:37:49 2006 +0000 +++ b/src/unexmacosx.c Tue Nov 07 23:22:48 2006 +0000 @@ -69,10 +69,10 @@ fact, the earliest one starts a few hundred bytes beyond the end of the last load command. The linker option -headerpad controls the minimum size of this padding. Its setting can be changed in - s/darwin.h. A value of 0x300, e.g., leaves room for about 15 - additional load commands for the newly created __DATA segments (at - 56 bytes each). Unexec fails if there is not enough room for these - new segments. + s/darwin.h. A value of 0x690, e.g., leaves room for 30 additional + load commands for the newly created __DATA segments (at 56 bytes + each). Unexec fails if there is not enough room for these new + segments. The __TEXT segment contains the sections __text, __cstring, __picsymbol_stub, and __const and the __DATA segment contains the @@ -112,6 +112,20 @@ #include <assert.h> +#ifdef _LP64 +#define mach_header mach_header_64 +#define segment_command segment_command_64 +#undef VM_REGION_BASIC_INFO_COUNT +#define VM_REGION_BASIC_INFO_COUNT VM_REGION_BASIC_INFO_COUNT_64 +#undef VM_REGION_BASIC_INFO +#define VM_REGION_BASIC_INFO VM_REGION_BASIC_INFO_64 +#undef LC_SEGMENT +#define LC_SEGMENT LC_SEGMENT_64 +#define vm_region vm_region_64 +#define section section_64 +#undef MH_MAGIC +#define MH_MAGIC MH_MAGIC_64 +#endif #define VERBOSE 1 @@ -123,9 +137,6 @@ mapped to dynamically loaded libraries and will not be dumped. */ #define VM_DATA_TOP (20 * 1024 * 1024) -/* Used by malloc_freezedry and malloc_jumpstart. */ -int malloc_cookie; - /* Type of an element on the list of regions to be dumped. */ struct region_t { vm_address_t address; @@ -137,47 +148,49 @@ }; /* Head and tail of the list of regions to be dumped. */ -struct region_t *region_list_head = 0; -struct region_t *region_list_tail = 0; +static struct region_t *region_list_head = 0; +static struct region_t *region_list_tail = 0; /* Pointer to array of load commands. */ -struct load_command **lca; +static struct load_command **lca; /* Number of load commands. */ -int nlc; +static int nlc; /* The highest VM address of segments loaded by the input file. Regions with addresses beyond this are assumed to be allocated dynamically and thus require dumping. */ -vm_address_t infile_lc_highest_addr = 0; +static vm_address_t infile_lc_highest_addr = 0; /* The lowest file offset used by the all sections in the __TEXT segments. This leaves room at the beginning of the file to store the Mach-O header. Check this value against header size to ensure the added load commands for the new __DATA segments did not overwrite any of the sections in the __TEXT segment. */ -unsigned long text_seg_lowest_offset = 0x10000000; +static unsigned long text_seg_lowest_offset = 0x10000000; /* Mach header. */ -struct mach_header mh; +static struct mach_header mh; /* Offset at which the next load command should be written. */ -unsigned long curr_header_offset = sizeof (struct mach_header); +static unsigned long curr_header_offset = sizeof (struct mach_header); -/* Current adjustment that needs to be made to offset values because - of additional data segments. */ -unsigned long delta = 0; +/* Offset at which the next segment should be written. */ +static unsigned long curr_file_offset = 0; -int infd, outfd; +static unsigned long pagesize; +#define ROUNDUP_TO_PAGE_BOUNDARY(x) (((x) + pagesize - 1) & ~(pagesize - 1)) -int in_dumped_exec = 0; +static int infd, outfd; -malloc_zone_t *emacs_zone; +static int in_dumped_exec = 0; + +static malloc_zone_t *emacs_zone; /* file offset of input file's data segment */ -off_t data_segment_old_fileoff; +static off_t data_segment_old_fileoff = 0; -struct segment_command *data_segment_scp; +static struct segment_command *data_segment_scp; /* Read N bytes from infd into memory starting at address DEST. Return true if successful, false otherwise. */ @@ -286,7 +299,7 @@ print_region (vm_address_t address, vm_size_t size, vm_prot_t prot, vm_prot_t max_prot) { - printf ("%#10x %#8x ", address, size); + printf ("%#10lx %#8lx ", (long) address, (long) size); print_prot (prot); putchar (' '); print_prot (max_prot); @@ -304,7 +317,7 @@ print_region (r->address, r->size, r->protection, r->max_protection); } -void +static void print_regions () { task_t target_task = mach_task_self (); @@ -412,23 +425,40 @@ } -#define MAX_UNEXEC_REGIONS 200 +#define MAX_UNEXEC_REGIONS 400 -int num_unexec_regions; -vm_range_t unexec_regions[MAX_UNEXEC_REGIONS]; +static int num_unexec_regions; +typedef struct { + vm_range_t range; + vm_size_t filesize; +} unexec_region_info; +static unexec_region_info unexec_regions[MAX_UNEXEC_REGIONS]; static void unexec_regions_recorder (task_t task, void *rr, unsigned type, vm_range_t *ranges, unsigned num) { + vm_address_t p; + vm_size_t filesize; + while (num && num_unexec_regions < MAX_UNEXEC_REGIONS) { - unexec_regions[num_unexec_regions++] = *ranges; - printf ("%#8x (sz: %#8x)\n", ranges->address, ranges->size); + /* Subtract the size of trailing null pages from filesize. It + can be smaller than vmsize in segment commands. In such a + case, trailing pages are initialized with zeros. */ + for (p = ranges->address + ranges->size; p > ranges->address; + p -= sizeof (int)) + if (*(((int *) p)-1)) + break; + filesize = ROUNDUP_TO_PAGE_BOUNDARY (p - ranges->address); + assert (filesize <= ranges->size); + + unexec_regions[num_unexec_regions].filesize = filesize; + unexec_regions[num_unexec_regions++].range = *ranges; + printf ("%#10lx (sz: %#8lx/%#8lx)\n", (long) (ranges->address), + (long) filesize, (long) (ranges->size)); ranges++; num--; } - if (num_unexec_regions == MAX_UNEXEC_REGIONS) - fprintf (stderr, "malloc_freezedry_recorder: too many regions\n"); } static kern_return_t @@ -438,7 +468,7 @@ return KERN_SUCCESS; } -void +static void find_emacs_zone_regions () { num_unexec_regions = 0; @@ -449,13 +479,16 @@ (vm_address_t) emacs_zone, unexec_reader, unexec_regions_recorder); + + if (num_unexec_regions == MAX_UNEXEC_REGIONS) + unexec_error ("find_emacs_zone_regions: too many regions"); } static int unexec_regions_sort_compare (const void *a, const void *b) { - vm_address_t aa = ((vm_range_t *) a)->address; - vm_address_t bb = ((vm_range_t *) b)->address; + vm_address_t aa = ((unexec_region_info *) a)->range.address; + vm_address_t bb = ((unexec_region_info *) b)->range.address; if (aa < bb) return -1; @@ -469,7 +502,7 @@ unexec_regions_merge () { int i, n; - vm_range_t r; + unexec_region_info r; qsort (unexec_regions, num_unexec_regions, sizeof (unexec_regions[0]), &unexec_regions_sort_compare); @@ -477,9 +510,11 @@ r = unexec_regions[0]; for (i = 1; i < num_unexec_regions; i++) { - if (r.address + r.size == unexec_regions[i].address) + if (r.range.address + r.range.size == unexec_regions[i].range.address + && r.range.size - r.filesize < 2 * pagesize) { - r.size += unexec_regions[i].size; + r.filesize = r.range.size + unexec_regions[i].filesize; + r.range.size += unexec_regions[i].range.size; } else { @@ -500,7 +535,11 @@ switch (lc) { case LC_SEGMENT: +#ifndef _LP64 printf ("LC_SEGMENT "); +#else + printf ("LC_SEGMENT_64 "); +#endif break; case LC_LOAD_DYLINKER: printf ("LC_LOAD_DYLINKER "); @@ -541,14 +580,14 @@ int j; scp = (struct segment_command *) lc; - printf (" %-16.16s %#10x %#8x\n", - scp->segname, scp->vmaddr, scp->vmsize); + printf (" %-16.16s %#10lx %#8lx\n", + scp->segname, (long) (scp->vmaddr), (long) (scp->vmsize)); sectp = (struct section *) (scp + 1); for (j = 0; j < scp->nsects; j++) { - printf (" %-16.16s %#10x %#8x\n", - sectp->sectname, sectp->addr, sectp->size); + printf (" %-16.16s %#10lx %#8lx\n", + sectp->sectname, (long) (sectp->addr), (long) (sectp->size)); sectp++; } } @@ -620,7 +659,7 @@ printf ("Highest address of load commands in input file: %#8x\n", infile_lc_highest_addr); - printf ("Lowest offset of all sections in __TEXT segment: %#8x\n", + printf ("Lowest offset of all sections in __TEXT segment: %#8lx\n", text_seg_lowest_offset); printf ("--- List of Load Commands in Input File ---\n"); @@ -644,21 +683,23 @@ struct section *sectp; int j; - scp->fileoff += delta; + scp->fileoff = curr_file_offset; sectp = (struct section *) (scp + 1); for (j = 0; j < scp->nsects; j++) { - sectp->offset += delta; + sectp->offset += curr_file_offset - old_fileoff; sectp++; } - printf ("Writing segment %-16.16s at %#8x - %#8x (sz: %#8x)\n", - scp->segname, scp->fileoff, scp->fileoff + scp->filesize, - scp->filesize); + printf ("Writing segment %-16.16s @ %#8lx (%#8lx/%#8lx @ %#10lx)\n", + scp->segname, (long) (scp->fileoff), (long) (scp->filesize), + (long) (scp->vmsize), (long) (scp->vmaddr)); if (!unexec_copy (scp->fileoff, old_fileoff, scp->filesize)) unexec_error ("cannot copy segment from input to output file"); + curr_file_offset += ROUNDUP_TO_PAGE_BOUNDARY (scp->filesize); + if (!unexec_write (curr_header_offset, lc, lc->cmdsize)) unexec_error ("cannot write load command to header"); @@ -683,14 +724,18 @@ struct segment_command *scp = (struct segment_command *) lc; struct section *sectp; int j; - unsigned long header_offset, file_offset, old_file_offset; + unsigned long header_offset, old_file_offset; - printf ("Writing segment %-16.16s at %#8x - %#8x (sz: %#8x)\n", - scp->segname, scp->fileoff, scp->fileoff + scp->filesize, - scp->filesize); + /* The new filesize of the segment is set to its vmsize because data + blocks for segments must start at region boundaries. Note that + this may leave unused locations at the end of the segment data + block because the total of the sizes of all sections in the + segment is generally smaller than vmsize. */ + scp->filesize = scp->vmsize; - if (delta != 0) - unexec_error ("cannot handle multiple DATA segments in input file"); + printf ("Writing segment %-16.16s @ %#8lx (%#8lx/%#8lx @ %#10lx)\n", + scp->segname, curr_file_offset, (long)(scp->filesize), + (long)(scp->vmsize), (long) (scp->vmaddr)); /* Offsets in the output file for writing the next section structure and segment data block, respectively. */ @@ -700,7 +745,7 @@ for (j = 0; j < scp->nsects; j++) { old_file_offset = sectp->offset; - sectp->offset = sectp->addr - scp->vmaddr + scp->fileoff; + sectp->offset = sectp->addr - scp->vmaddr + curr_file_offset; /* The __data section is dumped from memory. The __bss and __common sections are also dumped from memory but their flag fields require changing (from S_ZEROFILL to S_REGULAR). The @@ -762,21 +807,16 @@ else unexec_error ("unrecognized section name in __DATA segment"); - printf (" section %-16.16s at %#8x - %#8x (sz: %#8x)\n", - sectp->sectname, sectp->offset, sectp->offset + sectp->size, - sectp->size); + printf (" section %-16.16s at %#8lx - %#8lx (sz: %#8lx)\n", + sectp->sectname, (long) (sectp->offset), + (long) (sectp->offset + sectp->size), (long) (sectp->size)); header_offset += sizeof (struct section); sectp++; } - /* The new filesize of the segment is set to its vmsize because data - blocks for segments must start at region boundaries. Note that - this may leave unused locations at the end of the segment data - block because the total of the sizes of all sections in the - segment is generally smaller than vmsize. */ - delta = scp->vmsize - scp->filesize; - scp->filesize = scp->vmsize; + curr_file_offset += ROUNDUP_TO_PAGE_BOUNDARY (scp->filesize); + if (!unexec_write (curr_header_offset, scp, sizeof (struct segment_command))) unexec_error ("cannot write header of __DATA segment"); curr_header_offset += lc->cmdsize; @@ -784,8 +824,7 @@ /* Create new __DATA segment load commands for regions on the region list that do not corresponding to any segment load commands in the input file. - */ - file_offset = scp->fileoff + scp->filesize; + */ for (j = 0; j < num_unexec_regions; j++) { struct segment_command sc; @@ -793,23 +832,22 @@ sc.cmd = LC_SEGMENT; sc.cmdsize = sizeof (struct segment_command); strncpy (sc.segname, SEG_DATA, 16); - sc.vmaddr = unexec_regions[j].address; - sc.vmsize = unexec_regions[j].size; - sc.fileoff = file_offset; - sc.filesize = unexec_regions[j].size; + sc.vmaddr = unexec_regions[j].range.address; + sc.vmsize = unexec_regions[j].range.size; + sc.fileoff = curr_file_offset; + sc.filesize = unexec_regions[j].filesize; sc.maxprot = VM_PROT_READ | VM_PROT_WRITE; sc.initprot = VM_PROT_READ | VM_PROT_WRITE; sc.nsects = 0; sc.flags = 0; - printf ("Writing segment %-16.16s at %#8x - %#8x (sz: %#8x)\n", - sc.segname, sc.fileoff, sc.fileoff + sc.filesize, - sc.filesize); + printf ("Writing segment %-16.16s @ %#8lx (%#8lx/%#8lx @ %#10lx)\n", + sc.segname, (long) (sc.fileoff), (long) (sc.filesize), + (long) (sc.vmsize), (long) (sc.vmaddr)); - if (!unexec_write (sc.fileoff, (void *) sc.vmaddr, sc.vmsize)) + if (!unexec_write (sc.fileoff, (void *) sc.vmaddr, sc.filesize)) unexec_error ("cannot write new __DATA segment"); - delta += sc.filesize; - file_offset += sc.filesize; + curr_file_offset += ROUNDUP_TO_PAGE_BOUNDARY (sc.filesize); if (!unexec_write (curr_header_offset, &sc, sc.cmdsize)) unexec_error ("cannot write new __DATA segment's header"); @@ -821,7 +859,7 @@ /* Copy a LC_SYMTAB load command from the input file to the output file, adjusting the file offset fields. */ static void -copy_symtab (struct load_command *lc) +copy_symtab (struct load_command *lc, long delta) { struct symtab_command *stp = (struct symtab_command *) lc; @@ -898,7 +936,7 @@ /* Copy a LC_DYSYMTAB load command from the input file to the output file, adjusting the file offset fields. */ static void -copy_dysymtab (struct load_command *lc) +copy_dysymtab (struct load_command *lc, long delta) { struct dysymtab_command *dstp = (struct dysymtab_command *) lc; @@ -927,7 +965,7 @@ /* Copy a LC_TWOLEVEL_HINTS load command from the input file to the output file, adjusting the file offset fields. */ static void -copy_twolevelhints (struct load_command *lc) +copy_twolevelhints (struct load_command *lc, long delta) { struct twolevel_hints_command *tlhp = (struct twolevel_hints_command *) lc; @@ -964,6 +1002,7 @@ dump_it () { int i; + long linkedit_delta = 0; printf ("--- Load Commands written to Output File ---\n"); @@ -977,6 +1016,9 @@ { /* save data segment file offset and segment_command for unrelocate */ + if (data_segment_old_fileoff) + unexec_error ("cannot handle multiple DATA segments" + " in input file"); data_segment_old_fileoff = scp->fileoff; data_segment_scp = scp; @@ -984,18 +1026,26 @@ } else { + if (strncmp (scp->segname, SEG_LINKEDIT, 16) == 0) + { + if (linkedit_delta) + unexec_error ("cannot handle multiple LINKEDIT segments" + " in input file"); + linkedit_delta = curr_file_offset - scp->fileoff; + } + copy_segment (lca[i]); } } break; case LC_SYMTAB: - copy_symtab (lca[i]); + copy_symtab (lca[i], linkedit_delta); break; case LC_DYSYMTAB: - copy_dysymtab (lca[i]); + copy_dysymtab (lca[i], linkedit_delta); break; case LC_TWOLEVEL_HINTS: - copy_twolevelhints (lca[i]); + copy_twolevelhints (lca[i], linkedit_delta); break; default: copy_other (lca[i]); @@ -1005,7 +1055,7 @@ if (curr_header_offset > text_seg_lowest_offset) unexec_error ("not enough room for load commands for new __DATA segments"); - printf ("%d unused bytes follow Mach-O header\n", + printf ("%ld unused bytes follow Mach-O header\n", text_seg_lowest_offset - curr_header_offset); mh.sizeofcmds = curr_header_offset - sizeof (struct mach_header); @@ -1024,6 +1074,7 @@ if (in_dumped_exec) unexec_error ("Unexec from a dumped executable is not supported."); + pagesize = getpagesize (); infd = open (infile, O_RDONLY, 0); if (infd < 0) { @@ -1081,8 +1132,8 @@ int i; for (i = 0; i < num_unexec_regions; i++) - if ((vm_address_t) ptr - unexec_regions[i].address - < unexec_regions[i].size) + if ((vm_address_t) ptr - unexec_regions[i].range.address + < unexec_regions[i].range.size) return 1; return 0;
--- a/src/w32fns.c Tue Nov 07 02:37:49 2006 +0000 +++ b/src/w32fns.c Tue Nov 07 23:22:48 2006 +0000 @@ -2081,32 +2081,7 @@ if (!hprevinst) { - Lisp_Object ifa; - w32_init_class (hinst); - - /* Handle the -geometry command line option and the geometry - settings in the registry. They are decoded and put into - initial-frame-alist by w32-win.el:x-handle-geometry. */ - ifa = Fsymbol_value (intern ("initial-frame-alist")); - if (CONSP (ifa)) - { - Lisp_Object lt = Fassq (Qleft, ifa); - Lisp_Object tp = Fassq (Qtop, ifa); - - if (!NILP (lt)) - { - lt = XCDR (lt); - if (INTEGERP (lt)) - left = lt; - } - if (!NILP (tp)) - { - tp = XCDR (tp); - if (INTEGERP (tp)) - top = tp; - } - } } if (f->size_hint_flags & USPosition || f->size_hint_flags & PPosition)
--- a/src/w32menu.c Tue Nov 07 02:37:49 2006 +0000 +++ b/src/w32menu.c Tue Nov 07 23:22:48 2006 +0000 @@ -235,10 +235,6 @@ /* Current depth within submenus. */ static int menu_items_submenu_depth; -/* Flag which when set indicates a dialog or menu has been posted by - Xt on behalf of one of the widget sets. */ -static int popup_activated_flag; - static int next_menubar_widget_id; /* This is set nonzero after the user activates the menu bar, and set @@ -2148,7 +2144,6 @@ /* Display the menu. */ lw_pop_up_all_widgets (dialog_id); - popup_activated_flag = 1; /* Process events that apply to the menu. */ popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), dialog_id); @@ -2428,13 +2423,6 @@ return 1; } -int -popup_activated () -{ - /* popup_activated_flag not actually used on W32 */ - return 0; -} - /* Display help string for currently pointed to menu item. Not supported on NT 3.51 and earlier, as GetMenuItemInfo is not available. */ @@ -2537,6 +2525,21 @@ #endif /* HAVE_MENUS */ +/* The following is used by delayed window autoselection. */ + +DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_p, 0, 0, 0, + doc: /* Return t if a menu or popup dialog is active on selected frame. */) + () +{ +#ifdef HAVE_MENUS + FRAME_PTR f; + f = SELECTED_FRAME (); + return (f->output_data.w32->menubar_active > 0) ? Qt : Qnil; +#else + return Qnil; +#endif /* HAVE_MENUS */ +} + void syms_of_w32menu () { globals_of_w32menu (); @@ -2549,6 +2552,7 @@ staticpro (&Qdebug_on_next_call); defsubr (&Sx_popup_menu); + defsubr (&Smenu_or_popup_active_p); #ifdef HAVE_MENUS defsubr (&Sx_popup_dialog); #endif
--- a/src/w32proc.c Tue Nov 07 02:37:49 2006 +0000 +++ b/src/w32proc.c Tue Nov 07 23:22:48 2006 +0000 @@ -486,7 +486,8 @@ { for (cp = child_procs+(child_proc_count-1); cp >= child_procs; cp--) /* some child_procs might be sockets; ignore them */ - if (CHILD_ACTIVE (cp) && cp->procinfo.hProcess) + if (CHILD_ACTIVE (cp) && cp->procinfo.hProcess + && (cp->fd < 0 || (fd_info[cp->fd].flags & FILE_AT_EOF) != 0)) { wait_hnd[nh] = cp->procinfo.hProcess; cps[nh] = cp;
--- a/src/xdisp.c Tue Nov 07 02:37:49 2006 +0000 +++ b/src/xdisp.c Tue Nov 07 23:22:48 2006 +0000 @@ -22935,7 +22935,7 @@ struct buffer *b; /* When a menu is active, don't highlight because this looks odd. */ -#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI) +#if defined (USE_X_TOOLKIT) || defined (USE_GTK) if (popup_activated ()) return; #endif
--- a/src/xfns.c Tue Nov 07 02:37:49 2006 +0000 +++ b/src/xfns.c Tue Nov 07 23:22:48 2006 +0000 @@ -2120,27 +2120,35 @@ if (!xfs) { char *fontsetname = xic_create_fontsetname (base_fontname, False); - char *p0 = fontsetname, *p1; /* New fontset. */ - /* FONTSETNAME contains a list of font names (specific fonts - first, general fonts last), but giving that to XCreateFontSet - at once occasionally fails (bug of X?). So, we try to call - XCreateFontSet for each fontname. */ - - while (p0) + xfs = XCreateFontSet (FRAME_X_DISPLAY (f), + fontsetname, &missing_list, + &missing_count, &def_string); + if (missing_list) + XFreeStringList (missing_list); + if (! xfs) { - p1 = strchr (p0, ','); - if (p1) - *p1 = '\0'; - xfs = XCreateFontSet (FRAME_X_DISPLAY (f), - p0, &missing_list, - &missing_count, &def_string); - if (missing_list) - XFreeStringList (missing_list); - if (xfs) - break; - p0 = p1 ? p1 + 1 : NULL; + /* FONTSETNAME contains a list of font names (specific fonts + first, general fonts last), but giving that to + XCreateFontSet at once occasionally fails (bug of X?). + So, we try to call XCreateFontSet for each fontname. */ + char *p0 = fontsetname, *p1; + + while (p0) + { + p1 = strchr (p0, ','); + if (p1) + *p1 = '\0'; + xfs = XCreateFontSet (FRAME_X_DISPLAY (f), + p0, &missing_list, + &missing_count, &def_string); + if (missing_list) + XFreeStringList (missing_list); + if (xfs) + break; + p0 = p1 ? p1 + 1 : NULL; + } } xfree (fontsetname); }
--- a/src/xmenu.c Tue Nov 07 02:37:49 2006 +0000 +++ b/src/xmenu.c Tue Nov 07 23:22:48 2006 +0000 @@ -1395,8 +1395,13 @@ Lisp_Object frame; { GtkWidget *menubar; + FRAME_PTR f; + + /* gcc 2.95 doesn't accept the FRAME_PTR declaration after + BLOCK_INPUT. */ + BLOCK_INPUT; - FRAME_PTR f = check_x_frame (frame); + f = check_x_frame (frame); if (FRAME_EXTERNAL_MENU_BAR (f)) set_frame_menubar (f, 0, 1); @@ -1409,7 +1414,7 @@ gtk_menu_shell_select_item (GTK_MENU_SHELL (menubar), GTK_WIDGET (children->data)); - + popup_activated_flag = 1; g_list_free (children); } @@ -3756,6 +3761,20 @@ #endif /* not USE_X_TOOLKIT */ #endif /* HAVE_MENUS */ + + +/* The following is used by delayed window autoselection. */ + +DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_p, 0, 0, 0, + doc: /* Return t if a menu or popup dialog is active. */) + () +{ +#ifdef HAVE_MENUS + return (popup_activated ()) ? Qt : Qnil; +#else + return Qnil; +#endif /* HAVE_MENUS */ +} void syms_of_xmenu () @@ -3773,6 +3792,7 @@ #endif defsubr (&Sx_popup_menu); + defsubr (&Smenu_or_popup_active_p); #if defined (USE_GTK) || defined (USE_X_TOOLKIT) defsubr (&Smenu_bar_open);
--- a/src/xsmfns.c Tue Nov 07 02:37:49 2006 +0000 +++ b/src/xsmfns.c Tue Nov 07 23:22:48 2006 +0000 @@ -561,7 +561,7 @@ DEFVAR_LISP ("x-session-previous-id", &Vx_session_previous_id, doc: /* The previous session id Emacs got from session manager. If Emacs is running on a window system that has a session manager, the -session manager gives Emacs a session id. It is feasible for Emacs lisp +session manager gives Emacs a session id. It is feasible for Emacs Lisp code to use the session id to save configuration in, for example, a file with a file name based on the session id. If Emacs is running when the window system is shut down, the session manager remembers that Emacs was
--- a/src/xterm.c Tue Nov 07 02:37:49 2006 +0000 +++ b/src/xterm.c Tue Nov 07 23:22:48 2006 +0000 @@ -8906,13 +8906,25 @@ x_raise_frame (f) struct frame *f; { + Lisp_Object frame; + const char *atom = "_NET_ACTIVE_WINDOW"; + + BLOCK_INPUT; if (f->async_visible) - { - BLOCK_INPUT; - XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f)); - XFlush (FRAME_X_DISPLAY (f)); - UNBLOCK_INPUT; - } + XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f)); + + XSETFRAME (frame, f); + /* See Window Manager Specification/Extended Window Manager Hints at + http://freedesktop.org/wiki/Standards_2fwm_2dspec */ + + Fx_send_client_event (frame, make_number (0), frame, + make_unibyte_string (atom, strlen (atom)), + make_number (32), + Fcons (make_number (1), + Fcons (make_number (time (NULL) * 1000), + Qnil))); + XFlush (FRAME_X_DISPLAY (f)); + UNBLOCK_INPUT; } /* Lower frame F. */