* emacs/: more WIP
This commit is contained in:
@ -42,7 +42,6 @@ notation) e.g. for mail headers")
|
||||
(defvar mu-date-format-long "%c" "date format (in strftime(2)
|
||||
notation) for the mail view and in replied/forwarded message quotations")
|
||||
|
||||
|
||||
(defvar mu-folder-draft "/home/djcb/Maildir/")
|
||||
|
||||
(defface mu-date-face '((t (:foreground "#8c5353"))) "")
|
||||
@ -64,6 +63,13 @@ notation) for the mail view and in replied/forwarded message quotations")
|
||||
|
||||
(defvar mu-own-address "djcb" "regexp matching my own address")
|
||||
|
||||
|
||||
;;; internal stuff
|
||||
(defvar mu-parent-buf nil "the parent buffer for a
|
||||
buffer (buffer-local), i.e., the buffer we'll return to when this
|
||||
buffer is killed")
|
||||
|
||||
|
||||
(defun mu-binary-version ()
|
||||
"get the version of the mu binary"
|
||||
(let ((cmd (concat mu-binary
|
||||
@ -157,8 +163,8 @@ Lisp data as a plist. Returns nil in case of error"
|
||||
(let* ((cmd (concat mu-binary " view --format=sexp " path))
|
||||
(str (shell-command-to-string cmd))
|
||||
(msglst (read-from-string str)))
|
||||
(if (msglst)
|
||||
(car msglist)
|
||||
(if msglst
|
||||
(car msglst)
|
||||
(progn (message "Failed to parse message") nil)))))
|
||||
|
||||
|
||||
@ -167,17 +173,105 @@ Lisp data as a plist. Returns nil in case of error"
|
||||
;; TODO
|
||||
)
|
||||
|
||||
|
||||
;; todo: check for unhandled marks
|
||||
(defun mu-quit-buffer ()
|
||||
"kill this find or view buffer"
|
||||
"kill this buffer, and switch to it's parentbuf if it is alive"
|
||||
(interactive)
|
||||
(if (or (equalp major-mode 'mu-find-mode)
|
||||
(equalp major-mode 'mu-view-mode))
|
||||
(kill-buffer)))
|
||||
(let ((parentbuf (mu-parent-buf)))
|
||||
(kill-buffer)
|
||||
(when (buffer-live-p parentbuf)
|
||||
(switch-to-buffer parentbuf))))
|
||||
|
||||
(defun mu-get-marked ()
|
||||
"get all marked messages as a list; each element is a cell;
|
||||
with 'action', 'source' , 'target'). ie one of three:
|
||||
('delete <path>)
|
||||
('trash <path> <target>)
|
||||
('move <path> <target>)"
|
||||
(let ((lst))
|
||||
(with-current-buffer mu-find-buffer-name
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward "^." nil t)
|
||||
(let* ((char0 (match-string 0))
|
||||
(action (get-text-property 0 'action char0))
|
||||
(path (get-text-property 0 'path char0))
|
||||
(target (get-text-property 0 'target char0)))
|
||||
(cond
|
||||
((eq action 'trash)
|
||||
(setq lst (cons (list 'trash path target) lst)))
|
||||
((eq action 'delete)
|
||||
(setq lst (cons (list 'delete path) lst)))
|
||||
((eq action 'move)
|
||||
(setq lst (cons (list 'move path target) lst))))))))
|
||||
lst))
|
||||
|
||||
(defun mu-execute ()
|
||||
"execute marked actions on messages"
|
||||
(interactive)
|
||||
(let* ((markedcount (mu-count-marked))
|
||||
(movenum (nth 0 markedcount)) (trashnum (nth 1 markedcount))
|
||||
(deletenum (nth 2 markedcount)))
|
||||
(if (= 0 (apply '+ markedcount))
|
||||
(message "No messages are marked")
|
||||
(if (and (< 0 movenum)
|
||||
(y-or-n-p (format "Do you want to move %d message(s)?" movenum)))
|
||||
(message "Moving message(s)"))
|
||||
(if (and (< 0 trashnum)
|
||||
(y-or-n-p (format "Do you want to move %d message(s) to trash?" trashnum)))
|
||||
(message "Trashing message(s)"))
|
||||
(if (and (< 0 deletenum)
|
||||
(yes-or-no-p (format "Do you want to permanently delete %d message(s)?"
|
||||
deletenum)))
|
||||
(message "Deleting message(s)"))
|
||||
(mu-find-refresh))))
|
||||
|
||||
|
||||
(defun mu-foreach-marked (func)
|
||||
"call FUNC for each marked message; the argument to FUNC is a list, either:
|
||||
with 'action', 'source' , 'target'). ie one of three:
|
||||
('delete <path>)
|
||||
('trash <path> <target>)
|
||||
('move <path> <target>)"
|
||||
(with-current-buffer mu-find-buffer-name
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward "^." nil t)
|
||||
(move-beginning-of-line 1)
|
||||
(let* ((char0 (match-string 0))
|
||||
(action (get-text-property 0 'action char0))
|
||||
(path (get-text-property 0 'path char0))
|
||||
(target (get-text-property 0 'target char0)))
|
||||
(cond
|
||||
((eq action 'trash) (funcall func (list 'trash path target)))
|
||||
((eq action 'delete) (funcall func (list 'delete path)))
|
||||
((eq action 'move) (funcall func (list 'move path target)))))
|
||||
(move-end-of-line 1)))))
|
||||
|
||||
(defun mu-count-marked ()
|
||||
"return a vector with three items (marked-move marked-trash
|
||||
marked-delete) which are the number of messages marked for each
|
||||
of those"
|
||||
(let ((result (make-vector 3 0)))
|
||||
(mu-foreach-marked
|
||||
(lambda (cell)
|
||||
(case (car cell)
|
||||
('move (aset result 0 (+ 1 (aref result 0))))
|
||||
('trash (aset result 1 (+ 1 (aref result 1))))
|
||||
('delete (aset result 2 (+ 1 (aref result 2)))))))
|
||||
(append result nil))) ;; convert to list
|
||||
|
||||
(defun mu-unmark-all ()
|
||||
"unmark all messages"
|
||||
(interactive)
|
||||
(let ((marked 0))
|
||||
(mu-foreach-marked (lambda(cell) (setq marked (+ 1 marked))))
|
||||
(if (= 0 marked)
|
||||
(message "No messages are marked")
|
||||
(when (y-or-n-p (format "Unmark %d message(s)?" marked))
|
||||
(mu-foreach-marked
|
||||
(lambda(cell)
|
||||
(let ((inhibit-read-only t))
|
||||
(delete-char 1)
|
||||
(insert-and-inherit " "))))))))
|
||||
|
||||
(provide 'mu-common)
|
||||
|
||||
@ -315,11 +315,11 @@ the mu find output")
|
||||
(delete-char 1)
|
||||
(case what
|
||||
('trash (insert-and-inherit
|
||||
(mu-str (propertize "d" 'action what))))
|
||||
(mu-str (propertize "d" 'action what 'target "/foo/bar"))))
|
||||
('delete (insert-and-inherit
|
||||
(mu-str (propertize "D" 'action what))))
|
||||
(mu-str (propertize "D" 'action what 'target "/foo/bar"))))
|
||||
('move (insert-and-inherit
|
||||
(mu-str (propertize "m" 'action what))))
|
||||
(mu-str (propertize "m" 'action what 'target "/foo/bar"))))
|
||||
('none (insert-and-inherit " ")))
|
||||
(forward-line))))))
|
||||
|
||||
|
||||
@ -46,7 +46,7 @@
|
||||
(format "On %s, %s wrote:\n"
|
||||
(format-time-string mu-date-format-long (plist-get msg :date))
|
||||
(cdr (car (plist-get msg :from)))))
|
||||
|
||||
|
||||
(defun mu-message-cite (msg)
|
||||
"cite an existing message"
|
||||
(let ((body
|
||||
@ -120,14 +120,10 @@ create a forwarded message. After creation, switch to the message editor"
|
||||
"create a reply to the message at point; After creation, switch
|
||||
to the message editor"
|
||||
(let ((path (mu-get-path)))
|
||||
(when path
|
||||
(let ())
|
||||
(when path
|
||||
(mu-ask-key "Reply to [s]ender only or to [a]ll?")
|
||||
(mu-message-reply-or-forward path))))
|
||||
|
||||
|
||||
|
||||
(mu-ask-key "Reply to [s]ender only or to [a]ll?")
|
||||
(mu-message-reply-or-forward path))
|
||||
|
||||
(defun mu-message-forward (path)
|
||||
"create a forward-message to the message at PATH; After
|
||||
creation, switch to the message editor"
|
||||
|
||||
@ -114,7 +114,7 @@ function returns the resulting name"
|
||||
|
||||
(defvar mu-view-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map "q" 'mu-view-quit-buffer)
|
||||
(define-key map "q" 'mu-quit-buffer)
|
||||
(define-key map "s" 'mu-find)
|
||||
(define-key map "f" 'mu-forward)
|
||||
(define-key map "r" 'mu-reply)
|
||||
@ -144,10 +144,4 @@ function returns the resulting name"
|
||||
(when (mu-find-prev)
|
||||
(mu-view (mu-get-path)))))
|
||||
|
||||
(defun mu-view-quit-buffer ()
|
||||
"quit this buffer and return to the find buffer"
|
||||
(interactive)
|
||||
(mu-quit-buffer)
|
||||
(switch-to-buffer mu-find-buffer-name))
|
||||
|
||||
(provide 'mu-view)
|
||||
|
||||
11
emacs/mu.el
11
emacs/mu.el
@ -38,19 +38,22 @@
|
||||
(define-key mu-find-mode-map "o" 'mu-find-change-sort)
|
||||
(define-key mu-find-mode-map "g" 'mu-find-refresh)
|
||||
(define-key mu-find-mode-map "m" 'mu-find-mark-for-move)
|
||||
(define-key mu-find-mode-map "d" 'mu-find-mark-for-thrash)
|
||||
(define-key mu-find-mode-map "d" 'mu-find-mark-for-trash)
|
||||
(define-key mu-find-mode-map "D" 'mu-find-mark-for-deletion)
|
||||
(define-key mu-find-mode-map "u" 'mu-find-unmark)
|
||||
(define-key mu-find-mode-map "U" 'mu-unmark-all)
|
||||
(define-key mu-find-mode-map "r" 'mu-reply)
|
||||
(define-key mu-view-mode-map "f" 'mu-forward)
|
||||
(define-key mu-find-mode-map "f" 'mu-forward)
|
||||
(define-key mu-find-mode-map "x" 'mu-execute)
|
||||
|
||||
(define-key mu-view-mode-map "q" 'mu-view-quit-buffer)
|
||||
|
||||
(define-key mu-view-mode-map "q" 'mu-quit-buffer)
|
||||
(define-key mu-view-mode-map "f" 'mu-view-find)
|
||||
(define-key mu-view-mode-map "n" 'mu-view-next)
|
||||
(define-key mu-view-mode-map "p" 'mu-view-prev)
|
||||
(define-key mu-view-mode-map "r" 'mu-reply)
|
||||
(define-key mu-view-mode-map "f" 'mu-forward)
|
||||
|
||||
(define-key mu-view-mode-map "x" 'mu-execute)
|
||||
|
||||
(provide 'mu)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user