emacs interface to beagle-query.


If you live in Emacs this could perhaps be useful.
I came across a blog post [1] discussing an emacs interface to
spotlight's CLI in OS X. The guy even posted a .el file and permission
to use it. I thought this was brilliant ! So I've adapted the .el file
to use beagle-query. It's very simple, but I don't know what
functionality might be missing. Of course even though it's just a few
lines of code, I have already managed to make it pretty messy and it's
very alpha quality:) But it works fine for me. I might clean it up if
more functionality is to be added.

To install:
I'm on Ubuntu Feisty with emacs-snapshot. It needs org-mode which I
think is included in emacs-22. Otherwise see [2].
Get the meta-search.el file and place it somewhere in your loadpath,
and add the line:

(require 'meta-search)  (**)

in .emacs.

To use it: 'M-x meta-search' and enter a path to start search from
(*). Leave at ~/ for entire home dir. Then specify the search string.
This string is passed verbatim to beagle-query, so add any options
that beagle-query accepts. In particular the ext:tex type options
might be useful. By default type:file is always passed.

(*) Of course all searches starts from ~/, the results are just post-filtered.
(**) I called it meta-search since one can also use tracker-search as
a backend. Just 'M-x customize-group', choose 'meta-search' and change
the command used.
[1] http://emacs.wordpress.com/2007/06/15/emacs-on-the-spotlight/
[2] http://staff.science.uva.nl/~dominik/Tools/org/

Feel free to comment.
Regards Bjørn
;;; meta-search.el --- Interface to the meta-search command

;; Copyright (C) 2007 Bjørn Haagensen
;; Copyright (C) 2007 Jose Antonio Ortega

;; Author: Bjørn Haagensen <bhaagensen gmail com>
;; Based on: mdfind.el by Jose Antonio Ortega <jao gnu org>
;; Keywords: data

;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.

;; This file is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING.  If not, write to
;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.

;;; Code:

(require 'org)

(defvar meta-search-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map [??] 'describe-mode)
    (define-key map [?q] 'close-meta-search-buffer)
    (define-key map [?n] 'org-next-link)
    (define-key map [?p] 'org-previous-link)
    (define-key map (kbd "TAB") 'org-next-link)
    (define-key map (kbd "RET") 'org-open-at-point)
    (define-key map [?o] 'org-open-at-point)
    (define-key map [?m] 'meta-search)
  "Keymap for `meta-search-mode'.")

(defun close-meta-search-buffer ()

(define-derived-mode meta-search-mode org-mode "meta-search"
  "meta-search results browser"
  (use-local-map meta-search-mode-map)
  (set (make-local-variable 'org-startup-folded) nil)
  (toggle-read-only 1))

(defun meta-search-headline (qr)
  (let ((rn (count-lines (point-min) (point-max))))
    (goto-char (point-min))
     (format "* %d results total for \"%s. Showing files\"\n" rn qr)) rn))

(defun meta-search-entries ()
  (let ((kill-whole-line nil)
        (pt (point))
	(prv nil))
    (while (not (eobp))
      (let* ((f (current-kill 0))
             (fn (file-name-nondirectory f))
             (ln_f (file-name-sans-extension fn))
	     (path (if (string= meta-search-engine "tracker-search")
		       (concat "file://" (file-name-directory f))
		     (file-name-directory f)))
	     (ln_p (substring path 7 nil)))
	(when (not (equal prv path))
	    (insert "** in folder: " (org-make-link-string path ln_p))
	    (open-line 1)
	(insert " (" (file-name-extension fn) ")    " 
		(org-make-link-string f ln_f))
	(setq prv path))

(defun meta-search ()
  (let ((dir (expand-file-name (read-file-name "Directory: ")))
	(qr (read-string "Search for: "))
        (bf (get-buffer-create "*meta-search*")))
    (with-current-buffer bf
      (message "Searching ...")
      (toggle-read-only -1)
      (delete-region (point-min) (point-max))
      (insert (shell-command-to-string 
	       (if (string= meta-search-engine "tracker-search")
		   (format "%s %s" meta-search-engine qr)
		   (format "%s type:file %s" meta-search-engine qr))))
      (sort-lines nil (point-min) (point-max))      
      (let ((no (meta-search-headline qr)))
        (when (> no 0)
	  (goto-line 2)
	  (while (not (eobp))
	    (if (not (string-match dir (current-kill 0)))
	  (goto-line 2)
	  (save-excursion (meta-search-entries))
	  (pop-to-buffer bf)
	  (goto-line 2) ; for some reason, next-link doesn't work at bob
      (message "%d results found" no)))
  (toggle-read-only 1))

(defgroup meta-search nil
  "Search for files using tracker or beagle.

meta-search allows you to search for files using tracker or
beagle as a backend from within emacs. The search string is
passed verbatim to either beagle-query or tracker search
tool. Hence for learning the search syntax, please reffer to
the documentation of the respective packages"
  :link '(url-link "http://beagle-project.org";)
  :link '(url-link "http://tracker-project.org";)
  :group 'convenience)

(defcustom meta-search-engine 'beagle-query
  "Specify which search backend to use."

  :type '(choice (const :tag "beagle-query" :value beagle-query)
		 (const :tag "tracker-search" :value tracker-search))
  :group 'meta-search)

(provide 'meta-search)

;;; meta-search.el ends here

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