]> code.delx.au - gnu-emacs-elpa/blobdiff - packages/el-search/el-search.el
Improve documentation and argument names of el-search-query-replace
[gnu-emacs-elpa] / packages / el-search / el-search.el
index c7b3499044464dc0f4d63fda00f67b521f9b1915..f0d7416fe679afd085e8dddaca6d14cf7a48c7bc 100644 (file)
@@ -65,7 +65,7 @@
 ;;   `(defvar ,_)
 ;;
 ;; you search for all defvar forms that don't specify an init value.
-;; 
+;;
 ;; The following will search for defvar forms with a docstring whose
 ;; first line is longer than 70 characters:
 ;;
 ;;    (define-key isearch-mode-map [(control ?%)] #'el-search-replace-from-isearch)
 ;;
 ;; The bindings in `isearch-mode-map' let you conveniently switch to
-;; elisp searching from isearch.
+;; "el-search" searching from isearch.
 ;;
 ;;
 ;; Bugs, Known Limitations
 ;;
 ;; the comment will be lost.
 ;;
+;; FIXME: when we have resumable sessions, pause and warn about this case.
+;;
 ;;
 ;;  Acknowledgments
 ;;  ===============
 ;; TODO:
 ;;
 ;; - detect infloops when replacing automatically (e.g. for 1 -> '(1))
+;;   Should we just fall back to interactive mode?
 ;;
 ;; - implement backward searching
 ;;
+;; - Make `el-search-pattern' accept an &optional limit, at least for
+;;   the non-interactive use case?
+;;
 ;; - improve docstrings
 ;;
 ;; - handle more reader syntaxes, e.g. #n, #n#
@@ -345,6 +351,7 @@ error."
 Don't move if already at beginning of a sexp.  Point must not be
 inside a string or comment.  `read' the expression at that point
 and return it."
+  ;; This doesn't catch end-of-buffer to keep the return value non-ambiguous
   (let ((not-done t) res)
     (while not-done
       (let ((stop-here nil)
@@ -680,7 +687,7 @@ of any kind matched by all PATTERNs are also matched.
    ((null (cdr patterns))
     (let ((pattern (car patterns)))
       `(app ,(apply-partially #'el-search--contains-p (el-search--matcher pattern))
-            (,'\`  (t (,'\, ,pattern))))))
+            (,'\` (t (,'\, ,pattern))))))
    (t `(and ,@(mapcar (lambda (pattern) `(contains ,pattern)) patterns)))))
 
 (el-search-defpattern not (pattern)
@@ -977,7 +984,7 @@ Hit any key to proceed."
                 (funcall do-replace)
               (while (not (pcase (if replaced-this
                                      (read-char-choice "[SPC ! q]  (? for help)"
-                                                       '(?\ ?! ?q ?n ??))
+                                                       '(?\ ?! ?q ?\C-g ?n ??))
                                    (read-char-choice
                                     (concat "Replace this occurrence"
                                             (if (or (string-match-p "\n" to-insert)
@@ -986,7 +993,7 @@ Hit any key to proceed."
                                             "? "
                                             (if splice "{splice} " "")
                                             "[y SPC r ! s q]  (? for help)" )
-                                    '(?y ?n ?r ?\ ?! ?q ?s ??)))
+                                    '(?y ?n ?r ?\ ?! ?q ?\C-g ?s ??)))
                             (?r (funcall do-replace)
                                 nil)
                             (?y (funcall do-replace)
@@ -1001,8 +1008,9 @@ Hit any key to proceed."
                             (?s (cl-callf not splice)
                                 (setq to-insert (funcall get-replacement-string))
                                 nil)
-                            (?q (setq done t)
-                                t)
+                            ((or ?q ?\C-g)
+                             (setq done t)
+                             t)
                             (?? (ignore (read-char el-search-search-and-replace-help-string))
                                 nil)))))
             (unless (or done (eobp)) (el-search--skip-expression nil t)))))
@@ -1015,19 +1023,26 @@ Hit any key to proceed."
 
 (defun el-search-query-replace-read-args ()
   (barf-if-buffer-read-only)
-  (let* ((from (el-search--read-pattern "Replace from: "))
+  (let* ((from (el-search--read-pattern "Query replace pattern: "))
          (to   (let ((el-search--initial-mb-contents nil))
                  (el-search--read-pattern "Replace with result of evaluation of: " from))))
     (list (el-search--wrap-pattern (read from)) (read to) to)))
 
 ;;;###autoload
-(defun el-search-query-replace (from to &optional to-input-string)
-  "Replace some occurrences of FROM pattern with evaluated TO."
+(defun el-search-query-replace (from-pattern to-expr &optional textual-to)
+  "Replace some matches of \"el-search\" pattern FROM-PATTERN.
+
+TO-EXPR is an Elisp expression that is evaluated repeatedly for
+each match with bindings created in FROM-PATTERN in effect to
+produce a replacement expression.
+
+As each match is found, the user must type a character saying
+what to do with it.  For directions, type ? at that time."
   (interactive (el-search-query-replace-read-args))
   (setq this-command 'el-search-query-replace) ;in case we come from isearch
-  (setq el-search-current-pattern from)
+  (setq el-search-current-pattern from-pattern)
   (barf-if-buffer-read-only)
-  (el-search-search-and-replace-pattern from to nil to-input-string))
+  (el-search-search-and-replace-pattern from-pattern to-expr nil textual-to))
 
 (defun el-search--take-over-from-isearch (&optional goto-left-end)
   (let ((other-end (and goto-left-end isearch-other-end))