;;; nnir.el --- search mail with various search engines -*- coding: utf-8 -*-
-;; Copyright (C) 1998-2015 Free Software Foundation, Inc.
+;; Copyright (C) 1998-2016 Free Software Foundation, Inc.
;; Author: Kai Großjohann <grossjohann@ls6.cs.uni-dortmund.de>
;; Swish-e and Swish++ backends by:
(require 'gnus-sum)
-(eval-when-compile
- (autoload 'nnimap-buffer "nnimap")
- (autoload 'nnimap-command "nnimap")
- (autoload 'nnimap-capability "nnimap")
- (autoload 'nnimap-wait-for-line "nnimap")
- (autoload 'nnimap-change-group "nnimap")
- (autoload 'nnimap-make-thread-query "nnimap")
- (autoload 'gnus-registry-action "gnus-registry")
- (autoload 'gnus-registry-get-id-key "gnus-registry")
- (autoload 'gnus-group-topic-name "gnus-topic"))
-
-
(nnoo-declare nnir)
(nnoo-define-basics nnir)
(defcustom nnir-swish++-additional-switches '()
"*A list of strings, to be given as additional arguments to swish++.
-Note that this should be a list. Ie, do NOT use the following:
+Note that this should be a list. I.e., do NOT use the following:
(setq nnir-swish++-additional-switches \"-i -w\") ; wrong
Instead, use this:
- (setq nnir-swish++-additional-switches '(\"-i\" \"-w\"))"
+ (setq nnir-swish++-additional-switches \\='(\"-i\" \"-w\"))"
:type '(repeat (string))
:group 'nnir)
(defcustom nnir-swish-e-additional-switches '()
"*A list of strings, to be given as additional arguments to swish-e.
-Note that this should be a list. Ie, do NOT use the following:
+Note that this should be a list. I.e., do NOT use the following:
(setq nnir-swish-e-additional-switches \"-i -w\") ; wrong
Instead, use this:
- (setq nnir-swish-e-additional-switches '(\"-i\" \"-w\"))
+ (setq nnir-swish-e-additional-switches \\='(\"-i\" \"-w\"))
This could be a server parameter."
:type '(repeat (string))
(defcustom nnir-hyrex-additional-switches '()
"*A list of strings, to be given as additional arguments for nnir-search.
-Note that this should be a list. Ie, do NOT use the following:
+Note that this should be a list. I.e., do NOT use the following:
(setq nnir-hyrex-additional-switches \"-ddl ddl.xml -c nnir\") ; wrong !
Instead, use this:
- (setq nnir-hyrex-additional-switches '(\"-ddl\" \"ddl.xml\" \"-c\" \"nnir\"))"
+ (setq nnir-hyrex-additional-switches \\='(\"-ddl\" \"ddl.xml\" \"-c\" \"nnir\"))"
:type '(repeat (string))
:group 'nnir)
The switches `-q', `-a', and `-s' are always used, very few other switches
make any sense in this context.
-Note that this should be a list. Ie, do NOT use the following:
+Note that this should be a list. I.e., do NOT use the following:
(setq nnir-namazu-additional-switches \"-i -w\") ; wrong
Instead, use this:
- (setq nnir-namazu-additional-switches '(\"-i\" \"-w\"))"
+ (setq nnir-namazu-additional-switches \\='(\"-i\" \"-w\"))"
:type '(repeat (string))
:group 'nnir)
(defcustom nnir-notmuch-additional-switches '()
"*A list of strings, to be given as additional arguments to notmuch.
-Note that this should be a list. Ie, do NOT use the following:
+Note that this should be a list. I.e., do NOT use the following:
(setq nnir-notmuch-additional-switches \"-i -w\") ; wrong
Instead, use this:
- (setq nnir-notmuch-additional-switches '(\"-i\" \"-w\"))"
+ (setq nnir-notmuch-additional-switches \\='(\"-i\" \"-w\"))"
:version "24.1"
:type '(repeat (string))
:group 'nnir)
;; Gnus glue.
+(declare-function gnus-group-topic-name "gnus-topic" ())
+
(defun gnus-group-make-nnir-group (nnir-extra-parms &optional specs)
"Create an nnir group. Prompt for a search query and determine
the groups to search as follows: if called from the *Server*
;;; Search Engine Interfaces:
+(autoload 'nnimap-change-group "nnimap")
+(declare-function nnimap-buffer "nnimap" ())
+(declare-function nnimap-command "nnimap" (&rest args))
+
;; imap interface
(defun nnir-run-imap (query srv &optional groups)
"Run a search against an IMAP back-end server.
(catch 'found
(mapcar
#'(lambda (group)
- (let (artlist)
- (condition-case ()
- (when (nnimap-change-group
- (gnus-group-short-name group) server)
- (with-current-buffer (nnimap-buffer)
- (message "Searching %s..." group)
- (let* ((arts 0)
- (literal+ (nnimap-capability "LITERAL+"))
- (search (split-string
- (if (string= criteria "")
- qstring
- (nnir-imap-make-query
- criteria qstring))
- "\n"))
- (coding (upcase
- (replace-regexp-in-string
- "-\\(unix\\|dos\\|mac\\)" ""
- (symbol-name
- (cdr default-process-coding-system)))))
- call result)
- (setq call (nnimap-send-command
- "UID SEARCH CHARSET %s %s" coding (pop search)))
- (while search ; Non-ascii search terms
- (unless literal+
- (nnimap-wait-for-line "^\\+\\(.*\\)\n"))
- (process-send-string (get-buffer-process (current-buffer)) (pop search))
- (process-send-string (get-buffer-process (current-buffer))
- (if (nnimap-newlinep nnimap-object)
- "\n"
- "\r\n")))
- (setq result (nnimap-get-response call))
- (mapc
- (lambda (artnum)
- (let ((artn (string-to-number artnum)))
- (when (> artn 0)
- (push (vector group artn 100)
- artlist)
- (when (assq 'shortcut query)
- (throw 'found (list artlist)))
- (setq arts (1+ arts)))))
- (and (car result)
- (cdr (assoc "SEARCH" (cdr result)))))
- (message "Searching %s... %d matches" group arts)))
- (message "Searching %s...done" group))
- (quit nil))
- (nreverse artlist)))
+ (let (artlist)
+ (condition-case ()
+ (when (nnimap-change-group
+ (gnus-group-short-name group) server)
+ (with-current-buffer (nnimap-buffer)
+ (message "Searching %s..." group)
+ (let ((arts 0)
+ (result (nnimap-command "UID SEARCH %s"
+ (if (string= criteria "")
+ qstring
+ (nnir-imap-make-query
+ criteria qstring)))))
+ (mapc
+ (lambda (artnum)
+ (let ((artn (string-to-number artnum)))
+ (when (> artn 0)
+ (push (vector group artn 100)
+ artlist)
+ (when (assq 'shortcut query)
+ (throw 'found (list artlist)))
+ (setq arts (1+ arts)))))
+ (and (car result)
+ (cdr (assoc "SEARCH" (cdr result)))))
+ (message "Searching %s... %d matches" group arts)))
+ (message "Searching %s...done" group))
+ (quit nil))
+ (nreverse artlist)))
groups))))))
(defun nnir-imap-make-query (criteria qstring)
(defun nnir-imap-expr-to-imap (criteria expr)
"Convert EXPR into an IMAP search expression on CRITERIA"
;; What sort of expression is this, eh?
- (let ((literal+ (nnimap-capability "LITERAL+")))
- (cond
- ;; Simple string term
- ((stringp expr)
- (format "%s %S" criteria expr))
- ;; Trivial term: and
- ((eq expr 'and) nil)
- ;; Composite term: or expression
- ((eq (car-safe expr) 'or)
- (format "OR %s %s"
- (nnir-imap-expr-to-imap criteria (second expr))
- (nnir-imap-expr-to-imap criteria (third expr))))
- ;; Composite term: just the fax, mam
- ((eq (car-safe expr) 'not)
- (format "NOT (%s)" (nnir-imap-query-to-imap criteria (rest expr))))
- ;; Composite term: non-ascii search term
- ((numberp (car-safe expr))
- (format "%s {%d%s}\n%s" criteria (car expr)
- (if literal+ "+" "") (second expr)))
- ;; Composite term: just expand it all.
- ((and (not (null expr)) (listp expr))
- (format "(%s)" (nnir-imap-query-to-imap criteria expr)))
- ;; Complex value, give up for now.
- (t (error "Unhandled input: %S" expr)))))
+ (cond
+ ;; Simple string term
+ ((stringp expr)
+ (format "%s %S" criteria expr))
+ ;; Trivial term: and
+ ((eq expr 'and) nil)
+ ;; Composite term: or expression
+ ((eq (car-safe expr) 'or)
+ (format "OR %s %s"
+ (nnir-imap-expr-to-imap criteria (second expr))
+ (nnir-imap-expr-to-imap criteria (third expr))))
+ ;; Composite term: just the fax, mam
+ ((eq (car-safe expr) 'not)
+ (format "NOT (%s)" (nnir-imap-query-to-imap criteria (rest expr))))
+ ;; Composite term: just expand it all.
+ ((and (not (null expr)) (listp expr))
+ (format "(%s)" (nnir-imap-query-to-imap criteria expr)))
+ ;; Complex value, give up for now.
+ (t (error "Unhandled input: %S" expr))))
(defun nnir-imap-parse-query (string)
((eq term 'and) 'and)
;; negated term
((eq term 'not) (list 'not (nnir-imap-next-expr)))
- ;; non-ascii search string
- ((and (stringp term)
- (not (= (string-bytes term)
- (length term))))
- (list (string-bytes term) term))
;; generic term
(t term))))
(let ((backend (car (gnus-server-to-method server))))
(nnoo-current-server-p (or backend 'nnir) server)))
+(autoload 'nnimap-make-thread-query "nnimap")
+(declare-function gnus-registry-get-id-key "gnus-registry" (id key))
+
(defun nnir-search-thread (header)
"Make an nnir group based on the thread containing the article
header. The current server will be searched. If the registry is
(forward-line)))))
groups))
+;; Behind gnus-registry-enabled test.
+(declare-function gnus-registry-action "gnus-registry"
+ (action data-header from &optional to method))
+
(defun nnir-registry-action (action data-header from &optional to method)
"Call `gnus-registry-action' with the original article group."
(gnus-registry-action