X-Git-Url: https://git.notmuchmail.org/git?p=notmuch;a=blobdiff_plain;f=emacs%2Fnotmuch-lib.el;h=d315f7656e9bc4a004575faa14be386a858cdb83;hp=cb9be30177013e7fc24783fc77091357043c801b;hb=6bd3d8af5431542f352f084b6366e88b98b019a1;hpb=8cbb5114a20c1217f23977fd5edca99a0b7a2955 diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el index cb9be301..d315f765 100644 --- a/emacs/notmuch-lib.el +++ b/emacs/notmuch-lib.el @@ -24,19 +24,182 @@ (defvar notmuch-command "notmuch" "Command to run the notmuch binary.") -;; XXX: This should be a generic function in emacs somewhere, not -;; here. -(defun point-invisible-p () - "Return whether the character at point is invisible. - -Here visibility is determined by `buffer-invisibility-spec' and -the invisible property of any overlays for point. It doesn't have -anything to do with whether point is currently being displayed -within the current window." - (let ((prop (get-char-property (point) 'invisible))) - (if (eq buffer-invisibility-spec t) - prop - (or (memq prop buffer-invisibility-spec) - (assq prop buffer-invisibility-spec))))) +(defgroup notmuch nil + "Notmuch mail reader for Emacs." + :group 'mail) + +(defgroup notmuch-hello nil + "Overview of saved searches, tags, etc." + :group 'notmuch) + +(defgroup notmuch-search nil + "Searching and sorting mail." + :group 'notmuch) + +(defgroup notmuch-show nil + "Showing messages and threads." + :group 'notmuch) + +(defgroup notmuch-send nil + "Sending messages from Notmuch." + :group 'notmuch) + +(custom-add-to-group 'notmuch-send 'message 'custom-group) + +(defgroup notmuch-crypto nil + "Processing and display of cryptographic MIME parts." + :group 'notmuch) + +(defgroup notmuch-hooks nil + "Running custom code on well-defined occasions." + :group 'notmuch) + +(defgroup notmuch-external nil + "Running external commands from within Notmuch." + :group 'notmuch) + +(defgroup notmuch-faces nil + "Graphical attributes for displaying text" + :group 'notmuch) + +(defcustom notmuch-search-oldest-first t + "Show the oldest mail first when searching." + :type 'boolean + :group 'notmuch-search) + +;; + +(defvar notmuch-search-history nil + "Variable to store notmuch searches history.") + +(defcustom notmuch-saved-searches nil + "A list of saved searches to display." + :type '(alist :key-type string :value-type string) + :group 'notmuch-hello) + +(defvar notmuch-folders nil + "Deprecated name for what is now known as `notmuch-saved-searches'.") + +(defun notmuch-saved-searches () + "Common function for querying the notmuch-saved-searches variable. + +We do this as a function to support the old name of the +variable (`notmuch-folders') as well as for the default value if +the user hasn't set this variable with the old or new value." + (if notmuch-saved-searches + notmuch-saved-searches + (if notmuch-folders + notmuch-folders + '(("inbox" . "tag:inbox") + ("unread" . "tag:unread"))))) + +(defun notmuch-version () + "Return a string with the notmuch version number." + (let ((long-string + ;; Trim off the trailing newline. + (substring (shell-command-to-string + (concat notmuch-command " --version")) + 0 -1))) + (if (string-match "^notmuch\\( version\\)? \\(.*\\)$" + long-string) + (match-string 2 long-string) + "unknown"))) + +(defun notmuch-config-get (item) + "Return a value from the notmuch configuration." + ;; Trim off the trailing newline + (substring (shell-command-to-string + (concat notmuch-command " config get " item)) + 0 -1)) + +(defun notmuch-database-path () + "Return the database.path value from the notmuch configuration." + (notmuch-config-get "database.path")) + +(defun notmuch-user-name () + "Return the user.name value from the notmuch configuration." + (notmuch-config-get "user.name")) + +(defun notmuch-user-primary-email () + "Return the user.primary_email value from the notmuch configuration." + (notmuch-config-get "user.primary_email")) + +(defun notmuch-user-other-email () + "Return the user.other_email value (as a list) from the notmuch configuration." + (split-string (notmuch-config-get "user.other_email") "\n")) + +(defun notmuch-kill-this-buffer () + "Kill the current buffer." + (interactive) + (kill-buffer (current-buffer))) + +(defun notmuch-prettify-subject (subject) + ;; This function is used by `notmuch-search-process-filter' which + ;; requires that we not disrupt its' matching state. + (save-match-data + (if (and subject + (string-match "^[ \t]*$" subject)) + "[No Subject]" + subject))) + +;; + +(defun notmuch-common-do-stash (text) + "Common function to stash text in kill ring, and display in minibuffer." + (kill-new text) + (message "Stashed: %s" text)) + +;; + +(defun notmuch-remove-if-not (predicate list) + "Return a copy of LIST with all items not satisfying PREDICATE removed." + (let (out) + (while list + (when (funcall predicate (car list)) + (push (car list) out)) + (setq list (cdr list))) + (nreverse out))) + +;; This lets us avoid compiling these replacement functions when emacs +;; is sufficiently new enough to supply them alone. We do the macro +;; treatment rather than just wrapping our defun calls in a when form +;; specifically so that the compiler never sees the code on new emacs, +;; (since the code is triggering warnings that we don't know how to get +;; rid of. +;; +;; A more clever macro here would accept a condition and a list of forms. +(defmacro compile-on-emacs-prior-to-23 (form) + "Conditionally evaluate form only on emacs < emacs-23." + (list 'when (< emacs-major-version 23) + form)) + +;; Compatibility functions for versions of emacs before emacs 23. +;; +;; Both functions here were copied from emacs 23 with the following copyright: +;; +;; Copyright (C) 1985, 1986, 1992, 1994, 1995, 1999, 2000, 2001, 2002, 2003, +;; 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +;; +;; and under the GPL version 3 (or later) exactly as notmuch itself. +(compile-on-emacs-prior-to-23 + (defun apply-partially (fun &rest args) + "Return a function that is a partial application of FUN to ARGS. +ARGS is a list of the first N arguments to pass to FUN. +The result is a new function which does the same as FUN, except that +the first N arguments are fixed at the values with which this function +was called." + (lexical-let ((fun fun) (args1 args)) + (lambda (&rest args2) (apply fun (append args1 args2)))))) + +(compile-on-emacs-prior-to-23 + (defun mouse-event-p (object) + "Return non-nil if OBJECT is a mouse click event." + (memq (event-basic-type object) '(mouse-1 mouse-2 mouse-3 mouse-movement)))) + +;; This variable is used only buffer local, but it needs to be +;; declared globally first to avoid compiler warnings. +(defvar notmuch-show-process-crypto nil) +(make-variable-buffer-local 'notmuch-show-process-crypto) (provide 'notmuch-lib) +