;;; moggle --- iterate headers and body in message-mode ;;; Commentary: ;; ;; This file: http://user.it.uu.se/~embe8573/conf/emacs-init/gnus/moggle.el ;; ;; .--------------------------------------------. ;; | moggle - message-mode body/headers | ;; | back-and-forth, one-keystroke, | ;; | very-fast-indeed iteration | ;; | by Emanuel Berg | ;; | embe8573 AT&T student DOS uu DOS se | ;; | updated: 16.01, 04/07/14 | ;; '--------------------------------------------' ;; ;; In the current message, hit one (1) key to go to ;; the next field to type. The first fields in ;; a message are the headers -- "To", "Subject", and ;; so on -- and last, there is the body. ;; ;; And, there is another key to do the exact same ;; thing, only in the opposite direction! ;; ;; By default, `next-header' is bound to TAB ("\t"), ;; and `previous-header' to BACKTAB (; i.e., ;; right-shift and TAB). ;; ;; This also plays seamlessly with the abbrevs of the ;; .mailrc file. Try it: setup an alias, type it in ;; the "To" header, and hit TAB. ;; ;; For example, for mail addresses, .mailrc can look ;; like this: ;; ;; alias john "John DiFool " ;; alias kate "Katherine Moss " ;; alias friends john kate ;; ;; For Usenet/Gmane groups, setup ordinary abbrevs: ;; geh -> gnu.emacs.help (gmane.emacs.help) and so on! ;; ;; ;; All in all, this makes for very rapid, mouse-free ;; editing of mails and Usenet/Gmane posts. Feel the ;; difference :) ;;; Code: (require 'message) (defun get-header-separator-pos () "Get the position of `mail-header-separator'." (save-excursion (rfc822-goto-eoh) (point) )) (defun at-end-of-line-p () "True iff point is at the end of the current line." (looking-at "$")) (defun next-line-header-or-body () "Go to the next header field. If already at the last header field, go to the message body." (if (re-search-forward ": " (get-header-separator-pos) t) ; NOERROR (end-of-line) (message-goto-body) )) (defun end-of-line-or-next-line () "If not at the end of a line, go there. Else, got to the next header field -- i.e., if it exists, at the line below." (if (at-end-of-line-p) (next-line-header-or-body) (end-of-line) )) (defun next-header () "Go to the next header field. If already at the last one, go to the message body." (interactive) (if (< (point) (get-header-separator-pos)) (progn (expand-abbrev) (end-of-line-or-next-line) ) (progn (goto-char (point-min)) (end-of-line-or-next-line) ))) (defun prev-header () "Go to the previous header field. If already at the first one, got to the message body." (interactive) (if (< (point) (get-header-separator-pos)) (progn (expand-abbrev) (if (= 1 (line-number-at-pos)) (message-goto-body) (forward-line -1) ) (end-of-line) ) (progn (goto-char (get-header-separator-pos)) (backward-char 1) ))) (define-key message-mode-map "\t" #'next-header) (define-key message-mode-map [backtab] #'prev-header) (provide 'moggle) ;;; moggle.el ends here