mu4e: clean up address completion

This commit is contained in:
djcb
2014-11-30 16:29:10 +02:00
parent 0b6ab46675
commit fcdb2c1a04

View File

@ -228,38 +228,48 @@ appear on disk."
(mu4e~proc-add (buffer-file-name) mu4e~draft-drafts-folder)) nil t)) (mu4e~proc-add (buffer-file-name) mu4e~draft-drafts-folder)) nil t))
(defun mu4e~compose-find-completion-style (some-style)
"Find completion style SOME-STYLE in completion-styles-alist, or return nil." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(find-if (lambda (style) (eq some-style (car style))) ;; address completion; inspired by org-contacts.el and
completion-styles-alist)) ;; https://github.com/nordlow/elisp/blob/master/mine/completion-styles-cycle.el
(defconst mu4e~completion-cycle-treshold 5 (defun mu4e~compose-complete-contact (&optional start)
"mu4e value for `completion-cycle-treshold'.") "Complete the text at START with a contact.
Ie. either 'name <email>' or 'email')."
(interactive)
(let ((mail-abbrev-mode-regexp mu4e~compose-address-fields-regexp)
(eoh ;; end-of-headers
(save-excursion
(goto-char (point-min))
(search-forward-regexp mail-header-separator nil t))))
;; try to complete only when we're in the headers area,
;; looking at an address field.
(when (and eoh (> eoh (point)) (mail-abbrev-in-expansion-header-p))
(let* ((end (point))
(start
(or start
(save-excursion
(re-search-backward "\\(\\`\\|[\n:,]\\)[ \t]*")
(goto-char (match-end 0))
(point)))))
(list start end mu4e~contacts-for-completion)))))
(defun mu4e~compose-setup-completion () (defun mu4e~compose-setup-completion ()
"Set up autocompletion of addresses." "Set up auto-completion of addresses."
(let ((compstyle (set (make-local-variable 'completion-ignore-case) t)
(or (mu4e~compose-find-completion-style 'substring) (set (make-local-variable 'completion-cycle-threshold) 7)
(mu4e~compose-find-completion-style 'partial-completion)))) (add-hook 'completion-at-point-functions
;; emacs-24+ has 'substring, otherwise we try partial-completion, otherwise 'mu4e~compose-complete-contact nil t))
;; we leave it at the default
(when compstyle ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(make-local-variable 'completion-styles) (defvar mu4e-compose-mode-map nil
(add-to-list 'completion-styles (car compstyle))) "Keymap for \"*mu4e-compose*\" buffers.")
(when (boundp 'completion-cycle-threshold) (unless mu4e-compose-mode-map
(make-local-variable 'completion-cycle-threshold) (setq mu4e-compose-mode-map
(setq completion-cycle-threshold mu4e~completion-cycle-treshold)) (let ((map (make-sparse-keymap)))
;; disable org-contacts support, since it prevents our autocompletion (define-key map (kbd "C-S-u") 'mu4e-update-mail-and-index)
(make-local-variable 'completion-at-point-functions) (define-key map (kbd "C-c C-u") 'mu4e-update-mail-and-index)
(remove 'org-contacts-message-complete-function completion-at-point-functions) map)))
(add-to-list 'completion-at-point-functions 'mu4e~compose-complete-contact)
;; needed for emacs 23...
(when (= emacs-major-version 23)
(make-local-variable 'message-completion-alist)
(setq message-completion-alist
(cons
(cons mu4e~compose-address-fields-regexp 'completion-at-point)
message-completion-alist)))))
(defvar mu4e-compose-mode-abbrev-table nil) (defvar mu4e-compose-mode-abbrev-table nil)
(define-derived-mode mu4e-compose-mode message-mode "mu4e:compose" (define-derived-mode mu4e-compose-mode message-mode "mu4e:compose"
@ -274,8 +284,6 @@ appear on disk."
;; if the default charset is not set, use UTF-8 ;; if the default charset is not set, use UTF-8
(unless message-default-charset (unless message-default-charset
(setq message-default-charset 'utf-8)) (setq message-default-charset 'utf-8))
;; make completion case-insensitive
(set (make-local-variable 'completion-ignore-case) t)
;; make sure mu4e is started in the background (ie. we don't want to error ;; make sure mu4e is started in the background (ie. we don't want to error
;; out when sending the message; better to do it now if there's a problem) ;; out when sending the message; better to do it now if there's a problem)
(mu4e~start) ;; start mu4e in background, if needed (mu4e~start) ;; start mu4e in background, if needed
@ -286,13 +294,9 @@ appear on disk."
(setq default-directory (expand-file-name "~/")) (setq default-directory (expand-file-name "~/"))
;; offer completion for e-mail addresses ;; offer completion for e-mail addresses
(when (and mu4e-compose-complete-addresses (when mu4e-compose-complete-addresses
(boundp 'completion-at-point-functions))
(mu4e~compose-setup-completion)) (mu4e~compose-setup-completion))
(define-key mu4e-compose-mode-map (kbd "C-S-u") 'mu4e-update-mail-and-index)
(define-key mu4e-compose-mode-map (kbd "C-c C-u") 'mu4e-update-mail-and-index)
;; setup the fcc-stuff, if needed ;; setup the fcc-stuff, if needed
(add-hook 'message-send-hook (add-hook 'message-send-hook
(lambda () ;; mu4e~compose-save-before-sending (lambda () ;; mu4e~compose-save-before-sending
@ -504,29 +508,6 @@ draft message."
(interactive) (interactive)
(mu4e-compose 'new)) (mu4e-compose 'new))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; address completion; inspired by org-contacts.el
(defun mu4e~compose-complete-contact (&optional start)
"Complete the text at START with a contact.
Ie. either 'name <email>' or 'email')."
(interactive)
(let ((mail-abbrev-mode-regexp mu4e~compose-address-fields-regexp)
(eoh ;; end-of-headers
(save-excursion
(goto-char (point-min))
(search-forward-regexp mail-header-separator nil t))))
;; try to complete only when we're in the headers area,
;; looking at an address field.
(when (and eoh (> eoh (point)) (mail-abbrev-in-expansion-header-p))
(let* ((end (point))
(start
(or start
(save-excursion
(re-search-backward "\\(\\`\\|[\n:,]\\)[ \t]*")
(goto-char (match-end 0))
(point)))))
(list start end mu4e~contacts-for-completion)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -608,7 +589,7 @@ beginning of the buffer."
(let ((old-position (point))) (let ((old-position (point)))
(message-goto-body) (message-goto-body)
(when (equal (point) old-position) (when (equal (point) old-position)
(beginning-of-buffer)))) (goto-char (point-min)))))
(define-key mu4e-compose-mode-map (define-key mu4e-compose-mode-map
(vector 'remap 'beginning-of-buffer) 'mu4e-compose-goto-top) (vector 'remap 'beginning-of-buffer) 'mu4e-compose-goto-top)
@ -620,11 +601,11 @@ end of the buffer."
(interactive) (interactive)
(let ((old-position (point)) (let ((old-position (point))
(message-position (save-excursion (message-goto-body) (point)))) (message-position (save-excursion (message-goto-body) (point))))
(end-of-buffer) (goto-char (point-max))
(when (re-search-backward message-signature-separator message-position t) (when (re-search-backward message-signature-separator message-position t)
(previous-line)) (forward-line -1))
(when (equal (point) old-position) (when (equal (point) old-position)
(end-of-buffer)))) (goto-char (point-max)))))
(define-key mu4e-compose-mode-map (define-key mu4e-compose-mode-map
(vector 'remap 'end-of-buffer) 'mu4e-compose-goto-bottom) (vector 'remap 'end-of-buffer) 'mu4e-compose-goto-bottom)