commit 89ce83b20249dfb4e45f09dfdddf4c4b66d82968 (HEAD, refs/remotes/origin/master) Merge: d546ed1 50650cb Author: Paul Eggert Date: Thu May 5 23:11:11 2016 -0700 Merge from origin/emacs-25 50650cb Doc fixes for fclist and grep 5e814e0 Minor doc fixes for quoting 3347a73 `nreverse' the marker pairs list 1a4127d Use save-excursion in xref-location-marker more ab3ba91 shell-quote-argument DIR when appropriate 922c7a3 Rework xref-query-replace-in-results 3fe3510 * lisp/replace.el (query-replace-read-from): Use minibuffer-w... 0932b94 Fix todo-mode bug involving archived items (bug#23447) e68ad1f ; * etc/NEWS: Tiny edit. (Bug#23432) adc80b7 ; * test/automated/xref-tests.el: Add copyright and license. 4d8fd9c Handle "empty line" regexp in xref searches f559b37 Add tests for xref-collect-matches 6428aa0 Use grep-find-ignored-directories instead of vc-directory-exc... 6f82d8e Clear buffer-undo-list when showing xrefs c68a091 Note the quote translation in `message' in section "incompati... 52f86a7 * etc/NEWS: Mention (message "%s" (format ...)). 93703c5 (Common Keywords): Correct what missing :group means 79e5800 Improve documentation of Dired's 'A' and 'Q' commands 2ea2a2f Doc fixes for quoting 8544b98 posnp doc clarification 805204f Mention what a missing :group does ec554d7 Fix documentation of dired-aux search/replace commands commit 50650cb6887d99b01eeb1e686fc1f695c2a0c64a Author: Paul Eggert Date: Thu May 5 12:48:33 2016 -0700 Doc fixes for fclist and grep A newline is needed between two fc-list calls. egrep and fgrep have been withdrawn from POSIX, so document grep -E and grep -F instead. diff --git a/doc/emacs/frames.texi b/doc/emacs/frames.texi index 23ccd6a..a7e709f 100644 --- a/doc/emacs/frames.texi +++ b/doc/emacs/frames.texi @@ -764,7 +764,8 @@ Fontconfig fonts, you can use the @command{fc-list} command to list the available fixed-width fonts, like this: @example -fc-list :spacing=mono fc-list :spacing=charcell +fc-list :spacing=mono +fc-list :spacing=charcell @end example @noindent @@ -772,7 +773,7 @@ For server-side X fonts, you can use the @command{xlsfonts} program to list the available fixed-width fonts, like this: @example -xlsfonts -fn '*x*' | egrep "^[0-9]+x[0-9]+" +xlsfonts -fn '*x*' | grep -E '^[0-9]+x[0-9]+' xlsfonts -fn '*-*-*-*-*-*-*-*-*-*-*-m*' xlsfonts -fn '*-*-*-*-*-*-*-*-*-*-*-c*' @end example diff --git a/etc/PROBLEMS b/etc/PROBLEMS index be9400b..533c4e9 100644 --- a/etc/PROBLEMS +++ b/etc/PROBLEMS @@ -1655,7 +1655,7 @@ which combination produces "M-x" in the echo area. You can also use the 'xmodmap' utility to show all the keys which produce a Meta modifier: - xmodmap -pk | egrep -i "meta|alt" + xmodmap -pk | grep -Ei "meta|alt" A more convenient way of finding out which keys produce a Meta modifier is to use the 'xkbprint' utility, if it's available on your system: diff --git a/lisp/cedet/cedet-cscope.el b/lisp/cedet/cedet-cscope.el index 9a54d34..373149c 100644 --- a/lisp/cedet/cedet-cscope.el +++ b/lisp/cedet/cedet-cscope.el @@ -52,7 +52,7 @@ SCOPE is the scope of the search, such as 'project or 'subdirs." ;; -0 = Find C symbol ;; -1 = Find global definition ;; -3 = Find references - ;; -6 = Find egrep pattern + ;; -6 = Find grep -E pattern ;; -7 = Find file (let ((idx (cond ((eq type 'file) "-7") diff --git a/lisp/cedet/semantic/symref.el b/lisp/cedet/semantic/symref.el index 088740b..516a4f3 100644 --- a/lisp/cedet/semantic/symref.el +++ b/lisp/cedet/semantic/symref.el @@ -266,7 +266,7 @@ Returns an object of class `semantic-symref-result'." ;;;###autoload (defun semantic-symref-find-text (text &optional scope) "Find a list of occurrences of TEXT in the current project. -TEXT is a regexp formatted for use with egrep. +TEXT is a regexp formatted for use with grep -E. Optional SCOPE specifies which file set to search. Defaults to `project'. Refers to `semantic-symref-tool', to determine the reference tool to use for the current buffer. diff --git a/lisp/man.el b/lisp/man.el index 2b2ee99..5acf90b 100644 --- a/lisp/man.el +++ b/lisp/man.el @@ -964,7 +964,7 @@ otherwise look like a page name. An \"apropos\" query with -k gives a buffer of matching page names or descriptions. The pattern argument is usually an -\"egrep\" style regexp. +\"grep -E\" style regexp. -k pattern" diff --git a/src/bidi.c b/src/bidi.c index c23ff95..573e513 100644 --- a/src/bidi.c +++ b/src/bidi.c @@ -2498,10 +2498,10 @@ typedef struct bpa_stack_entry { And finally, cross-reference these two: - fgrep -w -f brackets.txt decompositions.txt + grep -Fw -f brackets.txt decompositions.txt where "decompositions.txt" was produced by the 1st script, and - "brackets.txt" by the 2nd script. In the output of fgrep, look + "brackets.txt" by the 2nd script. In the output of grep, look only for decompositions that don't begin with some compatibility formatting tag, such as "". Only decompositions that consist solely of character codepoints are relevant to bidi commit d546ed13b04521308ef7ec8e7e5b68e03f1bbb38 Author: Simen Heggestøyl Date: Thu May 5 21:21:10 2016 +0200 Support completion of HTML tags in CSS selectors * lisp/textmodes/css-mode.el (css--html-tags): New variable holding a list of HTML tags for completion. (css--nested-selectors-allowed): New variable for determining whether nested selectors are allowed in the current mode. (css--complete-selector): New function for completing part of a CSS selector. (css-completion-at-point): Support completion of selectors. (scss-mode): Allow nested selectors. diff --git a/etc/NEWS b/etc/NEWS index 21602ff..e202612 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -282,8 +282,8 @@ different group ID. ** CSS mode --- -*** Support for completing attribute values and bang-rules using the -'completion-at-point' command. +*** Support for completing attribute values, at-rules, bang-rules, and +HTML tags using the 'completion-at-point' command. +++ ** Emacs now supports character name escape sequences in character and diff --git a/lisp/textmodes/css-mode.el b/lisp/textmodes/css-mode.el index e30fb3e..cf407ef 100644 --- a/lisp/textmodes/css-mode.el +++ b/lisp/textmodes/css-mode.el @@ -30,10 +30,12 @@ ;; - electric ; and } ;; - filling code with auto-fill-mode ;; - fix font-lock errors with multi-line selectors +;; - support completion of user-defined classes names and IDs ;;; Code: (require 'seq) +(require 'sgml-mode) (require 'smie) (defgroup css nil @@ -824,15 +826,40 @@ the string PROPERTY." (list (point) end (cons "inherit" (css--property-values property)))))))) +(defvar css--html-tags (mapcar #'car html-tag-alist) + "List of HTML tags. +Used to provide completion of HTML tags in selectors.") + +(defvar css--nested-selectors-allowed nil + "Non-nil if nested selectors are allowed in the current mode.") +(make-variable-buffer-local 'css--nested-selectors-allowed) + +;; TODO: Currently only supports completion of HTML tags. By looking +;; at open HTML mode buffers we should be able to provide completion +;; of user-defined classes and IDs too. +(defun css--complete-selector () + "Complete part of a CSS selector at point." + (when (or (= (nth 0 (syntax-ppss)) 0) css--nested-selectors-allowed) + (save-excursion + (let ((end (point))) + (skip-chars-backward "-[:alnum:]") + (list (point) end css--html-tags))))) + (defun css-completion-at-point () "Complete current symbol at point. Currently supports completion of CSS properties, property values, pseudo-elements, pseudo-classes, at-rules, and bang-rules." - (or (css--complete-property) - (css--complete-bang-rule) + (or (css--complete-bang-rule) (css--complete-property-value) (css--complete-pseudo-element-or-class) - (css--complete-at-rule))) + (css--complete-at-rule) + (seq-let (prop-beg prop-end prop-table) (css--complete-property) + (seq-let (sel-beg sel-end sel-table) (css--complete-selector) + (when (or prop-table sel-table) + `(,@(if prop-table + (list prop-beg prop-end) + (list sel-beg sel-end)) + ,(completion-table-merge prop-table sel-table))))))) ;;;###autoload (define-derived-mode css-mode prog-mode "CSS" @@ -990,6 +1017,7 @@ pseudo-elements, pseudo-classes, at-rules, and bang-rules." (setq-local comment-end-skip "[ \t]*\\(?:\n\\|\\*+/\\)") (setq-local css--at-ids (append css-at-ids scss-at-ids)) (setq-local css--bang-ids (append css-bang-ids scss-bang-ids)) + (setq-local css--nested-selectors-allowed t) (setq-local font-lock-defaults (list (scss-font-lock-keywords) nil t))) commit 67fa7f13d499eb5fc1d697da6c636b20728da22f Author: Lars Ingebrigtsen Date: Thu May 5 19:41:11 2016 +0200 Make `R' in eww work more reliably * lisp/net/eww.el (eww-score-readability): Protect against null children. diff --git a/lisp/net/eww.el b/lisp/net/eww.el index 34cb02c..6a84003 100644 --- a/lisp/net/eww.el +++ b/lisp/net/eww.el @@ -669,11 +669,13 @@ the like." (setq score (- (length (split-string (dom-text node)))))) (t (dolist (elem (dom-children node)) - (if (stringp elem) - (setq score (+ score (length (split-string elem)))) + (cond + ((stringp elem) + (setq score (+ score (length (split-string elem))))) + ((consp elem) (setq score (+ score (or (cdr (assoc :eww-readability-score (cdr elem))) - (eww-score-readability elem)))))))) + (eww-score-readability elem))))))))) ;; Cache the score of the node to avoid recomputing all the time. (dom-set-attribute node :eww-readability-score score) score)) commit 5e814e02f0b0b85fa486975eced09e4a7ed8ce5c Author: Paul Eggert Date: Thu May 5 06:39:17 2016 -0700 Minor doc fixes for quoting * doc/lispref/control.texi (Signaling Errors): * doc/lispref/display.texi (Displaying Messages): Don’t say that formats “generate”. Try to word more clearly. * etc/NEWS: Coalesce near-duplicate entries. diff --git a/doc/lispref/control.texi b/doc/lispref/control.texi index 75d8d28..0cdb035 100644 --- a/doc/lispref/control.texi +++ b/doc/lispref/control.texi @@ -1100,12 +1100,13 @@ These examples show typical uses of @code{error}: error symbol @code{error}, and a list containing the string returned by @code{format-message}. -A format that quotes with grave accents and apostrophes @t{`like -this'} typically generates curved quotes @t{‘like this’}. In -contrast, a format that quotes with only apostrophes @t{'like this'} -typically generates two closing curved quotes @t{’like this’}, an -unusual style in English. @xref{Keys in Documentation}, for how the -@code{text-quoting-style} variable affects generated quotes. +The @code{text-quoting-style} variable controls what quotes are +generated; @xref{Keys in Documentation}. A call using a format like +@t{"Missing `%s'"} with grave accents and apostrophes typically +generates a message like @t{"Missing ‘foo’"} with matching curved +quotes. In contrast, a call using a format like @t{"Missing '%s'"} +with only apostrophes typically generates a message like @t{"Missing +’foo’"} with only closing curved quotes, an unusual style in English. @strong{Warning:} If you want to use your own string as an error message verbatim, don't just write @code{(error @var{string})}. If @var{string} diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index b0cd873..181bff0 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -265,12 +265,13 @@ properties, it is displayed with the specified faces (@pxref{Faces}). The string is also added to the @file{*Messages*} buffer, but without text properties (@pxref{Logging Messages}). -A format that quotes with grave accents and apostrophes @t{`like -this'} typically generates curved quotes @t{‘like this’}. In -contrast, a format that quotes with only apostrophes @t{'like this'} -typically generates two closing curved quotes @t{’like this’}, an -unusual style in English. @xref{Keys in Documentation}, for how the -@code{text-quoting-style} variable affects generated quotes. +The @code{text-quoting-style} variable controls what quotes are +generated; @xref{Keys in Documentation}. A call using a format like +@t{"Missing `%s'"} with grave accents and apostrophes typically +generates a message like @t{"Missing ‘foo’"} with matching curved +quotes. In contrast, a call using a format like @t{"Missing '%s'"} +with only apostrophes typically generates a message like @t{"Missing +’foo’"} with only closing curved quotes, an unusual style in English. In batch mode, the message is printed to the standard error stream, followed by a newline. diff --git a/etc/NEWS b/etc/NEWS index 7d6e533..6c522e0 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1476,11 +1476,12 @@ display of diagnostics and help, but not of info. As the variable is not intended for casual use, it is not a user option. +++ -** `message' now translates various sorts of single quotes in its -format string according to the value of `text-quoting-style' (see -above). This translation cannot be disabled. To get the old -behavior of `message', use `format', which is not affected by -`text-quoting-style', e.g. (message "%s" (format "...." foo bar)). +** Message-issuing functions like 'message' and 'error' now translate +various sorts of single quotes in their format strings according to +the value of 'text-quoting-style' (see above). This translation +cannot be disabled. To get the old behavior, use 'format', which is +not affected by 'text-quoting-style', e.g., (message "%s" (format +"...." foo bar)). +++ ** substitute-command-keys now replaces quotes. @@ -1490,14 +1491,6 @@ either curved single quotes or grave accents and apostrophes. As before, characters preceded by \= are output as-is. +++ -** Message-issuing functions 'error', 'message', etc. now convert quotes. -They use the new 'format-message' function instead of plain 'format', -so that they now follow user preference as per 'text-quoting-style' -when processing curved single quotes, grave accents, and apostrophes -in their format argument. To process % directives but not quotes, you -can use calls like (message "%s" (format FORMAT ARG1 ... ARGn)). - -+++ ** The character classes [:alpha:] and [:alnum:] in regular expressions now match multibyte characters using Unicode character properties. If you want the old behavior where they matched any character with commit 3347a733e0778dfefaeabe28ae73f4226236a881 Author: Dmitry Gutov Date: Thu May 5 16:01:52 2016 +0300 `nreverse' the marker pairs list * lisp/progmodes/xref.el (xref--buf-pairs-iterator): `nreverse' the marker pairs list for each buffer before returning. diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 1c28390..f651dc9 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -570,7 +570,7 @@ references displayed in the current *xref* buffer." (t (setq chunk-done t next-pair pair)))))))) - (cons file-buf pairs))) + (cons file-buf (nreverse pairs)))) (:cleanup (dolist (pair all-pairs) (move-marker (car pair) nil) commit 25f455815bfaa868dc470d445413df9a7a546c46 Author: Alan Mackenzie Date: Thu May 5 11:05:49 2016 +0000 Call hack-local-variables from major modes rather than from file visiting This prevents file/directory local variables from being lost when the major mode is set or changed. This fixes bug #15577 and bug #23407. * lisp/files.el (normal-mode): Call `hack-local-variables' when the major mode function hasn't already done so. (hack-local-variables): Rename parameter `mode-only' to `handle-mode', make its previous non-nil setting be t, and introduce the following action for a non-nil non-t value: apply all settings apart from `mode'. * lisp/subr.el (run-mode-hooks): call `hack-local-variables' for buffers which are visiting files. * doc/emacs/custom.texi (File Variables): Note that setting a major mode also sets file variables. (Directory Variables): Note that `mode', `eval', and `unibyte' can be set as dir local variables, but `coding' can't. * doc/lispref/modes.texi (Major Mode Conventions): Say that `run-mode-hooks' also calls `hack-local-variables'. (Auto Major Mode): Say that `find-file' no longer runs `hack-local-variables', as from 25.2. Remove vagueness from `normal-mode' and `set-auto-mode' by saying that the mode IS SET, not merely "selected" or "chosen". (Mode Hooks): Document change to `run-mode-hooks'. * doc/lispref/variables.texi (File Local Variables): Document change to `hack-local-variables'. diff --git a/doc/emacs/custom.texi b/doc/emacs/custom.texi index 5cb52e6..01637ae 100644 --- a/doc/emacs/custom.texi +++ b/doc/emacs/custom.texi @@ -1037,9 +1037,10 @@ explicitly. For example, here's how to obtain the default value of @cindex file local variables A file can specify local variable values to use when editing the -file with Emacs. Visiting the file checks for local variable -specifications; it automatically makes these variables local to the -buffer, and sets them to the values specified in the file. +file with Emacs. Visiting the file or setting a major mode checks for +local variable specifications; it automatically makes these variables +local to the buffer, and sets them to the values specified in the +file. @menu * Specifying File Variables:: Specifying file local variables. @@ -1344,6 +1345,12 @@ be applied in the current directory, not in any subdirectories. Finally, it specifies a different @file{ChangeLog} file name for any file in the @file{src/imported} subdirectory. +You can specify the variables @code{mode}, @code{eval}, and +@code{unibyte} in your @file{.dir-locals.el}, and they have the same +meanings as they would have in file local variables. @code{coding} +cannot be specified as a directory local variable. @xref{File +Variables}. + @findex add-dir-local-variable @findex delete-dir-local-variable @findex copy-file-locals-to-dir-locals diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index ae79128..76e5174 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -445,7 +445,8 @@ other packages would interfere with them. Each major mode should have a normal @dfn{mode hook} named @code{@var{modename}-mode-hook}. The very last thing the major mode command should do is to call @code{run-mode-hooks}. This runs the normal -hook @code{change-major-mode-after-body-hook}, the mode hook, +hook @code{change-major-mode-after-body-hook}, the mode hook, the +function @code{hack-local-variables} (when the buffer is visiting a file), and then the normal hook @code{after-change-major-mode-hook}. @xref{Mode Hooks}. @@ -525,11 +526,12 @@ the buffer based on information in the file name or in the file itself. It also processes local variables specified in the file text. @deffn Command normal-mode &optional find-file -This function establishes the proper major mode and buffer-local variable -bindings for the current buffer. First it calls @code{set-auto-mode} -(see below), then it runs @code{hack-local-variables} to parse, and -bind or evaluate as appropriate, the file's local variables -(@pxref{File Local Variables}). +This function establishes the proper major mode and buffer-local +variable bindings for the current buffer. It calls +@code{set-auto-mode} (see below). As from Emacs 25.2, it no longer +runs @code{hack-local-variables}, this now being done in +@code{run-mode-hooks} at the initialization of major modes +(@pxref{Mode Hooks}). If the @var{find-file} argument to @code{normal-mode} is non-@code{nil}, @code{normal-mode} assumes that the @code{find-file} function is calling @@ -543,9 +545,9 @@ If you run @code{normal-mode} interactively, the argument @var{find-file} is normally @code{nil}. In this case, @code{normal-mode} unconditionally processes any file local variables. -The function calls @code{set-auto-mode} to choose a major mode. If this -does not specify a mode, the buffer stays in the major mode determined -by the default value of @code{major-mode} (see below). +The function calls @code{set-auto-mode} to choose and set a major +mode. If this does not specify a mode, the buffer stays in the major +mode determined by the default value of @code{major-mode} (see below). @cindex file mode specification error @code{normal-mode} uses @code{condition-case} around the call to the @@ -555,16 +557,17 @@ mode specification error}, followed by the original error message. @defun set-auto-mode &optional keep-mode-if-same @cindex visited file mode - This function selects the major mode that is appropriate for the -current buffer. It bases its decision (in order of precedence) on the -@w{@samp{-*-}} line, on any @samp{mode:} local variable near the end of -a file, on the @w{@samp{#!}} line (using @code{interpreter-mode-alist}), -on the text at the beginning of the buffer (using -@code{magic-mode-alist}), and finally on the visited file name (using -@code{auto-mode-alist}). @xref{Choosing Modes, , How Major Modes are -Chosen, emacs, The GNU Emacs Manual}. If @code{enable-local-variables} -is @code{nil}, @code{set-auto-mode} does not check the @w{@samp{-*-}} -line, or near the end of the file, for any mode tag. + This function selects and sets the major mode that is appropriate +for the current buffer. It bases its decision (in order of +precedence) on the @w{@samp{-*-}} line, on any @samp{mode:} local +variable near the end of a file, on the @w{@samp{#!}} line (using +@code{interpreter-mode-alist}), on the text at the beginning of the +buffer (using @code{magic-mode-alist}), and finally on the visited +file name (using @code{auto-mode-alist}). @xref{Choosing Modes, , How +Major Modes are Chosen, emacs, The GNU Emacs Manual}. If +@code{enable-local-variables} is @code{nil}, @code{set-auto-mode} does +not check the @w{@samp{-*-}} line, or near the end of the file, for +any mode tag. @vindex inhibit-local-variables-regexps There are some file types where it is not appropriate to scan the file @@ -907,13 +910,14 @@ use the following functions to handle these conventions automatically. @defun run-mode-hooks &rest hookvars Major modes should run their mode hook using this function. It is similar to @code{run-hooks} (@pxref{Hooks}), but it also runs -@code{change-major-mode-after-body-hook} and -@code{after-change-major-mode-hook}. +@code{change-major-mode-after-body-hook}, @code{hack-local-variables} +(when the buffer is visiting a file) (@pxref{File Local Variables}), +and @code{after-change-major-mode-hook}. When this function is called during the execution of a -@code{delay-mode-hooks} form, it does not run the hooks immediately. -Instead, it arranges for the next call to @code{run-mode-hooks} to run -them. +@code{delay-mode-hooks} form, it does not run the hooks or +@code{hack-local-variables} immediately. Instead, it arranges for the +next call to @code{run-mode-hooks} to run them. @end defun @defmac delay-mode-hooks body@dots{} diff --git a/doc/lispref/variables.texi b/doc/lispref/variables.texi index 6c53e9b..dd3f18b 100644 --- a/doc/lispref/variables.texi +++ b/doc/lispref/variables.texi @@ -1613,7 +1613,7 @@ any form of file-local variable. For examples of why you might want to use this, @pxref{Auto Major Mode}. @end defvar -@defun hack-local-variables &optional mode-only +@defun hack-local-variables &optional handle-mode This function parses, and binds or evaluates as appropriate, any local variables specified by the contents of the current buffer. The variable @code{enable-local-variables} has its effect here. However, this @@ -1630,11 +1630,15 @@ is non-@code{nil}; it always calls the other hook. This function ignores a @samp{mode} element if it specifies the same major mode as the buffer already has. -If the optional argument @var{mode-only} is non-@code{nil}, then all -this function does is return a symbol specifying the major mode, -if the @w{@samp{-*-}} line or the local variables list specifies one, -and @code{nil} otherwise. It does not set the mode nor any other -file-local variable. +If the optional argument @var{handle-mode} is @code{t}, then all this +function does is return a symbol specifying the major mode, if the +@w{@samp{-*-}} line or the local variables list specifies one, and +@code{nil} otherwise. It does not set the mode or any other +file-local variable. If @var{handle-mode} has any value other than +@code{nil} or @code{t}, any settings of @samp{mode} in the +@w{@samp{-*-}} line or the local variables list are ignored, and the +other settings are applied. If @var{handle-mode} is @code{nil}, all +the file local variables are set. @end defun @defvar file-local-variables-alist diff --git a/lisp/files.el b/lisp/files.el index 132ebce..d89b2f5 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -2322,8 +2322,12 @@ in that case, this function acts as if `enable-local-variables' were t." ;; s-a-m and h-l-v may parse the same regions, looking for "mode:". (with-demoted-errors "File mode specification error: %s" (set-auto-mode)) - (with-demoted-errors "File local-variables error: %s" - (hack-local-variables))) + ;; `delay-mode-hooks' being non-nil will have prevented the major + ;; mode's call to `run-mode-hooks' from calling + ;; `hack-local-variables'. In that case, call it now. + (when delay-mode-hooks + (with-demoted-errors "File local-variables error: %s" + (hack-local-variables 'no-mode)))) ;; Turn font lock off and on, to make sure it takes account of ;; whatever file local variables are relevant to it. (when (and font-lock-mode @@ -3297,11 +3301,15 @@ DIR-NAME is the name of the associated directory. Otherwise it is nil." ;; TODO? Warn once per file rather than once per session? (defvar hack-local-variables--warned-lexical nil) -(defun hack-local-variables (&optional mode-only) +(defun hack-local-variables (&optional handle-mode) "Parse and put into effect this buffer's local variables spec. Uses `hack-local-variables-apply' to apply the variables. -If MODE-ONLY is non-nil, all we do is check whether a \"mode:\" +If HANDLE-MODE is nil, we apply all the specified local +variables. If HANDLE-MODE is neither nil nor t, we do the same, +except that any settings of `mode' are ignored. + +If HANDLE-MODE is t, all we do is check whether a \"mode:\" is specified, and return the corresponding mode symbol, or nil. In this case, we try to ignore minor-modes, and only return a major-mode. @@ -3319,7 +3327,7 @@ local variables, but directory-local variables may still be applied." (let ((enable-local-variables (and local-enable-local-variables enable-local-variables)) result) - (unless mode-only + (unless (eq handle-mode t) (setq file-local-variables-alist nil) (with-demoted-errors "Directory-local variables error: %s" ;; Note this is a no-op if enable-local-variables is nil. @@ -3327,18 +3335,19 @@ local variables, but directory-local variables may still be applied." ;; This entire function is basically a no-op if enable-local-variables ;; is nil. All it does is set file-local-variables-alist to nil. (when enable-local-variables - ;; This part used to ignore enable-local-variables when mode-only - ;; was non-nil. That was inappropriate, eg consider the + ;; This part used to ignore enable-local-variables when handle-mode + ;; was t. That was inappropriate, eg consider the ;; (artificial) example of: ;; (setq local-enable-local-variables nil) ;; Open a file foo.txt that contains "mode: sh". ;; It correctly opens in text-mode. ;; M-x set-visited-file name foo.c, and it incorrectly stays in text-mode. (unless (or (inhibit-local-variables-p) - ;; If MODE-ONLY is non-nil, and the prop line specifies a + ;; If HANDLE-MODE is t, and the prop line specifies a ;; mode, then we're done, and have no need to scan further. - (and (setq result (hack-local-variables-prop-line mode-only)) - mode-only)) + (and (setq result (hack-local-variables-prop-line + (eq handle-mode t))) + (eq handle-mode t))) ;; Look for "Local variables:" line in last page. (save-excursion (goto-char (point-max)) @@ -3393,7 +3402,7 @@ local variables, but directory-local variables may still be applied." (goto-char (point-min)) (while (not (or (eobp) - (and mode-only result))) + (and (eq handle-mode t) result))) ;; Find the variable name; (unless (looking-at hack-local-variable-regexp) (error "Malformed local variable line: %S" @@ -3410,7 +3419,7 @@ local variables, but directory-local variables may still be applied." (forward-char 1) (let ((read-circle nil)) (setq val (read (current-buffer)))) - (if mode-only + (if (eq handle-mode t) (and (eq var 'mode) ;; Specifying minor-modes via mode: is ;; deprecated, but try to reject them anyway. @@ -3432,6 +3441,7 @@ local variables, but directory-local variables may still be applied." ;; to use 'thisbuf's name in the ;; warning message. (or (buffer-file-name thisbuf) "")))))) + ((and (eq var 'mode) handle-mode)) (t (ignore-errors (push (cons (if (eq var 'eval) @@ -3440,8 +3450,8 @@ local variables, but directory-local variables may still be applied." val) result)))))) (forward-line 1)))))))) ;; Now we've read all the local variables. - ;; If MODE-ONLY is non-nil, return whether the mode was specified. - (if mode-only result + ;; If HANDLE-MODE is t, return whether the mode was specified. + (if (eq handle-mode t) result ;; Otherwise, set the variables. (hack-local-variables-filter result nil) (hack-local-variables-apply))))) diff --git a/lisp/subr.el b/lisp/subr.el index afc86a7..f67f70f 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1737,10 +1737,14 @@ if it is empty or a duplicate." (defun run-mode-hooks (&rest hooks) "Run mode hooks `delayed-mode-hooks' and HOOKS, or delay HOOKS. -If the variable `delay-mode-hooks' is non-nil, does not run any hooks, +Call `hack-local-variables' to set up file local and directory local +variables. + +If the variable `delay-mode-hooks' is non-nil, does not do anything, just adds the HOOKS to the list `delayed-mode-hooks'. Otherwise, runs hooks in the sequence: `change-major-mode-after-body-hook', -`delayed-mode-hooks' (in reverse order), HOOKS, and finally +`delayed-mode-hooks' (in reverse order), HOOKS, then runs +`hack-local-variables' and finally runs the hook `after-change-major-mode-hook'. Major mode functions should use this instead of `run-hooks' when running their FOO-mode-hook." (if delay-mode-hooks @@ -1751,6 +1755,9 @@ this instead of `run-hooks' when running their FOO-mode-hook." (setq hooks (nconc (nreverse delayed-mode-hooks) hooks)) (setq delayed-mode-hooks nil) (apply 'run-hooks (cons 'change-major-mode-after-body-hook hooks)) + (if (buffer-file-name) + (with-demoted-errors "File local-variables error: %s" + (hack-local-variables 'no-mode))) (run-hooks 'after-change-major-mode-hook))) (defmacro delay-mode-hooks (&rest body) commit 1a4127dbd625ea64f535b3bd09844a99161290a6 Author: Dmitry Gutov Date: Thu May 5 04:28:14 2016 +0300 Use save-excursion in xref-location-marker more * lisp/progmodes/elisp-mode.el (xref-location-marker): Use save-excursion, in order not to alter the value of point if the buffer is currently open in the background (problem reported by Robert Weiner). * lisp/progmodes/etags.el (xref-location-marker): Same. diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index fc4501d..6c6c380 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -826,8 +826,9 @@ non-nil result supercedes the xrefs produced by (pcase-let (((cl-struct xref-elisp-location symbol type file) l)) (let ((buffer-point (find-function-search-for-symbol symbol type file))) (with-current-buffer (car buffer-point) - (goto-char (or (cdr buffer-point) (point-min))) - (point-marker))))) + (save-excursion + (goto-char (or (cdr buffer-point) (point-min))) + (point-marker)))))) (cl-defmethod xref-location-group ((l xref-elisp-location)) (xref-elisp-location-file l)) diff --git a/lisp/progmodes/etags.el b/lisp/progmodes/etags.el index a2a0df2..890d552 100644 --- a/lisp/progmodes/etags.el +++ b/lisp/progmodes/etags.el @@ -2146,8 +2146,9 @@ for \\[find-tag] (which see)." (with-slots (tag-info file) l (let ((buffer (find-file-noselect file))) (with-current-buffer buffer - (etags-goto-tag-location tag-info) - (point-marker))))) + (save-excursion + (etags-goto-tag-location tag-info) + (point-marker)))))) (cl-defmethod xref-location-line ((l xref-etags-location)) (with-slots (tag-info) l commit ab3ba912fc7b91b7b147ea36fabe461dc99a9fb8 Author: Dmitry Gutov Date: Thu May 5 04:15:23 2016 +0300 shell-quote-argument DIR when appropriate * lisp/progmodes/project.el (project-file-completion-table): `shell-quote-argument' DIR as well. * lisp/progmodes/xref.el (xref--rgrep-command): Pass DIR through `shell-quote-argument' (bug#23453). Thanks for Kaushal Modi for pointing out the problem. Assert that DIR doesn't start with `~'. diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 9c8a88c..a51c383 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -172,7 +172,8 @@ to find the list of ignores for each directory." (let ((command (format "%s %s %s -type f -print0" find-program - dir + (shell-quote-argument + (expand-file-name dir)) (xref--find-ignores-arguments (project-ignores project dir) (expand-file-name dir))))) diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 17bfdb6..1c28390 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -941,6 +941,8 @@ IGNORES is a list of glob patterns." (require 'find-dired) ; for `find-name-arg' (defvar grep-find-template) (defvar find-name-arg) + ;; `shell-quote-argument' quotes the tilde as well. + (cl-assert (not (string-match-p "\\`~" dir))) (grep-expand-template grep-find-template regexp @@ -952,14 +954,13 @@ IGNORES is a list of glob patterns." (concat " -o " find-name-arg " ")) " " (shell-quote-argument ")")) - dir + (shell-quote-argument dir) (xref--find-ignores-arguments ignores dir))) (defun xref--find-ignores-arguments (ignores dir) "Convert IGNORES and DIR to a list of arguments for 'find'. IGNORES is a list of glob patterns. DIR is an absolute directory, used as the root of the ignore globs." - ;; `shell-quote-argument' quotes the tilde as well. (cl-assert (not (string-match-p "\\`~" dir))) (when ignores (concat commit 922c7a3e48e649ad67bd12b1f83343b730dd1bc4 Author: Dmitry Gutov Date: Thu May 5 02:52:34 2016 +0300 Rework xref-query-replace-in-results * lisp/progmodes/xref.el (xref-query-replace-in-results): Collect all xrefs from the buffer first, then delegate most of the processing to the value returned by xref--buf-pairs-iterator. (xref--buf-pairs-iterator): New function. Return an "iterator" which partitions returned markers into buffers, and only processes markers from one buffer at a time. When an xref is out of date, skip it with a message instead of signaling error (bug#23284). (xref--outdated-p): Extract from xref--buf-pairs-iterator. Trim CR from both strings before comparing. (xref--query-replace-1): Remove the variable current-buf, no need to track it anymore. Simplify the filter-predicate and search functions accordingly. Iterate over buffer-markers pairs returned by the iterator, and call `perform-replace' for each of them. Use multi-query-replace-map (bug#23284). Use `switch-to-buffer' every time after the first, in order not to jump between windows. * test/automated/xref-tests.el (xref--buf-pairs-iterator-groups-markers-by-buffers-1) (xref--buf-pairs-iterator-groups-markers-by-buffers-2) (xref--buf-pairs-iterator-cleans-up-markers): New tests. diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 62cef23..17bfdb6 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -521,58 +521,86 @@ references displayed in the current *xref* buffer." (let ((fr (read-regexp "Xref query-replace (regexp)" ".*"))) (list fr (read-regexp (format "Xref query-replace (regexp) %s with: " fr))))) - (let ((reporter (make-progress-reporter (format "Saving search results...") - 0 (line-number-at-pos (point-max)))) - (counter 0) - pairs item) + (let* (item xrefs iter) + (save-excursion + (while (setq item (xref--search-property 'xref-item)) + (when (xref-match-length item) + (push item xrefs)))) (unwind-protect (progn - (save-excursion - (goto-char (point-min)) - ;; TODO: This list should be computed on-demand instead. - ;; As long as the UI just iterates through matches one by - ;; one, there's no need to compute them all in advance. - ;; Then we can throw away the reporter. - (while (setq item (xref--search-property 'xref-item)) - (when (xref-match-length item) - (save-excursion - (let* ((loc (xref-item-location item)) - (beg (xref-location-marker loc)) - (end (move-marker (make-marker) - (+ beg (xref-match-length item)) - (marker-buffer beg)))) - ;; Perform sanity check first. - (xref--goto-location loc) - ;; FIXME: The check should probably be a generic - ;; function, instead of the assumption that all - ;; matches contain the full line as summary. - ;; TODO: Offer to re-scan otherwise. - (unless (equal (buffer-substring-no-properties - (line-beginning-position) - (line-end-position)) - (xref-item-summary item)) - (user-error "Search results out of date")) - (progress-reporter-update reporter (cl-incf counter)) - (push (cons beg end) pairs))))) - (setq pairs (nreverse pairs))) - (unless pairs (user-error "No suitable matches here")) - (progress-reporter-done reporter) - (xref--query-replace-1 from to pairs)) - (dolist (pair pairs) - (move-marker (car pair) nil) - (move-marker (cdr pair) nil))))) + (goto-char (point-min)) + (setq iter (xref--buf-pairs-iterator (nreverse xrefs))) + (xref--query-replace-1 from to iter)) + (funcall iter :cleanup)))) + +(defun xref--buf-pairs-iterator (xrefs) + (let (chunk-done item next-pair file-buf pairs all-pairs) + (lambda (action) + (pcase action + (:next + (when (or xrefs next-pair) + (setq chunk-done nil) + (when next-pair + (setq file-buf (marker-buffer (car next-pair)) + pairs (list next-pair) + next-pair nil)) + (while (and (not chunk-done) + (setq item (pop xrefs))) + (save-excursion + (let* ((loc (xref-item-location item)) + (beg (xref-location-marker loc)) + (end (move-marker (make-marker) + (+ beg (xref-match-length item)) + (marker-buffer beg)))) + (let ((pair (cons beg end))) + (push pair all-pairs) + ;; Perform sanity check first. + (xref--goto-location loc) + (if (xref--outdated-p item + (buffer-substring-no-properties + (line-beginning-position) + (line-end-position))) + (message "Search result out of date, skipping") + (cond + ((null file-buf) + (setq file-buf (marker-buffer beg)) + (push pair pairs)) + ((equal file-buf (marker-buffer beg)) + (push pair pairs)) + (t + (setq chunk-done t + next-pair pair)))))))) + (cons file-buf pairs))) + (:cleanup + (dolist (pair all-pairs) + (move-marker (car pair) nil) + (move-marker (cdr pair) nil))))))) + +(defun xref--outdated-p (item line-text) + ;; FIXME: The check should probably be a generic function instead of + ;; the assumption that all matches contain the full line as summary. + (let ((summary (xref-item-summary item)) + (strip (lambda (s) (if (string-match "\r\\'" s) + (substring-no-properties s 0 -1) + s)))) + (not + ;; Sometimes buffer contents include ^M, and sometimes Grep + ;; output includes it, and they don't always match. + (equal (funcall strip line-text) + (funcall strip summary))))) ;; FIXME: Write a nicer UI. -(defun xref--query-replace-1 (from to pairs) +(defun xref--query-replace-1 (from to iter) (let* ((query-replace-lazy-highlight nil) - current-beg current-end current-buf + (continue t) + did-it-once buf-pairs pairs + current-beg current-end ;; Counteract the "do the next match now" hack in ;; `perform-replace'. And still, it'll report that those ;; matches were "filtered out" at the end. (isearch-filter-predicate (lambda (beg end) (and current-beg - (eq (current-buffer) current-buf) (>= beg current-beg) (<= end current-end)))) (replace-re-search-function @@ -581,19 +609,22 @@ references displayed in the current *xref* buffer." (while (and (not found) pairs) (setq pair (pop pairs) current-beg (car pair) - current-end (cdr pair) - current-buf (marker-buffer current-beg)) - (xref--with-dedicated-window - (pop-to-buffer current-buf)) + current-end (cdr pair)) (goto-char current-beg) (when (re-search-forward from current-end noerror) (setq found t))) found)))) - ;; FIXME: Despite this being a multi-buffer replacement, `N' - ;; doesn't work, because we're not using - ;; `multi-query-replace-map', and it would expect the below - ;; function to be called once per buffer. - (perform-replace from to t t nil))) + (while (and continue (setq buf-pairs (funcall iter :next))) + (if did-it-once + ;; Reuse the same window for subsequent buffers. + (switch-to-buffer (car buf-pairs)) + (xref--with-dedicated-window + (pop-to-buffer (car buf-pairs))) + (setq did-it-once t)) + (setq pairs (cdr buf-pairs)) + (setq continue + (perform-replace from to t t nil nil multi-query-replace-map))) + (unless did-it-once (user-error "No suitable matches here")))) (defvar xref--xref-buffer-mode-map (let ((map (make-sparse-keymap))) diff --git a/test/automated/xref-tests.el b/test/automated/xref-tests.el index b288e2d..079b196 100644 --- a/test/automated/xref-tests.el +++ b/test/automated/xref-tests.el @@ -60,3 +60,32 @@ (should (string-match-p "file2\\.txt\\'" (xref-location-group (nth 0 locs)))) (should (equal 1 (xref-location-line (nth 0 locs)))) (should (equal 0 (xref-file-location-column (nth 0 locs)))))) + +(ert-deftest xref--buf-pairs-iterator-groups-markers-by-buffers-1 () + (let* ((xrefs (xref-collect-matches "foo" "*" xref-tests-data-dir nil)) + (iter (xref--buf-pairs-iterator xrefs)) + (cons (funcall iter :next))) + (should (null (funcall iter :next))) + (should (string-match "file1\\.txt\\'" (buffer-file-name (car cons)))) + (should (= 2 (length (cdr cons)))))) + +(ert-deftest xref--buf-pairs-iterator-groups-markers-by-buffers-2 () + (let* ((xrefs (xref-collect-matches "bar" "*" xref-tests-data-dir nil)) + (iter (xref--buf-pairs-iterator xrefs)) + (cons1 (funcall iter :next)) + (cons2 (funcall iter :next))) + (should (null (funcall iter :next))) + (should-not (equal (car cons1) (car cons2))) + (should (= 1 (length (cdr cons1)))) + (should (= 1 (length (cdr cons2)))))) + +(ert-deftest xref--buf-pairs-iterator-cleans-up-markers () + (let* ((xrefs (xref-collect-matches "bar" "*" xref-tests-data-dir nil)) + (iter (xref--buf-pairs-iterator xrefs)) + (cons1 (funcall iter :next)) + (cons2 (funcall iter :next))) + (funcall iter :cleanup) + (should (null (marker-position (car (nth 0 (cdr cons1)))))) + (should (null (marker-position (cdr (nth 0 (cdr cons1)))))) + (should (null (marker-position (car (nth 0 (cdr cons2)))))) + (should (null (marker-position (cdr (nth 0 (cdr cons2)))))))) commit 3fe351072841becbb1902c19f784890949f41c1d Author: Juri Linkov Date: Wed May 4 23:05:33 2016 +0300 * lisp/replace.el (query-replace-read-from): Use minibuffer-with-setup-hook to set minibuffer-local value of text-property-default-nonsticky. (Bug#23418, bug#23127) diff --git a/lisp/replace.el b/lisp/replace.el index 801c605..26e5875 100644 --- a/lisp/replace.el +++ b/lisp/replace.el @@ -191,18 +191,15 @@ wants to replace FROM with TO." ;; a region in order to specify the minibuffer input. ;; That should not clobber the region for the query-replace itself. (save-excursion - ;; The `with-current-buffer' ensures that the binding - ;; for `text-property-default-nonsticky' isn't a buffer - ;; local binding in the current buffer, which - ;; `read-from-minibuffer' wouldn't see. - (with-current-buffer (window-buffer (minibuffer-window)) - (let ((text-property-default-nonsticky - (cons '(separator . t) text-property-default-nonsticky))) - (if regexp-flag - (read-regexp prompt nil 'query-replace-from-to-history) - (read-from-minibuffer - prompt nil nil nil 'query-replace-from-to-history - (car (if regexp-flag regexp-search-ring search-ring)) t)))))) + (minibuffer-with-setup-hook + (lambda () + (setq-local text-property-default-nonsticky + (cons '(separator . t) text-property-default-nonsticky))) + (if regexp-flag + (read-regexp prompt nil 'query-replace-from-to-history) + (read-from-minibuffer + prompt nil nil nil 'query-replace-from-to-history + (car (if regexp-flag regexp-search-ring search-ring)) t))))) (to)) (if (and (zerop (length from)) query-replace-defaults) (cons (caar query-replace-defaults) commit 0932b948971770201b135d5f0dee82b91a1eef92 Author: Stephen Berman Date: Wed May 4 21:52:32 2016 +0200 Fix todo-mode bug involving archived items (bug#23447) * lisp/calendar/todo-mode.el (todo-jump-to-category): When jumping from Todo Categories mode to a category with only archived items and todo-skip-archived-categories is non-nil, make sure the archive file buffer is in Todo Archive mode to prevent todo-category-select from raising an error, and don't set todo-current-todo-file, since that makes todo-show display the archived category. Remove a no-op call to kill-buffer, which is already called in todo-insert-category-line. diff --git a/lisp/calendar/todo-mode.el b/lisp/calendar/todo-mode.el index 0529e97..8e75258 100644 --- a/lisp/calendar/todo-mode.el +++ b/lisp/calendar/todo-mode.el @@ -902,17 +902,19 @@ Categories mode." (todo-show) (let* ((archive (eq where 'archive)) (cat (unless archive where)) + (goto-archive (and cat + todo-skip-archived-categories + (zerop (todo-get-count 'todo cat)) + (zerop (todo-get-count 'done cat)) + (not (zerop (todo-get-count 'archived cat))))) (file0 (when cat ; We're in Todo Categories mode. - ;; With non-nil `todo-skip-archived-categories' - ;; jump to archive file of a category with only - ;; archived items. - (if (and todo-skip-archived-categories - (zerop (todo-get-count 'todo cat)) - (zerop (todo-get-count 'done cat)) - (not (zerop (todo-get-count 'archived cat)))) + (if goto-archive + ;; If the category has only archived items and + ;; `todo-skip-archived-categories' is non-nil, jump to + ;; the archive category. (concat (file-name-sans-extension todo-current-todo-file) ".toda") - ;; Otherwise, jump to current todo file. + ;; Otherwise, jump to the category in the todo file. todo-current-todo-file))) (len (length todo-categories)) (cat+file (unless cat @@ -923,18 +925,15 @@ Categories mode." (category (or cat (car cat+file)))) (unless cat (setq file0 (cdr cat+file))) (with-current-buffer (find-file-noselect file0 'nowarn) - (setq todo-current-todo-file file0) - ;; If called from Todo Categories mode, clean up before jumping. - (if (string= (buffer-name) todo-categories-buffer) - (kill-buffer)) - (set-window-buffer (selected-window) - (set-buffer (find-buffer-visiting file0))) - (unless todo-global-current-todo-file - (setq todo-global-current-todo-file todo-current-todo-file)) - (todo-category-number category) - (todo-category-select) - (goto-char (point-min)) - (when add-item (todo-insert-item--basic)))))) + (when goto-archive (todo-archive-mode)) + (set-window-buffer (selected-window) + (set-buffer (find-buffer-visiting file0))) + (unless todo-global-current-todo-file + (setq todo-global-current-todo-file todo-current-todo-file)) + (todo-category-number category) + (todo-category-select) + (goto-char (point-min)) + (when add-item (todo-insert-item--basic)))))) (defun todo-next-item (&optional count) "Move point down to the beginning of the next item. commit e68ad1f3f08268f0642ba19e7c894f9e05cb8e6f Author: Glenn Morris Date: Wed May 4 13:23:21 2016 -0400 ; * etc/NEWS: Tiny edit. (Bug#23432) diff --git a/etc/NEWS b/etc/NEWS index dbc2944..7d6e533 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1715,9 +1715,11 @@ permissions set to temporary values (e.g., for creating private files). --- ** Function 'system-name' now returns an updated value if the current -system's name has changed or if the Emacs process has changed systems, -and to avoid long waits it no longer consults DNS to canonicalize the -name. The variable 'system-name' is now obsolete. +system's name has changed or if the Emacs process has changed systems. +To avoid long waits it no longer consults DNS to canonicalize the name +(in some cases this may affect generated message-id headers - customize +'message-user-fqdn' if this bothers you). The variable 'system-name' +is now obsolete. +++ ** Function 'write-region' no longer outputs "Wrote FILE" in batch mode. commit adc80b7e238e09b1b8c392ecf902d2b978d9016d Author: Glenn Morris Date: Tue May 3 19:36:40 2016 -0700 ; * test/automated/xref-tests.el: Add copyright and license. diff --git a/test/automated/xref-tests.el b/test/automated/xref-tests.el index 28ca351..b288e2d 100644 --- a/test/automated/xref-tests.el +++ b/test/automated/xref-tests.el @@ -1,3 +1,28 @@ +;;; xref-tests.el --- tests for xref + +;; Copyright (C) 2016 Free Software Foundation, Inc. + +;; Author: Dmitry Gutov + +;; 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 3 of the License, 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. If not, see . + +;;; Commentary: + +;;; Code: + (require 'xref) (require 'cl-lib) commit 4d8fd9cf338cf9b5dfc613657adfeabff2d9c14e Author: Dmitry Gutov Date: Wed May 4 01:59:29 2016 +0300 Handle "empty line" regexp in xref searches * lisp/progmodes/xref.el (xref--collect-matches-1): Stop after one match if re-search-forward doesn't move point (bug#23426). * test/automated/xref-tests.el (xref-collect-matches-finds-an-empty-line-regexp-match): Uncomment test. diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 540c7b0..62cef23 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -1016,7 +1016,11 @@ directory, used as the root of the ignore globs." (syntax-propertize line-end) ;; FIXME: This results in several lines with the same ;; summary. Solve with composite pattern? - (while (re-search-forward regexp line-end t) + (while (and + ;; REGEXP might match an empty string. Or line. + (or (null matches) + (> (point) line-beg)) + (re-search-forward regexp line-end t)) (let* ((beg-column (- (match-beginning 0) line-beg)) (end-column (- (match-end 0) line-beg)) (loc (xref-make-file-location file line beg-column)) diff --git a/test/automated/xref-tests.el b/test/automated/xref-tests.el index 1b500c3..28ca351 100644 --- a/test/automated/xref-tests.el +++ b/test/automated/xref-tests.el @@ -28,10 +28,10 @@ (should (equal 0 (xref-file-location-column (nth 0 locs)))) (should (equal 4 (xref-file-location-column (nth 1 locs)))))) -;; (ert-deftest xref-collect-matches-finds-an-empty-line-regexp-match () -;; (let* ((matches (xref-collect-matches "^$" "*" xref-tests-data-dir nil)) -;; (locs (mapcar #'xref-item-location matches))) -;; (should (= 1 (length matches))) -;; (should (string-match-p "file2\\.txt\\'" (xref-location-group (nth 0 locs)))) -;; (should (equal 1 (xref-location-line (nth 0 locs)))) -;; (should (equal 0 (xref-file-location-column (nth 0 locs)))))) +(ert-deftest xref-collect-matches-finds-an-empty-line-regexp-match () + (let* ((matches (xref-collect-matches "^$" "*" xref-tests-data-dir nil)) + (locs (mapcar #'xref-item-location matches))) + (should (= 1 (length matches))) + (should (string-match-p "file2\\.txt\\'" (xref-location-group (nth 0 locs)))) + (should (equal 1 (xref-location-line (nth 0 locs)))) + (should (equal 0 (xref-file-location-column (nth 0 locs)))))) commit f559b374a30f3615261f7a902fc3428cac6289f4 Author: Dmitry Gutov Date: Wed May 4 01:38:02 2016 +0300 Add tests for xref-collect-matches * test/automated/xref-tests.el: New file. Add tests for xref-collect-matches. diff --git a/test/automated/data/xref/file1.txt b/test/automated/data/xref/file1.txt new file mode 100644 index 0000000..5d7cc54 --- /dev/null +++ b/test/automated/data/xref/file1.txt @@ -0,0 +1,2 @@ +foo foo +bar diff --git a/test/automated/data/xref/file2.txt b/test/automated/data/xref/file2.txt new file mode 100644 index 0000000..9f075f2 --- /dev/null +++ b/test/automated/data/xref/file2.txt @@ -0,0 +1,2 @@ + +bar diff --git a/test/automated/xref-tests.el b/test/automated/xref-tests.el new file mode 100644 index 0000000..1b500c3 --- /dev/null +++ b/test/automated/xref-tests.el @@ -0,0 +1,37 @@ +(require 'xref) +(require 'cl-lib) + +(defvar xref-tests-data-dir + (expand-file-name "data/xref/" + (file-name-directory (or load-file-name (buffer-file-name))))) + +(ert-deftest xref-collect-matches-finds-none-for-some-regexp () + (should (null (xref-collect-matches "zzz" "*" xref-tests-data-dir nil)))) + +(ert-deftest xref-collect-matches-finds-some-for-bar () + (let* ((matches (xref-collect-matches "bar" "*" xref-tests-data-dir nil)) + (locs (cl-sort (mapcar #'xref-item-location matches) + #'string< + :key #'xref-location-group))) + (should (= 2 (length matches))) + (should (string-match-p "file1\\.txt\\'" (xref-location-group (nth 0 locs)))) + (should (string-match-p "file2\\.txt\\'" (xref-location-group (nth 1 locs)))))) + +(ert-deftest xref-collect-matches-finds-two-matches-on-the-same-line () + (let* ((matches (xref-collect-matches "foo" "*" xref-tests-data-dir nil)) + (locs (mapcar #'xref-item-location matches))) + (should (= 2 (length matches))) + (should (string-match-p "file1\\.txt\\'" (xref-location-group (nth 0 locs)))) + (should (string-match-p "file1\\.txt\\'" (xref-location-group (nth 1 locs)))) + (should (equal 1 (xref-location-line (nth 0 locs)))) + (should (equal 1 (xref-location-line (nth 1 locs)))) + (should (equal 0 (xref-file-location-column (nth 0 locs)))) + (should (equal 4 (xref-file-location-column (nth 1 locs)))))) + +;; (ert-deftest xref-collect-matches-finds-an-empty-line-regexp-match () +;; (let* ((matches (xref-collect-matches "^$" "*" xref-tests-data-dir nil)) +;; (locs (mapcar #'xref-item-location matches))) +;; (should (= 1 (length matches))) +;; (should (string-match-p "file2\\.txt\\'" (xref-location-group (nth 0 locs)))) +;; (should (equal 1 (xref-location-line (nth 0 locs)))) +;; (should (equal 0 (xref-file-location-column (nth 0 locs)))))) commit 6428aa044ad872e9b8b60d825b7cbcb38ae3e492 Author: Dmitry Gutov Date: Wed May 4 01:02:43 2016 +0300 Use grep-find-ignored-directories instead of vc-directory-exclusion-list * lisp/dired-aux.el (dired-do-find-regexp): Use grep-find-ignored-directories instead of vc-directory-exclusion-list. The result should be functionally similar (the former uses the latter as the default value), but it should be more consistent and appropriate WRT user customizations. (dired-do-find-regexp-and-replace): Update the docstring. * lisp/dired.el: Update the corresponding autoloads. * doc/emacs/dired.texi (Operating on Files): Update the documentation accordingly. diff --git a/doc/emacs/dired.texi b/doc/emacs/dired.texi index aa717df..1b10ebc 100644 --- a/doc/emacs/dired.texi +++ b/doc/emacs/dired.texi @@ -796,12 +796,12 @@ where you can navigate between matches and display them as needed using the commands described in @ref{Xref Commands}. @vindex grep-find-ignored-files @r{(Dired)} -@vindex vc-directory-exclusion-list @r{(Dired)} +@vindex grep-find-ignored-directories @r{(Dired)} If any of the marked files are directories, then this command searches all of the files in those directories, and any of their subdirectories, recursively, except files whose names match @code{grep-find-ignored-files} and subdirectories whose names match -@code{vc-directory-exclusion-list}. +@code{grep-find-ignored-directories}. @kindex Q @r{(Dired)} @findex dired-do-find-regexp-and-replace @@ -822,7 +822,7 @@ Like with @code{dired-do-find-regexp}, if any of the marked files are directories, this command performs replacements in all of the files in those directories, and in any of their subdirectories, recursively, except for files whose names match @code{grep-find-ignored-files} and -subdirectories whose names match @code{vc-directory-exclusion-list}. +subdirectories whose names match @code{grep-find-ignored-directories}. @end table @node Shell Commands in Dired diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 5ee3c11..b9111a8 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -2722,17 +2722,18 @@ with the command \\[tags-loop-continue]." "Find all matches for REGEXP in all marked files. For any marked directory, all of its files are searched recursively. However, files matching `grep-find-ignored-files' and subdirectories -matching `vc-directory-exclusion-list' are skipped in the marked +matching `grep-find-ignored-directories' are skipped in the marked directories. REGEXP should use constructs supported by your local `grep' command." (interactive "sSearch marked files (regexp): ") (require 'grep) (defvar grep-find-ignored-files) + (defvar grep-find-ignored-directories) (let* ((files (dired-get-marked-files)) (ignores (nconc (mapcar (lambda (s) (concat s "/")) - vc-directory-exclusion-list) + grep-find-ignored-directories) grep-find-ignored-files)) (xrefs (cl-mapcan (lambda (file) @@ -2749,7 +2750,7 @@ REGEXP should use constructs supported by your local `grep' command." "Replace matches of FROM with TO, in all marked files. For any marked directory, matches in all of its files are replaced, recursively. However, files matching `grep-find-ignored-files' -and subdirectories matching `vc-directory-exclusion-list' are skipped +and subdirectories matching `grep-find-ignored-directories' are skipped in the marked directories. REGEXP should use constructs supported by your local `grep' command." diff --git a/lisp/dired.el b/lisp/dired.el index 2cc3c88..b838e64 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -3919,7 +3919,7 @@ Ask means pop up a menu for the user to select one of copy, move or link." ;;; Start of automatically extracted autoloads. -;;;### (autoloads nil "dired-aux" "dired-aux.el" "00fe45cfae47cace47cffc09afca6832") +;;;### (autoloads nil "dired-aux" "dired-aux.el" "8346506b9ef7167fd55b5eac7e6617a1") ;;; Generated autoloads from dired-aux.el (autoload 'dired-diff "dired-aux" "\ @@ -4426,7 +4426,7 @@ with the command \\[tags-loop-continue]. Find all matches for REGEXP in all marked files. For any marked directory, all of its files are searched recursively. However, files matching `grep-find-ignored-files' and subdirectories -matching `vc-directory-exclusion-list' are skipped in the marked +matching `grep-find-ignored-directories' are skipped in the marked directories. REGEXP should use constructs supported by your local `grep' command. @@ -4437,7 +4437,7 @@ REGEXP should use constructs supported by your local `grep' command. Replace matches of FROM with TO, in all marked files. For any marked directory, matches in all of its files are replaced, recursively. However, files matching `grep-find-ignored-files' -and subdirectories matching `vc-directory-exclusion-list' are skipped +and subdirectories matching `grep-find-ignored-directories' are skipped in the marked directories. REGEXP should use constructs supported by your local `grep' command. commit 6f82d8ef7d3aea2d05677d2792f89b8e6084d66a Author: Dmitry Gutov Date: Wed May 4 00:42:43 2016 +0300 Clear buffer-undo-list when showing xrefs * lisp/progmodes/xref.el (xref--show-xref-buffer): Clear buffer-undo-list and temporarily bind it to t while rendering the buffer contents. diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index b5632af..540c7b0 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -687,7 +687,9 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)." (defun xref--show-xref-buffer (xrefs alist) (let ((xref-alist (xref--analyze xrefs))) (with-current-buffer (get-buffer-create xref-buffer-name) - (let ((inhibit-read-only t)) + (setq buffer-undo-list nil) + (let ((inhibit-read-only t) + (buffer-undo-list t)) (erase-buffer) (xref--insert-xrefs xref-alist) (xref--xref-buffer-mode) commit c68a09107c1f7459c626d38be5e0e991912e57ec Author: Alan Mackenzie Date: Tue May 3 20:27:48 2016 +0000 Note the quote translation in `message' in section "incompatible changes". * etc/NEWS: Note that `message' translates quotes, that the translation cannot be disabled, and that `format' can be used to get the old behavior back. diff --git a/etc/NEWS b/etc/NEWS index 21ebba5..dbc2944 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1476,6 +1476,13 @@ display of diagnostics and help, but not of info. As the variable is not intended for casual use, it is not a user option. +++ +** `message' now translates various sorts of single quotes in its +format string according to the value of `text-quoting-style' (see +above). This translation cannot be disabled. To get the old +behavior of `message', use `format', which is not affected by +`text-quoting-style', e.g. (message "%s" (format "...." foo bar)). + ++++ ** substitute-command-keys now replaces quotes. That is, it converts documentation strings' quoting style as per the value of 'text-quoting-style'. Doc strings in source code can use commit 52f86a755b0befb6ad2a26bdb4edc46e2152b593 Author: Paul Eggert Date: Tue May 3 13:30:21 2016 -0700 * etc/NEWS: Mention (message "%s" (format ...)). diff --git a/etc/NEWS b/etc/NEWS index b5d2b44..21ebba5 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1487,7 +1487,8 @@ before, characters preceded by \= are output as-is. They use the new 'format-message' function instead of plain 'format', so that they now follow user preference as per 'text-quoting-style' when processing curved single quotes, grave accents, and apostrophes -in their format argument. +in their format argument. To process % directives but not quotes, you +can use calls like (message "%s" (format FORMAT ARG1 ... ARGn)). +++ ** The character classes [:alpha:] and [:alnum:] in regular expressions commit 93703c547a96bc257d4e4c1ae4c84e60cf217810 Author: Lars Ingebrigtsen Date: Tue May 3 19:06:13 2016 +0200 (Common Keywords): Correct what missing :group means * doc/lispref/customize.texi (Common Keywords): Correct what missing :group means. diff --git a/doc/lispref/customize.texi b/doc/lispref/customize.texi index de130d5..4a6f7f2 100644 --- a/doc/lispref/customize.texi +++ b/doc/lispref/customize.texi @@ -68,8 +68,7 @@ cause confusion.} @item :group @var{group} Put this customization item in group @var{group}. If this keyword is missing from a customization item, it'll be placed in the same group -as the previous customization item that had a @code{:group} spec (in -the same file). +that was last defined (in the current file). When you use @code{:group} in a @code{defgroup}, it makes the new group a subgroup of @var{group}. commit 79e58003aa91ea1273f2588c3891a6ad9c5d282e Author: Eli Zaretskii Date: Tue May 3 19:14:31 2016 +0300 Improve documentation of Dired's 'A' and 'Q' commands * lisp/dired-aux.el (dired-do-find-regexp) (dired-do-find-regexp-and-replace): Mention 'grep-find-ignored-files' and 'vc-directory-exclusion-list', and also the fact that REGEXP should be palatable by Grep. (Bug#23426) * lisp/dired.el: Update the corresponding autoload forms. * doc/emacs/dired.texi (Operating on Files): Mention 'grep-find-ignored-files' and 'vc-directory-exclusion-list'. (Bug#23429) diff --git a/doc/emacs/dired.texi b/doc/emacs/dired.texi index 089b109..aa717df 100644 --- a/doc/emacs/dired.texi +++ b/doc/emacs/dired.texi @@ -795,6 +795,14 @@ This command is a variant of @code{xref-find-references} where you can navigate between matches and display them as needed using the commands described in @ref{Xref Commands}. +@vindex grep-find-ignored-files @r{(Dired)} +@vindex vc-directory-exclusion-list @r{(Dired)} +If any of the marked files are directories, then this command searches +all of the files in those directories, and any of their +subdirectories, recursively, except files whose names match +@code{grep-find-ignored-files} and subdirectories whose names match +@code{vc-directory-exclusion-list}. + @kindex Q @r{(Dired)} @findex dired-do-find-regexp-and-replace @cindex search and replace in multiple files (in Dired) @@ -809,6 +817,12 @@ and you can use the special commands in that buffer (@pxref{Xref Commands}). In particular, if you exit the query replace loop, you can use @kbd{r} in that buffer to replace more matches. @xref{Identifier Search}. + +Like with @code{dired-do-find-regexp}, if any of the marked files are +directories, this command performs replacements in all of the files in +those directories, and in any of their subdirectories, recursively, +except for files whose names match @code{grep-find-ignored-files} and +subdirectories whose names match @code{vc-directory-exclusion-list}. @end table @node Shell Commands in Dired diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index cef4a96..5ee3c11 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -2720,7 +2720,12 @@ with the command \\[tags-loop-continue]." ;;;###autoload (defun dired-do-find-regexp (regexp) "Find all matches for REGEXP in all marked files. -For any marked directory, all of its files are searched recursively." +For any marked directory, all of its files are searched recursively. +However, files matching `grep-find-ignored-files' and subdirectories +matching `vc-directory-exclusion-list' are skipped in the marked +directories. + +REGEXP should use constructs supported by your local `grep' command." (interactive "sSearch marked files (regexp): ") (require 'grep) (defvar grep-find-ignored-files) @@ -2743,7 +2748,11 @@ For any marked directory, all of its files are searched recursively." (defun dired-do-find-regexp-and-replace (from to) "Replace matches of FROM with TO, in all marked files. For any marked directory, matches in all of its files are replaced, -recursively." +recursively. However, files matching `grep-find-ignored-files' +and subdirectories matching `vc-directory-exclusion-list' are skipped +in the marked directories. + +REGEXP should use constructs supported by your local `grep' command." (interactive (let ((common (query-replace-read-args diff --git a/lisp/dired.el b/lisp/dired.el index 41525a4..2cc3c88 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -4425,13 +4425,22 @@ with the command \\[tags-loop-continue]. (autoload 'dired-do-find-regexp "dired-aux" "\ Find all matches for REGEXP in all marked files. For any marked directory, all of its files are searched recursively. +However, files matching `grep-find-ignored-files' and subdirectories +matching `vc-directory-exclusion-list' are skipped in the marked +directories. + +REGEXP should use constructs supported by your local `grep' command. \(fn REGEXP)" t nil) (autoload 'dired-do-find-regexp-and-replace "dired-aux" "\ Replace matches of FROM with TO, in all marked files. For any marked directory, matches in all of its files are replaced, -recursively. +recursively. However, files matching `grep-find-ignored-files' +and subdirectories matching `vc-directory-exclusion-list' are skipped +in the marked directories. + +REGEXP should use constructs supported by your local `grep' command. \(fn FROM TO)" t nil) commit 2ea2a2f1a5b5b2e1b20f1ee8c86058334d0a2652 Author: Paul Eggert Date: Tue May 3 08:02:16 2016 -0700 Doc fixes for quoting * doc/emacs/text.texi, doc/lispintro/emacs-lisp-intro.texi: * doc/lispref/control.texi, doc/lispref/display.texi: * doc/lispref/help.texi, doc/lispref/strings.texi, lisp/subr.el: * src/callint.c, src/doprnt.c, src/editfns.c: Document quoting a bit more systematically. Problem reported by Alan Mackenzie (Bug#23425). diff --git a/doc/emacs/text.texi b/doc/emacs/text.texi index 66f01b4..579f788 100644 --- a/doc/emacs/text.texi +++ b/doc/emacs/text.texi @@ -862,8 +862,8 @@ indenting the current line. @xref{Indentation}, for details. Text mode turns off the features concerned with comments except when you explicitly invoke them. It changes the syntax table so that -single-quotes are considered part of words (e.g., @samp{don't} is -considered one word). However, if a word starts with a single-quote, +apostrophes are considered part of words (e.g., @samp{don't} is +considered one word). However, if a word starts with an apostrophe, it is treated as a prefix for the purposes of capitalization (e.g., @kbd{M-c} converts @samp{'hello'} into @samp{'Hello'}, as expected). diff --git a/doc/lispintro/emacs-lisp-intro.texi b/doc/lispintro/emacs-lisp-intro.texi index 78c1865..eea46af 100644 --- a/doc/lispintro/emacs-lisp-intro.texi +++ b/doc/lispintro/emacs-lisp-intro.texi @@ -1004,11 +1004,11 @@ the name stands for ``Lots of Isolated Silly Parentheses''. But the claim is unwarranted. Lisp stands for LISt Processing, and the programming language handles @emph{lists} (and lists of lists) by putting them between parentheses. The parentheses mark the boundaries -of the list. Sometimes a list is preceded by a single apostrophe or -quotation mark, @samp{'}@footnote{The single apostrophe or quotation -mark is an abbreviation for the function @code{quote}; you need not -think about functions now; functions are defined in @ref{Making -Errors, , Generate an Error Message}.} Lists are the basis of Lisp. +of the list. Sometimes a list is preceded by an apostrophe @samp{'}, +called a @dfn{single-quote} in Lisp.@footnote{A single-quote is an +abbreviation for the special form @code{quote}; you need not think +about special forms now. @xref{Complications}.} Lists are the basis +of Lisp. @menu * Lisp Lists:: What are lists? @@ -2490,14 +2490,7 @@ in the list and then at the function definition bound to that symbol. Then the instructions in the function definition are carried out. @item -A single quotation mark, -@ifinfo -' -@end ifinfo -@ifnotinfo -@code{'} -@end ifnotinfo -, tells the Lisp interpreter that it should +A single-quote @samp{'} 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. @@ -7610,7 +7603,8 @@ displays in which grave accent and apostrophe were often mirror images suitable for use as quotes. On most modern displays this is no longer true, and when these two ASCII characters appear in documentation strings or diagnostic message formats, Emacs typically transliterates -them to curved single quotes, so that the abovequoted symbol appears +them to @dfn{curved quotes} (left and right single quotation marks), +so that the abovequoted symbol appears as @t{‘case-fold-search’}. Source-code strings can also simply use curved quotes directly. @@ -17117,7 +17111,7 @@ This line is a short, but complete Emacs Lisp expression. We are already familiar with @code{setq}. It sets the following variable, @code{major-mode}, to the subsequent value, which is @code{text-mode}. -The single quote mark before @code{text-mode} tells Emacs to deal directly +The single-quote before @code{text-mode} tells Emacs to deal directly with the @code{text-mode} symbol, not with whatever it might stand for. @xref{set & setq, , Setting the Value of a Variable}, for a reminder of how @code{setq} works. @@ -17284,11 +17278,11 @@ 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 +@code{compare-windows} is preceded by a single-quote; otherwise, Emacs would first try to evaluate the symbol to determine its value. These three things, the double quotation marks, the backslash before -the @samp{C}, and the single quote mark are necessary parts of +the @samp{C}, and the single-quote are necessary parts of keybinding that I tend to forget. Fortunately, I have come to remember that I should look at my existing @file{.emacs} file, and adapt what is there. diff --git a/doc/lispref/control.texi b/doc/lispref/control.texi index 3f48c45..75d8d28 100644 --- a/doc/lispref/control.texi +++ b/doc/lispref/control.texi @@ -1100,10 +1100,12 @@ These examples show typical uses of @code{error}: error symbol @code{error}, and a list containing the string returned by @code{format-message}. -In a format string containing single quotes, curved quotes @t{‘like -this’} and grave quotes @t{`like this'} work better than straight -quotes @t{'like this'}, as @code{error} typically formats every -straight quote as a curved closing quote. +A format that quotes with grave accents and apostrophes @t{`like +this'} typically generates curved quotes @t{‘like this’}. In +contrast, a format that quotes with only apostrophes @t{'like this'} +typically generates two closing curved quotes @t{’like this’}, an +unusual style in English. @xref{Keys in Documentation}, for how the +@code{text-quoting-style} variable affects generated quotes. @strong{Warning:} If you want to use your own string as an error message verbatim, don't just write @code{(error @var{string})}. If @var{string} diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index c80f78c..b0cd873 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -265,10 +265,12 @@ properties, it is displayed with the specified faces (@pxref{Faces}). The string is also added to the @file{*Messages*} buffer, but without text properties (@pxref{Logging Messages}). -In a format string containing single quotes, curved quotes @t{‘like -this’} and grave quotes @t{`like this'} work better than straight -quotes @t{'like this'}, as @code{message} typically formats every -straight quote as a curved closing quote. +A format that quotes with grave accents and apostrophes @t{`like +this'} typically generates curved quotes @t{‘like this’}. In +contrast, a format that quotes with only apostrophes @t{'like this'} +typically generates two closing curved quotes @t{’like this’}, an +unusual style in English. @xref{Keys in Documentation}, for how the +@code{text-quoting-style} variable affects generated quotes. In batch mode, the message is printed to the standard error stream, followed by a newline. diff --git a/doc/lispref/help.texi b/doc/lispref/help.texi index 58a11f2..b945e43 100644 --- a/doc/lispref/help.texi +++ b/doc/lispref/help.texi @@ -335,10 +335,14 @@ specifies @var{mapvar}'s value as the keymap for any following @item ‘ @itemx ` (left single quotation mark and grave accent) both stand for a left quote. +This generates a left single quotation mark, an apostrophe, or a grave +accent depending on the value of @code{text-quoting-style}. @item ’ @itemx ' (right single quotation mark and apostrophe) both stand for a right quote. +This generates a right single quotation mark or an apostrophe +depending on the value of @code{text-quoting-style}. @item \= quotes the following character and is discarded; thus, @samp{\=`} puts diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi index 9d6613c..c6563f7 100644 --- a/doc/lispref/strings.texi +++ b/doc/lispref/strings.texi @@ -834,8 +834,14 @@ if any. This function acts like @code{format}, except it also converts any curved single quotes in @var{string} as per the value of @code{text-quoting-style}, and treats grave accent (@t{`}) and -apostrophe (@t{'}) as if they were curved single quotes. @xref{Keys -in Documentation}. +apostrophe (@t{'}) as if they were curved single quotes. + +A format that quotes with grave accents and apostrophes @t{`like +this'} typically generates curved quotes @t{‘like this’}. In +contrast, a format that quotes with only apostrophes @t{'like this'} +typically generates two closing curved quotes @t{’like this’}, an +unusual style in English. @xref{Keys in Documentation}, for how the +@code{text-quoting-style} variable affects generated quotes. @end defun @cindex @samp{%} in format diff --git a/lisp/subr.el b/lisp/subr.el index 0f02170..3ac61f9 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -290,21 +290,27 @@ This function accepts any number of arguments, but ignores them." ;; Signal a compile-error if the first arg is missing. (defun error (&rest args) - "Signal an error, making error message by passing all args to `format'. + "Signal an error, making a message by passing args to `format-message'. In Emacs, the convention is that error messages start with a capital letter but *do not* end with a period. Please follow this convention -for the sake of consistency." +for the sake of consistency. + +Note: (error \"%s\" VALUE) makes the message VALUE without +interpreting format characters like `%', `\\=`', and `\\=''." (declare (advertised-calling-convention (string &rest args) "23.1")) (signal 'error (list (apply #'format-message args)))) (defun user-error (format &rest args) - "Signal a pilot error, making error message by passing all args to `format'. + "Signal a pilot error, making a message by passing args to `format-message'. In Emacs, the convention is that error messages start with a capital letter but *do not* end with a period. Please follow this convention for the sake of consistency. This is just like `error' except that `user-error's are expected to be the result of an incorrect manipulation on the part of the user, rather than the -result of an actual problem." +result of an actual problem. + +Note: (user-error \"%s\" VALUE) makes the message VALUE without +interpreting format characters like `%', `\\=`', and `\\=''." (signal 'user-error (list (apply #'format-message format args)))) (defun define-error (name message &optional parent) diff --git a/src/callint.c b/src/callint.c index e56f7cd..053ee6c 100644 --- a/src/callint.c +++ b/src/callint.c @@ -272,7 +272,7 @@ invoke it. If KEYS is omitted or nil, the return value of { /* `args' will contain the array of arguments to pass to the function. `visargs' will contain the same list but in a nicer form, so that if we - pass it to `Fformat' it will be understandable to a human. */ + pass it to `Fformat_message' it will be understandable to a human. */ Lisp_Object *args, *visargs; Lisp_Object specs; Lisp_Object filter_specs; diff --git a/src/doprnt.c b/src/doprnt.c index 506bbc3..9d8b783 100644 --- a/src/doprnt.c +++ b/src/doprnt.c @@ -46,15 +46,15 @@ along with GNU Emacs. If not, see . */ ignored %s and %c conversions. (See below for the detailed documentation of what is supported.) However, this is okay, as this function is supposed to be called from `error' and similar functions, and thus does not need to - support features beyond those in `Fformat', which is used by `error' on the - Lisp level. */ + support features beyond those in `Fformat_message', which is used + by `error' on the Lisp level. */ /* In the FORMAT argument this function supports ` and ' as directives that output left and right quotes as per ‘text-quoting style’. It also supports the following %-sequences: %s means print a string argument. - %S is silently treated as %s, for loose compatibility with `Fformat'. + %S is treated as %s, for loose compatibility with `Fformat_message'. %d means print a `signed int' argument in decimal. %o means print an `unsigned int' argument in octal. %x means print an `unsigned int' argument in hex. diff --git a/src/editfns.c b/src/editfns.c index f0ce4e7..a858e6e 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -3665,10 +3665,11 @@ In batch mode, the message is printed to the standard error stream, followed by a newline. The first argument is a format control string, and the rest are data -to be formatted under control of the string. See `format' for details. +to be formatted under control of the string. See `format-message' for +details. -Note: Use (message "%s" VALUE) to print the value of expressions and -variables to avoid accidentally interpreting `%' as format specifiers. +Note: (message "%s" VALUE) displays the string VALUE without +interpreting format characters like `%', `\\=`', and `\\=''. If the first argument is nil or the empty string, the function clears any existing message; this lets the minibuffer contents show. See @@ -3696,7 +3697,8 @@ DEFUN ("message-box", Fmessage_box, Smessage_box, 1, MANY, 0, doc: /* Display a message, in a dialog box if possible. If a dialog box is not available, use the echo area. The first argument is a format control string, and the rest are data -to be formatted under control of the string. See `format' for details. +to be formatted under control of the string. See `format-message' for +details. If the first argument is nil or the empty string, clear any existing message; let the minibuffer contents show. @@ -3727,7 +3729,8 @@ If this command was invoked with the mouse, use a dialog box if `use-dialog-box' is non-nil. Otherwise, use the echo area. The first argument is a format control string, and the rest are data -to be formatted under control of the string. See `format' for details. +to be formatted under control of the string. See `format-message' for +details. If the first argument is nil or the empty string, clear any existing message; let the minibuffer contents show. commit 8544b9879c652e7c700652a4ba6fd17245163bd4 Author: Lars Ingebrigtsen Date: Tue May 3 00:08:31 2016 +0200 posnp doc clarification * lisp/subr.el (posnp): Mention that a posn object is returned from `event-start' (bug#18211). diff --git a/lisp/subr.el b/lisp/subr.el index 3f5d6e4..0f02170 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1117,6 +1117,7 @@ The return value is a positive integer." (defun posnp (obj) "Return non-nil if OBJ appears to be a valid `posn' object specifying a window. +A `posn' object is returned from functions such as `event-start'. If OBJ is a valid `posn' object, but specifies a frame rather than a window, return nil." ;; FIXME: Correct the behavior of this function so that all valid commit 805204f3efdf3e9cb3ccd2783b7ba44f8c1fdb5a Author: Lars Ingebrigtsen Date: Tue May 3 00:02:50 2016 +0200 Mention what a missing :group does * doc/lispref/customize.texi (Common Keywords): Document that a missing :group reuses the group from the preceding item (bug#21601). diff --git a/doc/lispref/customize.texi b/doc/lispref/customize.texi index 14e6eb3..de130d5 100644 --- a/doc/lispref/customize.texi +++ b/doc/lispref/customize.texi @@ -66,9 +66,13 @@ cause confusion.} @kindex group@r{, customization keyword} @item :group @var{group} -Put this customization item in group @var{group}. When you use -@code{:group} in a @code{defgroup}, it makes the new group a subgroup of -@var{group}. +Put this customization item in group @var{group}. If this keyword is +missing from a customization item, it'll be placed in the same group +as the previous customization item that had a @code{:group} spec (in +the same file). + +When you use @code{:group} in a @code{defgroup}, it makes the new +group a subgroup of @var{group}. If you use this keyword more than once, you can put a single item into more than one group. Displaying any of those groups will show this commit ec554d7741d2ff2828ecaa437cc26a6e615f1319 Author: Eli Zaretskii Date: Mon May 2 22:57:06 2016 +0300 Fix documentation of dired-aux search/replace commands * lisp/dired-aux.el (dired-do-find-regexp) (dired-do-find-regexp-and-replace): Doc fixes. (Bug#23429) * lisp/dired.el: Update the corresponding autoload forms. diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 08db187..cef4a96 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -2719,7 +2719,8 @@ with the command \\[tags-loop-continue]." ;;;###autoload (defun dired-do-find-regexp (regexp) - "Find all matches for REGEXP in all marked files, recursively." + "Find all matches for REGEXP in all marked files. +For any marked directory, all of its files are searched recursively." (interactive "sSearch marked files (regexp): ") (require 'grep) (defvar grep-find-ignored-files) @@ -2740,7 +2741,9 @@ with the command \\[tags-loop-continue]." ;;;###autoload (defun dired-do-find-regexp-and-replace (from to) - "Replace matches of FROM with TO, in all marked files, recursively." + "Replace matches of FROM with TO, in all marked files. +For any marked directory, matches in all of its files are replaced, +recursively." (interactive (let ((common (query-replace-read-args diff --git a/lisp/dired.el b/lisp/dired.el index ab111be..41525a4 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -3919,7 +3919,7 @@ Ask means pop up a menu for the user to select one of copy, move or link." ;;; Start of automatically extracted autoloads. -;;;### (autoloads nil "dired-aux" "dired-aux.el" "6b3eb2080834b976621adc041c42f5cc") +;;;### (autoloads nil "dired-aux" "dired-aux.el" "00fe45cfae47cace47cffc09afca6832") ;;; Generated autoloads from dired-aux.el (autoload 'dired-diff "dired-aux" "\ @@ -4423,12 +4423,15 @@ with the command \\[tags-loop-continue]. \(fn FROM TO &optional DELIMITED)" t nil) (autoload 'dired-do-find-regexp "dired-aux" "\ -Find all matches for REGEXP in all marked files, recursively. +Find all matches for REGEXP in all marked files. +For any marked directory, all of its files are searched recursively. \(fn REGEXP)" t nil) (autoload 'dired-do-find-regexp-and-replace "dired-aux" "\ -Replace matches of FROM with TO, in all marked files, recursively. +Replace matches of FROM with TO, in all marked files. +For any marked directory, matches in all of its files are replaced, +recursively. \(fn FROM TO)" t nil)