2006/06/20
# [xyzzy] [KaMailV3] 添付ファイルとして送信されたメールの表示
添付形式のメールを KaMailV3 で開けるように。あらかじめ,*kamail3-part-file* で設定したフォルダを作成しておく。一時ファイルを作らなくっても処理できそうですが,この方が簡単そうなので。message モードや summary モードで,x する。
;;; message/rfc822 な part の一時ファイル (defvar *kamail3-part-file* (merge-pathnames "_part_.eml" *message-attachment-directory*)) ;;; message/rfc822 な part は,何もいわずに表示するように。 (defun message-save-attachment (part &optional execute savefile) (unless (junk::mailstructure-p *message-structure*) (return-from message-save-attachment)) (let ((structure (message-get-part *message-structure* part))) (if (junk::mailstructure-p structure) (let* ((header (junk::mailstructure-headers structure)) (content (junk::mail-get-header-content "content-type" header)) ) (if (and execute (equal (caar content) "message") (equal (cdar content) "rfc822")) (let ((partfile *kamail3-part-file*)) (message-save-part structure partfile) (message-show partfile)) (progn (setq savefile (or savefile (message-save-dialog (junk::mail-get-filename header)))) (when (and savefile (message-save-part structure savefile)) (kamail3-message "saved: ~A" savefile) (when (and execute (no-or-yes-p "ファイルを実行しますか?\n~A" savefile)) (shell-execute savefile nil))) )) ) (kamail3-error "part not found: ~S" part))))
これまた,標準の関数を上書きしているので,要注意なのです。
2006/06/19
# YAMAHA SR400
久々にまじまじと眺めてみた。むかしからとっても興味深く見つめているバイクなので,また,いつか買える時期がきたならば,ぜひ乗ってみたいバイクの一つ。
私が初めて見たのは,おそらく '85 モデル。うら若き高校生のころの話です。当時はただのとっつぁんばいくにしか見えなくて,何の興味もいだかず。その後,年を経るごとに興味もわいてきましたが,フロントブレーキがドラムブレーキであることが少々気になっていました。が,しかし,最新モデルでは,知らぬ間に元の(という表現は正しいか!?)ディスクブレーキに戻されている模様。で,俄然そそられる存在に。
こちらのサイトもとってもステキ。
# [xyzzy] [KaMailV3] フォルダ指定
Query で,フォルダを指定する方法を tori さんに教わった。例えば,inbox フォルダを subject 順に並べたい場合は,こんな感じ。
Query: x-kamail3-folder=km3:inbox order<subject
archive フォルダから,1週間分取り出したい場合は,こんな感じ。
Query: x-kamail3-folder=km3:archive date:1w
しかし,安心フォルダはうまくいかないようなので,初めて詳細検索機能を使ってみた。(これは,私の推測)
Query: Attribute: x-kamail3-status STREQ U Order: subject
な感じでできるみたい。STREQ とかは,このあたりを参考に。結果が使えそうであれば,C-x C-s で,検索条件をフォルダとして登録。
2006/06/12
2006/06/11
# [xyzzy] [KaMailV3] 乗り換え準備中
試用のつもりで,ここ1ヶ月半ほど使ってみているうちに,もう手放せない状態に。readme.html によると,まだ実験段階とのことなので,あまり手を加えるべきではないと思いつつ,抑えきれないこの気持ち。
V3 では,本当に必要な機能のみに絞って実装するとのことなので,欲しいものは自分で作ってみることに。site-lisp/kamail3-plus.l を作成し,~/.kamail3/config.l からロードする。モノによっては,標準の関数を上書きしてしまっていたりなのです。ということで,祟りがないことを祈るばかり。
とりあえず,config.l のサンプルにない変数で設定をしているあたり。
;;; edit-mode のメジャーモードは email-mode で (setq *edit-major-mode* 'email-mode) ;;; セパレータ文字列 (setq *draft-line-string* "=") ;;; 返信/転送時の表示ヘッダ (setq *draft-header-field-list-quote* '("subject" "from" "date" "message-id")) ;;; Message バッファに Bcc ヘッダも表示 (setq *message-header-field-list* '("date" "from" "subject" "to" "cc" "bcc" "reply-to" "x-mailer" "user-agent")) ;;; 添付ファイルの保存フォルダ (setq *message-attachment-directory* (merge-pathnames "kamail3" (map-backslash-to-slash (get-special-folder-location :personal))))
# [xyzzy] [KaMailV3] Draft バッファ削除時に問い合わせ
何度か編集途中の Draft バッファを削除してしまい,悲しい目にあっているので。
(defun draft-close-if () (interactive) (when (yes-or-no-p "Draft を閉じますよー。") (draft-close))) (define-key *draft-map* #\q 'draft-close-if)
※少々まぎらわしい表現であったのを,修正。(2006-06-12)
# [xyzzy] [KaMailV3] アドレス補完計画(キーワードファイル版)
KaMail で使っていたアドレスファイルを,KaMailV3 でも使えるように。Draft バッファのヘッダ行で k すると,ミニバッファで補完が効きます。
;;; アドレスファイル (~/etc/ADDRESS) (defvar *kamail3-keyword-file* "ADDRESS") (defvar *kamail3-keyword-hash-table* nil) (defvar *kamail3-keyword-completion-list* nil) ;;; 起動時設定 (defun kamail3-keyword-init-address-complete () (and *kamail3-keyword-file* (null *kamail3-keyword-hash-table*) (setq *kamail3-keyword-hash-table* (load-keyword-file *kamail3-keyword-file* t))) (when *kamail3-keyword-hash-table* (make-local-variable 'keyword-hash-table) (setq keyword-hash-table *kamail3-keyword-hash-table*))) (add-hook '*kamail3-start-hook* 'kamail3-keyword-init-address-complete) ;;; キーワードリストからアドレス補完入力 (defun kamail3-keyword-address-complete-read (field) (interactive) (let ((field (or field (completing-read "header: " '("to" "cc" "bcc") :must-match t)))) (or *kamail3-keyword-completion-list* (setq *kamail3-keyword-completion-list* (make-list-from-keyword-table *kamail3-keyword-hash-table*)) (return-from kamail3-keyword-address-complete-read nil)) (let (adr) (message "キーワードファイルからアドレスを補完(TAB)します。") (setq adr (completing-read (format nil "Address Keyword (~A): " (string-capitalize field)) *kamail3-keyword-completion-list*)) (draft-add-header-addr field adr)))) ;;; カーソル位置によりヘッダを判定しアドレス補完入力 (defun kamail3-keyword-draft-edit-address () (interactive) (multiple-value-bind (from to tag) (find-text-attribute-point (point)) (kamail3-keyword-address-complete-read (when (or (equal tag "to") (equal tag "cc") (equal tag "bcc")) tag)))) (define-key *draft-map* '#\k 'kamail3-keyword-draft-edit-address)
# [xyzzy] [KaMailV3] バッファタブを隠す
いつものように,バッファタブを隠してみる。
;;; バッファタブを隠す (setq *buffer-prefix* " *KaMail-V3 ") (setq *buffer-summary* (concat *buffer-prefix* "Summary*")) (setq *buffer-message* (concat *buffer-prefix* "Message*")) (setq *buffer-draft* (concat *buffer-prefix* "Draft*")) (setq *buffer-edit* (concat *buffer-prefix* "Edit*")) (setq *buffer-send* (concat *buffer-prefix* "Send*")) (setq *buffer-signature* (concat *buffer-prefix* "Signature*")) (setq *buffer-source* (concat *buffer-prefix* "Source*")) (setq *buffer-fetch* (concat *buffer-prefix* "Fetch*")) (setq *buffer-he-parse* (concat *buffer-prefix* "HyperEstraier Parse*")) (setq *buffer-he-temp* (concat *buffer-prefix* "HyperEstraier Temp*")) (setq *summary-buffer-partial-temp* (concat *buffer-prefix* "Partial Temp*"))
# [xyzzy] [KaMailV3] バッファの切替
バッファタブを隠してしまうと,バッファの切替ができないので,とりあえずポップアップメニューを作成。
;;; メッセージバッファへ移動 (defun kamail3-switch-message () (interactive) (let ((buf *buffer-message*)) (when (find-buffer buf) (set-buffer buf)))) ;;; バッファの切替 (defvar *kamail3-F2-org-func* #'select-buffer) (defun kamail3-select-buffer () (interactive) (if (string= (ed::pseudo-frame-name ed::*current-pseudo-frame*) km3::*pframe-name*) (let ((menu (create-popup-menu nil))) (continue-pre-selection) (save-excursion (dolist (buffer (buffer-list)) (let ((item (buffer-name buffer))) (when (string-match (regexp-quote *buffer-prefix*) item) (add-menu-item menu nil item #'(lambda () (interactive) (switch-to-buffer item) (when (equal *buffer-source* (buffer-name (selected-buffer))) (let ((keymap (copy-keymap (local-keymap)))) (define-key keymap #\RET 'kamail3-switch-message) (define-key keymap #\ESC 'kamail3-switch-message) (define-key keymap #\q 'kamail3-switch-message) (define-key keymap #\Q 'kamail3-switch-message) (use-keymap keymap)))) #'(lambda () (when (string= item (buffer-name (selected-buffer))) :check))))))) (track-popup-menu menu)) (funcall *kamail3-F2-org-func*))) (global-set-key #\F2 'kamail3-select-buffer)
# [xyzzy] [KaMailV3] スクロール関連
Enter で,メッセージの表示&前方スクロール。Ctrl+Enter で,メッセージの表示&後方スクロール。KaMailV3 本体のコードを流用させていただいてます。
;;; メッセージの表示&前方スクロール (defun summary-view-mail-or-scroll-forward (&optional backward) (interactive) (let* ((msg (summary-message-current)) (num (car msg)) (header (cdr msg)) (file (summary-message-file header))) (when file (if (and (equal file *message-file-current*) (message-window-get)) (let (scroll-end) (message-window-set) (unless (if backward (pos-visible-in-window-p (point-min)) (pos-visible-in-window-p (point-max))) (scroll-window (if backward (- 1) 1))) (other-window 1)) (progn (unless (file-exist-p file) (error "ファイルがありません: ~S" file)) (summary-recenter) (when (message-show file) (other-window 1) (summary-message-seen-if msg) )))))) (define-key *summary-map* #\RET 'summary-view-mail-or-scroll-forward) ;;; メッセージの表示&後方スクロール (defun summary-view-mail-or-scroll-backward () (interactive) (summary-view-mail-or-scroll-forward t)) (define-key *summary-map* #\C-j 'summary-view-mail-or-scroll-backward)
# [xyzzy] [KaMailV3] メッセージを表示&メッセージウィンドウに移動&既読に
v で。こちらも,KaMailV3 本体のコードを流用しています。
(defun my-summary-view-mail () (interactive) (let* ((msg (summary-message-current)) (num (car msg)) (header (cdr msg)) (file (summary-message-file header))) (unless file (return-from summary-view-mail)) (if (and (equal file *message-file-current*) (message-window-get)) (message-window-set) (progn (summary-message-seen-if msg) (message-show file))) t)) (define-key *summary-map* #\v 'my-summary-view-mail)
# [xyzzy] [KaMailV3] 送信者アドレスを""でくくらない
kamail3/defs.l の format-address を思い切って上書きです。
(defun format-address (email name) (if name ;(format nil "\"~A\" <~A>" name email) (format nil "~A <~A>" name email) email))
# [xyzzy] [KaMailV3] From が自分の場合は,"To:宛先"を表示
KaMail 風にしたくって。これまた kamail3/summary.l の summary-print-line を上書きです。
(defun summary-print-line (num header &optional indent-string) (let* ((path (junk::mail-get-header-value "_lpath" header)) (fromstr (junk::mail-get-header-value "from" header)) (from fromstr) (to (junk::mail-get-header-value "to" header)) from-string (title (junk::mail-get-header-value "subject" header)) (datestr (junk::mail-get-header-value "date" header)) (date (and datestr (junk::rfc822-parse-date (if (listp datestr) (car datestr) datestr)))) (status (attr-status-get header)) (multipart-p (junk::mail-multipart-p header)) (marked (summary-message-marked num)) ) ;(multiple-value-bind (email name) ;(parse-address from) ;(setq from-string (or name email from))) (multiple-value-bind (email name) (parse-address from) (setq from-string (if (member email *from-address* :key #'car :test #'string=) (multiple-value-bind (email name) (parse-address to) (concat "To:" (or name email to))) (or name email from)))) (apply #'set-text-attribute (point) (progn (insert (summary-mark-string marked)) (point)) num *attribute-summary-mark*) … 省略 … (insert "\n")))