emacs-devel
[Top][All Lists]
Advanced

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

isearch for doc-view.el (was: doc-view cache file permissions)


From: Tassilo Horn
Subject: isearch for doc-view.el (was: doc-view cache file permissions)
Date: Mon, 05 Nov 2007 13:01:11 +0100
User-agent: Gnus/5.110007 (No Gnus v0.7) Emacs/23.0.50 (gnu/linux)

Stefan Monnier <address@hidden> writes:

Hi Stefan,

>> I don't see any reason why some isearch-like behavior wouldn't be
>> possible.  Of course, we cannot highlight of the matches, so another
>> C-s should jump to the next page with a match instead of the next
>> match which could be on the same page.
>
> We may even be able to reuse the isearch machinery and just set
> isearch-search-fun-function.

I'm trying to implement that now, but I have some problems with it.  I
set isearch-search-fun-function buffer-locally to
doc-view-isearch-function in doc-view-mode.  If I describe this variable
in a doc-view buffer, it says it hat the desired value.  But when I hit
C-s to start isearch and edebug isearch-search-fun it shows up that
isearch-search-fun-function is nil then.  But why is that?

This variable is neither set to nil in isearch.el nor doc-view.el.

After I leave isearch with C-g the variable's buffer-local value has
disappeared.

Here's my patch.  It's just a simple start, but doc-view-search-forward
seems to work correctly.

Index: lisp/doc-view.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/doc-view.el,v
retrieving revision 1.18
diff -u -r1.18 doc-view.el
--- lisp/doc-view.el    1 Nov 2007 03:53:32 -0000       1.18
+++ lisp/doc-view.el    5 Nov 2007 11:41:33 -0000
@@ -101,11 +101,11 @@
 
 ;; Todo:
 ;; - better menu.
-;; - don't use `find-file'.
 ;; - Bind slicing to a drag event.
 ;; - zoom (the whole document and/or just the region around the cursor).
 ;; - get rid of the silly arrow in the fringe.
 ;; - improve anti-aliasing (pdf-utils gets it better).
