;; (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
(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'.")
(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
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'.
(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)
(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
+ 'el-search-query-replace-history)))
from to)
(with-temp-buffer
(emacs-lisp-mode)
(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 (point-max))
+ (buffer-string))
el-search-query-replace-history))
+ (el-search--pushnew-to-history from 'el-search-history)
(list (el-search--wrap-pattern (read from)) (read to) to)))
;;;###autoload