[elpa] master 24ce066: packages/javaimp: Restructure code, add some tests.
branch: master commit 24ce066b6a6a195cdb06bbf87b92df502718806f Author: Filipp Gunbin Commit: Filipp Gunbin packages/javaimp: Restructure code, add some tests. * Restructure xml parsing code for test convenience. * Add 2 simple tests. --- packages/javaimp/javaimp-tests.el | 23 + packages/javaimp/javaimp.el | 197 + 2 files changed, 113 insertions(+), 107 deletions(-) diff --git a/packages/javaimp/javaimp-tests.el b/packages/javaimp/javaimp-tests.el new file mode 100644 index 000..cd8acb2 --- /dev/null +++ b/packages/javaimp/javaimp-tests.el @@ -0,0 +1,23 @@ +;;; javaimp-tests.el --- javaimp module tests -*- lexical-binding: t; -*- + +;; Copyright (C) 2016 Free Software Foundation, Inc. + +;; Author: Filipp Gunbin +;; Maintainer: Filipp Gunbin + +(require 'ert) +(require 'javaimp) + +(ert-deftest javaimp-test--maven-xml-extract-projects--project () + (with-temp-buffer +(insert "") +(let ((projects (javaimp--maven-xml-extract-projects +(xml-parse-region (point-min) (point-max) + (should (eql (length projects) 1) + +(ert-deftest javaimp-test--maven-xml-extract-projects--projects () + (with-temp-buffer +(insert "") +(let ((projects (javaimp--maven-xml-extract-projects +(xml-parse-region (point-min) (point-max) + (should (eql (length projects) 2) diff --git a/packages/javaimp/javaimp.el b/packages/javaimp/javaimp.el index a14d3da..52abbaa 100644 --- a/packages/javaimp/javaimp.el +++ b/packages/javaimp/javaimp.el @@ -245,7 +245,14 @@ module file." (equal (javaimp-module-file (javaimp-node-contents tree)) file)) javaimp-project-forest)) -(let ((tree (javaimp--maven-xml-load-tree file))) +(message "Loading file %s..." file) +(let* ((xml-tree + (javaimp--maven-call file "help:effective-pom" +#'javaimp--maven-xml-effective-pom-handler)) + (projects (javaimp--maven-xml-extract-projects xml-tree)) + (modules (mapcar #'javaimp--maven-xml-parse-project projects)) + ;; first module is always root + (tree (javaimp--maven-build-tree (car modules) nil modules file))) (if tree (push tree javaimp-project-forest))) (message "Loaded tree for %s" file))) @@ -253,72 +260,46 @@ module file." ;; Maven XML routines -(defun javaimp--maven-xml-load-tree (file) - "Invokes `mvn help:effective-pom' on FILE and using its output -creates a tree of Maven projects starting from FILE. Children -which link to the parent via the element are inheriting -children and are also included. Subordinate modules with no -inheritance are not included." - (let ((xml-tree (javaimp--maven-xml-read-effective-pom file))) -(cond ((assq 'project xml-tree) - (let* ((project-elt (assq 'project xml-tree)) - (submodules (javaimp--xml-children - (javaimp--xml-child 'modules project-elt) - 'module))) -(and submodules - ;; no real children - (message "Independent submodules: %s" - (mapconcat #'javaimp--xml-first-child submodules ", "))) -(let ((module (javaimp--maven-xml-parse-module project-elt))) - (javaimp--maven-build-tree - (javaimp-module-id module) nil (list module) file - ((assq 'projects xml-tree) - ;; we have are inheriting children - they and their children, if - ;; any, are listed in a linear list - (let* ((project-elts (javaimp--xml-children -(assq 'projects xml-tree) 'project)) - (all-modules (mapcar #'javaimp--maven-xml-parse-module project-elts))) -(message "Total modules: %d" (length all-modules)) -(javaimp--maven-build-tree - (javaimp-module-id (car all-modules)) nil all-modules file))) +(defun javaimp--maven-xml-effective-pom-handler () + (let ((start +(save-excursion + (progn +(goto-char (point-min)) +(re-search-forward "<\\?xml\\|")) +(match-end 0) +(xml-parse-region start end))) + +(defun javaimp--maven-xml-extract-projects (xml-tree) + "Analyzes result of `mvn help:effective-pom' and returns list +of elements" + (let ((project (assq 'project xml-tree)) + (projects (assq 'projects xml-tree))) +(cond (project + (list project)) + (projects + (javaimp--xml-children projects 'project)) (t - ;; neither nor - error - (error "Invalid `help:effective-pom' output") - -(defun javaimp--maven-xml-read-effective-pom (pom) - "Calls `mvn help:effective:pom and returns XML parse tree" - (message "Loading root pom %s..." pom) - (javaimp--maven-call -
[elpa] master 536fab6 15/24: Give el-search--s a more meaningful name
branch: master commit 536fab673d45a8df019da0e813aded5db25c88d8 Author: Michael Heerdegen Commit: Michael Heerdegen Give el-search--s a more meaningful name Rename `el-search--s' to `el-search--transform-nontrivial-lpat'. --- packages/el-search/el-search.el |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/el-search/el-search.el b/packages/el-search/el-search.el index 4afcd91..ed2efcf 100644 --- a/packages/el-search/el-search.el +++ b/packages/el-search/el-search.el @@ -756,7 +756,7 @@ matches any of these expressions: "argument not a string or vector") `(pred (el-search--match-key-sequence ,key-sequence))) -(defun el-search--s (expr) +(defun el-search--transform-nontrivial-lpat (expr) (cond ((symbolp expr) `(or (symbol ,(symbol-name expr)) (,'\` (,'quote(,'\, (symbol ,(symbol-name expr) @@ -807,7 +807,7 @@ could use this pattern: ('_ '`(,_)) ('_? '(or '() `(,_))) ;FIXME: useful - document? or should we provide a (? PAT) ;thing? -(_ `(,'\` ((,'\, ,(el-search--s elt))) +(_ `(,'\` ((,'\, ,(el-search--transform-nontrivial-lpat elt))) lpats) ,@(if match-end '() '(_)
[elpa] master b885ef1 03/24: el-search--check-pattern-args: make arg TYPE a string
branch: master commit b885ef128521e85f46c83ba51f44f2d8098beeb0 Author: Michael Heerdegen Commit: Michael Heerdegen el-search--check-pattern-args: make arg TYPE a string --- packages/el-search/el-search.el | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/el-search/el-search.el b/packages/el-search/el-search.el index 764d77e..84fb1c8 100644 --- a/packages/el-search/el-search.el +++ b/packages/el-search/el-search.el @@ -546,11 +546,11 @@ return nil (no error)." (defun el-search--check-pattern-args (type args predicate &optional message) "Check whether all ARGS fulfill PREDICATE. -Raise an error if not. TYPE and optional argument MESSAGE are -used to construct the error message." +Raise an error if not. The string arguments TYPE and optional +MESSAGE are used to construct the error message." (mapc (lambda (arg) (unless (funcall predicate arg) -(error (concat "Pattern `%S': " +(error (concat "Pattern `%s': " (or message (format "argument doesn't fulfill %S" predicate)) ": %S") type arg))) @@ -617,7 +617,7 @@ matches the list (1 2 3 4 5 6 7 8 9) and binds `x' to (4 5 6)." (el-search-defpattern string (&rest regexps) "Matches any string that is matched by all REGEXPS." - (el-search--check-pattern-args 'string regexps #'el-search--stringish-p + (el-search--check-pattern-args "string" regexps #'el-search--stringish-p "Argument not a string") `(and (pred stringp) ,@(mapcar (lambda (thing) `(pred (el-search--smart-string-match-p @@ -626,7 +626,7 @@ matches the list (1 2 3 4 5 6 7 8 9) and binds `x' to (4 5 6)." (el-search-defpattern symbol (&rest regexps) "Matches any symbol whose name is matched by all REGEXPS." - (el-search--check-pattern-args 'symbol regexps #'el-search--stringish-p + (el-search--check-pattern-args "symbol" regexps #'el-search--stringish-p "Argument not a string") `(and (pred symbolp) (app symbol-name (string ,@regexps @@ -684,7 +684,7 @@ REGEXP can also be a symbol, in which case (concat \"^\" (symbol-name regexp) \"$\") is used as regular expression." - (el-search--check-pattern-args 'source (list regexp) #'el-search--stringish-p + (el-search--check-pattern-args "source" (list regexp) #'el-search--stringish-p "Argument not a string") `(pred (el-search--match-symbol-file ,(if (symbolp regexp) (symbol-name regexp) regexp @@ -716,7 +716,7 @@ matches any of these expressions: [(control ?s)]" (when (eq (car-safe key-sequence) 'kbd) (setq key-sequence (kbd (cadr key-sequence - (el-search--check-pattern-args 'keys (list key-sequence) (lambda (x) (or (stringp x) (vectorp x))) + (el-search--check-pattern-args "keys" (list key-sequence) (lambda (x) (or (stringp x) (vectorp x))) "argument not a string or vector") `(pred (el-search--match-key-sequence ,key-sequence)))
[elpa] master c356b2d 19/24: Rename a local variable
branch: master commit c356b2dd3e09715d82f8c2da212e891fd5dfd9c3 Author: Michael Heerdegen Commit: Michael Heerdegen Rename a local variable --- packages/el-search/el-search.el |6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/el-search/el-search.el b/packages/el-search/el-search.el index 0f40e83..7cfe477 100644 --- a/packages/el-search/el-search.el +++ b/packages/el-search/el-search.el @@ -1016,12 +1016,12 @@ Hit any key to proceed." (unless (eq this-command last-command) (el-search-hl-other-matches pattern))) (let* ((region (list (point) (el-search--end-of-sexp))) - (substring (apply #'buffer-substring-no-properties region)) - (expr (read substring)) + (original-text (apply #'buffer-substring-no-properties region)) + (expr (read original-text)) (replaced-this nil) (new-expr (funcall get-replacement expr)) (get-replacement-string - (lambda () (el-search--format-replacement new-expr substring to-input-string splice))) + (lambda () (el-search--format-replacement new-expr original-text to-input-string splice))) (to-insert (funcall get-replacement-string)) (replacement-contains-another-match (with-temp-buffer
[elpa] master 91192f5 10/24: Add patterns for character properties
branch: master commit 91192f5895f2e4d1ff8eec6faeab40099867ac89 Author: Michael Heerdegen Commit: Michael Heerdegen Add patterns for character properties --- packages/el-search/el-search.el | 50 +++ 1 file changed, 50 insertions(+) diff --git a/packages/el-search/el-search.el b/packages/el-search/el-search.el index db57a5e..a15a2d4 100644 --- a/packages/el-search/el-search.el +++ b/packages/el-search/el-search.el @@ -803,6 +803,56 @@ could use this pattern: lpats) ,@(if match-end '() '(_) +(el-search-defpattern char-prop (property) + "Matches the object if completely covered with PROPERTY. +This pattern matches the object if its representation in the +search buffer is completely covered with the character property +PROPERTY. + +This pattern always tests the complete expression in the search +buffer, it is not possible to test subexpressions calculated in +the search pattern." + `(guard (and (get-char-property (point) ',property) + ,(macroexp-let2 nil limit '(scan-sexps (point) 1) + `(= (next-single-char-property-change + (point) ',property nil ,limit) + ,limit) + +(el-search-defpattern includes-prop (property) + "Matches the object if partly covered with PROPERTY. +This pattern matches the object if its representation in the +search buffer is partly covered with the character property +PROPERTY. + +This pattern always tests the complete expression in the search +buffer, it is not possible to test subexpressions calculated in +the search pattern." + `(guard (or (get-char-property (point) ',property) + ,(macroexp-let2 nil limit '(scan-sexps (point) 1) + `(not (= (next-single-char-property-change + (point) ',property nil ,limit) + ,limit)) + +(el-search-defpattern change () + "Matches the object if it is part of a change. +This is equivalent to (char-prop diff-hl-hunk). + +You need `diff-hl-mode' turned on, provided by the library +\"diff-hl\" available in Gnu Elpa." + (or (bound-and-true-p diff-hl-mode) + (error "diff-hl-mode not enabled")) + '(char-prop diff-hl-hunk)) + +(el-search-defpattern changed () + "Matches the object if it contains a change. +This is equivalent to (includes-prop diff-hl-hunk). + +You need `diff-hl-mode' turned on, provided by the library +\"diff-hl\" available in Gnu Elpa." + (or (bound-and-true-p diff-hl-mode) + (error "diff-hl-mode not enabled")) + '(includes-prop diff-hl-hunk)) + Highlighting
[elpa] master b09bb1b 16/24: Use `pp-to-string' to print replacement expression
branch: master commit b09bb1b61d57fee70a6b83f576ead0fee0f329bd Author: Michael Heerdegen Commit: Michael Heerdegen Use `pp-to-string' to print replacement expression --- packages/el-search/el-search.el | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/el-search/el-search.el b/packages/el-search/el-search.el index ed2efcf..eba4a5d 100644 --- a/packages/el-search/el-search.el +++ b/packages/el-search/el-search.el @@ -292,11 +292,10 @@ error." case-fold-search))) (string-match-p regexp string))) -(defun el-search--print (expr) - (let ((print-quoted t) -(print-length nil) +(defun el-search--pp-to-string (expr) + (let ((print-length nil) (print-level nil)) -(prin1-to-string expr))) +(pp-to-string expr))) (defvar el-search-read-expression-map (let ((map (make-sparse-keymap))) @@ -518,8 +517,8 @@ return nil (no error)." (with-temp-buffer (emacs-lisp-mode) (insert (if splice -(mapconcat #'el-search--print replacement " ") - (el-search--print replacement))) +(mapconcat #'el-search--pp-to-string replacement " ") + (el-search--pp-to-string replacement))) (goto-char 1) (let (start this-sexp end orig-match-start orig-match-end done) (while (and (< (point) (point-max))
[elpa] master 99e8724 08/24: Handle replacements containing another match
branch: master commit 99e8724cd9ce1a7e8f7596e15fc9bb76d7c3e365 Author: Michael Heerdegen Commit: Michael Heerdegen Handle replacements containing another match --- packages/el-search/el-search.el | 37 - 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/packages/el-search/el-search.el b/packages/el-search/el-search.el index f0d7416..1a4ca5a 100644 --- a/packages/el-search/el-search.el +++ b/packages/el-search/el-search.el @@ -196,9 +196,6 @@ ;; ;; 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 @@ -953,7 +950,8 @@ Hit any key to proceed." (defun el-search-search-and-replace-pattern (pattern replacement &optional splice to-input-string) (let ((replace-all nil) (nbr-replaced 0) (nbr-skipped 0) (done nil) (el-search-keep-hl t) (opoint (point)) -(get-replacement (el-search--matcher pattern replacement))) +(get-replacement (el-search--matcher pattern replacement)) +(skip-matches-in-replacement 'ask)) (unwind-protect (while (and (not done) (el-search--search-pattern pattern t)) (setq opoint (point)) @@ -969,6 +967,16 @@ Hit any key to proceed." (get-replacement-string (lambda () (el-search--format-replacement new-expr substring to-input-string splice))) (to-insert (funcall get-replacement-string)) + (replacement-contains-another-match + (with-temp-buffer +(emacs-lisp-mode) +(insert to-insert) +(goto-char 1) +(el-search--skip-expression new-expr) +(condition-case nil +(progn (el-search--ensure-sexp-start) + (el-search--search-pattern pattern t)) + (end-of-buffer nil (do-replace (lambda () (atomic-change-group (apply #'delete-region region) @@ -1013,7 +1021,26 @@ Hit any key to proceed." t) (?? (ignore (read-char el-search-search-and-replace-help-string)) nil) -(unless (or done (eobp)) (el-search--skip-expression nil t) +(unless (or done (eobp)) + (cond + ((not (and replaced-this replacement-contains-another-match)) +(el-search--skip-expression nil t)) + ((eq skip-matches-in-replacement 'ask) +(if (setq skip-matches-in-replacement + (yes-or-no-p "Match in replacement - always skip? ")) +(forward-sexp) + (el-search--skip-expression nil t) + (when replace-all +(setq replace-all nil) +(message "Falling back to interactive mode") +(sit-for 3. + (skip-matches-in-replacement (forward-sexp)) + (t +(el-search--skip-expression nil t) +(message "Replacement contains another match%s" + (if replace-all " - falling back to interactive mode" "")) +(setq replace-all nil) +(sit-for 3.))) (el-search-hl-remove) (goto-char opoint) (message "Replaced %d matches%s"
[elpa] master 03dd4e7 06/24: Comment and whitespace changes only
branch: master commit 03dd4e7c674eee10c61c1ae683d6ea41b8d24258 Author: Michael Heerdegen Commit: Michael Heerdegen Comment and whitespace changes only --- packages/el-search/el-search.el | 15 +++ 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/packages/el-search/el-search.el b/packages/el-search/el-search.el index 26857ef..9f115e0 100644 --- a/packages/el-search/el-search.el +++ b/packages/el-search/el-search.el @@ -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: ;; @@ -163,7 +163,7 @@ ;;(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 @@ -185,6 +185,8 @@ ;; ;; the comment will be lost. ;; +;; FIXME: when we have resumable sessions, pause and warn about this case. +;; ;; ;; Acknowledgments ;; === @@ -195,9 +197,13 @@ ;; 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) @@ -1003,7 +1010,7 @@ Hit any key to proceed." nil) ((or ?q ?\C-g) (setq done t) -t) + t) (?? (ignore (read-char el-search-search-and-replace-help-string)) nil) (unless (or done (eobp)) (el-search--skip-expression nil t)
[elpa] master 41fc28b 01/24: New user option: el-search-use-sloppy-strings
branch: master commit 41fc28b91e17b168401d404078a77fbee0c86d21 Author: Michael Heerdegen Commit: Michael Heerdegen New user option: el-search-use-sloppy-strings --- packages/el-search/el-search.el | 34 ++ 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/packages/el-search/el-search.el b/packages/el-search/el-search.el index a1bdd23..f5db2eb 100644 --- a/packages/el-search/el-search.el +++ b/packages/el-search/el-search.el @@ -264,6 +264,26 @@ done independently for every single matching operation. If nil, the value of `case-fold-search' is decisive." :type 'boolean) +(defcustom el-search-use-sloppy-strings nil + "Whether to allow the usage of \"sloppy strings\". +When this option is turned on, for faster typing you are allowed +to specify symbols instead of strings as arguments to an +\"el-search\" pattern type that would otherwise accept only +strings, and their names will be used as input (with other words, +this spares you to type the string delimiters in many cases). + +For example, + + \(source ^cl\) + +is then equivalent to + + \(source \"^cl\"\) + +When this option is off, the first form would just signal an +error." + :type 'boolean) + Helpers @@ -592,9 +612,13 @@ matches the list (1 2 3 4 5 6 7 8 9) and binds `x' to (4 5 6)." (,'\, ,(car more-patterns))) (t `(append ,pattern (append ,@more-patterns))) +(defun el-search--stringish-p (thing) + (or (stringp thing) (and el-search-use-sloppy-strings (symbolp thing + (el-search-defpattern string (&rest regexps) "Matches any string that is matched by all REGEXPS." - (el-search--check-pattern-args 'string regexps #'stringp) + (el-search--check-pattern-args 'string regexps #'el-search--stringish-p + "Argument not a string") (let ((string (make-symbol "string")) (regexp (make-symbol "regexp"))) `(and (pred stringp) @@ -605,7 +629,8 @@ matches the list (1 2 3 4 5 6 7 8 9) and binds `x' to (4 5 6)." (el-search-defpattern symbol (&rest regexps) "Matches any symbol whose name is matched by all REGEXPS." - (el-search--check-pattern-args 'symbol regexps #'stringp) + (el-search--check-pattern-args 'symbol regexps #'el-search--stringish-p + "Argument not a string") `(and (pred symbolp) (app symbol-name (string ,@regexps @@ -662,8 +687,9 @@ REGEXP can also be a symbol, in which case (concat \"^\" (symbol-name regexp) \"$\") is used as regular expression." - (el-search--check-pattern-args 'source (list regexp) #'stringp) - `(pred (el-search--match-symbol-file ,regexp))) + (el-search--check-pattern-args 'source (list regexp) #'el-search--stringish-p + "Argument not a string") + `(pred (el-search--match-symbol-file ,(if (symbolp regexp) (symbol-name regexp) regexp (defun el-search--match-key-sequence (keys expr) (when-let ((expr-keys (pcase expr
[elpa] master 098582b 20/24: Reduce duration of a `sit-for'
branch: master commit 098582b08bc1117ad748e6e212adc7d1d20c9ef2 Author: Michael Heerdegen Commit: Michael Heerdegen Reduce duration of a `sit-for' --- packages/el-search/el-search.el |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/el-search/el-search.el b/packages/el-search/el-search.el index 7cfe477..90be0ac 100644 --- a/packages/el-search/el-search.el +++ b/packages/el-search/el-search.el @@ -1096,7 +1096,7 @@ Hit any key to proceed." (message "Replacement contains another match%s" (if replace-all " - falling back to interactive mode" "")) (setq replace-all nil) -(sit-for 3.))) +(sit-for 2.))) (el-search-hl-remove) (goto-char opoint) (message "Replaced %d matches%s"
[elpa] master 01e5bcd 22/24: Clean up el-search-read-expression-map; add some doc
branch: master commit 01e5bcdc4998f64f2feeed1a8bd938280b2d6c4a Author: Michael Heerdegen Commit: Michael Heerdegen Clean up el-search-read-expression-map; add some doc --- packages/el-search/el-search.el | 15 --- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/packages/el-search/el-search.el b/packages/el-search/el-search.el index 2d032e6..77faf7b 100644 --- a/packages/el-search/el-search.el +++ b/packages/el-search/el-search.el @@ -162,8 +162,12 @@ ;;(define-key isearch-mode-map [(control ?S)] #'el-search-search-from-isearch) ;;(define-key isearch-mode-map [(control ?%)] #'el-search-replace-from-isearch) ;; +;;(define-key el-search-read-expression-map [(control ?S)] #'exit-minibuffer) +;; ;; The bindings in `isearch-mode-map' let you conveniently switch to -;; "el-search" searching from isearch. +;; "el-search" searching from isearch. The binding in +;; `el-search-read-expression-map' allows you to hit C-S twice to +;; start a search for the last search pattern. ;; ;; ;; Bugs, Known Limitations @@ -303,8 +307,7 @@ error." (define-key map [(control ?g)] #'abort-recursive-edit) (define-key map [up] nil) (define-key map [down] nil) -(define-key map [(control meta backspace)] #'backward-kill-sexp) -(define-key map [(control ?S)] #'exit-minibuffer) +(define-key map [(control ?j)] #'newline) map) "Map for reading input with `el-search-read-expression'.") @@ -950,6 +953,12 @@ Search current buffer for expressions that are matched by `pcase' PATTERN. Use `read' to transform buffer contents into expressions. +Use `emacs-lisp-mode' for reading input. Some keys in the +minibuffer have a special binding: to make it possible to edit +multi line input, C-j inserts a newline, and up and down move the +cursor vertically - see `el-search-read-expression-map' for more +details. + Additional `pcase' pattern types to be used with this command can be defined with `el-search-defpattern'.
[elpa] master 3d72d1d 11/24: Address compiler warnings
branch: master commit 3d72d1d6aef4aecdda3b068ba4de319f456d870a Author: Michael Heerdegen Commit: Michael Heerdegen Address compiler warnings --- packages/el-search/el-search.el | 13 +++-- 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/el-search/el-search.el b/packages/el-search/el-search.el index a15a2d4..c56c9d0 100644 --- a/packages/el-search/el-search.el +++ b/packages/el-search/el-search.el @@ -332,6 +332,9 @@ error." (read-from-minibuffer prompt initial-contents el-search-read-expression-map read (or hist 'read-expression-history) default))) +(defvar el-search-history '() + "List of input strings.") + (defvar el-search--initial-mb-contents nil) (defun el-search--read-pattern (prompt &optional default read) @@ -584,6 +587,10 @@ MESSAGE are used to construct the error message." type arg))) args)) +(defvar el-search-current-pattern nil) + +(defvar el-search-success nil) + Additional pattern type definitions @@ -928,12 +935,6 @@ You need `diff-hl-mode' turned on, provided by the library Core functions -(defvar el-search-history '() - "List of input strings.") - -(defvar el-search-success nil) -(defvar el-search-current-pattern nil) - ;;;###autoload (defun el-search-pattern (pattern) "Start new or resume last elisp search.
[elpa] master 149acb9 07/24: Improve documentation and argument names of el-search-query-replace
branch: master commit 149acb9fc154d61f8536a395947db1a5ef65dc4b Author: Michael Heerdegen Commit: Michael Heerdegen Improve documentation and argument names of el-search-query-replace --- packages/el-search/el-search.el | 17 - 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/packages/el-search/el-search.el b/packages/el-search/el-search.el index 9f115e0..f0d7416 100644 --- a/packages/el-search/el-search.el +++ b/packages/el-search/el-search.el @@ -1023,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))
[elpa] master bace971 02/24: Rewrite `string' pattern definition
branch: master commit bace971d3cff75963ee52d0157c091caaba857ac Author: Michael Heerdegen Commit: Michael Heerdegen Rewrite `string' pattern definition --- packages/el-search/el-search.el | 11 --- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/packages/el-search/el-search.el b/packages/el-search/el-search.el index f5db2eb..764d77e 100644 --- a/packages/el-search/el-search.el +++ b/packages/el-search/el-search.el @@ -619,13 +619,10 @@ matches the list (1 2 3 4 5 6 7 8 9) and binds `x' to (4 5 6)." "Matches any string that is matched by all REGEXPS." (el-search--check-pattern-args 'string regexps #'el-search--stringish-p "Argument not a string") - (let ((string (make-symbol "string")) -(regexp (make-symbol "regexp"))) -`(and (pred stringp) - (pred (lambda (,string) - (cl-every - (lambda (,regexp) (el-search--smart-string-match-p ,regexp ,string)) - ',regexps)) + `(and (pred stringp) +,@(mapcar (lambda (thing) `(pred (el-search--smart-string-match-p + ,(if (symbolp thing) (symbol-name thing) thing + regexps))) (el-search-defpattern symbol (&rest regexps) "Matches any symbol whose name is matched by all REGEXPS."
[elpa] master 0b9fe9c 23/24: Set initial input for replace when coming from el-search-pattern
branch: master commit 0b9fe9c814c30b7715b55f769352e4200e3aea63 Author: Michael Heerdegen Commit: Michael Heerdegen Set initial input for replace when coming from el-search-pattern --- packages/el-search/el-search.el |8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/el-search/el-search.el b/packages/el-search/el-search.el index 77faf7b..1f4014a 100644 --- a/packages/el-search/el-search.el +++ b/packages/el-search/el-search.el @@ -1117,8 +1117,12 @@ Hit any key to proceed." (defun el-search-query-replace--read-args () (barf-if-buffer-read-only) - (let ((from-input (el-search--read-pattern "Query replace pattern: " nil nil - 'el-search-query-replace-history)) + (let ((from-input (let ((el-search--initial-mb-contents + (or el-search--initial-mb-contents + (and (eq last-command 'el-search-pattern) +(car el-search-history) + (el-search--read-pattern "Query replace pattern: " nil nil + 'el-search-query-replace-history))) from to) (with-temp-buffer (emacs-lisp-mode)
[elpa] master 3d0a12e 13/24: Fix el-search--ensure-sexp-start error at bob
branch: master commit 3d0a12e0de844c9a3899d32a709e3dc1e0c3d219 Author: Michael Heerdegen Commit: Michael Heerdegen Fix el-search--ensure-sexp-start error at bob --- packages/el-search/el-search.el |7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/el-search/el-search.el b/packages/el-search/el-search.el index 71b07ec..de219de 100644 --- a/packages/el-search/el-search.el +++ b/packages/el-search/el-search.el @@ -356,9 +356,10 @@ and return it." (while not-done (let ((stop-here nil) (looking-at-from-back (lambda (regexp n) -(save-excursion - (backward-char n) - (looking-at regexp) +(and (> (point) n) + (save-excursion + (backward-char n) + (looking-at regexp)) (while (not stop-here) (cond ((eobp) (signal 'end-of-buffer nil))
[elpa] master 5f9accc 18/24: Make query-replace accept FROM -> TO style input
branch: master commit 5f9accc41fe4b6364b124cc9af9703e91fba3c81 Author: Michael Heerdegen Commit: Michael Heerdegen Make query-replace accept FROM -> TO style input Use this format for history entries. --- packages/el-search/el-search.el | 50 --- 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/packages/el-search/el-search.el b/packages/el-search/el-search.el index 8e08571..0f40e83 100644 --- a/packages/el-search/el-search.el +++ b/packages/el-search/el-search.el @@ -333,14 +333,18 @@ error." (or hist 'read-expression-history) default))) (defvar el-search-history '() - "List of input strings.") + "List of search input strings.") + +(defvar el-search-query-replace-history '() + "List of input strings from `el-search-query-replace'.") (defvar el-search--initial-mb-contents nil) -(defun el-search--read-pattern (prompt &optional default read) +(defun el-search--read-pattern (prompt &optional default read histvar) + (cl-callf or histvar 'el-search-history) (let ((input (el-search-read-expression -prompt el-search--initial-mb-contents 'el-search-history default read))) -(if (or read (not (string= input ""))) input (car el-search-history +prompt el-search--initial-mb-contents histvar default read))) +(if (or read (not (string= input ""))) input (car (symbol-value histvar) (defun el-search--end-of-sexp () ;;Point must be at sexp beginning @@ -1102,9 +1106,31 @@ Hit any key to proceed." (defun el-search-query-replace--read-args () (barf-if-buffer-read-only) - (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 + (let ((from-input (el-search--read-pattern "Query replace pattern: " nil nil + 'el-search-query-replace-history)) +from to) +(with-temp-buffer + (emacs-lisp-mode) + (insert from-input) + (goto-char 1) + (forward-sexp) + (skip-chars-forward " \t\n") + ;; FIXME: maybe more sanity tests here... + (if (not (looking-at "->")) + (setq from from-input +to (let ((el-search--initial-mb-contents nil)) + (el-search--read-pattern "Replace with result of evaluation of: " from))) +(delete-char 2) +(goto-char 1) +(forward-sexp) +(setq from (buffer-substring 1 (point))) +(skip-chars-forward " \t\n") +(setq to (buffer-substring (point) (progn (forward-sexp) (point)) +(unless (and el-search-query-replace-history + (not (string= from from-input)) + (string= from-input (car el-search-query-replace-history))) + (push (format "%s -> %s" from to) ;FIXME: add line break when FROM or TO is multiline? +el-search-query-replace-history)) (list (el-search--wrap-pattern (read from)) (read to) to))) ;;;###autoload @@ -1117,7 +1143,15 @@ produce a replacement expression. Operate from point to (point-max). As each match is found, the user must type a character saying -what to do with it. For directions, type ? at that time." +what to do with it. For directions, type ? at that time. + +As an alternative to enter FROM-PATTERN and TO-EXPR separately, +you can also give an input of the form + + FROM-PATTERN -> TO-EXPR + +to the first prompt and specify both expressions at once. This +format is also used for history entries." (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-pattern)
[elpa] master f178717 12/24: Clarify the operation scope of replacing
branch: master commit f17871797356895ac51c8dbe213abb3f15c8cc87 Author: Michael Heerdegen Commit: Michael Heerdegen Clarify the operation scope of replacing --- packages/el-search/el-search.el |3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/el-search/el-search.el b/packages/el-search/el-search.el index c56c9d0..71b07ec 100644 --- a/packages/el-search/el-search.el +++ b/packages/el-search/el-search.el @@ -1112,7 +1112,8 @@ Hit any key to proceed." 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. +produce a replacement expression. Operate from point +to (point-max). As each match is found, the user must type a character saying what to do with it. For directions, type ? at that time."
[elpa] master 8d7b29c 21/24: Make sure not to lose the minibuffer-prompt face
branch: master commit 8d7b29c99927fe1b84e60bd39c11053f9d4f2dcf Author: Michael Heerdegen Commit: Michael Heerdegen Make sure not to lose the minibuffer-prompt face --- packages/el-search/el-search.el |2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/el-search/el-search.el b/packages/el-search/el-search.el index 90be0ac..2d032e6 100644 --- a/packages/el-search/el-search.el +++ b/packages/el-search/el-search.el @@ -309,6 +309,8 @@ error." "Map for reading input with `el-search-read-expression'.") (defun el-search--setup-minibuffer () + (let ((inhibit-read-only t)) +(put-text-property 1 (minibuffer-prompt-end) 'font-lock-face 'minibuffer-prompt)) (emacs-lisp-mode) (use-local-map el-search-read-expression-map) (setq font-lock-mode t)
[elpa] master f9980f6 05/24: Replacing: make C-g an alternative key for quitting
branch: master commit f9980f63fdbbad0edd01264c3c39dacaa56a393c Author: Michael Heerdegen Commit: Michael Heerdegen Replacing: make C-g an alternative key for quitting --- packages/el-search/el-search.el |7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/el-search/el-search.el b/packages/el-search/el-search.el index c7b3499..26857ef 100644 --- a/packages/el-search/el-search.el +++ b/packages/el-search/el-search.el @@ -977,7 +977,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 +986,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,7 +1001,8 @@ Hit any key to proceed." (?s (cl-callf not splice) (setq to-insert (funcall get-replacement-string)) nil) -(?q (setq done t) +((or ?q ?\C-g) + (setq done t) t) (?? (ignore (read-char el-search-search-and-replace-help-string)) nil)
[elpa] master bb98a1d 04/24: Rewrite replacement layout restoration
branch: master commit bb98a1df932aa66a4364539708f32c34d832c70d Author: Michael Heerdegen Commit: Michael Heerdegen Rewrite replacement layout restoration --- packages/el-search/el-search.el | 142 +-- 1 file changed, 78 insertions(+), 64 deletions(-) diff --git a/packages/el-search/el-search.el b/packages/el-search/el-search.el index 84fb1c8..c7b3499 100644 --- a/packages/el-search/el-search.el +++ b/packages/el-search/el-search.el @@ -194,12 +194,6 @@ ;; ;; TODO: ;; -;; - When replacing like (progn A B C) -> A B C, the layout of the -;; whole "group" A B C as a unit is lost. Instead of restoring layout -;; as we do now (via "read mappings"), we could just make a backup of -;; the original expression as a string, and use our search machinery -;; to find occurrences in the replacement recursively. -;; ;; - detect infloops when replacing automatically (e.g. for 1 -> '(1)) ;; ;; - implement backward searching @@ -501,48 +495,78 @@ point. Optional second argument, if non-nil, means if fail just return nil (no error)." (el-search--search-pattern-1 (el-search--matcher pattern) noerror)) -(defun el-search--do-subsexps (pos do-fun &optional ret-fun bound) - ;; In current buffer, for any expression start between POS and BOUND - ;; or (point-max), in order, call two argument function DO-FUN with - ;; the current sexp string and the ending position of the current - ;; sexp. When done, with RET-FUN given, call it with no args and - ;; return the result; else, return nil. - (save-excursion -(goto-char pos) -(condition-case nil -(while (< (point) (or bound (point-max))) - (let* ((this-sexp-end (save-excursion (thing-at-point--end-of-sexp) (point))) - (this-sexp-string (buffer-substring-no-properties (point) this-sexp-end))) -(funcall do-fun this-sexp-string this-sexp-end) -(el-search--skip-expression (read this-sexp-string)) -(el-search--ensure-sexp-start))) - (end-of-buffer)) -(when ret-fun (funcall ret-fun - -(defun el-search--create-read-map (&optional pos) - (let ((mapping '())) -(el-search--do-subsexps - (or pos (point)) - (lambda (sexp _) (push (cons (read sexp) sexp) mapping)) - (lambda () (nreverse mapping)) - (save-excursion (thing-at-point--end-of-sexp) (point) - -(defun el-search--repair-replacement-layout (printed mapping) - (with-temp-buffer -(insert printed) -(el-search--do-subsexps - (point-min) - (lambda (sexp sexp-end) - (when-let ((old (cdr (assoc (read sexp) mapping - (delete-region (point) sexp-end) - (when (string-match-p "\n" old) - (unless (looking-back "^[[:space:]]*" (line-beginning-position)) - (insert "\n")) - (unless (looking-at "[[:space:]\)]*$") - (insert "\n") - (backward-char))) - (save-excursion (insert old - (lambda () (buffer-substring (point-min) (point-max)) +(defun el-search--format-replacement (replacement original replace-expr-input splice) + ;; Return a printed representation of REPLACEMENT. Try to reuse the + ;; layout of subexpressions shared with the original (replaced) + ;; expression and the replace expression. + (if (and splice (not (listp replacement))) + (error "Expression to splice in is an atom") +(let ((orig-buffer (generate-new-buffer "orig-expr"))) + (with-current-buffer orig-buffer +(emacs-lisp-mode) +(insert original) +(when replace-expr-input (insert "\n\n" replace-expr-input))) + (unwind-protect + (with-temp-buffer +(emacs-lisp-mode) +(insert (if splice +(mapconcat #'el-search--print replacement " ") + (el-search--print replacement))) +(goto-char 1) +(let (start this-sexp end orig-match-start orig-match-end done) + (while (and (< (point) (point-max)) + (condition-case nil + (progn +(setq start (point) + this-sexp (read (current-buffer)) + end (point)) +t) +(end-of-buffer nil))) +(setq done nil orig-match-start nil) +(with-current-buffer orig-buffer + (goto-char 1) + (if (el-search--search-pattern `',this-sexp t) + (setq orig-match-start (point) +orig-match-end (progn (forward-sexp) (point))) +(setq done t))) +;; find out whether we have a sequence of equal expressions +(while (and (not done) +(condition-case nil +(progn (setq this-sexp (read (current-buffer))) t)
[elpa] master 246e1ff 17/24: Small fix in el-search--setup-minibuffer
branch: master commit 246e1ffcdab503b7a304e5894208a85830409fb2 Author: Michael Heerdegen Commit: Michael Heerdegen Small fix in el-search--setup-minibuffer --- packages/el-search/el-search.el |5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/el-search/el-search.el b/packages/el-search/el-search.el index eba4a5d..8e08571 100644 --- a/packages/el-search/el-search.el +++ b/packages/el-search/el-search.el @@ -313,8 +313,9 @@ error." (use-local-map el-search-read-expression-map) (setq font-lock-mode t) (funcall font-lock-function 1) - (backward-sexp) - (indent-sexp) + (goto-char (minibuffer-prompt-end)) + (when (looking-at ".*\n") +(indent-sexp)) (goto-char (point-max)) (when-let ((this-sexp (with-current-buffer (window-buffer (minibuffer-selected-window)) (thing-at-point 'sexp
[elpa] master 4b11cb8 09/24: Rename two functions
branch: master commit 4b11cb8a8e2bdaca912aacba041bf6eb67256911 Author: Michael Heerdegen Commit: Michael Heerdegen Rename two functions --- packages/el-search/el-search.el |8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/el-search/el-search.el b/packages/el-search/el-search.el index 1a4ca5a..db57a5e 100644 --- a/packages/el-search/el-search.el +++ b/packages/el-search/el-search.el @@ -947,7 +947,7 @@ s Toggle splicing mode. When splicing mode is Hit any key to proceed." "Help string for ? in `el-search-query-replace'.") -(defun el-search-search-and-replace-pattern (pattern replacement &optional splice to-input-string) +(defun el-search--search-and-replace-pattern (pattern replacement &optional splice to-input-string) (let ((replace-all nil) (nbr-replaced 0) (nbr-skipped 0) (done nil) (el-search-keep-hl t) (opoint (point)) (get-replacement (el-search--matcher pattern replacement)) @@ -1048,7 +1048,7 @@ Hit any key to proceed." (if (zerop nbr-skipped) "" (format " (%d skipped)" nbr-skipped) -(defun el-search-query-replace-read-args () +(defun el-search-query-replace--read-args () (barf-if-buffer-read-only) (let* ((from (el-search--read-pattern "Query replace pattern: ")) (to (let ((el-search--initial-mb-contents nil)) @@ -1065,11 +1065,11 @@ 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)) + (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-pattern) (barf-if-buffer-read-only) - (el-search-search-and-replace-pattern from-pattern to-expr nil textual-to)) + (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))
[elpa] master updated (24ce066 -> c835174)
mheerdegen pushed a change to branch master. from 24ce066 packages/javaimp: Restructure code, add some tests. new 41fc28b New user option: el-search-use-sloppy-strings new bace971 Rewrite `string' pattern definition new b885ef1 el-search--check-pattern-args: make arg TYPE a string new bb98a1d Rewrite replacement layout restoration new f9980f6 Replacing: make C-g an alternative key for quitting new 03dd4e7 Comment and whitespace changes only new 149acb9 Improve documentation and argument names of el-search-query-replace new 99e8724 Handle replacements containing another match new 4b11cb8 Rename two functions new 91192f5 Add patterns for character properties new 3d72d1d Address compiler warnings new f178717 Clarify the operation scope of replacing new 3d0a12e Fix el-search--ensure-sexp-start error at bob new c0d9ca7 Make el-search-pattern accept an optional NO-ERROR arg new 536fab6 Give el-search--s a more meaningful name new b09bb1b Use `pp-to-string' to print replacement expression new 246e1ff Small fix in el-search--setup-minibuffer new 5f9accc Make query-replace accept FROM -> TO style input new c356b2d Rename a local variable new 098582b Reduce duration of a `sit-for' new 8d7b29c Make sure not to lose the minibuffer-prompt face new 01e5bcd Clean up el-search-read-expression-map; add some doc new 0b9fe9c Set initial input for replace when coming from el-search-pattern new c835174 Improve history handling Summary of changes: packages/el-search/el-search.el | 465 --- 1 file changed, 338 insertions(+), 127 deletions(-)
[elpa] master c0d9ca7 14/24: Make el-search-pattern accept an optional NO-ERROR arg
branch: master commit c0d9ca7b1600ed24809b1796d9d9cc460e30392d Author: Michael Heerdegen Commit: Michael Heerdegen Make el-search-pattern accept an optional NO-ERROR arg --- packages/el-search/el-search.el |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/el-search/el-search.el b/packages/el-search/el-search.el index de219de..4afcd91 100644 --- a/packages/el-search/el-search.el +++ b/packages/el-search/el-search.el @@ -937,7 +937,7 @@ You need `diff-hl-mode' turned on, provided by the library Core functions ;;;###autoload -(defun el-search-pattern (pattern) +(defun el-search-pattern (pattern &optional no-error) "Start new or resume last elisp search. Search current buffer for expressions that are matched by `pcase' @@ -964,7 +964,7 @@ The following additional pattern types are currently defined:" (error "Please don't forget the quote when searching for a symbol")) (el-search--wrap-pattern pattern) (if (not (called-interactively-p 'any)) - (el-search--search-pattern pattern) + (el-search--search-pattern pattern no-error) (setq this-command 'el-search-pattern) ;in case we come from isearch (setq el-search-current-pattern pattern) (let ((opoint (point)))
[elpa] master c835174 24/24: Improve history handling
branch: master commit c835174aa35b47c4036aea0c56836b38bff43511 Author: Michael Heerdegen Commit: Michael Heerdegen Improve history handling --- packages/el-search/el-search.el | 48 +++ 1 file changed, 39 insertions(+), 9 deletions(-) diff --git a/packages/el-search/el-search.el b/packages/el-search/el-search.el index 1f4014a..b3c5891 100644 --- a/packages/el-search/el-search.el +++ b/packages/el-search/el-search.el @@ -345,11 +345,27 @@ error." (defvar el-search--initial-mb-contents nil) -(defun el-search--read-pattern (prompt &optional default read histvar) +(defun el-search--pushnew-to-history (input histvar) + (let ((hist-head (car (symbol-value histvar +(unless (or (string-match-p "\\`\\'" input) +(and (stringp hist-head) + (or (string= input hist-head) + (ignore-errors (equal (read input) (read hist-head)) + (push (if (string-match-p "\\`.+\n" input) +(with-temp-buffer + (emacs-lisp-mode) + (insert "\n" input) + (indent-region 1 (point)) + (buffer-string)) + input) +(symbol-value histvar) + +(defun el-search--read-pattern (prompt &optional default histvar) (cl-callf or histvar 'el-search-history) (let ((input (el-search-read-expression -prompt el-search--initial-mb-contents histvar default read))) -(if (or read (not (string= input ""))) input (car (symbol-value histvar) +prompt el-search--initial-mb-contents histvar default))) +(el-search--pushnew-to-history input histvar) +(if (not (string= input "")) input (car (symbol-value histvar) (defun el-search--end-of-sexp () ;;Point must be at sexp beginning @@ -967,16 +983,18 @@ The following additional pattern types are currently defined:" (interactive (list (if (and (eq this-command last-command) el-search-success) el-search-current-pattern - (let ((pattern - (el-search--read-pattern "Find pcase pattern: " - (car el-search-history) - t))) + (let* ((input (el-search--read-pattern "Find pcase pattern: " + (car el-search-history))) + (pattern (read input))) ;; A very common mistake: input "foo" instead of "'foo" (when (and (symbolp pattern) (not (eq pattern '_)) (or (not (boundp pattern)) (not (eq (symbol-value pattern) pattern (error "Please don't forget the quote when searching for a symbol")) + ;; Make input available also in query-replace history + (el-search--pushnew-to-history input 'el-search-query-replace-history) + ;; and wrap the PATTERN (el-search--wrap-pattern pattern) (if (not (called-interactively-p 'any)) (el-search--search-pattern pattern no-error) @@ -1121,7 +1139,7 @@ Hit any key to proceed." (or el-search--initial-mb-contents (and (eq last-command 'el-search-pattern) (car el-search-history) - (el-search--read-pattern "Query replace pattern: " nil nil + (el-search--read-pattern "Query replace pattern: " nil 'el-search-query-replace-history))) from to) (with-temp-buffer @@ -1144,8 +1162,20 @@ Hit any key to proceed." (unless (and el-search-query-replace-history (not (string= from from-input)) (string= from-input (car el-search-query-replace-history))) - (push (format "%s -> %s" from to) ;FIXME: add line break when FROM or TO is multiline? + (push (with-temp-buffer + (emacs-lisp-mode) + (insert (let ((newline-in-from (string-match-p "\n" from)) +(newline-in-to (string-match-p "\n" to))) +(format "%s%s%s ->%s%s" +(if (and (or newline-in-from newline-in-to) + (not (string-match-p "\\`\n" from))) "\n" "") +(if newline-in-from "\n" "" ) from +(if (and (or newline-in-from newline-in-to) + (not (string-match-p "\\`\n" to))) "\n" " ") to))) + (indent-region 1 (