+;; - Make it work with auto-compression-mode.
 
 (require 'dired)
 (require 'image-mode)
@@ -197,11 +197,9 @@
 (defvar doc-view-current-cache-dir nil
   "Only used internally.")
 
-(defvar doc-view-current-search-matches nil
-  "Only used internally.")
-
 (defvar doc-view-current-image nil
   "Only used internally.")
+
 (defvar doc-view-current-overlay)
 (defvar doc-view-pending-cache-flush nil)
 
@@ -211,6 +209,10 @@
 (defvar doc-view-previous-major-mode nil
   "Only used internally.")
 
+(defvar doc-view-last-isearch-function nil
+  "Only used internally.
+Used to distinguish between forward and backward isearch.")
+
 ;;;; DocView Keymaps
 
 (defvar doc-view-mode-map
@@ -237,10 +239,9 @@
     (define-key map (kbd "s m")       'doc-view-set-slice-using-mouse)
     (define-key map (kbd "s r")       'doc-view-reset-slice)
     ;; Searching
-    (define-key map (kbd "C-s")       'doc-view-search)
-    (define-key map (kbd "<find>")    'doc-view-search)
-    (define-key map (kbd "C-S-n")     'doc-view-search-next-match)
-    (define-key map (kbd "C-S-p")     'doc-view-search-previous-match)
+    (define-key map (kbd "C-s")       'isearch-forward)
+    (define-key map (kbd "<find>")    'isearch-forward)
+    (define-key map (kbd "C-r")       'isearch-backward)
     ;; Scrolling
     (define-key map [remap forward-char]  'image-forward-hscroll)
     (define-key map [remap backward-char] 'image-backward-hscroll)
@@ -294,17 +295,7 @@
           ;; Tell user if converting isn't finished yet
           (if doc-view-current-converter-process
               " (still converting...)\n"
-            "\n")
-          ;; Display context infos if this page matches the last search
-          (when (and doc-view-current-search-matches
-                     (assq doc-view-current-page
-                           doc-view-current-search-matches))
-            (concat (propertize "Search matches:\n" 'face 'bold)
-                    (let ((contexts ""))
-                      (dolist (m (cdr (assq doc-view-current-page
-                                            doc-view-current-search-matches)))
-                        (setq contexts (concat contexts "  - \"" m "\"\n")))
-                      contexts)))))
+            "\n")))
     ;; Update the buffer
     (doc-view-insert-image (nth (1- page) doc-view-current-files)
                            :pointer 'arrow)
@@ -500,9 +491,9 @@
       (setq doc-view-current-converter-process nil
            mode-line-process nil)
       ;; If the user looks at the DocView buffer where the conversion was
-      ;; performed, search anew.  This time it will be queried for a regexp.
+      ;; performed, search anew.
       (when (eq current-buffer proc-buffer)
-       (doc-view-search)))))
+       (funcall doc-view-last-isearch-function)))))
 
 (defun doc-view-pdf->txt (pdf txt)
   "Convert PDF to TXT asynchronously."
@@ -693,68 +684,21 @@
 
 ;;;; Searching
 
-(defun doc-view-search-internal (regexp file)
-  "Return a list of FILE's pages that contain text matching REGEXP.
-The value is an alist of the form (PAGE CONTEXTS) where PAGE is
-the pagenumber and CONTEXTS are all lines of text containing a match."
-  (with-temp-buffer
-    (insert-file-contents file)
-    (let ((page 1)
-         (lastpage 1)
-         matches)
-      (while (re-search-forward (concat "\\(?:\\([]\\)\\|\\("
-                                       regexp "\\)\\)") nil t)
-       (when (match-string 1) (incf page))
-       (when (match-string 2)
-         (if (/= page lastpage)
-             (push (cons page
-                          (list (buffer-substring
-                                 (line-beginning-position)
-                                 (line-end-position))))
-                    matches)
-           (setq matches (cons
-                          (append
-                           (or
-                            ;; This page already is a match.
-                            (car matches)
-                            ;; This is the first match on page.
-                            (list page))
-                           (list (buffer-substring
-                                  (line-beginning-position)
-                                  (line-end-position))))
-                          (cdr matches))))
-         (setq lastpage page)))
-      (nreverse matches))))
-
-(defun doc-view-search-no-of-matches (list)
-  "Extract the number of matches from the search result LIST."
-  (let ((no 0))
-    (dolist (p list)
-      (setq no (+ no (1- (length p)))))
-    no))
-
-(defun doc-view-search ()
-  "Query for a regexp and search the current document.
-If the current document hasn't been transformed to plain text
-till now do that first.  You should try searching anew when the
-conversion finished."
-  (interactive)
-  ;; New search, so forget the old results.
-  (setq doc-view-current-search-matches nil)
+(defun doc-view-isearch-function ()
+  "Return the function to use for the search."
+  (message "fooooo")
+  (if isearch-forward 'doc-view-search-forward 'doc-view-search-backward))
+
+(defun doc-view-isearch-text-file ()
+  "Return the text file used for searching or nil if it doesn't exist.
+If the text file doesn't exist start the conversion."
   (let ((txt (expand-file-name "doc.txt"
                                (doc-view-current-cache-dir))))
     (if (file-readable-p txt)
-       (progn
-         (setq doc-view-current-search-matches
-               (doc-view-search-internal
-                (read-from-minibuffer "Regexp: ")
-                txt))
-         (message "DocView: search yielded %d matches."
-                  (doc-view-search-no-of-matches
-                   doc-view-current-search-matches)))
-      ;; We must convert to TXT first!
+       txt
+      ;; We must convert to TXT first.
       (if doc-view-current-converter-process
-         (message "DocView: please wait till conversion finished.")
+         nil
        (let ((ext (file-name-extension buffer-file-name)))
          (cond
           ((string= ext "pdf")
@@ -772,35 +716,42 @@
            (doc-view-pdf->txt (expand-file-name "doc.pdf"
                                                  (doc-view-current-cache-dir))
                               txt))
-          (t (error "DocView doesn't know what to do"))))))))
-
-(defun doc-view-search-next-match (arg)
-  "Go to the ARGth next matching page."
-  (interactive "p")
-  (let* ((next-pages (doc-view-remove-if
-                     (lambda (i) (<= (car i) doc-view-current-page))
-                     doc-view-current-search-matches))
-        (page (car (nth (1- arg) next-pages))))
-    (if page
-       (doc-view-goto-page page)
-      (when (and
-            doc-view-current-search-matches
-            (y-or-n-p "No more matches after current page.  Wrap to first 
match? "))
-       (doc-view-goto-page (caar doc-view-current-search-matches))))))
+          (t (error "DocView doesn't know what to do")))
+         nil)))))
 
-(defun doc-view-search-previous-match (arg)
-  "Go to the ARGth previous matching page."
-  (interactive "p")
-  (let* ((prev-pages (doc-view-remove-if
-                     (lambda (i) (>= (car i) doc-view-current-page))
-                     doc-view-current-search-matches))
-        (page (car (nth (1- arg) (nreverse prev-pages)))))
-    (if page
-       (doc-view-goto-page page)
-      (when (and
-            doc-view-current-search-matches
-            (y-or-n-p "No more matches before current page.  Wrap to last 
match? "))
-       (doc-view-goto-page (caar (last doc-view-current-search-matches)))))))
+(defun doc-view-search-forward (regexp &rest args)
+  (interactive "sRegexp: ")
+  (message "Regexp = %s" regexp)
+  (setq doc-view-last-isearch-function 'doc-view-search-forward)
+  (let* ((txt (doc-view-isearch-text-file))
+        (page doc-view-current-page)
+        (cur-page page)
+        (pages (length doc-view-current-files))
+        (cur-buf (current-buffer)))
+    (if (not txt)
+       (message "DocView: Please wait till the conversian has finished.")
+      (set-buffer (find-file-noselect txt t))
+      (goto-char (point-min))
+      ;; Go to the beginning of the current page.
+      (unless (= cur-page 0)
+       (search-forward "" nil t (- cur-page 1)))
+      ;; Now do a regexp search forward and goto that page.
+      (let ((search-again t))
+       (while search-again
+         (re-search-forward (concat "\\(?:\\([]\\)\\|\\("
+                                    regexp "\\)\\)") nil t)
+         (when (match-string 1) (incf page))
+         (when (and (match-string 2)
+                    (/= cur-page page))
+           (message "match-str = %s" (buffer-substring 
(line-beginning-position)
+                                                       (line-end-position)))
+           (setq search-again nil))
+         (when (> page pages)
+           (setq search-again nil
+                 page nil)))
+       (set-buffer cur-buf)
+       (when page
+         (doc-view-goto-page page))))))
 
 ;;;; User interface commands and the mode
 
@@ -848,9 +799,11 @@
   (make-local-variable 'doc-view-current-slice)
   (make-local-variable 'doc-view-current-cache-dir)
   (make-local-variable 'doc-view-current-info)
-  (make-local-variable 'doc-view-current-search-matches)
+  (make-local-variable 'doc-view-last-isearch-function)
   (set (make-local-variable 'doc-view-current-overlay)
        (make-overlay (point-min) (point-max) nil t))
+  (set (make-local-variable 'isearch-search-fun-function)
+       'doc-view-isearch-function)
   (add-hook 'change-major-mode-hook
             (lambda () (delete-overlay doc-view-current-overlay))
             nil t)
Bye,
Tassilo

reply via email to

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