From ec554d7741d2ff2828ecaa437cc26a6e615f1319 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Mon, 2 May 2016 22:57:06 +0300 Subject: 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. --- lisp/dired-aux.el | 7 +++++-- lisp/dired.el | 9 ++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'lisp') diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 08db1877f1a..cef4a96b763 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 ab111bed1b1..41525a45595 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) -- cgit v1.2.1 From 8544b9879c652e7c700652a4ba6fd17245163bd4 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Tue, 3 May 2016 00:08:31 +0200 Subject: posnp doc clarification * lisp/subr.el (posnp): Mention that a posn object is returned from `event-start' (bug#18211). --- lisp/subr.el | 1 + 1 file changed, 1 insertion(+) (limited to 'lisp') diff --git a/lisp/subr.el b/lisp/subr.el index 3f5d6e427e9..0f021701e9f 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 -- cgit v1.2.1 From 2ea2a2f1a5b5b2e1b20f1ee8c86058334d0a2652 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 3 May 2016 08:02:16 -0700 Subject: 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). --- lisp/subr.el | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'lisp') diff --git a/lisp/subr.el b/lisp/subr.el index 0f021701e9f..3ac61f9a45f 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) -- cgit v1.2.1 From 79e58003aa91ea1273f2588c3891a6ad9c5d282e Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Tue, 3 May 2016 19:14:31 +0300 Subject: 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) --- lisp/dired-aux.el | 13 +++++++++++-- lisp/dired.el | 11 ++++++++++- 2 files changed, 21 insertions(+), 3 deletions(-) (limited to 'lisp') diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index cef4a96b763..5ee3c118cb1 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 41525a45595..2cc3c88dbc0 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) -- cgit v1.2.1 From 6f82d8ef7d3aea2d05677d2792f89b8e6084d66a Mon Sep 17 00:00:00 2001 From: Dmitry Gutov Date: Wed, 4 May 2016 00:42:43 +0300 Subject: 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. --- lisp/progmodes/xref.el | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lisp') diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index b5632af13ab..540c7b0e925 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) -- cgit v1.2.1 From 6428aa044ad872e9b8b60d825b7cbcb38ae3e492 Mon Sep 17 00:00:00 2001 From: Dmitry Gutov Date: Wed, 4 May 2016 01:02:43 +0300 Subject: 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. --- lisp/dired-aux.el | 7 ++++--- lisp/dired.el | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'lisp') diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 5ee3c118cb1..b9111a8d5b4 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 2cc3c88dbc0..b838e649848 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. -- cgit v1.2.1 From 4d8fd9cf338cf9b5dfc613657adfeabff2d9c14e Mon Sep 17 00:00:00 2001 From: Dmitry Gutov Date: Wed, 4 May 2016 01:59:29 +0300 Subject: 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. --- lisp/progmodes/xref.el | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'lisp') diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 540c7b0e925..62cef235988 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)) -- cgit v1.2.1 From 0932b948971770201b135d5f0dee82b91a1eef92 Mon Sep 17 00:00:00 2001 From: Stephen Berman Date: Wed, 4 May 2016 21:52:32 +0200 Subject: 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. --- lisp/calendar/todo-mode.el | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) (limited to 'lisp') diff --git a/lisp/calendar/todo-mode.el b/lisp/calendar/todo-mode.el index 0529e970333..8e752586053 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. -- cgit v1.2.1 From 3fe351072841becbb1902c19f784890949f41c1d Mon Sep 17 00:00:00 2001 From: Juri Linkov Date: Wed, 4 May 2016 23:05:33 +0300 Subject: * 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) --- lisp/replace.el | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'lisp') diff --git a/lisp/replace.el b/lisp/replace.el index 801c6058f74..26e5875dc08 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) -- cgit v1.2.1 From 922c7a3e48e649ad67bd12b1f83343b730dd1bc4 Mon Sep 17 00:00:00 2001 From: Dmitry Gutov Date: Thu, 5 May 2016 02:52:34 +0300 Subject: 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. --- lisp/progmodes/xref.el | 131 ++++++++++++++++++++++++++++++------------------- 1 file changed, 81 insertions(+), 50 deletions(-) (limited to 'lisp') diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 62cef235988..17bfdb69f8f 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))) -- cgit v1.2.1 From ab3ba912fc7b91b7b147ea36fabe461dc99a9fb8 Mon Sep 17 00:00:00 2001 From: Dmitry Gutov Date: Thu, 5 May 2016 04:15:23 +0300 Subject: 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 `~'. --- lisp/progmodes/project.el | 3 ++- lisp/progmodes/xref.el | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'lisp') diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 9c8a88c80fc..a51c383b93b 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 17bfdb69f8f..1c28390258c 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 -- cgit v1.2.1 From 1a4127dbd625ea64f535b3bd09844a99161290a6 Mon Sep 17 00:00:00 2001 From: Dmitry Gutov Date: Thu, 5 May 2016 04:28:14 +0300 Subject: 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. --- lisp/progmodes/elisp-mode.el | 5 +++-- lisp/progmodes/etags.el | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'lisp') diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index fc4501d0cbe..6c6c3803f9e 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 a2a0df2d6e1..890d55294cf 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 -- cgit v1.2.1 From 3347a733e0778dfefaeabe28ae73f4226236a881 Mon Sep 17 00:00:00 2001 From: Dmitry Gutov Date: Thu, 5 May 2016 16:01:52 +0300 Subject: `nreverse' the marker pairs list * lisp/progmodes/xref.el (xref--buf-pairs-iterator): `nreverse' the marker pairs list for each buffer before returning. --- lisp/progmodes/xref.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lisp') diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 1c28390258c..f651dc9cd18 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) -- cgit v1.2.1 From 50650cb6887d99b01eeb1e686fc1f695c2a0c64a Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 5 May 2016 12:48:33 -0700 Subject: 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. --- lisp/cedet/cedet-cscope.el | 2 +- lisp/cedet/semantic/symref.el | 2 +- lisp/man.el | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'lisp') diff --git a/lisp/cedet/cedet-cscope.el b/lisp/cedet/cedet-cscope.el index 9a54d341f56..373149c16e3 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 088740b2624..516a4f30414 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 2b2ee99a9be..5acf90baf28 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" -- cgit v1.2.1