[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Search minibuffer history
From: |
Juri Linkov |
Subject: |
Re: Search minibuffer history |
Date: |
Sun, 15 Jul 2007 23:04:43 +0300 |
User-agent: |
Gnus/5.11 (Gnus v5.11) Emacs/22.1.50 (gnu/linux) |
> It is best to give every function and variable a doc string, even if
> it is for internal use only. Your new functions, including
> `minibuffer-history-isearch-setup', `minibuffer-history-isearch-end',
> `minibuffer-history-isearch-search' and the rest need overall
> documentation. It has to be either a comment or a doc string, but it
> may as well be a doc string.
Is it OK to install the patch with doc strings? A copy of the patch is below:
Index: lisp/simple.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/simple.el,v
retrieving revision 1.865
diff -c -r1.865 simple.el
*** lisp/simple.el 7 Jul 2007 11:17:51 -0000 1.865
--- lisp/simple.el 13 Jul 2007 16:57:44 -0000
***************
*** 1300,1311 ****
(defvar minibuffer-temporary-goal-position nil)
! (defun next-history-element (n)
"Puts next element of the minibuffer history in the minibuffer.
! With argument N, it uses the Nth following element."
(interactive "p")
! (or (zerop n)
! (let ((narg (- minibuffer-history-position n))
(minimum (if minibuffer-default -1 0))
elt minibuffer-returned-to-present)
(if (and (zerop minibuffer-history-position)
--- 1300,1313 ----
(defvar minibuffer-temporary-goal-position nil)
! (defun next-history-element (n &optional narg)
"Puts next element of the minibuffer history in the minibuffer.
! With argument N, it uses the Nth following element.
! The optional argument NARG overrides the argument N and specifies the
! absolute history position instead of relative position specified by N."
(interactive "p")
! (or (and (zerop n) (not narg))
! (let ((narg (or narg (- minibuffer-history-position n)))
(minimum (if minibuffer-default -1 0))
elt minibuffer-returned-to-present)
(if (and (zerop minibuffer-history-position)
***************
*** 1344,1354 ****
elt))
(goto-char (or minibuffer-temporary-goal-position (point-max))))))
! (defun previous-history-element (n)
"Puts previous element of the minibuffer history in the minibuffer.
! With argument N, it uses the Nth previous element."
(interactive "p")
! (next-history-element (- n)))
(defun next-complete-history-element (n)
"Get next history element which completes the minibuffer before the point.
--- 1346,1358 ----
elt))
(goto-char (or minibuffer-temporary-goal-position (point-max))))))
! (defun previous-history-element (n &optional narg)
"Puts previous element of the minibuffer history in the minibuffer.
! With argument N, it uses the Nth previous element.
! The optional argument NARG overrides the argument N and specifies the
! absolute history position instead of relative position specified by N."
(interactive "p")
! (next-history-element (- n) narg))
(defun next-complete-history-element (n)
"Get next history element which completes the minibuffer before the point.
***************
*** 1381,1386 ****
--- 1385,1520 ----
;; the buffer; this should be 0 for normal buffers.
(1- (minibuffer-prompt-end)))
+ ;; isearch minibuffer history
+ (add-hook 'minibuffer-setup-hook 'minibuffer-history-isearch-setup)
+
+ (defvar minibuffer-history-isearch-message-overlay)
+ (make-variable-buffer-local 'minibuffer-history-isearch-message-overlay)
+
+ (defun minibuffer-history-isearch-setup ()
+ "Set up a minibuffer for using isearch to search the minibuffer history.
+ Intended to be added to `minibuffer-setup-hook'."
+ (set (make-local-variable 'isearch-search-fun-function)
+ 'minibuffer-history-isearch-search)
+ (set (make-local-variable 'isearch-message-function)
+ 'minibuffer-history-isearch-message)
+ (set (make-local-variable 'isearch-wrap-function)
+ 'minibuffer-history-isearch-wrap)
+ (set (make-local-variable 'isearch-push-state-function)
+ 'minibuffer-history-isearch-push-state)
+ (add-hook 'isearch-mode-end-hook 'minibuffer-history-isearch-end nil t))
+
+ (defun minibuffer-history-isearch-end ()
+ "Clean up the minibuffer after terminating an incremental search."
+ (if minibuffer-history-isearch-message-overlay
+ (delete-overlay minibuffer-history-isearch-message-overlay)))
+
+ (defun minibuffer-history-isearch-search ()
+ "Return the function for isearch that searches in the minibuffer history."
+ (cond
+ (isearch-word
+ (if isearch-forward 'word-search-forward 'word-search-backward))
+ (t
+ (lambda (string bound noerror)
+ (let ((search-fun
+ ;; Use standard functions to search within minibuffer text
+ (cond
+ (isearch-regexp
+ (if isearch-forward 're-search-forward 're-search-backward))
+ (t
+ (if isearch-forward 'search-forward 'search-backward))))
+ found)
+ ;; Avoid lazy-highlighting matches in the minibuffer prompt when
+ ;; searching forward. Lazy-highlight calls this lambda with the
+ ;; bound arg, so skip the minibuffer prompt.
+ (if (and bound isearch-forward (< (point) (minibuffer-prompt-end)))
+ (goto-char (minibuffer-prompt-end)))
+ (or
+ ;; 1. First try searching in the initial minibuffer text
+ (funcall search-fun string
+ (if isearch-forward bound (minibuffer-prompt-end))
+ noerror)
+ ;; 2. If the above search fails, start putting next/prev history
+ ;; elements in the minibuffer successively, and search the string
+ ;; in them. Do this only when bound is nil (i.e. not while
+ ;; lazy-highlighting search strings in the current minibuffer text).
+ (unless bound
+ (condition-case nil
+ (progn
+ (while (not found)
+ (cond (isearch-forward
+ (next-history-element 1)
+ (goto-char (minibuffer-prompt-end)))
+ (t
+ (previous-history-element 1)
+ (goto-char (point-max))))
+ (setq isearch-barrier (point) isearch-opoint (point))
+ ;; After putting the next/prev history element, search
+ ;; the string in them again, until next-history-element
+ ;; or previous-history-element raises an error at the
+ ;; beginning/end of history.
+ (setq found (funcall search-fun string
+ (unless isearch-forward
+ ;; For backward search, don't search
+ ;; in the minibuffer prompt
+ (minibuffer-prompt-end))
+ noerror)))
+ ;; Return point of the new search result
+ (point))
+ ;; Return nil when next(prev)-history-element fails
+ (error nil)))))))))
+
+ (defun minibuffer-history-isearch-message (&optional c-q-hack ellipsis)
+ "Display the minibuffer history search prompt.
+ It is either the standard isearch prompt displayed by `isearch-message'
+ in case of a search error, or an overlay with the isearch prompt displayed
+ over the original minibuffer prompt in case of successful search."
+ (if (not (and (minibufferp) isearch-success (not isearch-error)))
+ ;; Use standard function `isearch-message' when not in the minibuffer,
+ ;; or search fails, or has an error (like incomplete regexp).
+ ;; This function overwrites minibuffer text with isearch message,
+ ;; so it's possible to see what is wrong in the search string.
+ (isearch-message c-q-hack ellipsis)
+ ;; Otherwise, put the overlay with the standard isearch prompt over
+ ;; the initial minibuffer prompt.
+ (if (overlayp minibuffer-history-isearch-message-overlay)
+ (move-overlay minibuffer-history-isearch-message-overlay
+ (point-min) (minibuffer-prompt-end))
+ (setq minibuffer-history-isearch-message-overlay
+ (make-overlay (point-min) (minibuffer-prompt-end)))
+ (overlay-put minibuffer-history-isearch-message-overlay 'evaporate t))
+ (overlay-put minibuffer-history-isearch-message-overlay
+ 'display (isearch-message-prefix c-q-hack ellipsis))
+ ;; And clear any previous isearch message.
+ (message "")))
+
+ (defun minibuffer-history-isearch-wrap ()
+ "Wrap the minibuffer history search when search is failed.
+ Move point to the first history element for a forward search,
+ or to the last history element for a backward search."
+ (unless isearch-word
+ ;; When `minibuffer-history-isearch-search' fails on reaching the
+ ;; beginning/end of the history, wrap the search to the first/last
+ ;; minibuffer history element.
+ (if isearch-forward
+ (next-history-element 0 (length (symbol-value
minibuffer-history-variable)))
+ (next-history-element 0 0))
+ (setq isearch-success t))
+ (goto-char (if isearch-forward (minibuffer-prompt-end) (point-max))))
+
+ (defun minibuffer-history-isearch-push-state ()
+ "Save a function restoring the state of minibuffer history search.
+ Save `minibuffer-history-position' to the additional state parameter
+ in the search status stack."
+ `(lambda (cmd)
+ (minibuffer-history-isearch-pop-state cmd ,minibuffer-history-position)))
+
+ (defun minibuffer-history-isearch-pop-state (cmd hist-pos)
+ "Restore the minibuffer history search state.
+ Go to the history element by the absolute history position `hist-pos'."
+ (next-history-element 0 hist-pos))
+
+
;Put this on C-x u, so we can force that rather than C-_ into startup msg
(defalias 'advertised-undo 'undo)
Index: lisp/isearch.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/isearch.el,v
retrieving revision 1.298
diff -c -r1.298 isearch.el
*** lisp/isearch.el 9 Jul 2007 14:45:01 -0000 1.298
--- lisp/isearch.el 13 Jul 2007 16:56:55 -0000
***************
*** 164,169 ****
--- 164,173 ----
(defvar isearch-mode-end-hook-quit nil
"Non-nil while running `isearch-mode-end-hook' if user quit the search.")
+ (defvar isearch-message-function nil
+ "Function to call to display the search prompt.
+ If nil, use `isearch-message'.")
+
(defvar isearch-wrap-function nil
"Function to call to wrap the search when search is failed.
If nil, move point to the beginning of the buffer for a forward search,
***************
*** 715,721 ****
(null executing-kbd-macro))
(progn
(if (not (input-pending-p))
! (isearch-message))
(if (and isearch-slow-terminal-mode
(not (or isearch-small-window
(pos-visible-in-window-p))))
--- 725,733 ----
(null executing-kbd-macro))
(progn
(if (not (input-pending-p))
! (if isearch-message-function
! (funcall isearch-message-function)
! (isearch-message)))
(if (and isearch-slow-terminal-mode
(not (or isearch-small-window
(pos-visible-in-window-p))))
***************
*** 2020,2026 ****
(defun isearch-search ()
;; Do the search with the current search string.
! (isearch-message nil t)
(if (and (eq isearch-case-fold-search t) search-upper-case)
(setq isearch-case-fold-search
(isearch-no-upper-case-p isearch-string isearch-regexp)))
--- 2038,2046 ----
(defun isearch-search ()
;; Do the search with the current search string.
! (if isearch-message-function
! (funcall isearch-message-function nil t)
! (isearch-message nil t))
(if (and (eq isearch-case-fold-search t) search-upper-case)
(setq isearch-case-fold-search
(isearch-no-upper-case-p isearch-string isearch-regexp)))
--
Juri Linkov
http://www.jurta.org/emacs/
- Search minibuffer history, Juri Linkov, 2007/07/09
- Re: Search minibuffer history, Richard Stallman, 2007/07/10
- Re: Search minibuffer history, Juri Linkov, 2007/07/10
- Re: Search minibuffer history, Richard Stallman, 2007/07/10
- Re: Search minibuffer history, Juri Linkov, 2007/07/10
- Re: Search minibuffer history, Richard Stallman, 2007/07/11
- Re: Search minibuffer history, Juri Linkov, 2007/07/11
- Re: Search minibuffer history, Richard Stallman, 2007/07/12
- Re: Search minibuffer history,
Juri Linkov <=
- Re: Search minibuffer history, Stefan Monnier, 2007/07/16
- Re: Search minibuffer history, Juri Linkov, 2007/07/16
- Re: Search minibuffer history, Richard Stallman, 2007/07/16
- Re: Search minibuffer history, Juri Linkov, 2007/07/21
- Re: Search minibuffer history, Richard Stallman, 2007/07/11