they exit Isearch mode before displaying global help."
isearch-help-map)
+(defvar isearch--display-help-action '(nil (inhibit-same-window . t)))
+
(defun isearch-help-for-help ()
"Display Isearch help menu."
(interactive)
- (let (same-window-buffer-names same-window-regexps)
+ (let ((display-buffer-overriding-action isearch--display-help-action))
(isearch-help-for-help-internal))
(isearch-update))
"Show a list of all keys defined in Isearch mode, and their definitions.
This is like `describe-bindings', but displays only Isearch keys."
(interactive)
- (let (same-window-buffer-names same-window-regexps)
+ (let ((display-buffer-overriding-action isearch--display-help-action))
(with-help-window "*Help*"
(with-current-buffer standard-output
(princ "Isearch Mode Bindings:\n")
(defun isearch-describe-key ()
"Display documentation of the function invoked by isearch key."
(interactive)
- (let (same-window-buffer-names same-window-regexps)
+ (let ((display-buffer-overriding-action isearch--display-help-action))
(call-interactively 'describe-key))
(isearch-update))
(defun isearch-describe-mode ()
"Display documentation of Isearch mode."
(interactive)
- (let (same-window-buffer-names same-window-regexps)
+ (let ((display-buffer-overriding-action isearch--display-help-action))
(describe-function 'isearch-forward))
(isearch-update))
(define-key map "\C-x" nil)
(define-key map [?\C-x t] 'isearch-other-control-char)
(define-key map "\C-x8" nil)
- (define-key map "\C-x8\r" 'isearch-other-control-char)
+ (define-key map "\C-x8\r" 'isearch-insert-char-by-name)
map)
"Keymap for `isearch-mode'.")
(length succ-msg)
0))))
-(defun isearch-edit-string ()
- "Edit the search string in the minibuffer.
-The following additional command keys are active while editing.
-\\<minibuffer-local-isearch-map>
-\\[exit-minibuffer] to resume incremental searching with the edited string.
-\\[isearch-nonincremental-exit-minibuffer] to do one nonincremental search.
-\\[isearch-forward-exit-minibuffer] to resume isearching forward.
-\\[isearch-reverse-exit-minibuffer] to resume isearching backward.
-\\[isearch-complete-edit] to complete the search string using the search ring."
-
+(defmacro with-isearch-suspended (&rest body)
+ "Exit Isearch mode, run BODY, and reinvoke the pending search.
+You can update the global isearch variables by setting new values to
+`isearch-new-string', `isearch-new-message', `isearch-new-forward',
+`isearch-new-word', `isearch-new-case-fold'."
;; This code is very hairy for several reasons, explained in the code.
;; Mainly, isearch-mode must be terminated while editing and then restarted.
;; If there were a way to catch any change of buffer from the minibuffer,
;; this could be simplified greatly.
;; Editing doesn't back up the search point. Should it?
- (interactive)
- (condition-case nil
+ `(condition-case nil
(progn
(let ((isearch-nonincremental isearch-nonincremental)
(setq old-point (point) old-other-end isearch-other-end)
(unwind-protect
- (let* ((message-log-max nil)
- ;; Don't add a new search string to the search ring here
- ;; in `read-from-minibuffer'. It should be added only
- ;; by `isearch-update-ring' called from `isearch-done'.
- (history-add-new-input nil)
- ;; Binding minibuffer-history-symbol to nil is a work-around
- ;; for some incompatibility with gmhist.
- (minibuffer-history-symbol))
- (setq isearch-new-string
- (read-from-minibuffer
- (isearch-message-prefix nil isearch-nonincremental)
- (cons isearch-string (1+ (or (isearch-fail-pos)
- (length isearch-string))))
- minibuffer-local-isearch-map nil
- (if isearch-regexp
- (cons 'regexp-search-ring
- (1+ (or regexp-search-ring-yank-pointer -1)))
- (cons 'search-ring
- (1+ (or search-ring-yank-pointer -1))))
- nil t)
- isearch-new-message
- (mapconcat 'isearch-text-char-description
- isearch-new-string "")))
+ (progn ,@body)
;; Set point at the start (end) of old match if forward (backward),
;; so after exiting minibuffer isearch resumes at the start (end)
(isearch-abort) ;; outside of let to restore outside global values
)))
+(defun isearch-edit-string ()
+ "Edit the search string in the minibuffer.
+The following additional command keys are active while editing.
+\\<minibuffer-local-isearch-map>
+\\[exit-minibuffer] to resume incremental searching with the edited string.
+\\[isearch-nonincremental-exit-minibuffer] to do one nonincremental search.
+\\[isearch-forward-exit-minibuffer] to resume isearching forward.
+\\[isearch-reverse-exit-minibuffer] to resume isearching backward.
+\\[isearch-complete-edit] to complete the search string using the search ring."
+ (interactive)
+ (with-isearch-suspended
+ (let* ((message-log-max nil)
+ ;; Don't add a new search string to the search ring here
+ ;; in `read-from-minibuffer'. It should be added only
+ ;; by `isearch-update-ring' called from `isearch-done'.
+ (history-add-new-input nil)
+ ;; Binding minibuffer-history-symbol to nil is a work-around
+ ;; for some incompatibility with gmhist.
+ (minibuffer-history-symbol))
+ (setq isearch-new-string
+ (read-from-minibuffer
+ (isearch-message-prefix nil isearch-nonincremental)
+ (cons isearch-string (1+ (or (isearch-fail-pos)
+ (length isearch-string))))
+ minibuffer-local-isearch-map nil
+ (if isearch-regexp
+ (cons 'regexp-search-ring
+ (1+ (or regexp-search-ring-yank-pointer -1)))
+ (cons 'search-ring
+ (1+ (or search-ring-yank-pointer -1))))
+ nil t)
+ isearch-new-message
+ (mapconcat 'isearch-text-char-description
+ isearch-new-string "")))))
+
(defun isearch-nonincremental-exit-minibuffer ()
(interactive)
(setq isearch-nonincremental t)
\f
(defun isearch-delete-char ()
"Discard last input item and move point back.
+Last input means the last character or the last isearch command
+that added or deleted characters from the search string,
+moved point, toggled regexp mode or case-sensitivity, etc.
If no previous match was done, just beep."
(interactive)
(if (null (cdr isearch-cmds))
(defun isearch-del-char (&optional arg)
"Delete character from end of search string and search again.
+Unlike `isearch-delete-char', it only deletes the last character,
+but doesn't cancel the effect of other isearch command.
If search string is empty, just beep."
(interactive "p")
(if (= 0 (length isearch-string))
(lambda () (let ((inhibit-field-text-motion t))
(line-end-position (if (eolp) 2 1))))))
+(defun isearch-insert-char-by-name ()
+ "Read a character by its Unicode name and insert it into search string."
+ (interactive)
+ (with-isearch-suspended
+ (let ((char (read-char-by-name "Insert character (Unicode name or hex): ")))
+ (when char
+ (setq isearch-new-string (concat isearch-string (string char))
+ isearch-new-message (concat isearch-message
+ (mapconcat 'isearch-text-char-description
+ (string char) "")))))))
+
(defun isearch-search-and-update ()
;; Do the search and update the display.
(when (or isearch-success