Emacs info search enhancement



Hi all.

I've attached an emacs script which I highly recommend for sawfish
users. You can search both librep.info and sawfish.info without
constantly switching between them. 

For example, suppose you're in sawfish.info, and want to know about
'define-structure'. If you search for it by pressing "s" key, it
fails, because it is a rep function (special form ?). You had to
manually call librep.info, and do another search.

Now you do search *once* with my new function, info-search-multi.
In the above example, the first search directly brings you to the
desired location. Of course you can also search for a sawfish variable
from librep.info.


For infos other than sawfish and librep, then it will do usual search,
so it's harmless.

If it's ok, it can go trunk. Enjoy!
Teika kazura



;;; info-search-multi.el

;; Released to the Public Domain by the author Teika Kazura.
;; 

;; `Info-search' is enhanced, by virtually combining sawfish.info
;; and librep.info. You can search both files by one call.

;; Usage: put this file where you can load it, and in `emacs.el', put
;; (require 'info-search-multi)
;; Then in info mode, "s" key is replaced by `info-search-multi'.

(defvar info-search-multi-infos
  '("sawfish" "librep")
  "List of file names to be searched by `info-search-multi'. The order
will not be preserved.
 Usully you don't need suffixes, like \".info\" nor \".bz2\", but
if you specify info filenames directly when entering info mode, then
you have to add them.")

(defun info-search-multi ()
  "Do `Info-search' over several files, specified by
`info-search-multi-infos', in the listed order.
 For example, assume the list is '(\"sawfish\" \"librep\"). If the current
info is not one of them, then usual Info-search is done. If you're visiting
\"librep\", then the search is first done over it. When unfound, then
it will search in \"sawfish\".
 When an entire file is searched, then it will be put at the tail of
`info-search-multi-infos', so the next time it will be used lastly,
to prevent 'won't reach forever' case."

  (interactive)
  (let* (
	 (curbuf (current-buffer))
	 (curbuf-name (buffer-name curbuf))
	 (curfile (file-name-nondirectory Info-current-file))
	 tmpbuf
	 (tmpbuf-name " *info-search-multi-tmp*")

	 doFlag ;; when t, then do multi search

	 ;; This lists the files to be searched.
	 ;; If curfile also appears in info-search-multi-infos,
	 ;; don't worry, it will be removed soon.
	 (newlist (copy-tree (cons curfile info-search-multi-infos)))
	 ;; pointer for loop
	 (mycdr (cdr newlist))
	 (prevcdr newlist)
	 (first-loop t)
	 err-var
	 ev2
	 )
    ;; First, check if the currently visited info file is the one listed
    ;; in `info-search-multi-infos'.
    ;; At the same time, the duplicate item in `newlist' is deleted.
    (while mycdr
      (if (equal (car mycdr) curfile)
	  ;; Ok, we've got to do a multi search.
	  (progn
	    (setq doFlag t)
	    (setcdr prevcdr (cdr mycdr))
	    (setq mycdr nil)
	    (setq info-search-multi-infos newlist)
	    )
	;; next
	(setq mycdr (cdr mycdr))
	(setq prevcdr (cdr prevcdr))))

    (setq mycdr newlist)
    (while mycdr
      (unless first-loop
	(info (car mycdr)))
      (condition-case err-var
	  (progn
	    (if first-loop
		(call-interactively 'Info-search)
	      ;;
	      (Info-search (car Info-search-history))
	      )
	    ;; Found. Congratulations!!
	    (setq mycdr nil)
	    (setq ev2 nil)
	    )
	(search-failed		   ; Caught the signal of 'not found'.
	 ;; Save the value of err-var.
	 (setq ev2 err-var)

	 (if (not doFlag)
	     ;; Usual search. Just exit the loop.
	     (setq mycdr nil)
	   ;; Multi search failed.
	   (when first-loop
	     ;; From now on, we'll use tmpbuf.
	     (when (get-buffer tmpbuf-name)
	       (kill-buffer tmpbuf-name))
	     (rename-buffer tmpbuf-name)
	     (setq tmpbuf (get-buffer-create curbuf-name))
	     (switch-to-buffer tmpbuf)
	     (setq first-loop nil))
	   ;; Push the current file to the tail of info-search-multi-infos
	   (setq info-search-multi-infos
		 (append (cdr info-search-multi-infos)
			 (list (car mycdr))))
	   )
	 ) ;; end of error handler
	)  ;; end of condition-case
      (setq mycdr (cdr mycdr))
      )	;; end of while
    
    ;; Now, what was the result?
    (if (not ev2)
	;; Found.
	(when doFlag
	  ;; Multi-search
	  (when tmpbuf
	    ;; Replace the original buffer with the new one.
	    (kill-buffer curbuf) 
	    ))
      ;; Not found.
      (when doFlag
	;; Multi search needs cleanup.
	(switch-to-buffer curbuf)
	(kill-buffer tmpbuf)
	(rename-buffer curbuf-name))
      (signal (car ev2) (cdr ev2))
      )) ;; end of let
  )

(add-hook 'Info-mode-hook
	  (lambda () 
	    (define-key Info-mode-map "s" 'info-search-multi)
	    ))

(provide 'info-search-multi)


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