From: Tassilo Horn <tassilo@member.fsf.org>
To: emacs-devel@gnu.org
Subject: isearch for doc-view.el (was: doc-view cache file permissions)
Date: Mon, 05 Nov 2007 13:01:11 +0100 [thread overview]
Message-ID: <87sl3koq9k.fsf_-_@baldur.tsdh.de> (raw)
In-Reply-To: <jwvfxzn77av.fsf-monnier+emacs@gnu.org> (Stefan Monnier's message of "Sat, 03 Nov 2007 10:07:07 -0400")
[-- Attachment #1: Type: text/plain, Size: 1058 bytes --]
Stefan Monnier <monnier@iro.umontreal.ca> 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.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: doc-view.patch --]
[-- Type: text/x-patch, Size: 9312 bytes --]
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 "\\(?:\\([\f]\\)\\|\\("
- 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 "\f" 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 "\\(?:\\([\f]\\)\\|\\("
+ 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)
[-- Attachment #3: Type: text/plain, Size: 14 bytes --]
Bye,
Tassilo
[-- Attachment #4: Type: text/plain, Size: 142 bytes --]
_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-devel
next prev parent reply other threads:[~2007-11-05 12:01 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-10-30 18:50 doc-view cache file permissions Glenn Morris
2007-10-30 20:11 ` Stefan Monnier
2007-10-30 20:57 ` Glenn Morris
2007-10-30 21:56 ` Stefan Monnier
2007-10-31 7:22 ` Tassilo Horn
2007-10-31 7:56 ` Tassilo Horn
2007-10-31 15:10 ` Stefan Monnier
2007-10-31 17:46 ` Tassilo Horn
2007-10-31 18:21 ` Stefan Monnier
2007-10-31 19:44 ` Tassilo Horn
2007-10-31 20:41 ` Stefan Monnier
2007-11-02 20:44 ` Juri Linkov
2007-11-02 23:53 ` Tassilo Horn
2007-11-03 14:07 ` Stefan Monnier
2007-11-03 19:20 ` Tassilo Horn
2007-11-05 12:01 ` Tassilo Horn [this message]
2007-11-05 12:43 ` isearch for doc-view.el David Kastrup
2007-11-05 13:19 ` Tassilo Horn
2007-11-05 15:14 ` Stefan Monnier
2007-11-05 16:42 ` CEDET/senator kill the buffer-local value of isearch-search-fun-function (was: isearch for doc-view.el) Tassilo Horn
2007-11-05 21:01 ` isearch for doc-view.el Tassilo Horn
2007-11-05 21:20 ` Stefan Monnier
2007-11-05 21:51 ` Tassilo Horn
2007-11-06 0:44 ` Juri Linkov
2007-11-06 8:25 ` Tassilo Horn
2007-11-06 22:29 ` Juri Linkov
2007-11-07 8:41 ` Tassilo Horn
2007-11-10 21:57 ` Juri Linkov
2007-11-06 8:34 ` Tassilo Horn
2007-10-30 22:14 ` doc-view cache file permissions Reiner Steib
2007-10-31 0:52 ` Stefan Monnier
2007-10-30 20:34 ` Tassilo Horn
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
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87sl3koq9k.fsf_-_@baldur.tsdh.de \
--to=tassilo@member.fsf.org \
--cc=emacs-devel@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 public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).