commit 7c7b96eba0599d94ebf93032beb928cf2c043845 (HEAD, refs/remotes/origin/master) Author: Daiki Ueno Date: Sat Apr 11 16:01:18 2015 +0900 Respect more keyword args in `make-process' * process.c (Fmake_process): Respect `:sentinel' and `:filter' keywords as documented. diff --git a/src/process.c b/src/process.c index 5319c6c..3ffbbec 100644 --- a/src/process.c +++ b/src/process.c @@ -1483,8 +1483,8 @@ usage: (make-process &rest ARGS) */) pset_plist (XPROCESS (proc), Qnil); pset_type (XPROCESS (proc), Qreal); pset_buffer (XPROCESS (proc), buffer); - pset_sentinel (XPROCESS (proc), Qinternal_default_process_sentinel); - pset_filter (XPROCESS (proc), Qinternal_default_process_filter); + pset_sentinel (XPROCESS (proc), Fplist_get (contact, QCsentinel)); + pset_filter (XPROCESS (proc), Fplist_get (contact, QCfilter)); pset_command (XPROCESS (proc), Fcopy_sequence (command)); if (tem = Fplist_get (contact, QCnoquery), !NILP (tem)) commit 878058df46b593dd2afaad2086d8ff10bff367c2 Author: Dmitry Gutov Date: Sat Apr 11 07:09:28 2015 +0300 Extract ChangeLog entries when committing a directory * lisp/vc/vc-dispatcher.el (vc-log-edit): Update FIXME comment. * lisp/vc/log-edit.el (log-edit-changelog-insert-entries): Add a FIXME comment. (log-edit-changelog-entries): Extract from `log-edit-changelog-entries', handle FILE being a directory (http://lists.gnu.org/archive/html/emacs-devel/2015-04/msg00555.html). diff --git a/lisp/vc/log-edit.el b/lisp/vc/log-edit.el index e74ca72..f82c7e9 100644 --- a/lisp/vc/log-edit.el +++ b/lisp/vc/log-edit.el @@ -917,21 +917,8 @@ where LOGBUFFER is the name of the ChangeLog buffer, and each (log-edit-narrow-changelog) (goto-char (point-min)) - ;; Search for the name of FILE relative to the ChangeLog. If that - ;; doesn't occur anywhere, they're not using full relative - ;; filenames in the ChangeLog, so just look for FILE; we'll accept - ;; some false positives. - (let ((pattern (file-relative-name - file (file-name-directory changelog-file-name)))) - (if (or (string= pattern "") - (not (save-excursion - (search-forward pattern nil t)))) - (setq pattern (file-name-nondirectory file))) - - (setq pattern (concat "\\(^\\|[^[:alnum:]]\\)" - (regexp-quote pattern) - "\\($\\|[^[:alnum:]]\\)")) - + (let ((pattern (log-edit-changelog--pattern file + changelog-file-name))) (let (texts (pos (point))) (while (and (not (eobp)) (re-search-forward pattern nil t)) @@ -946,6 +933,25 @@ where LOGBUFFER is the name of the ChangeLog buffer, and each (cons (current-buffer) texts))))))))) +(defun log-edit-changelog--pattern (file changelog-file-name) + (if (eq (aref file (1- (length file))) ?/) + ;; Match any files inside this directory. + (concat "^\t\\* " (unless (string= file "./") file)) + ;; Search for the name of FILE relative to the ChangeLog. If that + ;; doesn't occur anywhere, they're not using full relative + ;; filenames in the ChangeLog, so just look for FILE; we'll accept + ;; some false positives. + (let ((pattern (file-relative-name + file (file-name-directory changelog-file-name)))) + ;; FIXME: When can the above return an empty string? + (if (or (string= pattern "") + (not (save-excursion + (search-forward pattern nil t)))) + (setq pattern (file-name-nondirectory file))) + (setq pattern (concat "\\(^\\|[^[:alnum:]]\\)" + (regexp-quote pattern) + "\\($\\|[^[:alnum:]]\\)"))))) + (defun log-edit-changelog-insert-entries (buffer beg end &rest files) "Insert the text from BUFFER between BEG and END. Rename relative filenames in the ChangeLog entry as FILES." @@ -957,6 +963,8 @@ Rename relative filenames in the ChangeLog entry as FILES." (setq bound (point-marker)) (when log-name (dolist (f files) + ;; FIXME: f can be a directory, a (possibly indirect) parent + ;; of the ChangeLog file. (save-excursion (goto-char opoint) (when (re-search-forward diff --git a/lisp/vc/vc-dispatcher.el b/lisp/vc/vc-dispatcher.el index 8b3e888..a2c1cba 100644 --- a/lisp/vc/vc-dispatcher.el +++ b/lisp/vc/vc-dispatcher.el @@ -606,9 +606,13 @@ NOT-URGENT means it is ok to continue if the user says not to save." (not (equal vc-log-fileset fileset)))) `((log-edit-listfun . (lambda () - ;; FIXME: Should expand the list for directories. - ;; Is the above still relevant? If so, it needs a - ;; better explanation. -- dgutov + ;; FIXME: When fileset includes directories, and + ;; there are relevant ChangeLog files inside their + ;; children, we don't find them. Either handle it + ;; in `log-edit-insert-changelog-entries' by + ;; walking down the file trees, or somehow pass + ;; `fileset-only-files' from `vc-next-action' + ;; through to this function. (let ((root (vc-root-dir))) ;; Returns paths relative to the root, so that ;; `log-edit-changelog-insert-entries' commit e3ee455d2992f4adddcd27196b47273f6cacb4e1 Author: Paul Eggert Date: Fri Apr 10 19:36:29 2015 -0700 Fix problems found by --enable-gcc-warnings * src/process.c (create_process, Fmake_pipe_process) (Fmake_network_process): Omit unused locals. diff --git a/src/process.c b/src/process.c index fbc634b..5319c6c 100644 --- a/src/process.c +++ b/src/process.c @@ -1220,8 +1220,8 @@ list of keywords. */) if (NILP (key) && SERIALCONN_P (process)) return list2 (Fplist_get (contact, QCport), Fplist_get (contact, QCspeed)); - /* FIXME: Return a meaningful value (e.g. the child ends of pipe), - if pipe process is useful for other purposes than receiving + /* FIXME: Return a meaningful value (e.g., the child end of the pipe) + if the pipe process is useful for purposes other than receiving stderr. */ if (NILP (key) && PIPECONN_P (process)) return Qt; @@ -1751,7 +1751,7 @@ static void create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) { struct Lisp_Process *p = XPROCESS (process); - int inchannel, outchannel, errchannel = -1; + int inchannel, outchannel; pid_t pid; int vfork_errno; int forkin, forkout, forkerr = -1; @@ -1798,7 +1798,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) struct Lisp_Process *pp = XPROCESS (p->stderrproc); forkerr = pp->open_fd[SUBPROCESS_STDOUT]; - errchannel = pp->open_fd[READ_FROM_SUBPROCESS]; /* Close unnecessary file descriptors. */ close_process_fd (&pp->open_fd[WRITE_TO_SUBPROCESS]); @@ -2128,7 +2127,7 @@ usage: (make-pipe-process &rest ARGS) */) struct Lisp_Process *p; struct gcpro gcpro1; Lisp_Object name, buffer; - Lisp_Object tem, val; + Lisp_Object tem; ptrdiff_t specpdl_count; int inchannel, outchannel; @@ -2203,7 +2202,7 @@ usage: (make-pipe-process &rest ARGS) */) { /* Setup coding systems for communicating with the network stream. */ - struct gcpro gcpro1; + /* Qt denotes we have not yet called Ffind_operation_coding_system. */ Lisp_Object coding_systems = Qt; Lisp_Object val; commit 68a74dd12ad8c28bfe6fb2c0232a7beea548c4c6 Author: Paul Eggert Date: Fri Apr 10 19:12:16 2015 -0700 Fix commit-msg to handle scissors lines * build-aux/git-hooks/commit-msg: Ignore every line after a scissors line, such as a line generated by 'git commit -v'. Problem reported by Johan Bockgård in: http://lists.gnu.org/archive/html/emacs-devel/2015-04/msg00580.html diff --git a/build-aux/git-hooks/commit-msg b/build-aux/git-hooks/commit-msg index 5b07b6c..ea8d909 100755 --- a/build-aux/git-hooks/commit-msg +++ b/build-aux/git-hooks/commit-msg @@ -62,7 +62,13 @@ exec $awk -v at_sign="$at_sign" -v cent_sign="$cent_sign" ' } } - /^#/ { next } + /^#/ { + # Ignore every line after a scissors line. + if (/^# *---* *(>[8%]|[8%]<) *---* *$/) { exit } + + # Ignore comment lines. + next + } !/^.*$/ { print "Invalid character (not UTF-8) in commit message" commit 42142f089d5ff62729a76c903029f9b0349d0dba Author: Paul Eggert Date: Fri Apr 10 19:12:16 2015 -0700 port commit-msg to Gawk 3.0.4 (1999) * build-aux/git-hooks/commit-msg (cent_sign_utf8_format, cent_sign) (print_at_sign, at_sign): New vars. Use them to avoid problems Eli Zaretskii encountered with Gawk 3.0.4 (1999) on MSYS. See: http://lists.gnu.org/archive/html/emacs-devel/2015-04/msg00566.html diff --git a/build-aux/git-hooks/commit-msg b/build-aux/git-hooks/commit-msg index 6721d53..5b07b6c 100755 --- a/build-aux/git-hooks/commit-msg +++ b/build-aux/git-hooks/commit-msg @@ -29,34 +29,36 @@ fi # Use a UTF-8 locale if available, so that the UTF-8 check works. # Use U+00A2 CENT SIGN to test whether the locale works. -cent_sign_utf8_octal='\302\242' -at_sign=` - printf "${cent_sign_utf8_octal}@" | - $awk '{print substr($0, 2)}' 2>/dev/null -` +cent_sign_utf8_format='\302\242\n' +cent_sign=`printf "$cent_sign_utf8_format"` +print_at_sign='{print substr("'$cent_sign'@", 2)}' +at_sign=`$awk "$print_at_sign" 2>/dev/null` if test "$at_sign" != @; then - at_sign=` - printf "${cent_sign_utf8_octal}@" | - LC_ALL=en_US.UTF-8 $awk '{print substr($0, 2)}' 2>/dev/null - ` + at_sign=`LC_ALL=en_US.UTF-8 $awk "$print_at_sign" 2>/dev/null` if test "$at_sign" = @; then LC_ALL=en_US.UTF-8; export LC_ALL fi fi # Check the log entry. -exec $awk ' +exec $awk -v at_sign="$at_sign" -v cent_sign="$cent_sign" ' BEGIN { + # These regular expressions assume traditional Unix unibyte behavior. + # They are needed for old or broken versions of awk, e.g., + # mawk 1.3.3 (1996), Gawk 3.0.4 (1999). + space = "[ \f\n\r\t\v]" + non_space = "[^ \f\n\r\t\v]" + non_print = "[\1-\37\177]" + + # Prefer POSIX regular expressions if available, as they do a + # better job of checking. Similarly, prefer POSIX negated + # expressions if UTF-8 also works. if (" " ~ /[[:space:]]/) { space = "[[:space:]]" - non_space = "[^[:space:]]" - non_print = "[^[:print:]]" - } else { - # mawk 1.3.3 does not support POSIX bracket expressions. - # Approximate them as best we can. - space = "[ \f\n\r\t\v]" - non_space = "[^ \f\n\r\t\v]" - non_print = "[\1-\37\177]" + if (at_sign == "@" && cent_sign ~ /^[[:print:]]$/) { + non_space = "[^[:space:]]" + non_print = "[^[:print:]]" + } } } commit 89b2bf617fa0619d57e8875d6d15aa765d765482 Author: Paul Eggert Date: Fri Apr 10 19:12:16 2015 -0700 Have commit-msg report commit failure * build-aux/git-hooks/commit-msg: If the commit is aborted, say so. Simplify by doing this at the end. Problem reported by Eli Zaretskii in: http://lists.gnu.org/archive/html/emacs-devel/2015-04/msg00566.html diff --git a/build-aux/git-hooks/commit-msg b/build-aux/git-hooks/commit-msg index 13a0535..6721d53 100755 --- a/build-aux/git-hooks/commit-msg +++ b/build-aux/git-hooks/commit-msg @@ -63,7 +63,7 @@ exec $awk ' /^#/ { next } !/^.*$/ { - print "Invalid character (not UTF-8) in commit message; see 'CONTRIBUTE'" + print "Invalid character (not UTF-8) in commit message" status = 1 } @@ -77,13 +77,13 @@ exec $awk ' sub(/^squash! /, "") if ($0 ~ "^" space) { - print "White space at start of commit message'\''s first line; see 'CONTRIBUTE'" + print "White space at start of commit message'\''s first line" status = 1 } } nlines == 2 && $0 ~ non_space { - print "Nonempty second line in commit message; see 'CONTRIBUTE'" + print "Nonempty second line in commit message" status = 1 } @@ -97,30 +97,33 @@ exec $awk ' } 78 < length && $0 ~ space { - print "Line longer than 78 characters in commit message; see 'CONTRIBUTE'" + print "Line longer than 78 characters in commit message" status = 1 } 140 < length { - print "Word longer than 140 characters in commit message; see 'CONTRIBUTE'" + print "Word longer than 140 characters in commit message" status = 1 } /^Signed-off-by: / { - print "'\''Signed-off-by:'\'' in commit message; see 'CONTRIBUTE'" + print "'\''Signed-off-by:'\'' in commit message" status = 1 } $0 ~ non_print { - print "Unprintable character in commit message; see 'CONTRIBUTE'" + print "Unprintable character in commit message" status = 1 } END { if (nlines == 0) { - print "Empty commit message; see 'CONTRIBUTE'" + print "Empty commit message" status = 1 } + if (status != 0) { + print "Commit aborted; please see the file 'CONTRIBUTE'" + } exit status } ' <"$1" commit c0984249eb65641a0876594183c80fd8e6b37962 Author: Thomas Fitzsimmons Date: Fri Apr 10 21:55:40 2015 -0400 Clean up LDAP Configuration section of EUDC manual * doc/misc/eudc.texi: Combine indices. (LDAP Configuration): Use command markup. Add index entries. Change formatting. Wrap long lines. Add noindent markup. diff --git a/doc/misc/eudc.texi b/doc/misc/eudc.texi index 9757c82..76a25c1 100644 --- a/doc/misc/eudc.texi +++ b/doc/misc/eudc.texi @@ -4,6 +4,8 @@ @settitle Emacs Unified Directory Client (EUDC) Manual @afourpaper @documentencoding UTF-8 +@syncodeindex fn cp +@syncodeindex vr cp @c %**end of header @copying @@ -61,8 +63,7 @@ modify this GNU manual.'' * Usage:: The various usage possibilities explained * Credits:: Who's done what * GNU Free Documentation License:: The license for this documentation. -* Command and Function Index:: -* Variables Index:: +* Index:: @end menu @@ -220,15 +221,15 @@ email composition buffers (@pxref{Inline Query Expansion}) @section LDAP Configuration LDAP support is added by means of @file{ldap.el}, which is part of -Emacs. @file{ldap.el} needs an external command line utility named -@file{ldapsearch}, available as part of OpenLDAP +Emacs. @file{ldap.el} needs an external program called +@command{ldapsearch}, available as part of OpenLDAP (@url{http://www.openldap.org/}). The configurations in this section were tested with OpenLDAP 2.4.23. The following examples use a base of @code{ou=people,dc=example,dc=com} and the host name -@code{directory.example.com}, a server that supports LDAP-over-SSL -(the @code{ldaps} protocol, with default port @code{636}) and which +@code{ldaps.gnu.org}, a server that supports LDAP-over-SSL (the +@code{ldaps} protocol, with default port @code{636}) and which requires authentication by the user @code{emacsuser} with password @code{s3cr3t}. @@ -244,14 +245,21 @@ example, attempting to TAB-complete the following: To: * Smith @end example +@noindent will return all LDAP entries with surnames that begin with @code{Smith}. In every LDAP query it makes, EUDC implicitly appends the wildcard character to the end of the last word. +@menu +* Emacs-only Configuration:: Configure with @file{.emacs} +* External Configuration:: Configure with @file{/etc/openldap/ldap.conf} +@end menu + +@node Emacs-only Configuration @subsection Emacs-only Configuration Emacs can pass most required configuration options via the -@file{ldapsearch} command-line. One exception is certificate +@command{ldapsearch} command-line. One exception is certificate configuration for LDAP-over-SSL, which must be specified in @file{/etc/openldap/ldap.conf}. On systems that provide such certificates as part of the @code{OpenLDAP} installation, this can be @@ -269,14 +277,19 @@ LDAP: '(define-key message-mode-map (kbd "TAB") 'eudc-expand-inline)) (customize-set-variable 'eudc-server-hotlist '(("" . bbdb) - ("ldaps://directory.example.com" . ldap))) + ("ldaps://ldaps.gnu.org" . ldap))) (customize-set-variable 'ldap-host-parameters-alist - '(("ldaps://directory.example.com" + '(("ldaps://ldaps.gnu.org" base "ou=people,dc=example,dc=com" binddn "example\\emacsuser" passwd ldap-password-read))) @end lisp +@findex ldap-password-read +@vindex passwd +@vindex password-cache +@vindex password-cache-expiry +@findex password-reset Specifying the function @code{ldap-password-read} for @code{passwd} will cause Emacs to prompt interactively for the password. The password will then be validated and cached, unless @@ -285,6 +298,7 @@ password will then be validated and cached, unless password is cached. If you want to clear the cache, call @code{password-reset}. +@node External Configuration @subsection External Configuration Your system may already be configured for a default LDAP server. For @@ -292,17 +306,19 @@ example, @file{/etc/openldap/ldap.conf} might contain: @example BASE ou=people,dc=example,dc=com -URI ldaps://directory.example.com +URI ldaps://ldaps.gnu.org TLS_CACERTDIR /etc/openldap/certs @end example -To authenticate, the @dfn{bind distinguished name (binddn)} is -required, in this case, @code{example\emacsuser}, along with the -password. These can be specified in @file{~/.authinfo.gpg} with the -following line: +@cindex bind distinguished name +@cindex binddn +Authentication requires a password, and a @dfn{bind distinguished name +(binddn)} representing the user, in this case, +@code{example\emacsuser}. These can be specified in +@file{~/.authinfo.gpg} with the following line: @example -machine ldaps://directory.example.com binddn example\emacsuser password s3cr3t +machine ldaps://ldaps.gnu.org binddn example\emacsuser password s3cr3t @end example Then in the @file{.emacs} init file, these expressions suffice to @@ -313,15 +329,15 @@ configure EUDC for LDAP: '(define-key message-mode-map (kbd "TAB") 'eudc-expand-inline)) (customize-set-variable 'eudc-server-hotlist '(("" . bbdb) - ("ldaps://directory.example.com" . ldap))) + ("ldaps://ldaps.gnu.org" . ldap))) (customize-set-variable 'ldap-host-parameters-alist - '(("ldaps://directory.example.com" + '(("ldaps://ldaps.gnu.org" auth-source t))) @end lisp For this example where we only care about one server, the server name can be omitted in @file{~/.authinfo.gpg} and @file{.emacs}, in which -case @file{ldapsearch} defaults to the host name in +case @command{ldapsearch} defaults to the host name in @file{/etc/openldap/ldap.conf}. The @file{~/.authinfo.gpg} line becomes: @@ -330,13 +346,16 @@ The @file{~/.authinfo.gpg} line becomes: binddn example\emacsuser password s3cr3t @end example +@noindent and the @file{.emacs} expressions become: @lisp (eval-after-load "message" '(define-key message-mode-map (kbd "TAB") 'eudc-expand-inline)) -(customize-set-variable 'eudc-server-hotlist '(("" . bbdb) ("" . ldap))) -(customize-set-variable 'ldap-host-parameters-alist '(("" auth-source t))) +(customize-set-variable 'eudc-server-hotlist + '(("" . bbdb) ("" . ldap))) +(customize-set-variable 'ldap-host-parameters-alist + '(("" auth-source t))) @end lisp @node Usage @@ -1043,14 +1062,9 @@ in testing and proofreading the code and docs of @file{ph.el}. @appendix GNU Free Documentation License @include doclicense.texi -@node Command and Function Index -@unnumbered Command and Function Index - -@printindex fn - -@node Variables Index -@unnumbered Variables Index +@node Index +@unnumbered Index -@printindex vr +@printindex cp @bye commit f55ea05bdf60e24c09f9064fc0d2e8a114d6e358 Author: Daiki Ueno Date: Tue Apr 7 17:42:09 2015 +0900 Add facility to collect stderr of async subprocess * src/w32.h (register_aux_fd): New function declaration. * src/w32.c (register_aux_fd): New function. * src/process.h (struct Lisp_Process): New member stderrproc. * src/process.c (PIPECONN_P): New macro. (PIPECONN1_P): New macro. (Fdelete_process, Fprocess_status, Fset_process_buffer) (Fset_process_filter, Fset_process_sentinel, Fstop_process) (Fcontinue_process): Handle pipe process specially. (create_process): Respect p->stderrproc. (Fmake_pipe_process): New function. (Fmake_process): Add new keyword argument :stderr. (wait_reading_process_output): Specially handle a pipe process when it gets an EOF. (syms_of_process): Register Qpipe and Smake_pipe_process. * doc/lispref/processes.texi (Asynchronous Processes): Document `make-pipe-process' and `:stderr' keyword of `make-process'. * lisp/subr.el (start-process): Suggest to use `make-process' handle standard error separately. * test/automated/process-tests.el (process-test-stderr-buffer) (process-test-stderr-filter): New tests. * etc/NEWS: Mention new process type `pipe' and its usage with the `:stderr' keyword of `make-process'. diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi index 3e9cc50..f228921 100644 --- a/doc/lispref/processes.texi +++ b/doc/lispref/processes.texi @@ -741,6 +741,58 @@ Initialize the process filter to @var{filter}. @item :sentinel @var{sentinel} Initialize the process sentinel to @var{sentinel}. + +@item :stderr @var{stderr} +Associate @var{stderr} with the standard error of the process. +@var{stderr} is either a buffer or a pipe process created with +@code{make-pipe-process}. +@end table + +The original argument list, modified with the actual connection +information, is available via the @code{process-contact} function. +@end defun + +@defun make-pipe-process &rest args +This function creates a bidirectional pipe which can be attached to a +child process (currently only useful with the @code{:stderr} keyword +of @code{make-process}). + +The arguments @var{args} are a list of keyword/argument pairs. +Omitting a keyword is always equivalent to specifying it with value +@code{nil}, except for @code{:coding}. +Here are the meaningful keywords: + +@table @asis +@item :name @var{name} +Use the string @var{name} as the process name. It is modified if +necessary to make it unique. + +@item :buffer @var{buffer} +Use @var{buffer} as the process buffer. + +@item :coding @var{coding} +If @var{coding} is a symbol, it specifies the coding system to be +used for both reading and writing of data from and to the +connection. If @var{coding} is a cons cell +@w{@code{(@var{decoding} . @var{encoding})}}, then @var{decoding} +will be used for reading and @var{encoding} for writing. + +If @var{coding} is @code{nil}, the default rules for finding the +coding system will apply. @xref{Default Coding Systems}. + +@item :noquery @var{query-flag} +Initialize the process query flag to @var{query-flag}. +@xref{Query Before Exit}. + +@item :stop @var{stopped} +If @var{stopped} is non-@code{nil}, start the process in the +``stopped'' state. + +@item :filter @var{filter} +Initialize the process filter to @var{filter}. + +@item :sentinel @var{sentinel} +Initialize the process sentinel to @var{sentinel}. @end table The original argument list, modified with the actual connection diff --git a/etc/NEWS b/etc/NEWS index 80c664f..8ee6db6 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -674,6 +674,10 @@ word syntax, use `\sw' instead. * Lisp Changes in Emacs 25.1 +** New process type `pipe', which can be used in combination with the +`:stderr' keyword of make-process to handle standard error output +of subprocess. + ** New function `make-process' provides an alternative interface to `start-process'. It allows programs to set process parameters such as process filter, sentinel, etc., through keyword arguments (similar to diff --git a/lisp/subr.el b/lisp/subr.el index 00acdb6..3b536f2 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1936,9 +1936,9 @@ PROGRAM is the program file name. It is searched for in `exec-path' \(which see). If nil, just associate a pty with the buffer. Remaining arguments are strings to give program as arguments. -If you want to separate standard output from standard error, invoke -the command through a shell and redirect one of them using the shell -syntax." +If you want to separate standard output from standard error, use +`make-process' or invoke the command through a shell and redirect +one of them using the shell syntax." (unless (fboundp 'make-process) (error "Emacs was compiled without subprocess support")) (apply #'make-process diff --git a/src/process.c b/src/process.c index 2800fa5..fbc634b 100644 --- a/src/process.c +++ b/src/process.c @@ -189,6 +189,8 @@ process_socket (int domain, int type, int protocol) #define NETCONN1_P(p) (EQ (p->type, Qnetwork)) #define SERIALCONN_P(p) (EQ (XPROCESS (p)->type, Qserial)) #define SERIALCONN1_P(p) (EQ (p->type, Qserial)) +#define PIPECONN_P(p) (EQ (XPROCESS (p)->type, Qpipe)) +#define PIPECONN1_P(p) (EQ (p->type, Qpipe)) /* Number of events of change of status of a process. */ static EMACS_INT process_tick; @@ -411,6 +413,11 @@ pset_write_queue (struct Lisp_Process *p, Lisp_Object val) { p->write_queue = val; } +static void +pset_stderrproc (struct Lisp_Process *p, Lisp_Object val) +{ + p->stderrproc = val; +} static Lisp_Object @@ -837,7 +844,7 @@ nil, indicating the current buffer's process. */) p = XPROCESS (process); p->raw_status_new = 0; - if (NETCONN1_P (p) || SERIALCONN1_P (p)) + if (NETCONN1_P (p) || SERIALCONN1_P (p) || PIPECONN1_P (p)) { pset_status (p, list2 (Qexit, make_number (0))); p->tick = ++process_tick; @@ -903,7 +910,7 @@ nil, indicating the current buffer's process. */) status = p->status; if (CONSP (status)) status = XCAR (status); - if (NETCONN1_P (p) || SERIALCONN1_P (p)) + if (NETCONN1_P (p) || SERIALCONN1_P (p) || PIPECONN1_P (p)) { if (EQ (status, Qexit)) status = Qclosed; @@ -987,7 +994,7 @@ Return BUFFER. */) CHECK_BUFFER (buffer); p = XPROCESS (process); pset_buffer (p, buffer); - if (NETCONN1_P (p) || SERIALCONN1_P (p)) + if (NETCONN1_P (p) || SERIALCONN1_P (p) || PIPECONN1_P (p)) pset_childp (p, Fplist_put (p->childp, QCbuffer, buffer)); setup_process_coding_systems (process); return buffer; @@ -1063,7 +1070,7 @@ The string argument is normally a multibyte string, except: } pset_filter (p, filter); - if (NETCONN1_P (p) || SERIALCONN1_P (p)) + if (NETCONN1_P (p) || SERIALCONN1_P (p) || PIPECONN1_P (p)) pset_childp (p, Fplist_put (p->childp, QCfilter, filter)); setup_process_coding_systems (process); return filter; @@ -1095,7 +1102,7 @@ It gets two arguments: the process, and a string describing the change. */) sentinel = Qinternal_default_process_sentinel; pset_sentinel (p, sentinel); - if (NETCONN1_P (p) || SERIALCONN1_P (p)) + if (NETCONN1_P (p) || SERIALCONN1_P (p) || PIPECONN1_P (p)) pset_childp (p, Fplist_put (p->childp, QCsentinel, sentinel)); return sentinel; } @@ -1204,7 +1211,8 @@ list of keywords. */) Fprocess_datagram_address (process)); #endif - if ((!NETCONN_P (process) && !SERIALCONN_P (process)) || EQ (key, Qt)) + if ((!NETCONN_P (process) && !SERIALCONN_P (process) && !PIPECONN_P (process)) + || EQ (key, Qt)) return contact; if (NILP (key) && NETCONN_P (process)) return list2 (Fplist_get (contact, QChost), @@ -1212,6 +1220,11 @@ list of keywords. */) if (NILP (key) && SERIALCONN_P (process)) return list2 (Fplist_get (contact, QCport), Fplist_get (contact, QCspeed)); + /* FIXME: Return a meaningful value (e.g. the child ends of pipe), + if pipe process is useful for other purposes than receiving + stderr. */ + if (NILP (key) && PIPECONN_P (process)) + return Qt; return Fplist_get (contact, key); } @@ -1386,10 +1399,15 @@ to use a pty, or nil to use the default specified through :sentinel SENTINEL -- Install SENTINEL as the process sentinel. +:stderr STDERR -- STDERR is either a buffer or a pipe process attached +to the standard error of subprocess. Specifying this implies +`:connection-type' is set to `pipe'. + usage: (make-process &rest ARGS) */) (ptrdiff_t nargs, Lisp_Object *args) { Lisp_Object buffer, name, command, program, proc, contact, current_dir, tem; + Lisp_Object xstderr, stderrproc; ptrdiff_t count = SPECPDL_INDEX (); struct gcpro gcpro1; USE_SAFE_ALLOCA; @@ -1433,6 +1451,27 @@ usage: (make-process &rest ARGS) */) if (!NILP (program)) CHECK_STRING (program); + stderrproc = Qnil; + xstderr = Fplist_get (contact, QCstderr); + if (PROCESSP (xstderr)) + { + if (!PIPECONN_P (xstderr)) + error ("Process is not a pipe process"); + stderrproc = xstderr; + } + else if (!NILP (xstderr)) + { + struct gcpro gcpro1, gcpro2; + CHECK_STRING (program); + GCPRO2 (buffer, current_dir); + stderrproc = CALLN (Fmake_pipe_process, + QCname, + concat2 (name, build_string (" stderr")), + QCbuffer, + Fget_buffer_create (xstderr)); + UNGCPRO; + } + proc = make_process (name); /* If an error occurs and we can't start the process, we want to remove it from the process list. This means that each error @@ -1463,6 +1502,13 @@ usage: (make-process &rest ARGS) */) else report_file_error ("Unknown connection type", tem); + if (!NILP (stderrproc)) + { + pset_stderrproc (XPROCESS (proc), stderrproc); + + XPROCESS (proc)->pty_flag = false; + } + #ifdef HAVE_GNUTLS /* AKA GNUTLS_INITSTAGE(proc). */ XPROCESS (proc)->gnutls_initstage = GNUTLS_STAGE_EMPTY; @@ -1705,10 +1751,10 @@ static void create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) { struct Lisp_Process *p = XPROCESS (process); - int inchannel, outchannel; + int inchannel, outchannel, errchannel = -1; pid_t pid; int vfork_errno; - int forkin, forkout; + int forkin, forkout, forkerr = -1; bool pty_flag = 0; char pty_name[PTY_NAME_SIZE]; Lisp_Object lisp_pty_name = Qnil; @@ -1746,6 +1792,18 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) outchannel = p->open_fd[WRITE_TO_SUBPROCESS]; inchannel = p->open_fd[READ_FROM_SUBPROCESS]; forkout = p->open_fd[SUBPROCESS_STDOUT]; + + if (!NILP (p->stderrproc)) + { + struct Lisp_Process *pp = XPROCESS (p->stderrproc); + + forkerr = pp->open_fd[SUBPROCESS_STDOUT]; + errchannel = pp->open_fd[READ_FROM_SUBPROCESS]; + + /* Close unnecessary file descriptors. */ + close_process_fd (&pp->open_fd[WRITE_TO_SUBPROCESS]); + close_process_fd (&pp->open_fd[SUBPROCESS_STDIN]); + } } #ifndef WINDOWSNT @@ -1792,6 +1850,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) char **volatile new_argv_volatile = new_argv; int volatile forkin_volatile = forkin; int volatile forkout_volatile = forkout; + int volatile forkerr_volatile = forkerr; struct Lisp_Process *p_volatile = p; pid = vfork (); @@ -1801,6 +1860,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) new_argv = new_argv_volatile; forkin = forkin_volatile; forkout = forkout_volatile; + forkerr = forkerr_volatile; p = p_volatile; pty_flag = p->pty_flag; @@ -1811,6 +1871,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) { int xforkin = forkin; int xforkout = forkout; + int xforkerr = forkerr; /* Make the pty be the controlling terminal of the process. */ #ifdef HAVE_PTYS @@ -1910,10 +1971,13 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) if (pty_flag) child_setup_tty (xforkout); + + if (xforkerr < 0) + xforkerr = xforkout; #ifdef WINDOWSNT - pid = child_setup (xforkin, xforkout, xforkout, new_argv, 1, current_dir); + pid = child_setup (xforkin, xforkout, xforkerr, new_argv, 1, current_dir); #else /* not WINDOWSNT */ - child_setup (xforkin, xforkout, xforkout, new_argv, 1, current_dir); + child_setup (xforkin, xforkout, xforkerr, new_argv, 1, current_dir); #endif /* not WINDOWSNT */ } @@ -1958,6 +2022,11 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) close_process_fd (&p->open_fd[READ_FROM_EXEC_MONITOR]); } #endif + if (!NILP (p->stderrproc)) + { + struct Lisp_Process *pp = XPROCESS (p->stderrproc); + close_process_fd (&pp->open_fd[SUBPROCESS_STDOUT]); + } } } @@ -2016,6 +2085,187 @@ create_pty (Lisp_Object process) p->pid = -2; } +DEFUN ("make-pipe-process", Fmake_pipe_process, Smake_pipe_process, + 0, MANY, 0, + doc: /* Create and return a bidirectional pipe process. + +In Emacs, pipes are represented by process objects, so input and +output work as for subprocesses, and `delete-process' closes a pipe. +However, a pipe process has no process id, it cannot be signaled, +and the status codes are different from normal processes. + +Arguments are specified as keyword/argument pairs. The following +arguments are defined: + +:name NAME -- NAME is the name of the process. It is modified if necessary to make it unique. + +:buffer BUFFER -- BUFFER is the buffer (or buffer-name) to associate +with the process. Process output goes at the end of that buffer, +unless you specify an output stream or filter function to handle the +output. If BUFFER is not given, the value of NAME is used. + +:coding CODING -- If CODING is a symbol, it specifies the coding +system used for both reading and writing for this process. If CODING +is a cons (DECODING . ENCODING), DECODING is used for reading, and +ENCODING is used for writing. + +:noquery BOOL -- When exiting Emacs, query the user if BOOL is nil and +the process is running. If BOOL is not given, query before exiting. + +:stop BOOL -- Start process in the `stopped' state if BOOL non-nil. +In the stopped state, a pipe process does not accept incoming data, +but you can send outgoing data. The stopped state is cleared by +`continue-process' and set by `stop-process'. + +:filter FILTER -- Install FILTER as the process filter. + +:sentinel SENTINEL -- Install SENTINEL as the process sentinel. + +usage: (make-pipe-process &rest ARGS) */) + (ptrdiff_t nargs, Lisp_Object *args) +{ + Lisp_Object proc, contact; + struct Lisp_Process *p; + struct gcpro gcpro1; + Lisp_Object name, buffer; + Lisp_Object tem, val; + ptrdiff_t specpdl_count; + int inchannel, outchannel; + + if (nargs == 0) + return Qnil; + + contact = Flist (nargs, args); + GCPRO1 (contact); + + name = Fplist_get (contact, QCname); + CHECK_STRING (name); + proc = make_process (name); + specpdl_count = SPECPDL_INDEX (); + record_unwind_protect (remove_process, proc); + p = XPROCESS (proc); + + if (emacs_pipe (p->open_fd + SUBPROCESS_STDIN) != 0 + || emacs_pipe (p->open_fd + READ_FROM_SUBPROCESS) != 0) + report_file_error ("Creating pipe", Qnil); + outchannel = p->open_fd[WRITE_TO_SUBPROCESS]; + inchannel = p->open_fd[READ_FROM_SUBPROCESS]; + + fcntl (inchannel, F_SETFL, O_NONBLOCK); + fcntl (outchannel, F_SETFL, O_NONBLOCK); + +#ifdef WINDOWSNT + register_aux_fd (inchannel); +#endif + + /* Record this as an active process, with its channels. */ + chan_process[inchannel] = proc; + p->infd = inchannel; + p->outfd = outchannel; + + if (inchannel > max_process_desc) + max_process_desc = inchannel; + + buffer = Fplist_get (contact, QCbuffer); + if (NILP (buffer)) + buffer = name; + buffer = Fget_buffer_create (buffer); + pset_buffer (p, buffer); + + pset_childp (p, contact); + pset_plist (p, Fcopy_sequence (Fplist_get (contact, QCplist))); + pset_type (p, Qpipe); + pset_sentinel (p, Fplist_get (contact, QCsentinel)); + pset_filter (p, Fplist_get (contact, QCfilter)); + pset_log (p, Qnil); + if (tem = Fplist_get (contact, QCnoquery), !NILP (tem)) + p->kill_without_query = 1; + if (tem = Fplist_get (contact, QCstop), !NILP (tem)) + pset_command (p, Qt); + eassert (! p->pty_flag); + + if (!EQ (p->command, Qt)) + { + FD_SET (inchannel, &input_wait_mask); + FD_SET (inchannel, &non_keyboard_wait_mask); + } +#ifdef ADAPTIVE_READ_BUFFERING + p->adaptive_read_buffering + = (NILP (Vprocess_adaptive_read_buffering) ? 0 + : EQ (Vprocess_adaptive_read_buffering, Qt) ? 1 : 2); +#endif + + /* Make the process marker point into the process buffer (if any). */ + if (BUFFERP (buffer)) + set_marker_both (p->mark, buffer, + BUF_ZV (XBUFFER (buffer)), + BUF_ZV_BYTE (XBUFFER (buffer))); + + { + /* Setup coding systems for communicating with the network stream. */ + struct gcpro gcpro1; + /* Qt denotes we have not yet called Ffind_operation_coding_system. */ + Lisp_Object coding_systems = Qt; + Lisp_Object val; + + tem = Fplist_get (contact, QCcoding); + val = Qnil; + if (!NILP (tem)) + { + val = tem; + if (CONSP (val)) + val = XCAR (val); + } + else if (!NILP (Vcoding_system_for_read)) + val = Vcoding_system_for_read; + else if ((!NILP (buffer) && NILP (BVAR (XBUFFER (buffer), enable_multibyte_characters))) + || (NILP (buffer) && NILP (BVAR (&buffer_defaults, enable_multibyte_characters)))) + /* We dare not decode end-of-line format by setting VAL to + Qraw_text, because the existing Emacs Lisp libraries + assume that they receive bare code including a sequence of + CR LF. */ + val = Qnil; + else + { + if (CONSP (coding_systems)) + val = XCAR (coding_systems); + else if (CONSP (Vdefault_process_coding_system)) + val = XCAR (Vdefault_process_coding_system); + else + val = Qnil; + } + pset_decode_coding_system (p, val); + + if (!NILP (tem)) + { + val = tem; + if (CONSP (val)) + val = XCDR (val); + } + else if (!NILP (Vcoding_system_for_write)) + val = Vcoding_system_for_write; + else if (NILP (BVAR (current_buffer, enable_multibyte_characters))) + val = Qnil; + else + { + if (CONSP (coding_systems)) + val = XCDR (coding_systems); + else if (CONSP (Vdefault_process_coding_system)) + val = XCDR (Vdefault_process_coding_system); + else + val = Qnil; + } + pset_encode_coding_system (p, val); + } + /* This may signal an error. */ + setup_process_coding_systems (proc); + + specpdl_ptr = specpdl + specpdl_count; + + UNGCPRO; + return proc; +} + /* Convert an internal struct sockaddr to a lisp object (vector or string). The address family of sa is not included in the result. */ @@ -4884,7 +5134,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, available now and a closed pipe. With luck, a closed pipe will be accompanied by subprocess termination and SIGCHLD. */ - else if (nread == 0 && !NETCONN_P (proc) && !SERIALCONN_P (proc)) + else if (nread == 0 && !NETCONN_P (proc) && !SERIALCONN_P (proc) + && !PIPECONN_P (proc)) ; #endif #ifdef HAVE_PTYS @@ -4916,8 +5167,18 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, #endif /* HAVE_PTYS */ /* If we can detect process termination, don't consider the process gone just because its pipe is closed. */ - else if (nread == 0 && !NETCONN_P (proc) && !SERIALCONN_P (proc)) + else if (nread == 0 && !NETCONN_P (proc) && !SERIALCONN_P (proc) + && !PIPECONN_P (proc)) ; + else if (nread == 0 && PIPECONN_P (proc)) + { + /* Preserve status of processes already terminated. */ + XPROCESS (proc)->tick = ++process_tick; + deactivate_process (proc); + if (EQ (XPROCESS (proc)->status, Qrun)) + pset_status (XPROCESS (proc), + list2 (Qexit, make_number (0))); + } else { /* Preserve status of processes already terminated. */ @@ -5954,7 +6215,8 @@ If PROCESS is a network or serial process, inhibit handling of incoming traffic. */) (Lisp_Object process, Lisp_Object current_group) { - if (PROCESSP (process) && (NETCONN_P (process) || SERIALCONN_P (process))) + if (PROCESSP (process) && (NETCONN_P (process) || SERIALCONN_P (process) + || PIPECONN_P (process))) { struct Lisp_Process *p; @@ -5983,7 +6245,8 @@ If PROCESS is a network or serial process, resume handling of incoming traffic. */) (Lisp_Object process, Lisp_Object current_group) { - if (PROCESSP (process) && (NETCONN_P (process) || SERIALCONN_P (process))) + if (PROCESSP (process) && (NETCONN_P (process) || SERIALCONN_P (process) + || PIPECONN_P (process))) { struct Lisp_Process *p; @@ -7030,7 +7293,7 @@ kill_buffer_processes (Lisp_Object buffer) FOR_EACH_PROCESS (tail, proc) if (NILP (buffer) || EQ (XPROCESS (proc)->buffer, buffer)) { - if (NETCONN_P (proc) || SERIALCONN_P (proc)) + if (NETCONN_P (proc) || SERIALCONN_P (proc) || PIPECONN_P (proc)) Fdelete_process (proc); else if (XPROCESS (proc)->infd >= 0) process_send_signal (proc, SIGHUP, Qnil, 1); @@ -7330,6 +7593,7 @@ syms_of_process (void) DEFSYM (Qreal, "real"); DEFSYM (Qnetwork, "network"); DEFSYM (Qserial, "serial"); + DEFSYM (Qpipe, "pipe"); DEFSYM (QCbuffer, ":buffer"); DEFSYM (QChost, ":host"); DEFSYM (QCservice, ":service"); @@ -7346,6 +7610,7 @@ syms_of_process (void) DEFSYM (QCplist, ":plist"); DEFSYM (QCcommand, ":command"); DEFSYM (QCconnection_type, ":connection-type"); + DEFSYM (QCstderr, ":stderr"); DEFSYM (Qpty, "pty"); DEFSYM (Qpipe, "pipe"); @@ -7451,6 +7716,7 @@ The variable takes effect when `start-process' is called. */); defsubr (&Sset_process_plist); defsubr (&Sprocess_list); defsubr (&Smake_process); + defsubr (&Smake_pipe_process); defsubr (&Sserial_process_configure); defsubr (&Smake_serial_process); defsubr (&Sset_network_process_option); diff --git a/src/process.h b/src/process.h index 36979dc..e889055 100644 --- a/src/process.h +++ b/src/process.h @@ -105,6 +105,9 @@ struct Lisp_Process Lisp_Object gnutls_cred_type; #endif + /* Pipe process attached to the standard error of this process. */ + Lisp_Object stderrproc; + /* After this point, there are no Lisp_Objects any more. */ /* alloc.c assumes that `pid' is the first such non-Lisp slot. */ diff --git a/src/w32.c b/src/w32.c index 6f16704..8721ed9 100644 --- a/src/w32.c +++ b/src/w32.c @@ -9473,6 +9473,26 @@ serial_configure (struct Lisp_Process *p, Lisp_Object contact) pset_childp (p, childp2); } +/* For make-pipe-process */ +void +register_aux_fd (int infd) +{ + child_process *cp; + + cp = new_child (); + if (!cp) + error ("Could not create child process"); + cp->fd = infd; + cp->status = STATUS_READ_ACKNOWLEDGED; + + if (fd_info[ infd ].cp != NULL) + { + error ("fd_info[fd = %d] is already in use", infd); + } + fd_info[ infd ].cp = cp; + fd_info[ infd ].hnd = (HANDLE) _get_osfhandle (infd); +} + #ifdef HAVE_GNUTLS ssize_t diff --git a/src/w32.h b/src/w32.h index 9b3521d..e62b93c 100644 --- a/src/w32.h +++ b/src/w32.h @@ -202,6 +202,7 @@ extern int random (void); extern int fchmod (int, mode_t); extern int sys_rename_replace (char const *, char const *, BOOL); extern int pipe2 (int *, int); +extern void register_aux_fd (int); extern void set_process_dir (char *); extern int sys_spawnve (int, char *, char **, char **); diff --git a/test/automated/process-tests.el b/test/automated/process-tests.el index dabfbc5..1dab615 100644 --- a/test/automated/process-tests.el +++ b/test/automated/process-tests.el @@ -72,4 +72,74 @@ (should (string= (buffer-string) "arg1 = \"x &y\", arg2 = \n")))) (when batfile (delete-file batfile)))))) +(ert-deftest process-test-stderr-buffer () + (skip-unless (executable-find "bash")) + (let* ((stdout-buffer (generate-new-buffer "*stdout*")) + (stderr-buffer (generate-new-buffer "*stderr*")) + (proc (make-process :name "test" + :command (list "bash" "-c" + (concat "echo hello stdout!; " + "echo hello stderr! >&2; " + "exit 20")) + :buffer stdout-buffer + :stderr stderr-buffer)) + (sentinel-called nil) + (start-time (float-time))) + (set-process-sentinel proc (lambda (proc msg) + (setq sentinel-called t))) + (while (not (or sentinel-called + (> (- (float-time) start-time) + process-test-sentinel-wait-timeout))) + (accept-process-output)) + (cl-assert (eq (process-status proc) 'exit)) + (cl-assert (= (process-exit-status proc) 20)) + (should (with-current-buffer stdout-buffer + (goto-char (point-min)) + (looking-at "hello stdout!"))) + (should (with-current-buffer stderr-buffer + (goto-char (point-min)) + (looking-at "hello stderr!"))))) + +(ert-deftest process-test-stderr-filter () + (skip-unless (executable-find "bash")) + (let* ((sentinel-called nil) + (stderr-sentinel-called nil) + (stdout-output nil) + (stderr-output nil) + (stdout-buffer (generate-new-buffer "*stdout*")) + (stderr-buffer (generate-new-buffer "*stderr*")) + (stderr-proc (make-pipe-process :name "stderr" + :buffer stderr-buffer)) + (proc (make-process :name "test" :buffer stdout-buffer + :command (list "bash" "-c" + (concat "echo hello stdout!; " + "echo hello stderr! >&2; " + "exit 20")) + :stderr stderr-proc)) + (start-time (float-time))) + (set-process-filter proc (lambda (proc input) + (push input stdout-output))) + (set-process-sentinel proc (lambda (proc msg) + (setq sentinel-called t))) + (set-process-filter stderr-proc (lambda (proc input) + (push input stderr-output))) + (set-process-sentinel stderr-proc (lambda (proc input) + (setq stderr-sentinel-called t))) + (while (not (or sentinel-called + (> (- (float-time) start-time) + process-test-sentinel-wait-timeout))) + (accept-process-output)) + (cl-assert (eq (process-status proc) 'exit)) + (cl-assert (= (process-exit-status proc) 20)) + (should sentinel-called) + (should (equal 1 (with-current-buffer stdout-buffer + (point-max)))) + (should (equal "hello stdout!\n" + (mapconcat #'identity (nreverse stdout-output) ""))) + (should stderr-sentinel-called) + (should (equal 1 (with-current-buffer stderr-buffer + (point-max)))) + (should (equal "hello stderr!\n" + (mapconcat #'identity (nreverse stderr-output) ""))))) + (provide 'process-tests) commit a2940cd43e7931d16d3a3ce2cf5d4acd148dd00c Author: Paul Eggert Date: Fri Apr 10 11:27:21 2015 -0700 Minor quoting etc. fixes to lispref manual * doc/lispref/tips.texi (Documentation Tips): Distinguish more clearly among grave accent, apostrophe, and single quote. * doc/lispref/README, doc/lispref/buffers.texi: * doc/lispref/commands.texi, doc/lispref/control.texi: * doc/lispref/customize.texi, doc/lispref/display.texi: * doc/lispref/elisp.texi, doc/lispref/files.texi: * doc/lispref/frames.texi, doc/lispref/hash.texi: * doc/lispref/help.texi, doc/lispref/internals.texi: * doc/lispref/loading.texi, doc/lispref/makefile.w32-in: * doc/lispref/markers.texi, doc/lispref/modes.texi: * doc/lispref/nonascii.texi, doc/lispref/objects.texi: * doc/lispref/os.texi, doc/lispref/positions.texi: * doc/lispref/strings.texi, doc/lispref/syntax.texi: * doc/lispref/text.texi, doc/lispref/tips.texi: * doc/lispref/two-volume-cross-refs.txt, doc/lispref/windows.texi: Use American-style double quoting in ordinary text, and quote 'like this' when single-quoting in ASCII text. Also, fix some minor spacing issues. diff --git a/doc/lispref/README b/doc/lispref/README index 5ca18a8..fd943ce 100644 --- a/doc/lispref/README +++ b/doc/lispref/README @@ -21,15 +21,15 @@ Buying a manual from the Free Software Foundation helps support our GNU development work. See . (At time of writing, this manual is out of print.) -* The master file for formatting this manual for Tex is called `elisp.texi'. +* The master file for formatting this manual for Tex is called 'elisp.texi'. It contains @include commands to include all the chapters that make up the manual. * This distribution contains a Makefile that you can use with GNU Make. -** To make an Info file, you need to install Texinfo, then run `make info'. +** To make an Info file, you need to install Texinfo, then run 'make info'. -** Use `make elisp.pdf' or `make elisp.html' to create PDF or HTML versions. +** Use 'make elisp.pdf' or 'make elisp.html' to create PDF or HTML versions. This file is part of GNU Emacs. diff --git a/doc/lispref/buffers.texi b/doc/lispref/buffers.texi index 1c1c423..49bfe82 100644 --- a/doc/lispref/buffers.texi +++ b/doc/lispref/buffers.texi @@ -844,7 +844,7 @@ names start with a space are not considered at all. If @var{buffer} is not supplied (or if it is not a live buffer), then @code{other-buffer} returns the first buffer in the selected frame's -local buffer list. (If @var{frame} is non-@code{nil}, it returns the +local buffer list. (If @var{frame} is non-@code{nil}, it returns the first buffer in @var{frame}'s local buffer list instead.) If @var{frame} has a non-@code{nil} @code{buffer-predicate} parameter, diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index 5e986de..aec7674 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi @@ -1462,7 +1462,7 @@ the symbols @code{handle} (the scroll bar handle), @code{above-handle} (the area above the handle), @code{below-handle} (the area below the handle), @code{up} (the up arrow at one end of the scroll bar), or @code{down} (the down arrow at one end of the scroll bar). -@c The `top', `bottom', and `end-scroll' codes don't seem to be used. +@c The 'top', 'bottom', and 'end-scroll' codes don't seem to be used. @end table @@ -1720,7 +1720,7 @@ occurred. @vindex mouse-wheel-up-event @vindex mouse-wheel-down-event -This kind of event is generated only on some kinds of systems. On some +This kind of event is generated only on some kinds of systems. On some systems, @code{mouse-4} and @code{mouse-5} are used instead. For portable code, use the variables @code{mouse-wheel-up-event} and @code{mouse-wheel-down-event} defined in @file{mwheel.el} to determine @@ -1856,7 +1856,7 @@ into another window. That produces a pair of events like these: @end smallexample The frame with input focus might not take up the entire screen, and -the user might move the mouse outside the scope of the frame. Inside +the user might move the mouse outside the scope of the frame. Inside the @code{track-mouse} special form, that produces an event like this: @smallexample diff --git a/doc/lispref/control.texi b/doc/lispref/control.texi index f512ad9..fb2e1bc 100644 --- a/doc/lispref/control.texi +++ b/doc/lispref/control.texi @@ -1025,7 +1025,7 @@ the circumstances of the error. The argument @var{error-symbol} must be an @dfn{error symbol}---a symbol defined with @code{define-error}. This is how Emacs Lisp classifies different -sorts of errors. @xref{Error Symbols}, for a description of error symbols, +sorts of errors. @xref{Error Symbols}, for a description of error symbols, error conditions and condition names. If the error is not handled, the two arguments are used in printing diff --git a/doc/lispref/customize.texi b/doc/lispref/customize.texi index 0d1b6fa..f984dbe 100644 --- a/doc/lispref/customize.texi +++ b/doc/lispref/customize.texi @@ -842,7 +842,7 @@ symbols, and symbols are not treated like other Lisp expressions. @item (radio @var{element-types}@dots{}) This is similar to @code{choice}, except that the choices are displayed -using `radio buttons' rather than a menu. This has the advantage of +using ``radio buttons'' rather than a menu. This has the advantage of displaying documentation for the choices when applicable and so is often a good choice for a choice between constant functions (@code{function-item} customization types). diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index b73e70d..54fe437 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -2790,7 +2790,7 @@ then the new definition of the @code{mode-line} face inherits from the functions instead of setting @code{face-remapping-alist} directly, to avoid trampling on remappings applied elsewhere. These functions are intended for buffer-local remappings, so they all make -@code{face-remapping-alist} buffer-local as a side-effect. They manage +@code{face-remapping-alist} buffer-local as a side-effect. They manage @code{face-remapping-alist} entries of the form @example @@ -2820,11 +2820,11 @@ pass this object as an argument to @code{face-remap-remove-relative} if you need to remove the remapping later. @example -;; Remap the `escape-glyph' face into a combination -;; of the `highlight' and `italic' faces: +;; Remap the 'escape-glyph' face into a combination +;; of the 'highlight' and 'italic' faces: (face-remap-add-relative 'escape-glyph 'highlight 'italic) -;; Increase the size of the `default' face by 50%: +;; Increase the size of the 'default' face by 50%: (face-remap-add-relative 'default :height 1.5) @end example @end defun @@ -4557,7 +4557,7 @@ not affect the amount of raising or lowering, which is based on the faces used for the text. @end table -@c We put all the `@code{(when ...)}' on one line to encourage +@c We put all the '@code{(when ...)}' on one line to encourage @c makeinfo's end-of-sentence heuristics to DTRT. Previously, the dot @c was at eol; the info file ended up w/ two spaces rendered after it. You can make any display specification conditional. To do that, @@ -5628,7 +5628,7 @@ so that it's easy to define special-purpose types of buttons for specific tasks. @defun define-button-type name &rest properties -Define a `button type' called @var{name} (a symbol). +Define a ``button type'' called @var{name} (a symbol). The remaining arguments form a sequence of @var{property value} pairs, specifying default property values for buttons with this type (a button's type may be set @@ -5781,7 +5781,7 @@ Return @code{t} if button-type @var{type} is a subtype of @var{supertype}. These are commands and functions for locating and operating on buttons in an Emacs buffer. -@code{push-button} is the command that a user uses to actually `push' +@code{push-button} is the command that a user uses to actually ``push'' a button, and is bound by default in the button itself to @key{RET} and to @key{mouse-2} using a local keymap in the button's overlay or text properties. Commands that are useful outside the buttons itself, @@ -6643,7 +6643,7 @@ Non-@acronym{ASCII}, non-printing characters @code{U+0080} to @samp{\230}). @item format-control -Characters of Unicode General Category `Cf', such as @samp{U+200E} +Characters of Unicode General Category ``Cf'', such as @samp{U+200E} (Left-to-Right Mark), but excluding characters that have graphic images, such as @samp{U+00AD} (Soft Hyphen). @@ -6652,9 +6652,9 @@ Characters for there is no suitable font, or which cannot be encoded by the terminal's coding system. @end table -@c FIXME: this can also be `acronym', but that's not currently +@c FIXME: this can also be 'acronym', but that's not currently @c completely implemented; it applies only to the format-control -@c group, and only works if the acronym is in `char-acronym-table'. +@c group, and only works if the acronym is in 'char-acronym-table'. The @var{method} symbol should be one of @code{zero-width}, @code{thin-space}, @code{empty-box}, or @code{hex-code}. These have the same meanings as in @code{glyphless-char-display}, above. diff --git a/doc/lispref/elisp.texi b/doc/lispref/elisp.texi index fc8ba7b..bf1fc4d 100644 --- a/doc/lispref/elisp.texi +++ b/doc/lispref/elisp.texi @@ -247,9 +247,9 @@ Appendices @end ignore @c Do NOT modify the following 3 lines! They must have this form to -@c be correctly identified by `texinfo-multiple-files-update'. In +@c be correctly identified by 'texinfo-multiple-files-update'. In @c particular, the detailed menu header line MUST be identical to the -@c value of `texinfo-master-menu-header'. See texnfo-upd.el. +@c value of 'texinfo-master-menu-header'. See texnfo-upd.el. @detailmenu --- The Detailed Node Listing --- diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi index 2739e3e..f4c9abd 100644 --- a/doc/lispref/files.texi +++ b/doc/lispref/files.texi @@ -423,7 +423,7 @@ To do so, execute the following code: You might wish to save the file modes value returned by @code{backup-buffer} and use that (if non-@code{nil}) to set the mode bits of the file that you write. This is what @code{save-buffer} -normally does. @xref{Making Backups,, Making Backup Files}. +normally does. @xref{Making Backups,, Making Backup Files}. The hook functions in @code{write-file-functions} are also responsible for encoding the data (if desired): they must choose a suitable coding @@ -3352,8 +3352,8 @@ from the buffer is actually written to the file, it intermixes the specified annotations at the corresponding positions. All this takes place without modifying the buffer. -@c ??? What about ``overriding'' conversions like those allowed -@c ??? for `write-region-annotate-functions', below? --ttn +@c ??? What about "overriding" conversions like those allowed +@c ??? for 'write-region-annotate-functions', below? --ttn In contrast, when reading, the annotations intermixed with the text are handled immediately. @code{insert-file-contents} sets point to @@ -3406,8 +3406,8 @@ with one argument, the number of characters inserted, and with point at the beginning of the inserted text. Each function should leave point unchanged, and return the new character count describing the inserted text as modified by the function. -@c ??? The docstring mentions a handler from `file-name-handler-alist' -@c "intercepting" `insert-file-contents'. Hmmm. --ttn +@c ??? The docstring mentions a handler from 'file-name-handler-alist' +@c "intercepting" 'insert-file-contents'. Hmmm. --ttn @end defvar We invite users to write Lisp programs to store and retrieve text diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi index 85695c6..e19472e 100644 --- a/doc/lispref/frames.texi +++ b/doc/lispref/frames.texi @@ -2693,7 +2693,7 @@ This function returns @code{t} if the screen can display shades of gray. This function returns non-@code{nil} if all the face attributes in @var{attributes} are supported (@pxref{Face Attributes}). -The definition of `supported' is somewhat heuristic, but basically +The definition of ``supported'' is somewhat heuristic, but basically means that a face containing all the attributes in @var{attributes}, when merged with the default face for display, can be represented in a way that's @@ -2703,14 +2703,14 @@ way that's different in appearance than the default face, and @item -`close in spirit' to what the attributes specify, if not exact. +``close in spirit'' to what the attributes specify, if not exact. @end enumerate Point (2) implies that a @code{:weight black} attribute will be satisfied by any display that can display bold, as will @code{:foreground "yellow"} as long as some yellowish color can be displayed, but @code{:slant italic} will @emph{not} be satisfied by -the tty display code's automatic substitution of a `dim' face for +the tty display code's automatic substitution of a ``dim'' face for italic. @end defun diff --git a/doc/lispref/hash.texi b/doc/lispref/hash.texi index bfa60e0..98da321 100644 --- a/doc/lispref/hash.texi +++ b/doc/lispref/hash.texi @@ -154,7 +154,7 @@ This is equivalent to @code{make-hash-table}, but with a different style argument list. The argument @var{test} specifies the method of key lookup. -This function is obsolete. Use @code{make-hash-table} instead. +This function is obsolete. Use @code{make-hash-table} instead. @end defun You can also create a new hash table using the printed representation diff --git a/doc/lispref/help.texi b/doc/lispref/help.texi index 5b3dd58..868d284 100644 --- a/doc/lispref/help.texi +++ b/doc/lispref/help.texi @@ -171,7 +171,7 @@ several symbols in a @file{*Help*} buffer. (defun describe-symbols (pattern) "Describe the Emacs Lisp symbols matching PATTERN. All symbols that have PATTERN in their name are described -in the `*Help*' buffer." +in the *Help* buffer." (interactive "sDescribe symbols matching: ") (let ((describe-func (function diff --git a/doc/lispref/internals.texi b/doc/lispref/internals.texi index a5fff72..0b8e288 100644 --- a/doc/lispref/internals.texi +++ b/doc/lispref/internals.texi @@ -898,14 +898,14 @@ DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p, @group switch (coordinates_in_window (w, x, y)) @{ - case ON_NOTHING: /* NOT in window at all. */ + case ON_NOTHING: /* NOT in window at all. */ return Qnil; @end group ... @group - case ON_MODE_LINE: /* In mode line of window. */ + case ON_MODE_LINE: /* In mode line of window. */ return Qmode_line; @end group @@ -1317,8 +1317,8 @@ except to shape their child windows. Emacs Lisp programs usually have no access to the parent windows; they operate on the windows at the leaves of the tree, which actually display buffers. -@c FIXME: These two slots and the `buffer' slot below were replaced -@c with a single slot `contents' on 2013-03-28. --xfq +@c FIXME: These two slots and the 'buffer' slot below were replaced +@c with a single slot 'contents' on 2013-03-28. --xfq @item hchild @itemx vchild These fields contain the window's leftmost child and its topmost child diff --git a/doc/lispref/loading.texi b/doc/lispref/loading.texi index 0ae8fbd..fc1def6 100644 --- a/doc/lispref/loading.texi +++ b/doc/lispref/loading.texi @@ -76,7 +76,7 @@ If Auto Compression mode is enabled, as it is by default, then if of the file before trying other file names. It decompresses and loads it if it exists. It looks for compressed versions by appending each of the suffixes in @code{jka-compr-load-suffixes} to the file name. -The value of this variable must be a list of strings. Its standard +The value of this variable must be a list of strings. Its standard value is @code{(".gz")}. If the optional argument @var{nosuffix} is non-@code{nil}, then diff --git a/doc/lispref/makefile.w32-in b/doc/lispref/makefile.w32-in index 4185629..c30d6e2 100644 --- a/doc/lispref/makefile.w32-in +++ b/doc/lispref/makefile.w32-in @@ -31,7 +31,7 @@ texinfodir = $(srcdir)/../misc INFO_EXT=.info INFO_OPTS=--no-split -# Redefine `TEX' if `tex' does not invoke plain TeX. For example: +# Redefine 'TEX' if 'tex' does not invoke plain TeX. For example: # TEX=platex TEX=tex INSTALL_INFO = install-info @@ -102,7 +102,7 @@ srcs = \ .PHONY: clean -# The info file is named `elisp'. +# The info file is named 'elisp'. info: $(infodir)/elisp$(INFO_EXT) diff --git a/doc/lispref/markers.texi b/doc/lispref/markers.texi index 48ac9f0..109e935 100644 --- a/doc/lispref/markers.texi +++ b/doc/lispref/markers.texi @@ -287,8 +287,8 @@ This function returns the position that @var{marker} points to, or This function returns the buffer that @var{marker} points into, or @code{nil} if it points nowhere. -@c FIXME: The `buffer' argument of `set-marker' already defaults to -@c the current buffer, why use `(current-buffer)' explicitly here? +@c FIXME: The 'buffer' argument of 'set-marker' already defaults to +@c the current buffer, why use '(current-buffer)' explicitly here? @example @group (setq m (make-marker)) @@ -712,4 +712,3 @@ A region is valid if it has a non-zero size, or if the user option cases, you should not use @code{region-active-p}, since if the region is empty it is often more appropriate to operate on point. @end defun - diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index bc247a9..8cb0f3d 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -749,7 +749,7 @@ The new mode has its own abbrev table, kept in the variable @item The new mode has its own mode hook, @code{@var{variant}-hook}. It runs this hook, after running the hooks of its ancestor modes, with -@code{run-mode-hooks}, as the last thing it does. @xref{Mode Hooks}. +@code{run-mode-hooks}, as the last thing it does. @xref{Mode Hooks}. @end itemize In addition, you can specify how to override other aspects of @@ -1122,7 +1122,7 @@ the conventions listed above: (let ((st (make-syntax-table))) (modify-syntax-entry ?\" ". " st) (modify-syntax-entry ?\\ ". " st) - ;; Add `p' so M-c on `hello' leads to `Hello', not `hello'. + ;; Add 'p' so M-c on 'hello' leads to 'Hello', not 'hello'. (modify-syntax-entry ?' "w p" st) st) "Syntax table used while in `text-mode'.") @@ -3425,7 +3425,7 @@ provided grammar is precise enough, @code{transpose-sexps} can correctly transpose the two arguments of a @code{+} operator, taking into account the precedence rules of the language. -Calling `smie-setup' is also sufficient to make TAB indentation work in +Calling @code{smie-setup} is also sufficient to make TAB indentation work in the expected way, extends @code{blink-matching-paren} to apply to elements like @code{begin...end}, and provides some commands that you can bind in the major mode keymap. @@ -3874,7 +3874,7 @@ of instructions (enclosed in a @code{@{...@}} or @code{begin...end} block). @var{method} should be the method name that was passed to -`smie-rules-function'. +@code{smie-rules-function}. @end defun @node SMIE Indentation Example diff --git a/doc/lispref/nonascii.texi b/doc/lispref/nonascii.texi index 50e50ff..05d5ca4 100644 --- a/doc/lispref/nonascii.texi +++ b/doc/lispref/nonascii.texi @@ -248,7 +248,7 @@ unibyte string, it is returned unchanged. Use this function for characters. @end defun -@c FIXME: Should `@var{character}' be `@var{byte}'? +@c FIXME: Should '@var{character}' be '@var{byte}'? @defun byte-to-string byte @cindex byte to string This function returns a unibyte string containing a single byte of @@ -1375,7 +1375,7 @@ alternatives described above. The optional argument @var{accept-default-p}, if non-@code{nil}, should be a function to determine whether a coding system selected -without user interaction is acceptable. @code{select-safe-coding-system} +without user interaction is acceptable. @code{select-safe-coding-system} calls this function with one argument, the base coding system of the selected coding system. If @var{accept-default-p} returns @code{nil}, @code{select-safe-coding-system} rejects the silently selected coding @@ -1437,7 +1437,7 @@ don't change these variables; instead, override them using @cindex file contents, and default coding system @defopt auto-coding-regexp-alist This variable is an alist of text patterns and corresponding coding -systems. Each element has the form @code{(@var{regexp} +systems. Each element has the form @code{(@var{regexp} . @var{coding-system})}; a file whose first few kilobytes match @var{regexp} is decoded with @var{coding-system} when its contents are read into a buffer. The settings in this alist take priority over diff --git a/doc/lispref/objects.texi b/doc/lispref/objects.texi index f4beca8..c7d71d2 100644 --- a/doc/lispref/objects.texi +++ b/doc/lispref/objects.texi @@ -595,8 +595,8 @@ FOO ; @r{A symbol named @samp{FOO}, different from @samp{foo}.} @cindex @samp{##} read syntax @ifinfo -@c This uses ``colon'' instead of a literal `:' because Info cannot -@c cope with a `:' in a menu +@c This uses "colon" instead of a literal ':' because Info cannot +@c cope with a ':' in a menu. @cindex @samp{#@var{colon}} read syntax @end ifinfo @ifnotinfo @@ -999,7 +999,7 @@ of a string returns the same string. The read syntax for a string is a double-quote, an arbitrary number of characters, and another double-quote, @code{"like this"}. To include a double-quote in a string, precede it with a backslash; thus, -@code{"\""} is a string containing just a single double-quote +@code{"\""} is a string containing just one double-quote character. Likewise, you can include a backslash by preceding it with another backslash, like this: @code{"this \\ is a single embedded backslash"}. diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi index 4df4a59..97fa083 100644 --- a/doc/lispref/os.texi +++ b/doc/lispref/os.texi @@ -974,7 +974,7 @@ to access the value of @var{variable}. If @var{value} is omitted or removes @var{variable} from the environment. Otherwise, @var{value} should be a string. -@c FIXME: Document `substitute-env-vars'? --xfq +@c FIXME: Document 'substitute-env-vars'? --xfq If the optional argument @var{substitute} is non-@code{nil}, Emacs calls the function @code{substitute-env-vars} to expand any environment variables in @var{value}. @@ -2384,7 +2384,7 @@ The path to a sound file to play when the notification pops up. @item :sound-name @var{name} A themable named sound from the freedesktop.org sound naming specification from @samp{$XDG_DATA_DIRS/sounds}, to play when the -notification pops up. Similar to the icon name, only for sounds. An +notification pops up. Similar to the icon name, only for sounds. An example would be @samp{"message-new-instant"}. @item :suppress-sound @@ -2393,9 +2393,9 @@ ability. @item :resident When set the server will not automatically remove the notification -when an action has been invoked. The notification will remain resident +when an action has been invoked. The notification will remain resident in the server until it is explicitly removed by the user or by the -sender. This hint is likely only useful when the server has the +sender. This hint is likely only useful when the server has the @code{:persistence} capability. @item :transient diff --git a/doc/lispref/positions.texi b/doc/lispref/positions.texi index 103161c..fc47f1c 100644 --- a/doc/lispref/positions.texi +++ b/doc/lispref/positions.texi @@ -664,7 +664,7 @@ quotes are ignored.) This function moves forward out of @var{arg} (default 1) levels of parentheses. A negative argument means move backward but still to a less deep spot. If @var{escape-strings} is non-@code{nil} (as it is -interactively), move out of enclosing strings as well. If +interactively), move out of enclosing strings as well. If @var{no-syntax-crossing} is non-@code{nil} (as it is interactively), prefer to break out of any enclosing string instead of moving to the start of a list broken across multiple strings. On error, location of point is diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi index aca6189..c2f0607 100644 --- a/doc/lispref/strings.texi +++ b/doc/lispref/strings.texi @@ -956,12 +956,12 @@ is not truncated. @example @group -(format "The word `%7s' has %d letters in it." +(format "The word '%7s' has %d letters in it." "foo" (length "foo")) - @result{} "The word ` foo' has 3 letters in it." -(format "The word `%7s' has %d letters in it." + @result{} "The word ' foo' has 3 letters in it." +(format "The word '%7s' has %d letters in it." "specification" (length "specification")) - @result{} "The word `specification' has 13 letters in it." + @result{} "The word 'specification' has 13 letters in it." @end group @end example @@ -1003,9 +1003,9 @@ ignored. (format "%-6d is padded on the right" 123) @result{} "123 is padded on the right" -(format "The word `%-7s' actually has %d letters in it." +(format "The word '%-7s' actually has %d letters in it." "foo" (length "foo")) - @result{} "The word `foo ' actually has 3 letters in it." + @result{} "The word 'foo ' actually has 3 letters in it." @end group @end example diff --git a/doc/lispref/syntax.texi b/doc/lispref/syntax.texi index 1f1dd6e..90daf34 100644 --- a/doc/lispref/syntax.texi +++ b/doc/lispref/syntax.texi @@ -203,7 +203,7 @@ suppressed. The Lisp modes have two string quote characters: double-quote (@samp{"}) and vertical bar (@samp{|}). @samp{|} is not used in Emacs Lisp, but it is used in Common Lisp. C also has two string quote characters: -double-quote for strings, and single-quote (@samp{'}) for character +double-quote for strings, and apostrophe (@samp{'}) for character constants. Human text has no string quote characters. We do not want quotation diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index da67ec2..d4b6950 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi @@ -512,7 +512,7 @@ non-@code{nil} and the character inserted is in the table @c Cross refs reworded to prevent overfull hbox. --rjc 15mar92 This command performs abbrev expansion if Abbrev mode is enabled and the inserted character does not have word-constituent -syntax. (@xref{Abbrevs}, and @ref{Syntax Class Table}.) It is also +syntax. (@xref{Abbrevs}, and @ref{Syntax Class Table}.) It is also responsible for calling @code{blink-paren-function} when the inserted character has close parenthesis syntax (@pxref{Blinking}). diff --git a/doc/lispref/tips.texi b/doc/lispref/tips.texi index 8970efe..cc1f0e4 100644 --- a/doc/lispref/tips.texi +++ b/doc/lispref/tips.texi @@ -657,23 +657,18 @@ starting double-quote is not part of the string! @anchor{Docstring hyperlinks} @item -@iftex When a documentation string refers to a Lisp symbol, write it as it -would be printed (which usually means in lower case), with single-quotes -around it. For example: @samp{`lambda'}. There are two exceptions: -write @code{t} and @code{nil} without single-quotes. -@end iftex -@ifnottex -When a documentation string refers to a Lisp symbol, write it as it -would be printed (which usually means in lower case), with single-quotes -around it. For example: @samp{lambda}. There are two exceptions: write -t and nil without single-quotes. (In this manual, we use a different -convention, with single-quotes for all symbols.) -@end ifnottex +would be printed (which usually means in lower case), with a grave +accent @samp{`} before and apostrophe @samp{'} after it. There are +two exceptions: write @code{t} and @code{nil} without surrounding +punctuation. For example: @samp{CODE can be `lambda', nil, or t.} +(In this manual, we use a different convention, with single-quotes +around symbols.) @cindex hyperlinks in documentation strings Help mode automatically creates a hyperlink when a documentation string -uses a symbol name inside single quotes, if the symbol has either a +uses a symbol name between grave accent and apostrophe, if the symbol +has either a function or a variable definition. You do not need to do anything special to make use of this feature. However, when a symbol has both a function definition and a variable definition, and you want to refer to @@ -716,16 +711,16 @@ documentation will be shown, even if the symbol is also defined as a variable or as a function. To make a hyperlink to Info documentation, write the name of the Info -node (or anchor) in single quotes, preceded by @samp{info node}, -@samp{Info node}, @samp{info anchor} or @samp{Info anchor}. The Info -file name defaults to @samp{emacs}. For example, +node (or anchor) between grave accent and apostrophe, preceded by +@samp{info node}, @samp{Info node}, @samp{info anchor} or @samp{Info +anchor}. The Info file name defaults to @samp{emacs}. For example, @smallexample See Info node `Font Lock' and Info node `(elisp)Font Lock Basics'. @end smallexample -Finally, to create a hyperlink to URLs, write the URL in single -quotes, preceded by @samp{URL}. For example, +Finally, to create a hyperlink to URLs, write the URL between grave +accent and apostrophe, preceded by @samp{URL}. For example, @smallexample The home page for the GNU project has more information (see URL diff --git a/doc/lispref/two-volume-cross-refs.txt b/doc/lispref/two-volume-cross-refs.txt index eded8c4..89336e1 100644 --- a/doc/lispref/two-volume-cross-refs.txt +++ b/doc/lispref/two-volume-cross-refs.txt @@ -108,8 +108,8 @@ on elisp2-fn-vol-number-added (volume-index-markup "II") to create elisp2-fn-vol-number-added -insert elisp2-fn-vol-number-added into vol1.fn: do following `cat' -insert elisp1-fn-vol-number-added into vol2.fn: do following `cat' +insert elisp2-fn-vol-number-added into vol1.fn: do following 'cat' +insert elisp1-fn-vol-number-added into vol2.fn: do following 'cat' % cat elisp2-fn-vol-number-added >> vol1.fn % cat elisp1-fn-vol-number-added >> vol2.fn @@ -126,7 +126,7 @@ Be sure that .fn file has no blank lines. ### Create merged .toc file with volume number headings. -append vol2.toc to vol1.toc with following `cat' +append vol2.toc to vol1.toc with following 'cat' % cat vol1.toc vol2.toc > elisp-toc-2vol.toc diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi index 8d6e124..6da3582 100644 --- a/doc/lispref/windows.texi +++ b/doc/lispref/windows.texi @@ -2412,7 +2412,7 @@ the window split and the values of and @code{split-width-threshold} (@pxref{Choosing Window Options}). Now suppose we combine this call with a preexisting setup for -`display-buffer-alist' as follows. +@code{display-buffer-alist} as follows. @example @group commit ca401f6fdc512f79d6015c1759a0e8e0c3de5c9a Author: Michael Albinus Date: Fri Apr 10 12:53:01 2015 +0200 Handle symlinked test directory in tramp-tests.el * test/automated/tramp-tests.el (tramp-test18-file-attributes) (tramp--test-check-files): Use `file-truename' for directories. diff --git a/test/automated/tramp-tests.el b/test/automated/tramp-tests.el index cc2c753..5bb05dc 100644 --- a/test/automated/tramp-tests.el +++ b/test/automated/tramp-tests.el @@ -981,9 +981,14 @@ This tests also `file-directory-p' and `file-accessible-directory-p'." This tests also `file-readable-p' and `file-regular-p'." (skip-unless (tramp--test-enabled)) - (let ((tmp-name1 (tramp--test-make-temp-name)) - (tmp-name2 (tramp--test-make-temp-name)) - attr) + ;; We must use `file-truename' for the temporary directory, because + ;; it could be located on a symlinked directory. This would let the + ;; test fail. + (let* ((tramp-test-temporary-file-directory + (file-truename tramp-test-temporary-file-directory)) + (tmp-name1 (tramp--test-make-temp-name)) + (tmp-name2 (tramp--test-make-temp-name)) + attr) (unwind-protect (progn (write-region "foo" nil tmp-name1) @@ -1535,9 +1540,14 @@ This requires restrictions of file name syntax." (defun tramp--test-check-files (&rest files) "Run a simple but comprehensive test over every file in FILES." - (let ((tmp-name1 (tramp--test-make-temp-name)) - (tmp-name2 (tramp--test-make-temp-name 'local)) - (files (delq nil files))) + ;; We must use `file-truename' for the temporary directory, because + ;; it could be located on a symlinked directory. This would let the + ;; test fail. + (let* ((tramp-test-temporary-file-directory + (file-truename tramp-test-temporary-file-directory)) + (tmp-name1 (tramp--test-make-temp-name)) + (tmp-name2 (tramp--test-make-temp-name 'local)) + (files (delq nil files))) (unwind-protect (progn (make-directory tmp-name1) commit 5aed69af5e224bdaf38b3f890e57864f8435b4f5 Author: Eli Zaretskii Date: Fri Apr 10 13:09:42 2015 +0300 Fix 'recenter' when visual-line-mode is turned on * src/window.c (Frecenter): Use the same code for GUI and TTY frames alike; use vmotion only for "initial" frames. This is because vmotion doesn't support visual-line-mode. Rewrite the 'iarg >= 0' case to use move_it_* functions instead of using vmotion, for the same reason. Fix the clipping of the argument value to support scroll-margin in all cases and avoid unwarranted recentering. Reported by Milan Stanojević in http://lists.gnu.org/archive/html/help-gnu-emacs/2015-04/msg00092.html, which see. diff --git a/src/window.c b/src/window.c index d59616d..55fcb8c 100644 --- a/src/window.c +++ b/src/window.c @@ -5799,10 +5799,9 @@ and redisplay normally--don't erase and redraw the frame. */) this_scroll_margin = max (0, min (scroll_margin, w->total_lines / 4)); - /* Handle centering on a graphical frame specially. Such frames can - have variable-height lines and centering point on the basis of - line counts would lead to strange effects. */ - if (FRAME_WINDOW_P (XFRAME (w->frame))) + /* Don't use redisplay code for initial frames, as the necessary + data structures might not be set up yet then. */ + if (!FRAME_INITIAL_P (XFRAME (w->frame))) { if (center_p) { @@ -5824,9 +5823,11 @@ and redisplay normally--don't erase and redraw the frame. */) ptrdiff_t nlines = min (PTRDIFF_MAX, -iarg); int extra_line_spacing; int h = window_box_height (w); + int ht = window_internal_height (w); void *itdata = bidi_shelve_cache (); - iarg = - max (-iarg, this_scroll_margin); + nlines = clip_to_bounds (this_scroll_margin + 1, nlines, + ht - this_scroll_margin); SET_TEXT_POS (pt, PT, PT_BYTE); start_display (&it, w, pt); @@ -5890,13 +5891,33 @@ and redisplay normally--don't erase and redraw the frame. */) } else { - struct position pos; + struct it it; + struct text_pos pt; + ptrdiff_t nlines = min (PTRDIFF_MAX, iarg); + int ht = window_internal_height (w); + void *itdata = bidi_shelve_cache (); + + nlines = clip_to_bounds (this_scroll_margin, nlines, + ht - this_scroll_margin - 1); + + SET_TEXT_POS (pt, PT, PT_BYTE); + start_display (&it, w, pt); - iarg = max (iarg, this_scroll_margin); + /* Move to the beginning of screen line containing PT. */ + move_it_by_lines (&it, 0); + + /* Move back to find the point which is ARG screen lines above PT. */ + if (nlines > 0) + { + it.current_y = 0; + it.vpos = 0; + move_it_by_lines (&it, -nlines); + } - pos = *vmotion (PT, PT_BYTE, -iarg, w); - charpos = pos.bufpos; - bytepos = pos.bytepos; + charpos = IT_CHARPOS (it); + bytepos = IT_BYTEPOS (it); + + bidi_unshelve_cache (itdata, 0); } } else