emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: next-matching-history-element default [patch]


From: Juri Linkov
Subject: Re: next-matching-history-element default [patch]
Date: Tue, 28 Dec 2004 03:28:34 +0200
User-agent: Gnus/5.110002 (No Gnus v0.2) Emacs/21.3.50 (gnu/linux)

Richard Stallman <address@hidden> writes:
> Thanks.  I'll install that.

This indeed fixes the long-standing problem in `next-matching-history-element'
(I think the reason it was not fixed for a long time is that everyone
uses M-r, not M-s which finds nothing from the initial history position),
but I have a change I implemented three months ago that will depreciate
`previous-matching-history-element' (and `next-matching-history-element').

The change I propose is to use isearch to search the minibuffer history.
This way Emacs will provide an incremental search in the history in
the same way as shells using readline already provide.

The following patch sets the value of `isearch-search-fun-function' in
the minibuffer to a function similar to `Info-isearch-search' used to
search through Info multiple nodes.

This also requires three fixes in isearch.el to work better
in the case when isearch-search-fun-function is specified
and when isearch is used in the minibuffer.

Index: lisp/simple.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/simple.el,v
retrieving revision 1.674
diff -u -r1.674 simple.el
--- lisp/simple.el      27 Dec 2004 16:34:43 -0000      1.674
+++ lisp/simple.el      28 Dec 2004 00:52:57 -0000
@@ -1143,11 +1143,13 @@
 
 (defvar minibuffer-temporary-goal-position nil)
 
-(defun next-history-element (n)
-  "Insert the next element of the minibuffer history into the minibuffer."
+(defun next-history-element (n &optional narg)
+  "Insert Nth next element of the minibuffer history into the minibuffer.
+The optional argument NARG overrides the N argument and specifies the
+absolute history position instead of relative position specified by N."
   (interactive "p")
-  (or (zerop n)
-      (let ((narg (- minibuffer-history-position n))
+  (unless (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)
@@ -1221,6 +1221,64 @@
   ;; 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 the minibuffer history
+(add-hook 'minibuffer-setup-hook 'minibuffer-isearch-initialize)
+
+(defun minibuffer-isearch-initialize ()
+  (set (make-local-variable 'isearch-search-fun-function)
+       'minibuffer-history-isearch-search)
+  (set (make-local-variable 'isearch-wrap-function)
+       'minibuffer-history-isearch-wrap)
+  (set (make-local-variable 'isearch-push-state-function)
+       'minibuffer-history-isearch-push-state))
+
+(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)))))
+        (or (funcall search-fun string
+                     (or bound (unless isearch-forward 
(minibuffer-prompt-end)))
+                     noerror)
+            (unless bound
+              (condition-case nil
+                  (progn
+                    (while (not (funcall
+                                 search-fun string
+                                 (unless isearch-forward 
(minibuffer-prompt-end))
+                                 noerror))
+                      (cond
+                       (isearch-forward
+                        (next-history-element 1)
+                        (goto-char (minibuffer-prompt-end)))
+                       (t
+                        (previous-history-element 1)
+                        (goto-char (point-max)))))
+                    (point))
+                (error nil)))))))))
+
+(defun minibuffer-history-isearch-wrap ()
+  (if (not isearch-word)
+      (if isearch-forward
+          (next-history-element 0 (length (symbol-value 
minibuffer-history-variable)))
+        (next-history-element 0 0)))
+  (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))
+
 
 ;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: /cvsroot/emacs/emacs/lisp/isearch.el,v
retrieving revision 1.249
diff -u -r1.249 isearch.el
--- lisp/isearch.el     15 Dec 2004 10:08:51 -0000      1.249
+++ lisp/isearch.el     28 Dec 2004 00:59:44 -0000
@@ -1300,9 +1300,11 @@
       ;; Not regexp, not reverse, or no match at point.
       (if (and isearch-other-end (not isearch-adjusted))
          (goto-char (if isearch-forward isearch-other-end
-                      (min isearch-opoint
-                           isearch-barrier
-                           (1+ isearch-other-end)))))
+                      (if isearch-search-fun-function
+                          (1+ isearch-other-end)
+                        (min isearch-opoint
+                             isearch-barrier
+                             (1+ isearch-other-end))))))
       (isearch-search)
       ))
   (isearch-push-state)
@@ -1879,10 +1881,19 @@
               isearch-message)
            (isearch-message-suffix c-q-hack ellipsis)
            )))
-    (if c-q-hack
+    (if (or (and (minibuffer-window-active-p (selected-window))
+                isearch-success
+                (not isearch-invalid-regexp))
+           c-q-hack)
        m
       (let ((message-log-max nil))
-       (message "%s" m)))))
+       (message "%s" m)
+       (when (and (minibuffer-window-active-p (selected-window))
+                  (not isearch-invalid-regexp))
+         (sit-for (or isearch-original-minibuffer-message-timeout
+                      minibuffer-message-timeout
+                       0))
+         (message ""))))))
 
 (defun isearch-message-prefix (&optional c-q-hack ellipsis nonincremental)
   ;; If about to search, and previous search regexp was invalid,
@@ -1900,6 +1911,7 @@
                   (if isearch-adjusted "pending " "")
                   (if (and isearch-wrapped
                            (not isearch-wrap-function)
+                           (not isearch-search-fun-function)
                            (if isearch-forward
                                (> (point) isearch-opoint)
                              (< (point) isearch-opoint)))

-- 
Juri Linkov
http://www.jurta.org/emacs/





reply via email to

[Prev in Thread] Current Thread [Next in Thread]