From: Juri Linkov <juri@jurta.org>
To: rms@gnu.org
Cc: emacs-devel@gnu.org
Subject: Re: Search minibuffer history
Date: Tue, 10 Jul 2007 16:14:46 +0300 [thread overview]
Message-ID: <87odikbdtl.fsf@jurta.org> (raw)
In-Reply-To: <E1I88QQ-00012l-C0@fencepost.gnu.org> (Richard Stallman's message of "Tue\, 10 Jul 2007 01\:38\:14 -0400")
> Thanks for bringing this up again. We should be able to install it soon,
> but first, the code needs a lot more comments.
>
> ! (if (or c-q-hack (and (minibufferp) isearch-success (not isearch-error)))
>
> What's the purpose of that new code?
This code prevents `isearch-message' from overwriting the minibuffer text
with the isearch prompt. Without this condition `isearch-message' calls
`message' that puts the isearch prompt over the minibuffer content, so the
user can't see the search string highlighted in the minibuffer.
However, your question helped me to realize that `isearch-message' is not
a proper place to put minibuffer-specific code. A general solution would
be to add a new function variable thats allows redefining `isearch-message'
with a specific function. The patch below adds a new variable
`isearch-message-function' and redefines it in simple.el to the function
`minibuffer-history-isearch-message'.
> (not isearch-wrap-function)
> + (not isearch-search-fun-function)
> (if isearch-forward
>
> What's the reasoning that shows this is generally correct?
The logic of adding the "Over(wrapped)" prefix is valid only for
searching a normal buffer since it compares point with the original
value isearch-opoint. When applied to the minibuffer history search,
it could compare the current minibuffer history position with the
original one. This requires implementing a minibuffer-specific code,
but really I don't find it worthy of adding another isearch variable to
allow overriding the logic of displaying the "Over" prefix. A new patch
below doesn't modify this behavior, and it is good enough for the
minibuffer history search:
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 10 Jul 2007 12:59:08 -0000
***************
*** 164,169 ****
--- 164,172 ----
(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.")
+
(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))))
--- 724,732 ----
(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)))
--- 2034,2042 ----
(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)))
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 10 Jul 2007 12:09:54 -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.
***************
*** 1380,1385 ****
--- 1384,1477 ----
;; Return the width of everything before the field at the end of
;; 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 (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 ()
+ (delete-overlay minibuffer-history-isearch-message-overlay))
+
+ (defun minibuffer-history-isearch-search ()
+ (cond
+ (isearch-word
+ (if isearch-forward 'word-search-forward 'word-search-backward))
+ (t
+ (lambda (string bound noerror)
+ (let ((search-fun
+ (cond
+ (isearch-regexp
+ (if isearch-forward 're-search-forward 're-search-backward))
+ (t
+ (if isearch-forward 'search-forward 'search-backward))))
+ found)
+ ;; Avoid lazy-highlighting minibuffer prompt
+ (if (and bound isearch-forward (< (point) (minibuffer-prompt-end)))
+ (goto-char (minibuffer-prompt-end)))
+ (or (funcall search-fun string
+ (if isearch-forward bound (minibuffer-prompt-end))
+ noerror)
+ ;; Search history unless lazy-highlighting
+ (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))
+ (setq found (funcall search-fun string
+ (unless isearch-forward
+ (minibuffer-prompt-end))
+ noerror)))
+ (point))
+ (error nil)))))))))
+
+ (defun minibuffer-history-isearch-message (&optional c-q-hack ellipsis)
+ (if (not (and (minibufferp) isearch-success (not isearch-error)))
+ (isearch-message c-q-hack ellipsis)
+ (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))
+ ;; Clear any previous isearch message
+ (message "")))
+
+ (defun minibuffer-history-isearch-wrap ()
+ (unless isearch-word
+ (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 ()
+ `(lambda (cmd)
+ (minibuffer-history-isearch-pop-state cmd ,minibuffer-history-position)))
+
+ (defun minibuffer-history-isearch-pop-state (cmd hist-pos)
+ (next-history-element 0 hist-pos))
+
\f
;Put this on C-x u, so we can force that rather than C-_ into startup msg
(defalias 'advertised-undo 'undo)
--
Juri Linkov
http://www.jurta.org/emacs/
next prev parent reply other threads:[~2007-07-10 13:14 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-07-09 20:59 Search minibuffer history Juri Linkov
2007-07-10 5:38 ` Richard Stallman
2007-07-10 13:14 ` Juri Linkov [this message]
2007-07-10 22:01 ` Richard Stallman
2007-07-10 22:31 ` Juri Linkov
2007-07-11 21:04 ` Richard Stallman
2007-07-11 22:55 ` Juri Linkov
2007-07-12 21:23 ` Richard Stallman
2007-07-15 20:04 ` Juri Linkov
2007-07-16 15:05 ` Stefan Monnier
2007-07-16 20:54 ` Juri Linkov
2007-07-16 15:49 ` Richard Stallman
2007-07-21 18:17 ` Juri Linkov
2007-07-11 21:04 ` Richard Stallman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87odikbdtl.fsf@jurta.org \
--to=juri@jurta.org \
--cc=emacs-devel@gnu.org \
--cc=rms@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.