Emacsに関連するDebianパッケージを幾つかメンテナンスしているので, 可能な限りDebianパッケージを使うことにしています.
leaf.elでEmacs のパッケージの導入と設定を行なう
:vc
キーワードで package-vc-install
を使います.
設定は Org mode で書きたい
というわけで, 設定は Org Babel で書いています.
本ファイル(README.org
) から,
Makefile 内の以下のスクリプトで ~/init.el
を生成し, byte-compile します.
init.el: README.org
@mkdir -p ~/.cache/emacs
@if [ ! -d ~/.cache/emacs/eln-cache ]; then \
echo ";; mkdir ~/.cache/emacs/eln-cache"; mkdir ~/.cache/emacs/eln-cache ;\
fi
@if [ ! -L eln-cache ]; then \
echo ";; ln -sf ~/.cache/emacs/eln-cache . "; ln -sf ~/.cache/emacs/eln-cache . ;\
fi
@mkdir -p elpa
@mkdir -p share
$(EMACS) --batch --eval \
"(progn \
(require 'ob-tangle) \
(org-babel-tangle-file \"$<\" \"$@\" \"emacs-lisp\"))"
$(EMACS) -l init.el --batch --eval '(kill-emacs)'
%.elc: %.el
$(EMACS) -l init.el -batch -f batch-byte-compile $<
出力される init.el
用のヘッダは以下の通り.
lexsical-binding
を有効にしておきます.
;; -*- lexical-binding: t -*-
;; (eval-when-compile
;; (require 'profiler)
;; (profiler-start 'cpu)
;; )
;; -*- lexical-binding: t -*-
;; (require 'profiler) ;; 必要に応じて有効化
;; (profiler-start 'cpu)
user-emacs-directory
以下にまとめられます.
ディレクトリ構成は以下のようにしました:
~/.emacs.d/ |-- Makefile ← byte-compile 用の rule |-- README.org ← 本ファイル.`org-babel-tangle' で init.el を生成 |-- eln-cache/ → ~/.cache/emacs/eln-cache への symlink: native compile 出力 |-- elpa/ ← package.el で導入したパッケージが置かれる場所 `-- share/ ← (基本的に)参照するだけの資源置き場所 ~/.cache/emacs ← 一次ファイルの置き場所
上記ディレクトリ構成を設定ファイルで使用するために ディレクトリ配置を宣言しておきます。
(eval-and-compile
(when load-file-name
(setq user-emacs-directory
(expand-file-name (file-name-directory load-file-name))))
(defconst my:d:share
(expand-file-name "share/" user-emacs-directory))
(defconst my:d:tmp
(expand-file-name ".cache/emacs/" (getenv "HOME")))
(defconst my:d:org
(expand-file-name "~/Nextcloud/org")))
Common-Lisp
的挙動が期待されているので,
cl-lib
を読み込んでおきます.
(eval-when-compile
(require 'cl-lib nil t))
また, Emacs 27 以降は cl が読み込まれていると `Package cl is deprecated’ が表示されるので, これを止めておきます.
(eval-and-compile
(setq byte-compile-warnings t)
;; (setq byte-compile-warnings '(not cl-functions free-vars docstrings unresolved))
)
(eval-and-compile
(if (and (fboundp 'native-comp-available-p)
(native-comp-available-p))
(setq native-comp-speed 2
native-comp-async-report-warnings-errors nil ;; 'silent
native-compile-target-directory (expand-file-name "eln-cache" user-emacs-directory)
native-comp-jit-compilation-deny-list '(".*-\\(loaddefs\\|autoloads\\)\\.\\(el\\.gz\\|el\\)")
))
(setq debug-on-error t))
(setq gc-cons-threshold most-positive-fixnum)
(setq package-enable-at-startup nil
package-quickstart nil)
;;
(push '(vertical-scroll-bars . nil) default-frame-alist)
(push '(menu-bar-lines . nil) default-frame-alist)
(push '(tool-bar-lines . nil) default-frame-alist)
(push '(scroll-bar-mode . nil) default-frame-alist)
(push '(blink-cursor-mode . nil) default-frame-alist)
(push '(column-number-mode . nil) default-frame-alist)
;;
(setq load-prefer-newer noninteractive)
;;
(setq frame-inhibit-implied-resize t)
;;
(setq site-run-file nil)
;; (setq file-name-handler-alist nil) ;; 🤔
(setq use-file-dialog nil)
;;
;; (setq native-comp-speed 2
;; native-compile-target-directory (expand-file-name "eln-cache" user-emacs-directory))
(provide 'early-init)
;;; early-init.el ends here
メモリ喰いな拡張を入れている場合には,
安易に gc-cons-threshold
を上げるのは考えものである.
「gc が走る→大きな領域を掃除するのでその間 emacs が止まる」
という事を頻繁に経験することになるだろう.
とはいえ, デフォルト値のままだと
起動時に結構 garbage-collect が走って遅くなるので,
起動時と early-init
では most-positive-fixnum
にしておいて,
起動後に emacs-startup-hook
で default に戻すようにしてみた.
ついでに idle-timer
で入力が無い時に GC を走らせることに.
(setq gc-cons-threshold most-positive-fixnum)
;; Run GC every 60 seconds if emacs is idle.
(run-with-idle-timer 60.0 t #'garbage-collect)
(add-hook 'emacs-startup-hook
(lambda ()
;; recover default value
(setq gc-cons-threshold 800000)))
(defconst my:saved-file-name-handler-alist file-name-handler-alist)
(setq file-name-handler-alist nil)
(add-hook 'emacs-startup-hook
(lambda ()
(setq file-name-handler-alist my:saved-file-name-handler-alist)))
Package 関連: package.el, leaf.el
package.el
で導入するので, 先ずはその設定.
;; elpa/gnutls workaround
(eval-and-compile
;; (when (version<= emacs-version "26.2") ;; => for syntax hightlight
;; (customize-set-variable 'gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3"))
(setq package-archives '(("gnu" . "https://elpa.gnu.org/packages/")
("melpa" . "https://melpa.org/packages/")
("org" . "https://orgmode.org/elpa/")
("nongnu" . "https://elpa.nongnu.org/nongnu/")
)
package-gnupghome-dir (expand-file-name ".gnupg" (getenv "HOME"))
package-quickstart nil
;; package-quickstart-file (expand-file-name "package-quickstart.el" my:d:tmp)
)
;; (add-hook 'kill-emacs-hook 'package-quickstart-refresh)
(if (and (fboundp 'native-comp-available-p)
(native-comp-available-p))
(setq package-native-compile t))
(package-initialize)
(unless (package-installed-p 'leaf)
(package-refresh-contents)
(package-install 'leaf t)
)
)
(leaf leaf-keywords
:doc "Use leaf as a package manager"
:url "https://github.com/conao3/leaf.el"
:ensure t
:init
(leaf blackout :ensure t)
(leaf hydra :ensure t)
:config
(leaf-keywords-init)
)
;;;###autoload
(defun my:shorten-file-path (fpath max-length)
"Show up to `max-length' characters of a directory name `fpath' like zsh"
(let* ((path (reverse (split-string (abbreviate-file-name fpath) "/")))
(output "")
(top (mapconcat 'identity (reverse (last path 3)) "/"))
(vmax (- max-length 4 (length top)))
(path (butlast path 3))
)
(while (and path
(and (< (length output) vmax) ;; > (for syntax)
(< (length (concat "/" (car path) output)) vmax))) ;; > (for syntax)
(setq output (concat "/" (car path) output))
(setq path (cdr path)))
;; 省略
(when path
(setq output (concat "/..." output)))
(format "%s%s" top output)))
;;;###autoload
(defun my:delete-file-if-no-contents ()
(when (and (buffer-file-name (current-buffer))
(= (point-min) (point-max)))
(delete-file
(buffer-file-name (current-buffer)))))
(add-hook 'after-save-hook 'my:delete-file-if-no-contents)
;;;###autoload
(defun my:make-scratch (&optional arg)
" *scratch* を作成して buffer-list に放り込む."
(interactive)
(progn
(set-buffer (get-buffer-create "*scratch*"))
(funcall initial-major-mode)
(erase-buffer)
(when (and initial-scratch-message (not inhibit-startup-message))
(insert initial-scratch-message))
(or arg
(progn
(setq arg 0)
(switch-to-buffer "*scratch*")))
(cond ((= arg 0) (message "*scratch* is cleared up."))
((= arg 1) (message "another *scratch* is created")))))
;;;###autoload
(defun my:buffer-name-list ()
"buffer 一覧の取得"
(mapcar (function buffer-name) (buffer-list)))
;;
(add-hook 'kill-buffer-query-functions
(lambda ()
(if (string= "*scratch*" (buffer-name))
(progn (my:make-scratch 0) nil)
t)))
(add-hook 'after-save-hook
(lambda ()
(unless (member "*scratch*" (my:buffer-name-list))
(my:make-scratch 1))))
ただし, RD や Markdown だと空白行に意味があったりするので, 必要に応じて拡張子で判断して外している.
(defvar my:delete-trailing-whitespace-exclude-suffix
(list "\\.rd$" "\\.md$" "\\.rbt$" "\\.rab$"))
;;;###autoload
(defun my:delete-trailing-whitespace ()
(interactive)
(eval-when-compile (require 'cl-lib nil t))
(cond
((equal nil
(cl-loop for pattern in my:delete-trailing-whitespace-exclude-suffix
thereis (string-match pattern buffer-file-name)))
(delete-trailing-whitespace))))
(add-hook 'before-save-hook 'my:delete-trailing-whitespace)
C-%
(つまり Control-Shift-5
)が入力できない, という話.
代わりに C-x @
を C-M-
に解釈させるように設定しておく.
;;;###autoload
; cargo cult adaptation of event-apply-control-modifier
(defun my:event-apply-control-meta-modifiers (ignore-prompt)
(ignore ignore-prompt)
(vector
(event-apply-modifier (event-apply-modifier (read-event)
'control 26 "C-")
'meta 27 "M-")))
(define-key function-key-map (kbd "C-x @") 'my:event-apply-control-meta-modifiers)
PATH
などの環境変数をEmacsに引き継ぐために
purcell/exec-path-from-shell を使います.
今の所
DEBEMAIL
DEBFULLNAME
GPG_AGENT_INFO
GPG_KEY_ID
PASSWORD_STORE_DIR
PATH
SHELL
SKKSERVER
TEXMFHOME
WSL_DISTRO_NAME
http_proxy
を読み込んでいます(多いな…).
ターミナルでEmacsを起動する場合は不要なんだよなぁ.
(leaf exec-path-from-shell
:ensure t
:custom
`((exec-path-from-shell-variables
. '("DEBEMAIL"
"DEBFULLNAME"
"GPG_AGENT_INFO"
"GPG_KEY_ID"
"PASSWORD_STORE_DIR"
"PATH"
"SHELL"
"SKKSERVER"
"TEXMFHOME"
"WSL_DISTRO_NAME"
"http_proxy"))
(exec-path-from-shell-arguments . nil))
:config
(exec-path-from-shell-initialize)
(setq user-full-name (concat (getenv "DEBFULLNAME"))
user-mail-address (concat (getenv "DEBEMAIL")))
(defconst my:d:password-store
(if (getenv "PASSWORD_STORE_DIR")
(expand-file-name (concat "Emacs/" (system-name))
(getenv "PASSWORD_STORE_DIR")) nil))
)
(set-language-environment "Japanese")
(prefer-coding-system 'utf-8)
(set-file-name-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-default 'buffer-file-coding-system 'utf-8)
なお, m17n.org の消滅によって上記設定に関する情報の参照元が消えた。 適切な参照元はどこだろう…?
Emacs23 から内部が Unicode ベースになっています。しかし文字コードの変換はGNU libcのiconvをベースにしているため,
機種依存文字を含む文字コードの変換をうまく行なえません。
そこで言語設定前に cp5022x.el
をインストールすることにしています。
(leaf cp5022x
:ensure t
:require t
:config
(set-charset-priority 'ascii 'japanese-jisx0208 'latin-jisx0201
'katakana-jisx0201 'iso-8859-1 'unicode)
(set-coding-system-priority 'utf-8 'euc-jp 'iso-2022-jp 'cp932)
)
(leaf locale-eaw-emoji
:vc (:url "https://github.com/uwabami/locale-eaw-emoji")
:hook
`(;;(emacs-startup-hook . eaw-and-emoji-fullwidth)
(emacs-startup-hook . eaw-half-emoji-fullwidth))
)
- [ ] 最近, EAWは一文字幅強制の方が良いかなぁ, とか悩み中.
(leaf cus-edit
:preface
(setq custom-file (expand-file-name "custom.el" my:d:tmp))
:custom
`((custom-file . ,(expand-file-name "custom.el" my:d:tmp)))
:hook
`((kill-emacs-hook . (lambda ()
(if (file-exists-p custom-file)
(delete-file custom-file)))))
)
custom.el
にある設定は極力こちらに移すようにしている.
- 大抵の場合ターミナル内で
-nw
として起動するし, メニューは触ったことないので使わないので, フレーム, ツールバー等を非表示にする. .elc
と.el
の timestamp を比較し, 新しい方を読み込む (load-prefer-newer
は Emacs >= 24.4 から).- yes or no を y or n に
他にもイロイロと. 設定が増えてきたら分ける.
(leaf cus-start
:custom
`(
;; 表示
(ring-bell-function . 'ignore) ; ベル無効化
;; 編集
(tab-width . 4) ;; tab 幅 4
(indent-tabs-mode . nil) ;; tab ではインデントしない
(fill-column . 78) ;; RFC5322 風味
(truncate-lines . nil) ;; 折り返し無し
(truncate-partial-width-windows . nil)
(paragraph-start . '"^\\([ ・○<\t\n\f]\\|(?[0-9a-zA-Z]+)\\)")
(auto-fill-mode . nil)
(next-line-add-newlines . nil) ;; バッファ終端で newline を入れない
(read-file-name-completion-ignore-case . t) ; 大文字小文字区別無し
(save-abbrevs . 'silent)
;; backup
(auto-save-list-file-prefix . ,(expand-file-name ".saves-" my:d:tmp))
(auto-save-default . t)
(auto-save-timeout . 15)
(auto-save-interval . 60)
(make-backup-files . t)
(backup-by-copying . t) ;; symlink は使わない
(backup-directory-alist . '(("." . ,my:d:tmp)))
(auto-save-file-name-transforms . '((".*" ,my:d:tmp t)))
(version-control . nil)
(kept-new-versions . 2)
(kept-old-versions . 2)
(delete-old-versions . t)
(delete-auto-save-files . t)
;; undo/redo - 数字に根拠無し
(undo-limit . 200000)
(undo-strong-limit . 260000)
(history-length . t) ;; 無制限(の筈)
;; (save-silently . t)
(use-short-answers . t)
;;
(safe-local-variable-values
. '((org-link-file-path-type . absolute)))
;;
(native-comp-jit-compilation-deny-list
. '(".*-\\(loaddefs\\|autoloads\\)\\.\\(el\\.gz\\|el\\)"))
)
:config
(when (boundp 'load-prefer-newer)
(setq load-prefer-newer t))
;; yes or no を y or n に
(when (< emacs-major-version 28) ;; >
(fset 'yes-or-no-p 'y-or-n-p))
)
(leaf startup
:custom
((inhibit-startup-screen . t)
(inhibit-startup-message . t)
(inhibit-startup-echo-area-message . t)
(initial-scratch-message . nil)
)
)
(leaf hl-line
:hook
(emacs-startup-hook . global-hl-line-mode)
)
(leaf simple
:hook
(emacs-startup-hook . transient-mark-mode)
)
(leaf paren
:custom
((show-paren-style . 'mixed))
:hook
(emacs-startup-hook . show-paren-mode)
)
linum-mode
を有効にした場合の桁表示を 5 桁に.
(leaf line-number-mode
:custom
((linum-format . "%5d ")
(line-number-mode . nil))
)
(leaf autorevert
:custom
((auto-revert-interval . 0.1))
:hook
(find-file-hook . global-auto-revert-mode)
)
(leaf savehist
:custom
`((savehist-file
. ,(expand-file-name "history" my:d:tmp)))
:hook
((emacs-startup-hook . savehist-mode))
)
~/.emacs.d/
以下にファイルが転がるのがなんか嫌なので,
気がつく度に設定している.
(leaf *change-default-file-location
:custom
`(;; url
(url-configuration-directory
. ,(expand-file-name "url" my:d:tmp))
;; nsm
(nsm-settings-file
. ,(expand-file-name "nsm.data" my:d:tmp))
;; bookmark
(bookmark-default-file
. ,(expand-file-name "bookmarks" my:d:tmp))
;; eshell
(eshell-directory-name
. ,(expand-file-name "eshell" my:d:tmp))
)
)
他にもイロイロありそう.
bookmark
はちゃんと使いこなしたい所ではあるが.
(leaf eldoc
:hook (emacs-lisp-mode-hook . turn-on-eldoc-mode)
;; :blackout t
:custom
`((eldoc-echo-area-prefer-doc-buffer . nil)
(eldoc-print-after-edit . t)
(eldoc-echo-area-use-multiline-p . nil))
:preface
(defun my:shutup-eldoc-message (f &optional string)
(unless (active-minibuffer-window)
(funcall f string)))
:advice
(:around eldoc-message
my:shutup-eldoc-message)
)
(leaf midnight
:custom
((clean-buffer-list-delay-general . 1))
:hook
(emacs-startup-hook . midnight-mode))
(leaf uniquify
:custom
((uniquify-buffer-name-style . 'post-forward-angle-brackets)
(uniquify-min-dir-content . 1))
)
(leaf whitespace
;; :blackout ((global-whitespace-mode . "")
;; (whitespace-mode . ""))
:hook (emacs-startup-hook . global-whitespace-mode)
:custom
((whitespace-line-column . 72)
(whitespace-style
. '(face ; faceを使う. *-mark に必要
trailing ; 行末の空白を対象.
tabs ; tab
spaces ; space
empty ; 前後の空行
space-mark ; 可視化の際の置き換えを有効化
tab-mark ; 可視化の際の置き換えを有効化
))
(whitespace-display-mappings . '((space-mark ?\u3000 [?\□])
(tab-mark ?\t [?\u00BB ?\t] [?\\ ?\t])))
(whitespace-space-regexp . "\\(\u3000+\\)")
(whitespace-trailing-regexp . "\\([ \u00A0]+\\)$")
(whitespace-global-modes . '(not eww-mode
term-mode
eshell-mode
org-agenda-mode
calendar-mode))
)
)
~/.emacs.d/tmp/emacs-places
に変更.
(leaf save-place
:custom
`((save-place . t)
(save-place-file . ,(expand-file-name "emacs-places" my:d:tmp))
;; add tramp-file-name-regexp
(save-place-ignore-files-regexp
. "\\(\\(?:COMMIT_EDITMSG\\|hg-editor-[[:alnum:]]+\\.txt\\|svn-commit\\.tmp\\|bzr_log\\.[[:alnum:]]+\\)$\\)\\|\\(\\`/[^/:]+:[^/:]*:\\)")
)
:hook (emacs-startup-hook . save-place-mode)
)
$Lastupdate: 2
($は半角) があったら
timestamp を更新する様にした.
(leaf time-stamp
:hook (before-save-hook . time-stamp)
:custom
((time-stamp-active . t)
(time-stamp-line-limit . 10)
(time-stamp-start . "$Lastupdate: 2")
(time-stamp-end . "\\$")
(time-stamp-format . "%Y-%02m-%02d %02H:%02M:%02S")
)
)
モード独自の設定(例えば Org とか)に関しては別途.
(leaf tramp
:preface
(defvar tramp-persistency-file-name (expand-file-name "tramp" my:d:tmp))
:custom
`((tramp-persistency-file-name . ,(expand-file-name "tramp" my:d:tmp))
(tramp-completion-reread-directory-timeout . nil)
(remote-file-name-inhibit-cache . nil)
(vc-ignore-dir-regexp
. ,(format "\\(%s\\)\\|\\(%s\\)"
locate-dominating-stop-dir-regexp
tramp-file-name-regexp))
)
:hook
(kill-emacs-hook . (lambda ()
(if (file-exists-p tramp-persistency-file-name)
(delete-file tramp-persistency-file-name))))
)
xdg-open/open
に丸投げ.
(leaf browse-url
;; :require t
:bind* ("C-c C-j" . browse-url-at-point)
:defer-config
(cond ((executable-find "xdg-open")
(setq browse-url-browser-function 'browse-url-xdg-open
browse-url-secondary-browser-function 'browse-url-xdg-open))
((eq system-type 'darwin)
(setq browse-url-browser-function 'browse-url-default-macosx-browser
browse-url-secondary-browser-function 'browse-url-default-macosx-browser))
(t
;; (setq browse-url-browser-function 'w3m-browse-url)
(setq browse-url-browser-function 'eww-browse-url)
))
)
(leaf server
:commands (server-running-p)
:init
(defun my:new-client-frame ()
"Create new GUI emacsclient"
(interactive)
(make-frame-on-display (getenv "DISPLAY")))
:hook
(emacs-startup-hook . (lambda ()
(unless (server-running-p)
(server-start))))
)
(leaf ps-mule
:if (executable-find "lpr")
:custom
((ps-multibyte-buffer . 'non-latin-printer)
(ps-printer-name . "PDF")
(ps-paper-size . 'a4)
;; (ps-n-up-printing . 2)
(ps-print-header . t)
(ps-print-footer . nil)
(ps-font-family . 'Courier)
(ps-font-size . '(9 . 10))
(ps-header-font-family . 'Helvetica)
(ps-header-font-size . '(10 . 12))
(ps-header-title-font-size . '(12 . 14))
(ps-line-number . nil)
;; (ps-line-number-font . "Times-Italic")
;; (ps-line-number-font-size . 6)
;; (ps-line-number-start . 1)
;; (ps-line-number-step . 1)
)
:hook
(defalias 'ps-mule-header-string-charset 'ignore)
:config
;; (setq ps-mule-font-info-database-default
;; '((iso-8859-1
;; (normal nil nil))
;; (katakana-jisx0201
;; (normal builtin "Ryumin-Light-Katakana")
;; (bold builtin "GothicBBB-Medium-Katakana"))
;; (latin-jisx0201
;; (normal builtin "Ryumin-Light-Hankaku")
;; (bold builtin "GothicBBB-Medium-Hankaku"))
;; (japanese-jisx0208
;; (normal builtin "Ryumin-Light-Ext-H")
;; (bold builtin "GothicBBB-Medium-Ext-H"))
;; (japanese-jisx0213-2
;; (normal builtin "Ryumin-Light-Ext-H")
;; (bold builtin "GothicBBB-Medium-Ext-H"))
;; (japanese-jisx0213.2004-1
;; (normal builtin "Ryumin-Light-2004-H")
;; (bold builtin "GothicBBB-Medium-H"))
;; (unicode-bmp
;; (normal builtin "Ryumin-Light-Ext-H")
;; (bold builtin "GothicBBB-Medium-Ext-H"))
;; )
;; )
)
tab-bar-mode
に elscreen から乗り換えた.
手癖で “C-o” を prefix で使いたいので, その設定をしていたり.
(leaf tab-bar-mode
:init
(defvar my:ctrl-o-map (make-sparse-keymap)
"My original keymap binded to C-o.")
(defalias 'my:ctrl-o-prefix my:ctrl-o-map)
(define-key global-map (kbd "C-o") 'my:ctrl-o-prefix)
(define-key my:ctrl-o-map (kbd "c") 'tab-new)
(define-key my:ctrl-o-map (kbd "C-c") 'tab-new)
(define-key my:ctrl-o-map (kbd "k") 'tab-close)
(define-key my:ctrl-o-map (kbd "C-k") 'tab-close)
(define-key my:ctrl-o-map (kbd "n") 'tab-next)
(define-key my:ctrl-o-map (kbd "C-n") 'tab-next)
(define-key my:ctrl-o-map (kbd "p") 'tab-previous)
(define-key my:ctrl-o-map (kbd "C-p") 'tab-previous)
;;;###autoload
(defun my:tab-bar-tab-name-truncated ()
"Custom: Generate tab name from the buffer of the selected window."
(let ((tab-name (buffer-name (window-buffer (minibuffer-selected-window))))
(ellipsis (cond
(tab-bar-tab-name-ellipsis)
((char-displayable-p ?…) "…")
("..."))))
(if (< (length tab-name) tab-bar-tab-name-truncated-max) ;; >
(format "%-12s" tab-name)
(propertize (truncate-string-to-width
tab-name tab-bar-tab-name-truncated-max nil nil
ellipsis)
'help-echo tab-name))))
:custom
((tab-bar-close-button-show . nil)
(tab-bar-close-last-tab-choice . nil)
(tab-bar-close-tab-select . 'left)
(tab-bar-history-mode . nil)
(tab-bar-new-tab-choice . "*scratch*")
(tab-bar-new-button-show . nil)
(tab-bar-tab-name-function . 'my:tab-bar-tab-name-truncated)
(tab-bar-tab-name-truncated-max . 12)
(tab-bar-separator . "|")
)
:hook
(emacs-startup-hook . tab-bar-mode)
;; :config
;; (tab-bar-mode +1)
)
leaf-plstore
でplstore
が使えるようになったので, その設定をしておく.auth-password-store
で auth-source としてpassword-store
を使う.
といった事をしている.
(leaf *authentication
:if (and (getenv "GPG_KEY_ID")
my:d:password-store)
:init
(setq leaf-default-plstore
(plstore-open
(expand-file-name "plstore.plist" my:d:password-store)))
(add-to-list 'vc-directory-exclusion-list
(expand-file-name my:d:password-store))
(leaf auth-source
:init
(setq auth-source-gpg-encrypt-to '(getenv "GPG_KEY_ID")))
(leaf password-store :ensure t)
(leaf auth-source-pass :ensure t)
(leaf plstore
:custom
`((plstore-secret-keys . 'silent)
(plstore-encrypt-to . ,(getenv "GPG_KEY_ID")))
)
)
gtk-immodule
なんかと衝突するので
~/.Xresources
で im を無効にしておくと良い.
例えば以下の様に:
! disable XIM
Emacs*useXIM: false
以前は別ファイルで行なっていた設定を customize にまとめた.
(leaf skk
:commands skk-make-indicator-alist
:bind (("C-x j" . skk-mode)
("C-x C-j" . skk-mode)
;; ("C-x C-j" . skk-auto-fill-mode)
;; ("C-j" . skk-mode)
("C-\\" . skk-mode)
)
:preface
(unless (file-directory-p (expand-file-name "skk" my:d:tmp))
(progn
(make-empty-file (expand-file-name "skk/keep" my:d:tmp) t)
(make-empty-file (expand-file-name "skk-jisyo/keep" my:d:tmp) t)))
;; override - -;
(defvar skk-get-jisyo-directory (expand-file-name "skk-jisyo" my:d:tmp))
(defvar skk-extra-jisyo-file-list nil)
:init
(setq default-input-method "japanese-skk")
:hook
(;; minibuffer では skk を無効化
(skk-mode-hook . (lambda ()
(and (skk-in-minibuffer-p)
(skk-mode-exit))))
)
:custom
`(;;
(skk-user-directory . ,(expand-file-name "skk" my:d:tmp))
;; 設定ファイルは Customize にまとめる. → 別ファイルでの設定はしない
(skk-init-file . "")
(skk-byte-compile-init-file . nil)
;; sticky shift を ; に割り当て
(skk-sticky-key . ";")
;; 変換候補の表示数
(skk-henkan-number-to-display-candidates . 10)
;; メニューを日本語にしない. どうせ menu は使わないし.
(skk-show-japanese-menu . nil)
;; 半角カタカナを入力可能に
(skk-use-jisx0201-input-method . t)
;; インジケータのカスタマイズ
(skk-latin-mode-string . "[_A]")
(skk-hiragana-mode-string . "[あ]")
(skk-katakana-mode-string . "[ア]")
(skk-jisx0208-latin-mode-string . "[A]")
(skk-jisx0201-mode-string . "[_ア]")
(skk-abbrev-mode-string . "[aA]")
;; カーソルに色は付けない
(skk-indicator-use-cursor-color . nil)
(skk-use-color-cursor . nil)
;; Enter で改行しない
(skk-egg-like-newline . t)
;; 対応する括弧の自動入力
(skk-auto-insert-paren . t)
;; 句読点変換ルールの追加
(skk-kuten-touten-alist . '((jp . ("。" . "、"))
(jp-en . ("。" . ", "))
(en-jp . ("." . ","))
(en . (". " . ", "))
(EN . ("." . ","))
))
;; 句読点変換ルール: default は ,.
(skk-kutouten-type . 'en)
;; 送り仮名が厳密に正しい候補を優先
(skk-henkan-strict-okuri-precedence . t)
;; 変換ルールの追加: 全角スペース入力ルールと日付入力無効化.
(skk-rom-kana-rule-list . '(("z " nil " ")
("@" nil "@")))
;; 辞書サーバ
(skk-server-host . ,(or (getenv "SKKSERVER") nil))
(skk-aux-large-jisyo
. ,(or (if (file-readable-p "/usr/share/skk/SKK-JISYO.L") "/usr/share/skk/SKK-JISYO.L") nil))
;; 冗長...?
(skk-large-jisyo
. ,(cond ((getenv "SKKSERVER") nil)
((if (file-readable-p "/usr/share/skk/SKK-JISYO.L") "/usr/share/skk/SKK-JISYO.L"))
(t (expand-file-name "skk-jisyo/SKK-JISYO.L" my:d:tmp))))
;; インクリメンタルサーチは migemo に任せる. hook も参照
(skk-isearch-mode-enable . nil)
(skk-isearch-start-mode . 'latin) ;; 不要?
;; ja-dic は利用しない
(skk-inhibit-ja-dic-search . t)
;; 辞書登録の際に送り仮名を削除
(skk-check-okurigana-on-touroku . 'auto)
;; 漢字登録のミスをチェック
(skk-check-okurigana-on-touroku . t)
;; 個人辞書の文字コード
(skk-jisyo-code . 'utf-8-unix)
)
:config
;; 環境毎に辞書の設定が煩雑になっていて, どうしたモンかなぁ...
(unless (or (or (getenv "SKKSERVER")
(file-readable-p "/usr/share/skk/SKK-JISYO.L"))
(file-exists-p (expand-file-name "SKK-JISYO.L" skk-get-jisyo-directory)))
(skk-get skk-get-jisyo-directory))
;; この
(if (file-exists-p "/usr/share/skk/SKK-JISYO.JIS3_4")
(add-to-list 'skk-extra-jisyo-file-list
(cons (expand-file-name "/usr/share/skk/SKK-JISYO.JIS3_4") 'euc-jisx0213) t))
(cond
((file-exists-p "/usr/local/share/skkdic/SKK-JISYO.emoji.utf8")
(dolist (file
'("SKK-JISYO.chibutsu.utf8"
"SKK-JISYO.tanudic4.utf8"
"SKK-JISYO.matsucon.utf8"
"SKK-JISYO.emoji.utf8"))
(add-to-list 'skk-extra-jisyo-file-list
(cons (expand-file-name file "/usr/local/share/skkdic/") 'utf-8) t )))
(t
(setq skk-extra-jisyo-file-list nil)))
)
(leaf recentf
:defun
(recentf-save-list recentf-cleanup)
:preface
(defun my:recentf-track-visited-file (_prev _curr)
(and buffer-file-name
(recentf-add-file buffer-file-name)))
:init
(leaf recentf-ext :ensure t)
:custom
`((recentf-save-file . ,(expand-file-name "recentf" my:d:tmp))
(recentf-max-saved-items . 500)
(recentf-auto-cleanup . 'mode)
(recentf-exclude . '(".recentf"
"^/tmp\\.*"
"^/private\\.*"
"^/var/folders\\.*"
"/TAGS$"
"\\.*草稿\\.*"
"^#\\.*"
"^/[^/:]+:"
"bookmarks"
"org-recent-headings.dat"
"^/mnt/c/\\.*"
"\\.*COMMIT_EDITMSG$"
))
)
)
;; テスト中
(leaf switch-buffer-functions
:ensure t
:after recent
:preface
(defun my:recentf-track-visited-file (_prev _curr)
(and buffer-file-name
(recentf-add-file buffer-file-name)))
;; :init
;; (add-hook 'switch-buffer-functions
;; #'my:recentf-track-visited-file)
:hook
(switch-buffer-functions
. my:recentf-track-visited-file)
)
japanese-holidays
による日本の休日の追加
(leaf calendar
:defvar calendar-holidays japanese-holidays
:custom
`(;; 月と曜日の表示調整
(calendar-month-name-array . ["01" "02" "03" "04" "05" "06"
"07" "08" "09" "10" "11" "12" ])
(calendar-day-name-array . ["日" "月" "火" "水" "木" "金" "土"])
(calendar-day-header-array . ["日" "月" "火" "水" "木" "金" "土"])
;; 日曜開始
(calendar-week-start-day . 0)
;; 祝日をカレンダーに表示
(calendar-mark-holidays-flag . t)
)
:config
(with-eval-after-load 'japanese-holidays
(setq calendar-holidays (append japanese-holidays holiday-local-holidays)))
)
(leaf japanese-holidays
:ensure t
:after calendar
:require t
:custom
`((japanese-holiday-weekend . '(0 6))
(japanese-holiday-weekend-marker
. '(holiday ;; 日
nil ;; 月
nil ;; 火
nil ;; 水
nil ;; 木
nil ;; 金
japanese-holiday-saturday))
)
:config
;; autoload
(defun my:japanese-holiday-show (&rest _args)
(let* ((date (calendar-cursor-to-date t))
;; (calendar-date-display-form '((format "%s年 %s月 %s日(%s)" year month day dayname)))
(date-string (calendar-date-string date))
(holiday-list (calendar-check-holidays date)))
(when holiday-list
(message "%s: %s" date-string (mapconcat #'identity holiday-list "; ")))))
:hook
((calendar-move-hook . my:japanese-holiday-show)
(calendar-today-visible-hook . japanese-holiday-mark-weekend)
(calendar-today-invisible-hook . japanese-holiday-mark-weekend)
(calendar-today-visible-hook . calendar-mark-today))
)
[home]
と [end]
は無いと途方に暮れます.
(leaf-keys (("C-h" . backward-delete-char)
("C-c M-a" . align-regexp)
("C-c ;" . comment-region)
("C-c M-;" . uncomment-region)
("C-/" . undo)
("C-c M-r" . replace-regexp)
("C-c r" . replace-string)
("<home>" . beginning-of-buffer)
("<end>" . end-of-buffer)
("C-c M-l" . toggle-truncate-lines)))
(leaf migemo
:if (executable-find "cmigemo")
:ensure t
:custom
`((migemo-user-dictionary . nil)
(migemo-regex-dictionary . nil)
(migemo-options . '("-q" "--emacs"))
(migemo-command . "cmigemo")
(migemo-coding-system . 'utf-8-unix)
(migemo-dictionary
. ,(or (if (file-exists-p "/usr/local/share/migemo/utf-8/migemo-dict")
"/usr/local/share/migemo/utf-8/migemo-dict")
"/usr/share/cmigemo/utf-8/migemo-dict"))
)
:hook
(emacs-startup-hook . migemo-init)
)
ace-link
も入れておく
(leaf eww
:preface
(unless (file-directory-p (expand-file-name "eww" my:d:tmp))
(make-directory (expand-file-name "eww" my:d:tmp)))
:init
(leaf ace-link :ensure t)
(leaf shr
:custom
((shr-use-colors . nil)
(shr-use-fonts . nil)
(shr-image-animate . nil)
(shr-width . 72))
)
:bind (("<f2>" . eww)
(:eww-mode-map
("r" . eww-reload)
("o" . eww)
("&" . eww-browse-with-external-browser)
("b" . eww-back-url)
("]" . eww-next-url)
("[" . eww-previous-url)
("g" . eww-top-url)
("h" . backward-char)
("j" . next-line)
("C-n" . next-line)
("k" . previous-line)
("C-p" . previous-line)
("l" . forward-char)
("/" . isearch-forward)
("?" . isearch-backward)
("n" . isearch-next)
("N" . isearch-previous)
("f" . ace-link-eww))
)
:custom
`((eww-bookmarks-directory . ,(expand-file-name "eww" my:d:tmp))
(eww-search-prefix
. "https://www.google.com/search?&gws_rd=cr&complete=0&pws=0&tbs=li:1&q=")
)
;; :advice (:around eww-colorize-region
;; my:shr-colorize-region--disable)
:config
(ace-link-setup-default)
)
(leaf ibuffer
:defun (ibuffer-current-buffer)
:defvar (ibuffer-formats)
:preface
(defun my:ibuffer-find-file ()
"Like `find-file', but default to the directory of the buffer at point."
(interactive)
(let ((default-directory
(let ((buf (ibuffer-current-buffer)))
(if (buffer-live-p buf)
(with-current-buffer buf
default-directory)
default-directory))))
(find-file default-directory)))
;;
:bind (("C-x C-b" . ibuffer-other-window)
("C-x b" . ibuffer-other-window)
("C-x M-b" . ibuffer)
(:ibuffer-mode-map
("C-x C-f" . my:ibuffer-find-file))
)
)
gpaste
を使っている.
(leaf xclip
:if (and (executable-find "xclip")
(eq system-type 'gnu/linux))
:ensure t
:hook (emacs-startup-hook
. (lambda () (xclip-mode +1)))
)
pbcopy/pbpase
の呼び出し方が変わった? 動かない時がある様な。
(leaf *macOSclipborad
:disabled t
:if (eq system-type 'darwin)
:preface
(defun my:copy-from-osx ()
"Get string via pbpaste"
(shell-command-to-string "pbpaste"))
(defun my:paste-to-osx (text &optional push)
"put `TEXT' via pbcopy with `PUSH' mode"
(let ((process-connection-type nil))
(let ((proc (start-process "pbcopy" "*Messages*" "pbcopy")))
(process-send-string proc text)
(process-send-eof proc))))
:config
(setq interprogram-cut-function 'my:paste-to-osx
interprogram-paste-function 'my:copy-from-osx)
)
(leaf helm :defer-config (helm-mode -1))
(leaf ivy :defer-config (ivy-mode -1))
(leaf *completion
:init
;; 補完で無視する拡張子の追加.そのうち増える.
(cl-loop for ext in
'(;; TeX
".dvi"
".fdb_latexmk"
".fls"
".ilg"
".jqz"
".nav"
".out"
".snm"
".synctex\\.gz"
".vrb"
;; fortran >= 90
".mod"
;; zsh
".zwc"
;; libtool
".in"
".libs/"
;; fxxkin Apple
".DS_Store"
"._DS_Store"
;; "org-id-locations"
)
do (add-to-list 'completion-ignored-extensions ext))
)
C-l
で一つ上の階層へ上がれる様にしたり.
(leaf vertico
:ensure t
:preface
(defun my:disable-selection ()
(when (eq minibuffer-completion-table #'org-tags-completion-function)
(setq-local vertico-map minibuffer-local-completion-map
completion-cycle-threshold nil
completion-styles '(basic))))
;;
;; @see https://misohena.jp/blog/2022-08-15-transition-ivy-to-vertico.html
;; 候補更新時に最初の候補を選択しない -> (vertico-preselect . 'prompt)
;; ただし require-matchがt(やそれに類するもの)で入力が空ではなくマッチする候
;; 補がある場合は、その候補の先頭を選択する。
(defun my:vertico--recompute (orig-fun pt content &rest args)
(let ((result (apply orig-fun pt content args)))
(if (and (not (equal content ""))
;; 入力が空の時は(require-matchであっても)defaultまたはnilを返
;; すことになっている。
(> (alist-get 'vertico--total result) 0) ;; < for syntax
;; completing-readの説明によれば
;; nil,confirm,confirm-after-completion以外はtのように
;; 振る舞うべき。
(not (memq minibuffer--require-match
'(nil confirm confirm-after-completion))))
(setf (alist-get 'vertico--index result) 0))
result))
;;
;;
(defun my:filename-upto-parent ()
"Move to parent directory like \"cd ..\" in find-file."
(interactive)
(let ((sep (eval-when-compile (regexp-opt '("/" "\\")))))
(save-excursion
(left-char 1)
(when (looking-at-p sep)
(delete-char 1)))
(save-match-data
(when (search-backward-regexp sep nil t)
(right-char 1)
(filter-buffer-substring (point)
(save-excursion (end-of-line) (point))
#'delete)))))
:advice
((:before vertico--setup
my:disable-selection)
(:around vertico--recompute-candidates
my:vertico--recompute)
)
:bind
(:vertico-map (("C-l" . my:filename-upto-parent)))
:custom-face
`((vertico-current
. '((t (:inherit hl-line :background unspecified)))))
:custom
`((vertico-count . 8)
(vertico-cycle . t)
(vertico-preselect . 'prompt)
(vertico-multiline . '(("↓" 0 1 (face vertico-multiline))
("…" 0 1 (face vertico-multiline))))
)
:config
:hook (emacs-startup-hook . vertico-mode)
)
(leaf marginalia
:ensure t
:init
;; 補完でも icon 表示
;;(leaf all-the-icons-completion
;; :ensure t
;; :hook
;; (emacs-startup-hook . all-the-icons-completion-mode)
;; )
:bind (("M-A" . marginalia-cycle)
(:minibuffer-local-map
("M-A" . marginalia-cycle)
))
:custom
`((marginalia-annotators
. '(marginalia-annotators-light marginalia-annotators-heavy nil))
(marginalia-align . 'right)
(marginalia-align-offset . -2) ;; icon 分引いておく
)
:hook
((emacs-startup-hook . marginalia-mode)
;;(marginalia-mode-hook . all-the-icons-completion-marginalia-setup)
)
)
consult-recent-file
のカスタマイズのみ.
(leaf consult
:ensure t
:bind (("C-x C-r" . my:consult-recent-file))
;; :defvar recentf-list
:custom
`(;; 増やさないと preview 時に theme がロードされない模様.
;; とりあえず default の 10 倍にしている. 1 MB かな?
(consult-preview-raw-size . 1024000)
(consult-async-refresh-delay . 0.2)
(consult-preview-key . nil)
(consult-narrow-key . "<")
)
:config
(defun my:consult-recent-file ()
"Find recent using `completing-read' with shorten filename"
(interactive)
(eval-when-compile (require 'recentf))
(recentf-mode +1)
(let ((files (mapcar (lambda (f)
(cons (my:shorten-file-path f (- (window-width) 2)) f))
recentf-list)))
(let ((selected
(consult--read (mapcar #'car files)
:prompt "Find recent file: "
:sort nil
:require-match t
:category 'file
:state (consult--file-preview)
:history 'file-name-history)))
(find-file (assoc-default selected files)))))
)
(leaf orderless
:ensure t
:custom
`((completion-styles . '(orderless))
(orderless-matching-styles
. '(orderless-prefixes
orderless-flex
orderless-regexp
orderless-initialism
orderless-literal))
)
)
company
より使い勝手が良い, 気がする.
(leaf corfu
:disabled t
:ensure t
:init
(leaf corfu-terminal
:ensure t
:custom (corfu-terminal-disable-on-gui . nil)
)
:bind
(:corfu-map
("TAB" . corfu-next)
("<tab>" . corfu-next)
("S-TAB" . corfu-previous)
("<backtab>" . corfu-previous)
("C-j" . corfu-next)
("C-n" . corfu-next)
("C-p" . corfu-previous)
("C-k" . corfu-previous))
:custom
`((completion-cycle-threshold . 4)
(tab-always-indent . 'complete)
(corfu-cycle . t) ;; Enable cycling for `corfu-next/previous'
(corfu-auto . t) ;; Enable auto completion
(corfu-preselect-first . nil) ;; Disable candidate preselection
;; (corfu-separator . ?\s) ;; Orderless field separator
;; (corfu-quit-at-boundary . nil) ;; Never quit at completion boundary
;; (corfu-quit-no-match . nil) ;; Never quit, even if there is no match
;; (corfu-preview-current . nil) ;; Disable current candidate preview
;; (corfu-on-exact-match . nil) ;; Configure handling of exact matches
;; (corfu-echo-documentation . nil) ;; Disable documentation in the echo area
;; (corfu-scroll-margin . 5) ;; Use scroll margin
)
:hook (emacs-startup-hook
. (lambda ()
(corfu-terminal-mode +1)
(global-corfu-mode)))
)
;; (leaf cape :ensure t)
;; ;; 補完候補を出すときの文脈を特定
;; (defvar my-capf-context nil)
;; (defun my-capf--corfu--auto-complete (old-fun &rest args)
;; ;; my-capf-context = 'in-corfu--auto-complete にして補完候補を出す。
;; (let ((my-capf-context 'in-corfu--auto-complete))
;; (apply old-fun args)))
;; (advice-add 'corfu--auto-complete :around #'my-capf--corfu--auto-complete)
;; ;; 追加の補完関数
;; (defun my-capf-additional ()
;; (pcase my-capf-context
;; ('in-corfu--auto-complete
;; ;; 自動補完の場合は確度の高い候補しか出さない。
;; nil)
;; (_
;; ;; 手動補完の場合は積極的にいろんな候補を出す。
;; (my-capf-manual))))
;; (add-hook 'completion-at-point-functions #'my-capf-additional 100)
;; ;; 手動補完時の補完関数
;; (defvar my-capf-manual nil)
;; (defun my-capf-manual ()
;; ;; capeパッケージの読み込みを遅延させる。
;; (unless my-capf-manual
;; (setq my-capf-manual
;; ;; いろんな補完候補を合成する。
;; (cape-super-capf
;; #'cape-file #'cape-dabbrev #'cape-abbrev #'cape-line)))
;; (funcall my-capf-manual))
wl-init-file
を指定することで, 設定ファイルを明示している.
(leaf wl
:if (file-exists-p "/etc/emacs/site-start.d/65wl-beta.el")
:defvar (wl-address-file
wl-folders-file
elmo-passwd-alist-file-name)
:commands (wl
wl-other-frame
wl-draft
wl-user-agent
wl-user-agent-compose
wl-draft-send
wl-draft-kill)
:preface
(defun my:wl-mode-line-buffer-identification (&optional id)
(ignore id)
(force-mode-line-update t))
(defconst my:d:wl-cache-directory
(expand-file-name "wanderlust" "~/.cache"))
(unless (file-directory-p
(expand-file-name "local/Trash" my:d:wl-cache-directory))
(make-directory
(expand-file-name "local/Trash" my:d:wl-cache-directory) t))
:advice (:override wl-mode-line-buffer-identification
my:wl-mode-line-buffer-identification)
:custom
`((elmo-msgdb-directory . my:d:wl-cache-directory)
(read-mail-command . #'wl)
(wl-init-file
. ,(expand-file-name "init-wl" user-emacs-directory))
(wl-demo . nil)
)
:init
(define-mail-user-agent
'wl-user-agent
'wl-user-agent-compose
'wl-draft-send
'wl-draft-kill
'mail-send-hook)
:pl-setq (wl-address-file
wl-folders-file
elmo-passwd-alist-file-name)
)
割と /etc/emacs/site-start.d/65wl-beta.el
と重複している気がするが.
(eval-when-compile
(require 'leaf-keywords)
(require 'cp5022x)
(require 'wl)
(require 'mime-def)
(leaf-keywords-init)
)
(leaf rail
:init
(unless (locate-library "rail")
(package-vc-install :url "https://github.com/uwabami/rail"))
(setq rail-emulate-genjis t)
:require t
)
(add-to-list 'mime-charset-coding-system-alist
'(iso-2022-jp . cp50220))
;; fxxkin outlook
(add-to-list 'mime-charset-coding-system-alist
'(gb2312 . gbk))
;;
(setq wl-mime-charset 'iso-2022-jp)
;; (setq wl-mime-charset 'utf-8-unix)
(leaf mime-setup
:preface
;; (leaf w3m-load)
;; (leaf mime-w3m :require t)
(setq mime-view-text/html-previewer 'shr)
)
どのアプリケーションで開くか → xdg-open
に丸投げ.
;; (defvar my:mime-preview-play-current-entity-appname "xdg-open"
;; "meadow なら fiber, mac なら open, linux なら xdg-open")
;; (cond
;; ((string-match "apple-darwin" system-configuration)
;; (setq my:mime-preview-play-current-entity-appname "open")
;; )
;; ((string-match "linux" system-configuration)
;; (setq my:mime-preview-play-current-entity-appname "xdg-open")
;; ))
;;
;; (unless (functionp #'mime-preview-play-current-entity-orig)
;; (fset #'mime-preview-play-current-entity-orig
;; (symbol-function #'mime-preview-play-current-entity)))
;; (defun mime-preview-play-current-entity (&optional ignore-examples mode)
;; (interactive "P")
;; (if (and mode (not (equal mode "play")))
;; (mime-preview-play-current-entity-orig ignore-examples mode)
;; (let* ((entity (get-text-property (point) 'mime-view-entity))
;; (name (mime-entity-safe-filename entity))
;; (filename (expand-file-name (if (and name (not (string= name "")))
;; name
;; (make-temp-name "EMI"))
;; (make-temp-file "EMI" 'directory))))
;; (mime-write-entity-content entity filename)
;; (message "External method is starting...")
;; (let* ((process-name
;; (concat my:mime-preview-play-current-entity-appname " " filename))
;; (process
;; (start-process process-name
;; mime-echo-buffer-name
;; my:mime-preview-play-current-entity-appname
;; filename)))
;; (set-alist 'mime-mailcap-method-filename-alist process filename)
;; (set-process-sentinel process 'mime-mailcap-method-sentinel)))))
(setq mime-play-delete-file-immediately nil)
(setq mime-view-mailcap-files '("~/.mailcap"))
~/.mailcap
自体は以下
applications/*; xdg-open %s;
image/*; xdg-open %s;
video/*; xdg-open %s;
MIME の例の保存先の変更
(setq mime-situation-examples-file
(concat my:d:tmp "mime-example"))
text/plain を html より優先.
(setq mime-view-type-subtype-score-alist
'(((text . plain) . 1)
((text . html) . 0)
))
音を鳴らすアレやコレの無効化
(setq mime-play-find-every-situations nil
process-connection-type nil)
(load (concat my:d:password-store "/wl-info.gpg"))
設定している内容は以下の通り
;; From: の設定
(setq wl-from (concat user-full-name " <" user-mail-address ">"))
;; (system-name) が FQDN を返さない場合、
;; `wl-local-domain' にホスト名を除いたドメイン名を設定
(setq wl-local-domain "example.com")
;; 自分のメールアドレスのリスト
(setq wl-user-mail-address-list
(list (wl-address-header-extract-address wl-from)
;; "[email protected]"
;; "[email protected]" ...
))
;; 自分の参加しているメーリングリストのリスト
(setq wl-subscribed-mailing-list
'("[email protected]"
"[email protected]"
"[email protected]"
;; "[email protected]" ...
))
(setq elmo-imap4-default-server "your imap server")
(setq elmo-imap4-default-port '993)
(setq elmo-imap4-default-stream-type 'ssl)
送信(SMTP)
(setq wl-smtp-posting-server "your smtp server")
(setq wl-smtp-posting-user "your account")
(setq wl-smtp-posting-port 587)
(setq wl-smtp-connection-type 'starttls)
(setq wl-smtp-authenticate-type "login")
(setq wl-template-alist
'(("default"
("From" . wl-from)
(wl-smtp-posting-server . "your smtp server")
(wl-smtp-posting-user . "your account")
(wl-smtp-posting-port . 587)
(wl-smtp-connection-type . 'starttls)
(wl-smtp-authenticate-type . "login")
)
("example1"
("From" . "Your Name <[email protected]>")
(wl-smtp-posting-server . "smtp.example1.com")
(wl-smtp-posting-user . "your account")
(wl-smtp-posting-port . 587)
(wl-smtp-connection-type . 'starttls)
(wl-smtp-authenticate-type . "login")
)
("example2"
("From" . "Your Name <[email protected]>")
(wl-smtp-posting-server . "smtp.example2.com")
(wl-smtp-posting-user . "your account")
(wl-smtp-posting-port . 587)
(wl-smtp-connection-type . 'starttls)
(wl-smtp-authenticate-type . "plain")
)
("ssh:smtp"
;; need ssh tunnel
;; ssh -f -N -L 20025:localhost:25 smtp.server.com
("From" . "Your Name <[email protected]>")
(wl-smtp-posting-server . "localhost")
(wl-smtp-posting-user . "your ssh account")
(wl-smtp-posting-port . 20025)
(wl-smtp-connection-type . 'nil)
(wl-smtp-authenticate-type . 'nil)
)
))
ssh tunnel を自動的にやる事はできないモンだろうか (送信時に open して, 送信後に close する, みたいなの).
ついでに template の切り替えに関して幾つか設定.
;; template 切り替え時に 内容を表示
(setq wl-template-visible-select t)
draft-mode
で C-c C-n
をするとテンプレートを切り替え
(define-key wl-draft-mode-map "\C-c\C-n" 'wl-template-select)
from に応じて wl-from, wl-envelope-from, 送信 smtp サーバを変更する送信時に変更
(add-hook 'wl-draft-send-hook
(lambda ()
(set (make-local-variable 'wl-from)
(std11-fetch-field "From"))))
送信時に自動的に wl-draft-config-alist を適用…しない?
(remove-hook 'wl-draft-send-hook 'wl-draft-config-exec)
(setq elmo-imap4-use-modified-utf7 t)
(setq wl-folder-check-async t)
~/.cache/wanderlust/
に集約している
local の Mail folder(MH) の位置
(setq elmo-localdir-folder-path "~/.cache/wanderlust/local")
local フォルダの設定:
.lost+found
は elmo-maildir-folder-path
からの相対パスになっていることに注意
(setq elmo-lost+found-folder ".lost+found")
(setq wl-queue-folder "+queue")
folders の位置の変更
;; (setq wl-folders-file "~/.mu(concat my:d:password-store "/wl-folders.gpg"))
Drafts, Trash の置き場所
(setq wl-draft-folder "+drafts")
(setq wl-trash-folder "+drash")
(setq elmo-lost+found-folder "+lost+found")
(setq wl-temporary-file-directory "~/Downloads/")
アドレス帳
(setq wl-use-petname t)
;; (setq wl-address-file "~/.mua/Address")
LDAP サーバからアドレスを引くことも可能. 以前は GCALDaemon を使って local に ldap サーバを上げていたのだけれども, Google Contacts の API が変わったらしく GCALDaemon で LDAP サーバは使えなくなったのでコメントアウト.
(setq wl-use-ldap t)
(setq wl-ldap-server "localhost")
(setq wl-ldap-port "389")
(setq wl-ldap-base "dc=math,dc=kyoto-u,dc=ac,dc=jp")
パスワードの保存先
;; (setq elmo-passwd-alist-file-name (concat my:d:password-store "/wl-passwd.gpg"))
(setq wl-fldmgr-make-backup nil)
(setq wl-fcc nil)
;; (setq wl-fcc "%Sent")
fcc を既読にする場合は以下.=wl-fcc= が nil の場合には意味は無い
(setq wl-fcc-force-as-read t)
bcc は常に自身に.
(setq wl-bcc (concat user-mail-address))
(setq wl-auto-check-folder-name "%INBOX")
(setq wl-default-spec "%")
(setq elmo-folder-update-confirm nil)
(setq elmo-folder-update-threshold nil)
(setq elmo-message-fetch-confirm nil)
(setq elmo-message-fetch-threshold nil)
(setq wl-prefetch-confirm nil)
(setq wl-prefetch-threshold nil)
終了時に確認しない
(setq wl-interactive-exit nil)
送信時は確認する
(setq wl-interactive-send t)
wl-trash-folder
への移動ではなく, 「delete」に.
(add-to-list 'wl-dispose-folder-alist
'("^%INBOX" . delete))
迷惑メール関連も
(add-to-list 'wl-dispose-folder-alist
'(".*Junk$" . delete))
(setq wl-message-truncate-lines nil)
draft も折り返す
(setq wl-draft-truncate-lines nil)
(setq wl-summary-mode-line-format "") ; "%f {%t}(%n/%u/%a)"
(setq wl-message-mode-line-format "") ; "<< %f:%F>> [%m]"
(setq mime-edit-split-message nil)
スレッドは常に閉じる
(setq wl-thread-insert-opened nil)
3 pain 表示 -> 使わない
(setq wl-stay-folder-window nil)
未読を優先的に読む
(setq wl-summary-move-order 'unread)
改ページ無視
(setq wl-break-pages nil)
icon を使わない → GUI でもメニュー表示してないし, 体感的には遅くなる
(setq wl-highlight-folder-with-icon nil)
印刷 → ps-print-buffer に任せる←まだ保留. エラー吐きよる….
(setq wl-print-buffer-function 'ps-print-buffer)
C-c C-j
を browse-url に明け渡す
(define-key wl-draft-mode-map "\C-c\C-j" 'browse-url-at-point)
M-u
で unread にする
(define-key wl-summary-mode-map "\M-u" 'wl-summary-mark-as-unread)
i
で sync <- Mew 風
(define-key wl-summary-mode-map "i" 'wl-summary-sync-update)
C-o
は elscreen で使う
(define-key wl-summary-mode-map "\C-o" nil )
M-o
で auto-refile
(Mew 風)
(define-key wl-summary-mode-map "\M-o" 'wl-summary-auto-refile)
(require 'elmo nil 'noerror)
(defun my:wl-summary-jump-to-referer-message ()
(interactive)
(when (wl-summary-message-number)
(if (eq (elmo-folder-type-internal wl-summary-buffer-elmo-folder) 'flag)
(progn
(let* ((referer (elmo-flag-folder-referrer
wl-summary-buffer-elmo-folder
(wl-summary-message-number)))
(folder (if (> (length referer) 1)
(completing-read
(format "Jump to (%s): " (car (car referer)))
referer
nil t nil nil (car (car referer)))
(car (car referer)))))
(wl-summary-goto-folder-subr folder 'no-sync nil nil t)
(wl-summary-jump-to-msg (cdr (assoc folder referer)))))
(when (eq (elmo-folder-type wl-summary-last-visited-folder) 'internal)
(wl-summary-goto-last-visited-folder)))))
(define-key wl-summary-mode-map "=" 'my:wl-summary-jump-to-referer-message)
(setq wl-summary-showto-folder-regexp ".*")
(setq wl-summary-from-function 'wl-summary-default-from)
(setq wl-summary-line-format
"%T%P%1@%1>%Y/%M/%D %21(%t%[%19(%c %f%)%]%) %#%~%s"
wl-summary-width (- (window-width) 1))
サマリ表示は切り詰めない
(setq wl-subject-length-limit t)
スレッドの幅の指定
(setq wl-thread-indent-level 2)
(setq wl-thread-have-younger-brother-str "+" ;; "├" ;; "+"
wl-thread-youngest-child-str "+" ;; "└" ;; "+"
wl-thread-vertical-str "|";; "│" ;; "|"
wl-thread-horizontal-str "-";; "─" ;; "-"
wl-thread-space-str " ")
以下の二つの設定を有効にするには
elmo-msgdb-extra-fields
を設定する必要がある.
この変数は振り分け判定にも使用するのでそこで設定している
;; 一覧表示での置き換え規則に追加
(defun my:wl-summary-line-for-me ()
(if (catch 'found
(let ((to (elmo-message-entity-field wl-message-entity 'to))
(cc (elmo-message-entity-field wl-message-entity 'cc)))
(when (or (stringp to) cc)
(setq to
(append (if (stringp to) (list to) to)
(when cc
(if (stringp cc) (list cc) cc)))))
(dolist (i to)
(when (wl-address-user-mail-address-p (eword-decode-string i))
(throw 'found t)))))
">"
""))
;; > を summary-line-format に追加
(setq wl-summary-line-format-spec-alist
(append wl-summary-line-format-spec-alist
'((?> (my:wl-summary-line-for-me)))))
(setq wl-summary-line-format-spec-alist
(append wl-summary-line-format-spec-alist
'((?@ (wl-summary-line-attached)))))
(setq mime-field-decoding-max-size 100000)
;; (setq mime-header-lexical-analyzer
;; '(
;; eword-analyze-quoted-string
;; eword-analyze-domain-literal
;; eword-analyze-comment
;; eword-analyze-spaces
;; eword-analyze-special
;; eword-analyze-encoded-word
;; eword-analyze-atom))
(with-eval-after-load 'eword-decode
(mime-set-field-decoder
'From nil 'eword-decode-and-unfold-unstructured-field-body)
(mime-set-field-decoder
'CC nil 'eword-decode-and-unfold-unstructured-field-body)
(mime-set-field-decoder
'To nil 'eword-decode-and-unfold-unstructured-field-body))
(setq wl-summary-divide-thread-when-subject-changed nil)
;; (defadvice std11-unfold-string (after simply activate)
;; (setq ad-return-value
;; (replace-regexp-in-string ad-return-value "[ \t]+" " ")))
(setq wl-folder-process-duplicates-alist
'(
(".*" . hide)
))
(defun wl-summary-overview-entity-compare-by-reply-date (a b)
"Compare message A and B by latest date of replies including thread."
(cl-letf (((symbol-function 'string-max2)
(lambda (x y) (cond ((string< x y) y) ;;>
('t x))))
((symbol-function 'elmo-entity-to-number)
(lambda (x) (elt (cddr x) 0)))
((symbol-function 'thread-number-get-date)
(lambda (x) (timezone-make-date-sortable
(elmo-msgdb-overview-entity-get-date
(elmo-message-entity
wl-summary-buffer-elmo-folder
x)))))
((symbol-function 'thread-get-family)
(lambda (x)
(cons x (wl-thread-entity-get-descendant
(wl-thread-get-entity x)))))
((symbol-function 'max-reply-date)
(lambda (x) (cond ((eq 'nil x)
'nil)
((eq 'nil (cdr x))
(thread-number-get-date (car x)))
('t
(string-max2 (thread-number-get-date (car x))
(max-reply-date (cdr x)))))))
)
(string< ;;>
(max-reply-date (thread-get-family (elmo-entity-to-number a)))
(max-reply-date (thread-get-family (elmo-entity-to-number b))))))
;; (defun wl-summary-overview-entity-compare-by-reply-date (a b)
;; "Compare message A and B by latest date of replies including thread."
;; (flet ((string-max2 (x y) (cond ((string< x y) y) ;;>
;; ('t x)))
;; (elmo-entity-to-number (x)
;; (elt (cddr x) 0))
;; (thread-number-get-date (x)
;; (timezone-make-date-sortable
;; (elmo-msgdb-overview-entity-get-date
;; (elmo-message-entity
;; wl-summary-buffer-elmo-folder
;; x))))
;; (thread-get-family (x)
;; (cons x (wl-thread-entity-get-descendant
;; (wl-thread-get-entity x))))
;; (max-reply-date (x)
;; (cond ((eq 'nil x)
;; 'nil)
;; ((eq 'nil (cdr x))
;; (thread-number-get-date (car x)))
;; ('t
;; (string-max2 (thread-number-get-date (car x))
;; (max-reply-date (cdr x))))))
;; )
;; (string< ;;>
;; (max-reply-date (thread-get-family (elmo-entity-to-number a)))
;; (max-reply-date (thread-get-family (elmo-entity-to-number b))))))
(add-to-list 'wl-summary-sort-specs 'reply-date)
(setq wl-summary-default-sort-spec 'reply-date)
$
以外を振り分け対象に
(setq wl-summary-auto-refile-skip-marks '("$"))
Content-Type
も登録.
あと Delivered-To
はメールの検索の時に結構重宝している.
(setq elmo-msgdb-extra-fields
'(
"List-Post"
"List-Id"
"List-ID" ;; たまに List-ID で来るメールあるよね?
"Resent-CC"
"Mailing-List"
"X-Mailing-List"
"X-ML-Address"
"X-ML-Name"
"X-ML-To"
"X-Loop"
"Delivered-To"
"Content-Type" ;; 添付の有無の表示の為に追加
"X-Google-Appengine-App-Id" ;; GAEの送信するメールの振り分け用
"To"
"Cc"
"From"
"Subject"
"Reply-To"
"Auto-Submitted" ;; Git commit/Cron notify
))
(setq wl-message-ignored-field-list '("^.*:"))
(setq wl-message-visible-field-list
'("^Subject:"
"^From:"
"^To:"
"^Cc:"
"^Date:"
"^Message-ID:"
))
(setq wl-message-sort-field-list
'("^Subject:"
"^From:"
"^To:"
"^Cc:"
"^Date:"
"^Message-ID:"
))
(setq wl-message-use-header-narrowing nil)
(setq wl-highlight-message-header-alist
'(("Subject[ \t]*:"
. wl-highlight-message-subject-header-contents)
("From[ \t]*:"
. wl-highlight-message-from-header-contents)
("Date[ \t]*:"
. wl-highlight-message-date-header-contents)
("\\(.*To\\|Cc\\|Newsgroups\\)[ \t]*:"
. wl-highlight-message-important-header-contents)
("\\(User-Agent\\|X-Mailer\\|X-Newsreader\\)[ \t]*:"
. wl-highlight-message-unimportant-header-contents)
))
;; face の色付け
(defun my:wl-set-face (face spec)
(make-face face)
(cond ((fboundp 'face-spec-set)
(face-spec-set face spec))
(t
(wl-declare-face face spec))))
;;
(my:wl-set-face
'wl-highlight-message-subject-header-contents
'((t (:foreground "#FF5252" :bold t :italic nil :weight bold ))))
(my:wl-set-face
'wl-highlight-message-from-header-contents
'((t (:foreground "#FFD740" :bold t :italic nil :weight bold ))))
(my:wl-set-face
'wl-highlight-message-date-header-contents
'((t (:foreground "#5CF19E" :bold t :italic nil :weight bold ))))
以下, 元々定義されているfaceの設定
;; (my:wl-set-face 'wl-highlight-folder-closed-face
;; '((t (:foreground "#4cff4c" :bold nil :italic nil :weight normal ))))
;; (my:wl-set-face 'wl-highlight-folder-few-face
;; '((t (:foreground "#FF4C4C" :bold t :italic nil :weight bold ))))
;; (my:wl-set-face 'wl-highlight-folder-zero-face
;; '((t (:foreground "#f6f3e8" :bold nil :italic nil :weight normal ))))
;; (my:wl-set-face 'wl-highlight-message-cited-text-1
;; '((t (:foreground "#7fff7f" :bold nil :italic nil :weight normal ))))
;; (my:wl-set-face 'wl-highlight-message-cited-text-2
;; '((t (:foreground "#ffff7f" :bold nil :italic nil :weight normal ))))
;; (my:wl-set-face 'wl-highlight-message-cited-text-3
;; '((t (:foreground "#7f7fff" :bold nil :italic nil :weight normal ))))
;; (my:wl-set-face 'wl-highlight-message-cited-text-4
;; '((t (:foreground "#7fffff" :bold nil :italic nil :weight normal ))))
;; (my:wl-set-face 'wl-highlight-message-cited-text-5
;; '((t (:foreground "#ff7fff" :bold nil :italic nil :weight normal ))))
;; (my:wl-set-face 'wl-highlight-message-cited-text-6
;; '((t (:foreground "#ff7f7f" :bold nil :italic nil :weight normal ))))
;; (my:wl-set-face 'wl-highlight-message-cited-text-7
;; '((t (:foreground "#4cff4c" :bold nil :italic nil :weight normal ))))
;; (my:wl-set-face 'wl-highlight-message-cited-text-8
;; '((t (:foreground "#ffff4c" :bold nil :italic nil :weight normal ))))
;; (my:wl-set-face 'wl-highlight-message-cited-text-9
;; '((t (:foreground "#4c4cff" :bold nil :italic nil :weight normal ))))
;; (my:wl-set-face 'wl-highlight-message-cited-text-10
;; '((t (:foreground "#4cffff" :bold nil :italic nil :weight normal ))))
;; (my:wl-set-face 'wl-highlight-message-cited-text-11
;; '((t (:foreground "#ff4cff" :bold nil :italic nil :weight normal ))))
;; (my:wl-set-face 'wl-highlight-message-cited-text-12
;; '((t (:foreground "#ff4c4c" :bold nil :italic nil :weight normal ))))
;; (my:wl-set-face 'wl-highlight-message-date-header-contents
;; '((t (:foreground "#4CFF4C" :bold t :italic nil :weight bold ))))
;; (my:wl-set-face 'wl-highlight-message-header-contents
;; '((t (:foreground "#aaaaaa" :bold nil :italic nil :weight normal ))))
;; (my:wl-set-face 'wl-highlight-message-headers
;; '((t (:foreground "#4CFFFF" :bold t :italic nil :weight bold ))))
;; (my:wl-set-face 'wl-highlight-message-important-header-contents2
;; '((t (:foreground "#4CFF4C" :bold nil :italic nil :weight normal ))))
;; (my:wl-set-face 'wl-highlight-message-signature
;; '((t (:foreground "#aaaaaa" :bold nil :italic nil :weight normal ))))
;; (my:wl-set-face 'wl-highlight-message-important-header-contents
;; '((t (:foreground "#FF4CFF" :bold t :italic nil :weight bold ))))
;; (my:wl-set-face 'wl-highlight-message-subject-header-contents
;; '((t (:foreground "#FF4C4C" :bold t :italic nil :weight bold ))))
;; (my:wl-set-face 'wl-highlight-message-unimportant-header-contents
;; '((t (:foreground "#aaaaaa" :bold nil :italic nil :weight normal ))))
;; (my:wl-set-face 'wl-highlight-summary-answered-face
;; '((t (:foreground "#4CFF4C" :bold nil :italic nil :weight normal ))))
;; (my:wl-set-face 'wl-highlight-summary-refiled-face
;; '((t (:foreground "#7F7FFF" :bold nil :italic nil :weight normal ))))
;; (my:wl-set-face 'wl-highlight-summary-thread-top-face
;; '((t (:foreground "#F6F3E8" :bold nil :italic nil :weight normal ))))
;; (my:wl-set-face 'wl-highlight-summary-important-flag-face
;; '((t (:foreground "#ffff4c" :bold nil :italic nil :weight normal ))))
;; (my:wl-set-face 'wl-highlight-folder-killed-face
;; '((t (:foreground "#4c4c4c" :5Dbold nil :italic nil ))))
;; (my:wl-set-face 'wl-highlight-folder-many-face
;; '((t (:foreground "#ff7fbf" :bold nil :italic nil ))))
;; (my:wl-set-face 'wl-highlight-folder-opened-face
;; '((t (:foreground "#4cffff" :bold nil :italic nil ))))
;; (my:wl-set-face 'wl-highlight-folder-path-face
;; '((t (:underline t :bold nil :italic nil ))))
;; (my:wl-set-face 'wl-highlight-folder-unknown-face
;; '((t (:foreground "#4cffff" :bold nil :italic nil ))))
;; (my:wl-set-face 'wl-highlight-folder-unread-face
;; '((t (:foreground "#4c4cff" :bold nil :italic nil ))))
;; (my:wl-set-face 'wl-highlight-header-separator-face
;; '((t (:inherit highlight :bold t ))))
;; (my:wl-set-face 'wl-highlight-message-citation-header
;; '((t (:foreground "#7fff7f" :bold nil :italic nil ))))
;; (my:wl-set-face 'wl-highlight-summary-copied-face
;; '((t (:foreground "#4CFFFF" :bold nil :italic nil ))))
;; (my:wl-set-face 'wl-highlight-summary-deleted-face
;; '((t (:foreground "#4c4c4c" :bold nil :italic nil ))))
;; (my:wl-set-face 'wl-highlight-summary-displaying-face
;; '((t (:underline t :bold nil :italic nil ))))
;; (my:wl-set-face 'wl-highlight-summary-disposed-face
;; '((t (:foreground "#aaaaaa" :bold nil :italic nil ))))
;; (my:wl-set-face 'wl-highlight-summary-flagged-face
;; '((t (:foreground "#ffff7f" :bold nil :italic nil ))))
;; (my:wl-set-face 'wl-highlight-summary-forwarded-face
;; '((t (:foreground "#7f7fff" :bold nil :italic nil ))))
;; (my:wl-set-face 'wl-highlight-summary-high-read-face
;; '((t (:foreground "#7fff7f" :bold nil :italic nil ))))
;; (my:wl-set-face 'wl-highlight-summary-high-unread-face
;; '((t (:foreground "#ffb347" :bold nil :italic nil ))))
;; (my:wl-set-face 'wl-highlight-summary-important-face
;; '((t (:foreground "#ffff4c" :bold nil :italic nil ))))
;; (my:wl-set-face 'wl-highlight-summary-killed-face
;; '((t (:foreground "#4c4c4c" :bold nil :italic nil ))))
;; (my:wl-set-face 'wl-highlight-summary-l:read-face
;; '((t (:foreground "#4CFF4C" :bold nil :italic nil ))))
;; (my:wl-set-face 'wl-highlight-summary-l:unread-face
;; '((t (:foreground "#7fbfff" :bold nil :italic nil ))))
;; (my:wl-set-face 'wl-highlight-summary-new-face
;; '((t (:foreground "#ff4c4c" :bold nil :italic nil ))))
;; (my:wl-set-face 'wl-highlight-summary-normal-face
;; '((t (:foreground "#f6f3e8" :bold nil :italic nil ))))
;; (my:wl-set-face 'wl-highlight-summary-prefetch-face
;; '((t (:foreground "#4c4cee" :bold nil :italic nil ))))
;; (my:wl-set-face 'wl-highlight-summary-resend-face
;; '((t (:foreground "#ffb347" :bold nil :italic nil ))))
;; (my:wl-set-face 'wl-highlight-summary-target-face
;; '((t (:foreground "#4CFFFF" :bold nil :italic nil ))))
;; (my:wl-set-face 'wl-highlight-summary-temp-face
;; '((t (:foreground "##ee4cee" :bold nil :italic nil ))))
;; (my:wl-set-face 'wl-highlight-summary-unread-face
;; '((t (:foreground "#ff4c4c" :bold nil :italic nil ))))
;; (my:wl-set-face 'wl-highlight-thread-indent-face
;; '((t (:underline t :bold nil :italic nil ))))
To:
, Cc:
から自分のアドレスを削除
(setq wl-draft-always-delete-myself t)
“a” (without-argument)では Reply-To:
や From:
などで
指定された唯一人または唯一つの投稿先に返信.
また, X-ML-Name:
と Reply-To:
がついているなら Reply-To:
宛に返信
(setq wl-draft-reply-without-argument-list
'((("X-ML-Name" "Reply-To") . (("Reply-To") nil nil))
("X-ML-Name" . (("To" "Cc") nil nil))
("Followup-To" . (nil nil ("Followup-To")))
("Newsgroups" . (nil nil ("Newsgroups")))
("Reply-To" . (("Reply-To") nil nil))
("Mail-Reply-To" . (("Mail-Reply-To") nil nil))
("From" . (("From") nil nil))))
C-u a
(with-argument)であれば関係する全ての人・投稿先に返信
(setq wl-draft-reply-with-argument-list
'(("Followup-To" . (("From") nil ("Followup-To")))
("Newsgroups" . (("From") nil ("Newsgroups")))
("Mail-Followup-To" . (("Mail-Followup-To") nil ("Newsgroups")))
("From" . (("From") ("To" "Cc") ("Newsgroups")))))
サマリ表示には petname を使うが, 引用には使わない
(setq wl-default-draft-cite-decorate-author nil)
;; (setq wl-auto-save-drafts-interval 300)
(setq wl-auto-save-drafts-interval nil)
(add-hook 'wl-draft-mode-hook
(lambda ()
(add-to-list 'mime-charset-type-list '(utf-8 8 nil))))
(add-hook 'wl-draft-mode-hook
(lambda ()
(progn
(require 'org-table)
#'turn-on-orgtbl)))
C-c <tab>
で signature を挿入するようにしている
(leaf c-sig
:commands insert-signature-eref
:config
(eval-when-compile (require 'wl))
(setq sig-insert-end t
sig-save-to-sig-name-alist nil
message-signature-file nil)
)
(define-key wl-draft-mode-map "\C-c\t" 'insert-signature-eref)
(add-hook 'wl-draft-mode-hook
(lambda ()
(define-key (current-local-map) "\C-c\C-w"
'insert-signature-eref)))
draft-mode
の文字コードをあらかじめ指定しておかないと,
送信時に文字コードが変換されるので不正な署名となってしまう.
もっとうまい方法/正攻法がありそうな気がするけれど, 使えてるから, まあ良いかな, とか.
(setq mime-pgp-verify-when-preview nil)
(defun my:epa-wl-decrypt-message ()
(interactive)
(save-window-excursion
(wl-summary-jump-to-current-message)
(wl-message-decrypt-pgp-nonmime)))
(defun my:epa-wl-verify-message ()
(interactive)
(save-selected-window
(wl-summary-jump-to-current-message)
(wl-message-verify-pgp-nonmime)))
(leaf-keys ((:wl-summary-mode-map
("C-c : d" . my:epa-wl-decrypt-message)
("C-c : v" . my:epa-wl-verify-message))
(:wl-draft-mode-map
("C-c : s" . epa-mail-sign)
("C-c : e" . epa-mail-encrypt)))
)
(leaf elmo-search
:config
(elmo-search-register-engine 'notmuch-custom 'local-file
:prog "notmuch-query-custom"
:args '(elmo-search-split-pattern-list)
:charset 'utf-8)
(setq elmo-search-default-engine 'notmuch-custom))
(leaf wl-qs
:config
(setq wl-quicksearch-folder "[]"
)
)
(leaf-keys ((:wl-summary-mode-map
("v" . wl-quicksearch-goto-search-folder-wrapper))
(:wl-folder-mode-map
("v" . wl-quicksearch-goto-search-folder-wrapper)))
)
実際の呼び出しはスレッドを全部取得したいので以下を呼び出している
#!/bin/sh
if [ ! x"$*" = x"" ] ; then
res=$(notmuch search --output=threads "$*")
fi
if [ ! x"$res" = x"" ] ; then
echo $res | xargs notmuch search --sort=oldest-first --output=files
fi
検索時にメールが多すぎると怒られるので. 数字は適当.
(setq elmo-multi-divide-number 2000000
elmo-multi-number 2000000)
mailto
のリンクを emacsclient で扱うために,
以下の関数を定義しておく
(defun my:mailto-compose-mail (mailto-url)
"Custom: handling mailto: link"
(if (and (stringp mailto-url)
(string-match "\\`mailto:" mailto-url))
(progn
(eval-and-compile (require 'rfc6068))
(let* ((headers (mapcar (lambda (h) (cons (intern (car h)) (cdr h)))
(rfc6068-parse-mailto-url mailto-url)))
(good-headers (cl-remove-if (lambda (h) (member (car h) '(Body))) headers))
(body (cdr (assoc 'Body headers))))
(wl-draft good-headers nil nil body)))))
Desktop の設定では
#!/bin/sh
# emacs-mailto-handler
mailto=$1
mailto="mailto:${mailto#mailto:}"
mailto=$(printf '%s\n' "$mailto" | sed -e 's/[\"]/\\&/g')
elisp_expr="(my:mailto-compose-mail \"$mailto\")"
emacsclient -a "" -n --eval "$elisp_expr" \
'(set-window-dedicated-p (selected-window) t)'
をメーラとして指定すれば良い.
GNOME は .desktop
ファイルが無いと「お気に入り」登録ができないので
以下のファイルを適当な名前で ~/.local/share/applications/
以下に放り込んでおくと良いだろう
[Desktop Entry]
Name=Emacs Mail Handler
GenericName=Mail User Agent
X-GNOME-FullName=Emacs Mail Handler
Comment=Use emacsclient as MUA, handling mailto link
Keywords=email
Exec=/home/uwabami/bin/emacs-mailto-handler %U
Icon=emacs25
Terminal=false
Type=Application
Categories=GNOME;GTK;Office;Email;
StartupNotify=false
MimeType=application/mbox;message/rfc822;x-scheme-handler/mailto;
(leaf mbsync
:if (executable-find "mbsync")
:ensure t
)
(leaf *deepl-translate
:commands my:deepl-translate
:bind (("C-x T" . my:deepl-translate))
:preface
(require 'url-util)
(defun my:deepl-translate (&optional string)
(interactive)
(setq string
(cond ((stringp string) string)
((use-region-p)
(buffer-substring (region-beginning) (region-end)))
(t
(save-excursion
(let (s)
(forward-char 1)
(backward-sentence)
(setq s (point))
(forward-sentence)
(buffer-substring s (point)))))))
(run-at-time 0.1 nil 'deactivate-mark)
(browse-url
(concat
"https://www.deepl.com/translator#en/ja/"
(url-hexify-string string)
)))
)
(leaf google-translate
:ensure t
:defvar google-translate-backend-method
:init
(defvar google-translate-translation-directions-alist '(("en" . "ja") ("ja" . "en")))
(leaf popup :ensure t)
(defun my:google-translate--search-tkk ()
"Search TKK. @see https://github.com/atykhonov/google-translate/issues/52"
(list 430675 2721866130))
:bind
("C-x t" . google-translate-smooth-translate)
:advice (:override google-translate--search-tkk
my:google-translate--search-tkk)
:config
(setq google-translate-translation-directions-alist '(("en" . "ja") ("ja" . "en"))
google-translate-backend-method 'curl)
)
aspell
を利用する.
(leaf flyspell
:if (executable-find "aspell")
;; :blackout (flyspell-mode . "F")
:custom
`((ispell-program-name . "aspell")
(ispell-check-comments . nil)
(ispell-skip-html . t)
(ispell-silently-savep . t)
)
:bind (:flyspell-mode-map
("C-." . nil)
("C-," . nil))
:defer-config
(add-to-list 'ispell-skip-region-alist '("[^\000-\377]+"))
)
lookup-el
ver. 1.4 系列を利用
(leaf lookup
:if (and (file-exists-p "/etc/emacs/site-start.d/50lookup-el.el")
(file-exists-p "/usr/local/share/dict/lookup-enabled"))
:commands (lookup lookup-region lookup-pattern)
:bind (("C-c w" . lookup-pattern)
("C-c W" . lookup-word))
:custom
(lookup-search-agents
. '((ndeb "/usr/local/share/dict/eijiro" :alias "英辞郎")
(ndeb "/usr/local/share/dict/waeijiro" :alias "和英辞郎")
(ndeb "/usr/local/share/dict/rikagaku5" :alias "理化学辞典 第5版")
(ndeb "/usr/local/share/dict/koujien4" :alias "広辞苑 第4版")
(ndeb "/usr/local/share/dict/wadai5" :alias "研究社 和英大辞典 第5版")
;; (ndeb "/usr/local/share/dict/eidai6" :alias "研究社 英和大辞典 第6版")
;; (ndeb "/usr/local/share/dict/colloc" :alias "研究社 英和活用大辞典 ")
))
)
(leaf text-adjust :vc (:url "https://github.com/uwabami/text-adjust.el"))
(leaf flycheck
:ensure t
:disabled t
;; :hook (prog-mode-hook . flycheck-mode)
:custom ((flycheck-display-errors-delay . 0.3))
:config
(leaf flycheck-popup-tip
:ensure t
:hook (flycheck-mode-hook . flycheck-popup-tip-mode))
;; (leaf flycheck-inline
;; :ensure t
;; :hook (flycheck-mode-hook . flycheck-inline-mode))
;;
(flycheck-define-checker textlint
"A linter for text."
:command ("textlint-wrapper.sh" source)
:error-patterns
((warning line-start (file-name) ":" line ":" column ": "
(id (one-or-more (not (any " "))))
(message (one-or-more not-newline)
(zero-or-more "\n" (any " ") (one-or-more not-newline)))
line-end))
:modes (text-mode markdown-mode gfm-mode org-mode wl-draft-mode draft-mode))
:hook
((text-mode-hook . flycheck-mode)
(markdown-mode-hook . flycheck-mode)
(gfm-mode-hook . flycheck-mode)
(org-mode-hook . flycheck-mode)
(wl-draft-mode-hook . flycheck-mode)
(draft-mode-hook . flycheck-mode))
)
(leaf smartparens
:disabled t
:ensure t
;; :blackout t
:defun (sp-pair)
:hook (emacs-startup-hook . smartparens-global-mode)
:config
(require 'smartparens-config)
(sp-pair "=" "=" :actions '(wrap))
(sp-pair "+" "+" :actions '(wrap))
(sp-pair "<" ">" :actions '(wrap))
(sp-pair "$" "$" :actions '(wrap))
)
#RRGGBB
のカラーコードに勝手に色が付く.CSS の編集中なんかで地味に便利.
(leaf rainbow-mode
:ensure t
;; :blackout `((rainbow-mode . ,(format " %s" "\x1F308")))
)
org-mode
が無いと生きていけない体になりました
目新しい設定はしていない, と思う.
;;; timestamp 更新文字列の変更:
;; org-mode では #+date: をひっかける用に(#は小文字).
;;;###autoload
(defun my:org-timestamp-hook ()
"Change `time-stamp-start' in org-mode"
(set (make-local-variable 'time-stamp-start) "#\\+date: ")
(set (make-local-variable 'time-stamp-end) "\$")
)
;; org-plus-contrib も使うかなぁ….
(leaf org
:ensure t
;; :blackout `((org-mode . ,(all-the-icons-icon-for-mode 'org-mode)))
:bind (("C-x n s" . org-narrow-to-subtree)
("C-x n w" . widen)
("C-c a" . org-agenda)
("C-x m" . org-capture)
("C-x M" . org-journal-new-entry)
)
;; 昔のメモ(howm)も org-mode で開く
:mode "\\.org\\'" "\\.howm\\'"
;; GTD: TODO→...→DONE としたエントリを =Arhive.org= に移動
;; - 一旦保留
;; (defun my:org-archive-done-tasks ()
;; (interactive)
;; (org-map-entries 'org-archive-subtree "/DONE" 'file))
:hook
`((org-mode-hook . my:org-timestamp-hook)
;; (org-todo-statistics-hook . my:org-archive-done-tasks)
;; (org-todo-after-statistics-hook . my:org-archive-done-tasks)
)
:custom
`(;; Nextcloud に保存する
(org-directory . ,(expand-file-name my:d:org))
;; return でリンクを辿る
(org-return-follows-link . t)
;; 見出しを畳んで表示
(org-startup-folded . t)
;; 折り返し無し
(org-startup-truncated . t)
;; インデントする
(org-adapt-indentation . t)
;; link handler → xdg-open 任せ
(org-file-apps-defaults . '((remote . emacs)
(system . "xdg-open %s")
(t . "xdg-open %s")))
(org-file-apps-defaults-gnu . '((remote . emacs)
(system . "xdg-open %s")
(t . "xdg-open %s")))
(org-file-apps . '((auto-mode . emacs)
("\\.mm\\'" . default)
("\\.x?html?\\'" . "xdg-open %s")
("\\.pdf\\'" . "xdg-open %s")))
;; GTD: 状態の追加
(org-todo-keywords . '((sequence "TODO(t)" "WAIT(w)" "SOMEDAY(s)" "|" "DONE(d)" "CANCEL(c)")
(type "ARTICLE(a)" "|" "DONE(d)")
(type "MEMO(m)" "|" "DONE(d)")))
(org-todo-keyword-faces . '(("TODO" . org-todo)
("WAIT" . org-todo)
("ARTICLE" . (:foreground "#7fbfff" :weight bold))
("MEMO" . (:foreground "#7fbfff" :weight bold))
("SOMEDAY" . (:foreground "#7fff7f" :weight bold))))
;; GTD: タグの追加
(org-tag-alist . '(("OFFICE" . ?o)
("HOME" . ?h)
("MAIL" . ?m)
("WORK" . ?w)
("Debian" . ?d)
("Computer" . ?c)
("Book" . ?b)
("Emacs" . ?e)
("TeX" . ?t)
("Ruby" . ?r)
("IGNORE" . ?i)
("PLANNED" . ?p)
))
;; Archive.org の位置指定
(org-archive-location . ,(expand-file-name "Archive.org::" my:d:org))
;; modules → とりあえずクリアしておく
(org-modules . '())
;; element-cache は使わない...うまく使えると良いんだけれど.
(org-element-use-cache . nil)
)
:defer-config
;; +打ち消し+ の font-lock の変更 →これはテーマに任せるべき?
;; (setq org-emphasis-alist
;; (cons '("+" '(:strike-through t :foreground "#999999"))
;; (cl-delete "+" org-emphasis-alist :key 'car :test 'equal)))
(require 'org-tempo nil 'noerror)
)
(leaf org-id
:commands
(my:org-id-add-custom-id
my:org-id-get-custom-id
my:org-custom-id-get
my:org-id-add-to-headlines-in-file
my:org-id-delete-all-id-in-file
)
:init
(leaf org-macs :commands org-with-point-at)
:custom
`((org-id-locations-file
. ,(expand-file-name "org-id-locations" my:d:tmp))
(org-id-link-to-org-use-id . 'create-if-interactive-and-no-custom-id)
)
:config
(defun my:org-id-add-custom-id ()
"Add \"CUSTOM_ID\" to the current tree if not assigned yet."
(interactive)
(my:org-custom-id-get nil t))
;;
(defun my:org-id-get-custom-id ()
"Return a part of UUID with an \"org\" prefix.
e.g. \"org3ca6ef0c\"."
(let* ((id (org-id-new "")))
(when (org-uuidgen-p id)
(downcase (concat "org" (substring (org-id-new "") 0 8))))))
;;
(defun my:org-custom-id-get (&optional pom create)
"Get the CUSTOM_ID property of the entry at point-or-marker POM.
See https://writequit.org/articles/emacs-org-mode-generate-ids.html"
(interactive)
(eval-when-compile (require 'org-macs))
(org-with-point-at pom
(let ((id (org-entry-get nil "CUSTOM_ID")))
(cond
((and id (stringp id) (string-match "\\S-" id))
id)
(create
(setq id (my:org-id-get-custom-id))
(unless id
(error "Invalid ID"))
(org-entry-put pom "CUSTOM_ID" id)
(message "--- CUSTOM_ID assigned: %s" id)
(org-id-add-location id (buffer-file-name (buffer-base-buffer)))
id)))))
;;
(defun my:org-id-delete-all-id-in-file ()
(interactive)
(goto-char 1)
(while (not (eq (point) (point-max)))
(org-next-visible-heading 1)
(let ((id (org-entry-get (point) "ID")))
(when id
(message "ID: %s" id)
(org-delete-property "ID"))))
(message "--- done."))
;;
(defun my:org-id-add-to-headlines-in-file ()
"Add CUSTOM_ID properties to all headlines in the current file.
See https://writequit.org/articles/emacs-org-mode-generate-ids.html"
(interactive)
(save-excursion
(widen)
(goto-char (point-min))
(when (re-search-forward "^#\\+options:.*auto-id:t" (point-max) t)
(org-map-entries
(lambda () (my:org-custom-id-get (point) 'create))))))
;;
:hook (before-save-hook
. (lambda ()
(when (and (eq major-mode 'org-mode)
(eq buffer-read-only nil))
(my:org-id-add-to-headlines-in-file))))
)
(leaf org-babel
;; :blackout `((org-src-mode . ,(format " %s" (all-the-icons-octicon "code"))))
:custom
`(;; font-lock
(org-src-fontify-natively . t)
;; TAB の挙動
(org-src-tab-acts-natively . t)
;; インデント
(org-edit-src-content-indentation . 0)
;; インデントを残す
(org-src-preserve-indentation . t)
;; load languages
(org-babel-load-languages
. '((emacs-lisp . t)
(ditaa . ,(file-exists-p "/usr/local/lib/jditaa.jar"))
(latex . ,(file-exists-p "/usr/bin/uplatex"))
)
)
)
)
(leaf ob-ditaa
:if (file-exists-p "/usr/local/lib/jditaa.jar")
:custom
((org-ditaa-jar-path . "/usr/local/lib/jditaa.jar"))
)
(leaf ob-latex
:if (file-exists-p "/usr/bin/uplatex")
)
org-gcal
と orgmine
で取得したデータも表示している.
ついでに
- 土曜日をの face を追加.
- 祝日, 休日を日曜と同じfaceにする.
なんて事もやっている.元ネタは Org-mode and holidays.
(leaf org-agenda
:if (file-directory-p my:d:org)
:preface
;; face は theme にまわすべき, かな?
(defface my:org-agenda-date-saturday
'((t (:foreground "#7FBFFF" :bold t )))
"Agenda 表示中の土曜日用のface"
:group 'org-agenda )
;; こっからは org-gcal で同期したカレンダーの色
(defface my:org-agenda-calendar-Univ
'((t (:foreground "#7FFF7F")))
"Agenda 表示中, Univ.org の表示 face"
:group 'org-agenda )
(defface my:org-agenda-calendar-Schedule
'((t (:foreground "#7FFFFF")))
"Agenda 表示中, Schedule.org の表示 face"
:group 'org-agenda )
(defface my:org-agenda-calendar-GFD
'((t (:foreground "#FFFF7F")))
"Agenda 表示中, GFD.org の表示 face"
:group 'org-agenda )
(defface my:org-agenda-calendar-DebianJP
'((t (:foreground "#BF7FFF")))
"Agenda 表示中, DebianJP.org の表示 face"
:group 'org-agenda )
;; (defface my:org-agenda-calendar-twitter
;; '((t (:foreground "#CCCCCC")))
;; "Agenda 表示中, Twitter log の表示 face"
;; :group 'org-agenda )
;;
;; font-lock の適用. loop減らせないかなぁ….
(defun my:org-agenda-finalize-font-lock ()
"Custom: apply custom font-lock"
(save-excursion
(goto-char (point-min))
(while (re-search-forward "Univ:" nil t)
(add-text-properties (match-beginning 0) (line-end-position)
'(face my:org-agenda-calendar-Univ)))
(goto-char (point-min))
(while (re-search-forward "Schedule:" nil t)
(add-text-properties (match-beginning 0) (line-end-position)
'(face my:org-agenda-calendar-Schedule)))
(goto-char (point-min))
(while (re-search-forward "DebianJP:" nil t)
(add-text-properties (match-beginning 0) (line-end-position)
'(face my:org-agenda-calendar-DebianJP)))
(goto-char (point-min))
(while (re-search-forward "GFD:" nil t)
(add-text-properties (match-beginning 0) (line-end-position)
'(face my:org-agenda-calendar-GFD)))
(goto-char (point-min))
(while (re-search-forward "twitter:" nil t)
(add-text-properties (match-beginning 0) (line-end-position)
'(face my:org-agenda-calendar-twitter)))
(goto-char (point-min))
(while (re-search-forward "祝日:\\|Holidays:\\|誕生日:" nil t)
(add-text-properties (match-beginning 0) (line-end-position)
'(face org-agenda-date-weekend)))
))
:custom
`((org-agenda-day-face-function
. (lambda (date)
(let ((face
(cond
;; 日曜日か日本の祝日
((or (= (calendar-day-of-week date) 0)
(let ((calendar-holidays japanese-holidays))
(calendar-check-holidays date)))
'org-agenda-date-weekend)
;; 土曜日
((= (calendar-day-of-week date) 6)
'my:org-agenda-date-saturday)
;; 普通の日
(t 'org-agenda-date))))
;; 今日は色を反転
(if (org-agenda-today-p date) (list :inherit face :underline t) face))))
(org-agenda-span . 'week)
(org-agenda-start-on-weekday . nil)
(org-agenda-format-date . "%Y/%m/%d (%a)")
(org-agenda-weekend-days . '(0))
(org-agenda-inhibit-startup . t)
(org-agenda-ignore-drawer-properties . '(effort appt))
(org-agenda-repeating-timestampo-show-all . t)
(org-agenda-sorting-strategy . '((agenda habit-down time-up timestamp-down priority-down category-keep)
(todo timestamp-down priority-down category-keep)
(tags priority-down category-keep)
(search category-keep)))
(org-agenda-custom-commands . '(("n" "agenda and all TODO list"
(
(agenda ""
((org-agenda-ndays 1)
(org-agenda-entry-types '(:timestamp :sexp))))
(todo "TODO"
((org-agenda-prefix-format " %i %-22:c"))
)
(todo "新規|着手|進行中|確認"
((org-agenda-prefix-format " %i %-22:c"))
)
(todo "WAIT"
((org-agenda-prefix-format " %i %-22:c"))
)
(todo "SOMEDAY"
((org-agenda-prefix-format " %i %-22:c"))
)
))
("N" "All memo entry"
(;;
(todo "MEMO")
))
)
)
)
:hook ((org-agenda-finalize-hook
. my:org-agenda-finalize-font-lock))
:defer-config
;; (defvar my:org-agenda-files nil)
(dolist (file
'(;; Archive.org ← 🤔
;; Calendar
"Holidays.org"
"Schedule.org"
"GFD.org"
"Univ.org"
"DebianJP.org"
;; INBOX
;; "INBOX.org"
;; misc
"twitter.org"
;; Project
"redmine_GFD.org"
"redmine_SSKLAB.org"
;; "redmine_FluidSoc.org"
))
(add-to-list 'org-agenda-files (expand-file-name file my:d:org)))
;;
(if (file-directory-p
(expand-file-name "journal/" my:d:org))
(dolist (file
(directory-files-recursively
(expand-file-name "journal/" my:d:org) "org$"))
(add-to-list 'org-agenda-files file)))
)
(leaf org-journal
:if (file-directory-p my:d:org)
:commands org-journal-new-entry
:ensure t
:hook
((org-journal-mode-hook
. (lambda()
(setq-local truncate-lines t))))
:custom
`((org-journal-file-type . 'yearly)
(org-journal-dir . ,(expand-file-name "journal" my:d:org))
(org-journal-file-format . "%Y.org")
(org-journal-cache-file
. ,(expand-file-name "org-journal.cache" my:d:tmp))
(org-journal-date-format . "%x (%a)")
(org-journal-time-format . "<%Y-%m-%d %R> ")
(org-journal-time-prefix . "** MEMO ")
(org-journal-enable-agenda-integration . t)
(org-journal-find-file . 'find-file)
(org-journal-carryover-delete-empty-journal . 'ask)
(org-journal-start-on-weekday . 0) ;; sunday
)
:config
(eval-and-compile 'browse-url)
;; (with-eval-after-load 'org-journal
;; (global-set-key (kbd "C-c C-j") 'browse-url-at-point))
)
C-x m
をメモにしている.
(leaf org-capture
:if (file-directory-p my:d:org)
:commands org-capture
:pl-setq
;; 名前がイケてないっ!
(my:org:calendar1 my:org:calendar2 my:org:calendar3 my:org:calendar4)
:config
(defun my:org-journal-add-date-entry-capture ()
(org-journal-new-entry t)
(goto-char (point-max))
)
(setq org-default-notes-file (expand-file-name "Memo.org" my:d:org))
(setq org-capture-templates
`(
("t" "TODO" plain
(function my:org-journal-add-date-entry-capture)
"** TODO %(format-time-string org-journal-time-format)%^{title} %^g\n %?\n %a"
:prepend nil
;; :unnarrowed nil
:kill-buffer t
)
("m" "メモを追加" plain
(function my:org-journal-add-date-entry-capture)
"** MEMO %(format-time-string org-journal-time-format)%?"
:prepend nil
;; :unnarrowed nil
:kill-buffer t
)
("a" "少し長めの記事を追加する" plain
(function my:org-journal-add-date-entry-capture)
"** ARTICLE %(format-time-string org-journal-time-format)%? "
:prepend nil
;; :unnarrowed nil
:kill-buffer t
)
("s" "個人予定表スケジュールを追加" plain
(file ,(expand-file-name "Schedule.org" my:d:org))
"* %^{prompt}\n :PROPERTIES:\n :calendar-id: %(format \"%s\" my:org:calendar1)\n :org-gcal-managed: org\n :END:\n :org-gcal:\n%?\n%i\n :END:"
:prepend nil
;; :unnarrowed nil
:kill-buffer t
)
("u" "仕事予定表スケジュールを追加" plain
(file ,(expand-file-name "Univ.org" my:d:org))
"* %^{prompt}\n :PROPERTIES:\n :calendar-id: %(format \"%s\" my:org:calendar2)\n :org-gcal-managed: org\n :END:\n :org-gcal:\n%?\n%i\n :END:"
:prepend nil
;; :unnarrowed nil
:kill-buffer t
)
("g" "GFD 関連 スケジュールを追加" plain
(file ,(expand-file-name "GFD.org" my:d:org))
"* %^{prompt}\n :PROPERTIES:\n :calendar-id: %(format \"%s\" my:org:calendar3)\n :org-gcal-managed: org\n :END:\n :org-gcal:\n%?\n%i\n :END:"
:prepend nil
;; :unnarrowed nil
:kill-buffer t
)
("h" "有給休暇・特別休暇を追加" plain
(file ,(expand-file-name "Holidays.org" my:d:org))
"* %^{prompt}\n :PROPERTIES:\n :calendar-id: %(format \"%s\" my:org:calendar4)\n :org-gcal-managed: org\n :END:\n :org-gcal:\n%?\n%i\n :END:"
:prepend nil
;; :unnarrowed nil
:kill-buffer t
)
)
)
)
password-store
を使って設定しておく.
ついでに agenda 表示の際の色付けを設定.
(leaf org-gcal
:if (and my:d:password-store
(and (file-directory-p my:d:org)
(executable-find "curl")))
:ensure t
;; :el-get (org-gcal
;; :type github
;; :pkgname "kidd/org-gcal.el")
:commands (org-gcal-fetch
org-gcal-sync
org-gcal-post-at-point
org-gcal-reload-client-id-secret)
;; :advice ((:before org-gcal-sync
;; org-gcal-reload-client-id-secret)
;; (:before org-gcal-fetch
;; org-gcal-reload-client-id-secret)
;; (:before org-gcal-post-at-point
;; org-gcal-reload-client-id-secret))
:preface
(setq org-gcal-dir (expand-file-name "org-gcal" my:d:tmp))
(unless (file-directory-p org-gcal-dir)
(make-directory org-gcal-dir))
;; (setq oauth2-auto-plstore (expand-file-name "oauth2-auto.plist" my:d:tmp))
;; (setq oauth2-auto-plstore (expand-file-name "oauth2-auto.plist" my:d:password-store))
:init
(leaf oauth2-auto
:custom
`(oauth2-auto-plstore . ,(expand-file-name "/run/user/1000/psd/uwabami-emacs-cache/oauth2-auto.plist"))
)
(leaf aio :ensure t)
(leaf alert :ensure t)
(leaf dash :ensure t)
;; (leaf oauth2-auto
;; ;; :el-get rhaps0dy/emacs-oauth2-auto
;; :el-get telotortium/emacs-oauth2-auto
;; :custom
;; `(oauth2-auto-plstore . ,(expand-file-name "oauth2-auto.plist" my:d:tmp))
;; )
;;
(leaf org-generic-id
:custom
`((org-generic-id-locations-file
. ,(expand-file-name "org-generic-id-locations" my:d:tmp))
)
)
(leaf request-deferred :ensure t)
(leaf request
:ensure t
:preface
(setq request-storage-directory (expand-file-name "request" my:d:tmp))
(unless (file-directory-p request-storage-directory)
(make-directory request-storage-directory))
:custom
`((request-storage-directory . ,(expand-file-name "request" my:d:tmp))
;; (request-backend . 'url-retrieve)
)
)
(leaf persist
:ensure t
:config
(setq persist--directory-location (expand-file-name "persist" my:d:tmp)))
:custom
`((org-gcal-dir
. ,(expand-file-name "org-gcal" my:d:tmp))
(org-gcal-token-file
. ,(expand-file-name "org-gcal/org-gcal-token" my:d:tmp))
(org-gcal-down-days . 180) ;; 未来 180 日
(org-gcal-up-days . 30) ;; 過去 30 日
(org-gcal-auto-archive . t)
(org-gcal-notify-p . nil)
(org-gcal-remove-api-cancelled-evetnts . t)
(org-gcal-remove-events-with-cancelled-todo . t)
(org-gcal-remove-api-cancelled-events . t)
(alert-log-messages . t)
(alert-default-style .'libnotify))
:pl-setq
(org-gcal-client-id
org-gcal-client-secret
org-gcal-file-alist)
)
(leaf *orgmine
:if (and my:d:password-store
(file-directory-p my:d:org))
:hook
`(org-mode-hook
. (lambda ()
(if (assoc "om_server" org-keyword-properties)
(orgmine-mode))))
:init
(setq enable-local-variables :safe)
(leaf elmine :ensure t)
;; (add-hook 'org-mode-hook
;; (lambda ()
;; (if (assoc "om_server" org-file-properties) (orgmine-mode))))
(leaf orgmine
:vc (:url "https://github.com/kametoku/orgmine" )
:commands (orgmine-mode)
:init
;; (defun my:orgmine-default-todo-keyword ()
;; "Custom: use `org-file-properties' for backward compatibility."
;; (or (cdr (assoc-string "om_default_todo" org-file-properties))
;; orgmine-default-todo-keyword
;; (nth 0 org-todo-keywords-1)
;; 1))
;; (defun my:orgmine-setup ()
;; "Custom: use `org-file-properties' for backward compatibility."
;; (let* ((server (cdr (assoc-string "om_server" org-file-properties t)))
;; (config (cdr (assoc-string server orgmine-servers t))))
;; (if config
;; (set (make-local-variable 'orgmine-server) server))
;; (mapc (lambda (elem)
;; (let* ((key (car elem))
;; (symbol (intern (format "orgmine-%s" key)))
;; (value (cdr elem)))
;; (if (memq key orgmine-valid-variables)
;; (progn
;; (set (make-local-variable symbol) value)
;; (if (eq key 'custom-fields)
;; (orgmine-setup-custom-fields value)))
;; (message "orgmine-setup: %s: skipped - invalid name" key))))
;; config))
;; (orgmine-setup-tags)
;; (run-hooks 'orgmine-setup-hook))
;; :advice
;; '((:override orgmine-default-todo-keyword my:orgmine-default-todo-keyword)
;; (:override orgmine-setup my:orgmine-setup))
:pl-setq orgmine-servers
:config
(setq orgmine-note-block-begin "#+begin_src gfm" ;; 要調整
orgmine-note-block-end "#+end_src\n")
)
)
(leaf org-wiki
:vc (:url "https://github.com/uwabami/org-wiki")
:if (file-directory-p "~/Public/cc-env")
:custom
`((org-wiki-location-alist . '("~/Public/cc-env"))
(org-wiki-location . "~/Public/cc-env")
(org-wiki-publish-relative . t)
(org-wiki-publish-root . "{{site.url}}/cc-env")
(org-wiki-completing-backend . 'completing-read)
(org-wiki-template
. ,(concat "#+TITLE: %n\n"
"#+date: 20\n"
"#+LAYOUT: default\n"
"#+PREMALINK: /cc-env/%n.html\n"
"#+options: auto-id:nil\n"
"#+REF: cc-env/%n\n"
"Related [[wiki:index][Index]] [[~/Public/cc-env/index.org::#orge0707863][Debian]]\n"
"* %n\n"
)))
)
(leaf ox
:preface
;; 空行の削除
(defun my:remove-org-newlines-at-cjk-text (&optional _mode)
"先頭が '*', '#', '|' でなく、改行の前後が日本の文字の場合は改行を除去"
(interactive)
(goto-char (point-min))
(while (re-search-forward "^\\([^|#*\n].+\\)\\(.\\)\n *\\(.\\)" nil t)
(if (and (> (string-to-char (match-string 2)) #x2000)
(> (string-to-char (match-string 3)) #x2000))
(replace-match "\\1\\2\\3"))
(goto-char (line-beginning-position))))
:hook
;; ((org-export-before-processing-hook . my:remove-org-newlines-at-cjk-text))
:custom
((org-export-backends . '(;; remove somve built-in
;; html
jekyll
latex
beamer))
(org-export-with-toc . nil)
(org-export-with-section-numbers . nil))
)
exporter は uwabami/ox-jekyll にあります.
(leaf ox-html
:after ox
:init
(leaf ox-jekyll
:if (file-directory-p "~/Public/cc-env")
:vc (:url "https://github.com/uwabami/ox-jekyll")
)
(leaf s :ensure t)
:custom
((org-html-table-align-individual-fields . nil)
(org-html-table-default-attributes . nil)
(org-html-html5-fancy . t)
(org-html-doctype . "html5")
;; (org-html-container-element . "div")
(org-html-inline-image-rules
. '(("file" . "\\.\\(jpeg\\|jpg\\|png\\|gif\\|webp\\|svg\\)\\'")
("http" . "\\.\\(jpeg\\|jpg\\|png\\|gif\\|webp\\|svg\\)\\'")
("https" . "\\.\\(jpeg\\|jpg\\|png\\|gif\\|webp\\|svg\\)\\'")))
)
:config
;;
(defun my:org-wiki-jekyll-finalized1 (contents backend info)
"Replace some URL"
(ignore info)
(when (org-export-derived-backend-p backend 'jekyll)
(require 's)
(s-replace
(format "<a href=\"file://%sREADME.html"
(expand-file-name user-emacs-directory))
"<a href=\"{{baseurl}}/cc-env/Emacs.html"
contents)))
;;
(defun my:org-wiki-jekyll-finalized2 (contents backend info)
"Replace some URL"
(ignore info)
(when (org-export-derived-backend-p backend 'jekyll)
(require 's)
(s-replace
(format "<a href=\"file://%s"
(expand-file-name "Public/" (getenv "HOME")))
"<a href=\"{{site.url}}/"
contents)))
;;
(defun my:org-wiki-jekyll-finalized3 (contents backend info)
"Replace some URL"
(ignore info)
(when (org-export-derived-backend-p backend 'jekyll)
(replace-regexp-in-string
" id=\"outline-container-org.+\" class=\"outline-.+\""
"" contents)))
;;
(defun my:org-wiki-jekyll-finalized4 (contents backend info)
"Replace some URL"
(ignore info)
(when (org-export-derived-backend-p backend 'jekyll)
(replace-regexp-in-string
"<a id=\"org.+?\"></a>"
"" contents)))
;;
(defun my:org-wiki-jekyll-finalized5 (contents backend info)
"Replace some URL"
(ignore info)
(when (org-export-derived-backend-p backend 'jekyll)
(replace-regexp-in-string
"<pre class=\"example\" id=\".+?\">"
"<pre class=\"example\">" contents)))
;;
(defun my:org-wiki-jekyll-finalized6 (contents backend info)
"Replace some URL"
(ignore info)
(when (org-export-derived-backend-p backend 'jekyll)
(replace-regexp-in-string
"<figure id=\".+?\">"
"<figure>" contents)))
;;
(add-to-list 'org-export-filter-body-functions
'my:org-wiki-jekyll-finalized1)
(add-to-list 'org-export-filter-body-functions
'my:org-wiki-jekyll-finalized2)
(add-to-list 'org-export-filter-body-functions
'my:org-wiki-jekyll-finalized3)
(add-to-list 'org-export-filter-body-functions
'my:org-wiki-jekyll-finalized4)
(add-to-list 'org-export-filter-body-functions
'my:org-wiki-jekyll-finalized5)
(add-to-list 'org-export-filter-body-functions
'my:org-wiki-jekyll-finalized6)
)
(leaf ox-latex
:after ox
:init
(leaf oc-natbib :after ox :require t)
:custom
`((org-latex-default-class . "my:uplatex")
(org-latex-pdf-process . '("latexmk -r ~/.latexmkrc -pdfdvi -recorder -output-directory='%o' %f"))
(org-latex-compiler . "latexmk")
(org-latex-listings . 'minted)
(org-format-latex-header . "\\documentclass[dvipdfmx]{standalone}
\\usepackage[usenames]{color}
\\usepackage{pgfplots}
\\usepgfplotslibrary{fillbetween,patchplots}
\\pgfplotsset{compat=newest}
\\usepackage{tikz}
\\usetikzlibrary{intersections,calc,arrows,arrows.meta,decorations.markings,fadings,decorations.pathreplacing,patterns}
\\definecolor{cud_blue}{HTML}{005aff}
\\definecolor{cud_green}{HTML}{03af7a}
\\definecolor{cud_orange}{HTML}{f6aa00}
\\definecolor{cud_red}{HTML}{ff4b00}
\\definecolor{cud_yellow}{HTML}{fff100}
\\definecolor{cud_cyan}{HTML}{4dc4ff}
\\definecolor{cud_pink}{HTML}{ff8082}
\\definecolor{cud_purple}{HTML}{990099}
\\definecolor{cud_brown}{HTML}{804000}
\\definecolor{cud_lightgrey}{HTML}{c8c8cb}
\\definecolor{cud_grey}{HTML}{84919e}
\\definecolor{blackblue}{HTML}{2C3E50}
\\def\\pgfsysdriver{pgfsys-dvipdfmx.def}
\[PACKAGES]
\[DEFAULT-PACKAGES]")
(org-latex-minted-options
. '(("frame" "lines")
("framesep=2mm")
("linenos=true")
("baselinestretch=1.2")
("breaklines")
))
;; (org-latex-default-table-environment . "tabularx")
(org-latex-default-packages-alist
. '(("utf8" "inputenc" t nil)
;; ("prefernoncjk" "pxcjkcat" t nil)
("T1" "fontenc" t nil)
("" "graphicx" t nil)
("normalem" "ulem" t nil) ;; udline に変更すべきかな?
("" "amsmath" t nil)
("" "amssymb" t nil)
("" "physics" t nil)
;; ("" "siunitx" t nil)
("" "hyperref" t nil)
("" "multirow" t nil)
("" "ltablex" t nil)
("" "wrapfig" t nil)
("" "silence" t nil)
("" "arydshln" t nil)
))
(org-latex-hyperref-template
.
"\\hypersetup{
pdfauthor={%a},
pdftitle={%t},
pdfkeywords={%k},
pdfsubject={%s},
pdfcreator={%c},
pdflang={%l}}
")
(org-latex-classes
. '(("my:uplatex"
"\\RequirePackage{plautopatch}\n\\documentclass[a4paper,uplatex,dvipdfmx]{jsarticle}\n\\plautopatchdisable{eso-pic}\n\\ifdefined\\endofdump\\else\\let\\endofdump\\relax\\fi
[DEFAULT-PACKAGES] [NO-PACKAGES] [EXTRA]"
("\\section\{%s\}" . "\\section*\{%s\}")
("\\subsection\{%s\}" . "\\subsection*\{%s\}")
("\\subsubsection\{%s\}" . "\\subsubsection*\{%s\}"))
("my:beamer"
"\\RequirePackage{plautopatch}\n\\documentclass[dvipdfmx,c,presentation]{beamer}\n\\plautopatchdisable{eso-pic}\n\\ifdefined\\endofdump\\else\\let\\endofdump\\relax\\fi
[DEFAULT-PACKAGES] [NO-PACKAGES] [EXTRA]"
("\\section\{%s\}" . "\\section*\{%s\}")
("\\subsection\{%s\}" . "\\subsection*\{%s\}")
("\\subsubsection\{%s\}" . "\\subsubsection*\{%s\}"))
("my:beamer169"
"\\RequirePackage{plautopatch}\n\\documentclass[dvipdfmx,c,presentation,aspectratio=169]{beamer}\n\\plautopatchdisable{eso-pic}\n\\ifdefined\\endofdump\\else\\let\\endofdump\\relax\\fi
[DEFAULT-PACKAGES] [NO-PACKAGES] [EXTRA]"
("\\section\{%s\}" . "\\section*\{%s\}")
("\\subsection\{%s\}" . "\\subsection*\{%s\}")
("\\subsubsection\{%s\}" . "\\subsubsection*\{%s\}"))
)
)
)
)
Beamer 関連: SHORT
系を追加している
(leaf ox-beamer
:after ox-latex
:init
(add-to-list 'org-export-options-alist
'(:shortdate "SHORT_DATE" nil nil))
(add-to-list 'org-export-options-alist
'(:shorttitle "SHORT_TITLE" nil nil))
(add-to-list 'org-export-options-alist
'(:shortauthor "SHORT_AUTHOR" nil nil))
(add-to-list 'org-export-options-alist
'(:institute "INSTITUTE" nil nil))
(add-to-list 'org-export-options-alist
'(:shortinstitute "SHORT_INSTITUTE" nil nil))
(add-to-list 'org-export-options-alist
'(:outlinetitle "OUTLINE_TITLE" nil nil))
;; customize
(defun my:org-beamer-template (contents info)
"Custom: support shortdate, shorttile, shortauthor, institute for beamer export"
(let ((title (org-export-data (plist-get info :title) info))
(subtitle (org-export-data (plist-get info :subtitle) info)))
(concat
;; Time-stamp.
(and (plist-get info :time-stamp-file)
(format-time-string "%% Created %Y-%m-%d %a %H:%M\n"))
;; LaTeX compiler
(org-latex--insert-compiler info)
;; Document class and packages.
(org-latex-make-preamble info)
;; Insert themes.
(let ((format-theme
(lambda (prop command)
(let ((theme (plist-get info prop)))
(when theme
(concat command
(if (not (string-match "\\[.*\\]" theme))
(format "{%s}\n" theme)
(format "%s{%s}\n"
(match-string 0 theme)
(org-trim
(replace-match "" nil nil theme))))))))))
(mapconcat (lambda (args) (apply format-theme args))
'((:beamer-theme "\\usetheme")
(:beamer-color-theme "\\usecolortheme")
(:beamer-font-theme "\\usefonttheme")
(:beamer-inner-theme "\\useinnertheme")
(:beamer-outer-theme "\\useoutertheme"))
""))
;; Possibly limit depth for headline numbering.
(let ((sec-num (plist-get info :section-numbers)))
(when (integerp sec-num)
(format "\\setcounter{secnumdepth}{%d}\n" sec-num)))
;; custom: Author support `shortauthor'
(let ((author (and (plist-get info :with-author)
(let ((auth (plist-get info :author)))
(and auth (org-export-data auth info)))))
(shortauthor (plist-get info :shortauthor))
(email (and (plist-get info :with-email)
(org-export-data (plist-get info :email) info))))
(cond ((and author shortauthor) (format "\\author[%s]{%s}\n" shortauthor author))
((and author shortauthor email (not (string= "" email)))
(format "\\author[%s]{%s\\thanks{%s}}\n" shortauthor author email))
((and author email (not (string= "" email)))
(format "\\author{%s\\thanks{%s}}\n" author email))
((or author email) (format "\\author{%s}\n" (or author email)))))
;; custom: Date support `shortdate'
(let ((date (and (plist-get info :with-date) (org-export-get-date info)))
(shortdate (plist-get info :shortdate)))
(cond ((and date shortdate)
(format "\\date[%s]{%s}\n" shortdate (org-export-data date info)))
(t (format "\\date{%s}\n" (org-export-data date info)))))
;; custom: Title support `shorttitle'
(let ((shorttitle (plist-get info :shorttitle)))
(cond ((and title shorttitle) (format "\\title[%s]{%s}\n" shorttitle title))
(t (format "\\title{%s}\n" title))))
;; custom: support `institute', `shortinstitute'
(let ((institute (plist-get info :institute))
(shortinstitute (plist-get info :shortinstitute)))
(cond ((and institute shortinstitute)
(format "\\institute[%s]{%s}\n" shortinstitute institute))
((or institute shortinstitute)
(format "\\institute{%s}\n" (or shortinstitute institute)))))
(when (org-string-nw-p subtitle)
(concat (format (plist-get info :beamer-subtitle-format) subtitle) "\n"))
;; Beamer-header
(let ((beamer-header (plist-get info :beamer-header)))
(when beamer-header
(format "%s\n" (plist-get info :beamer-header))))
;; 9. Hyperref options.
(let ((template (plist-get info :latex-hyperref-template)))
(and (stringp template)
(format-spec template (org-latex--format-spec info))))
;; Document start.
"\\begin{document}\n\n"
;; Title command.
(org-element-normalize-string
(cond ((not (plist-get info :with-title)) nil)
((string= "" title) nil)
((not (stringp org-latex-title-command)) nil)
((string-match "\\(?:[^%]\\|^\\)%s"
org-latex-title-command)
(format org-latex-title-command title))
(t org-latex-title-command)))
;; Table of contents.
(let ((depth (plist-get info :with-toc)))
(when depth
(concat
(format "\\begin{frame}%s{%s}\n"
(org-beamer--normalize-argument
(plist-get info :beamer-outline-frame-options) 'option)
(cond ((plist-get info :outlinetitle)
(plist-get info :outlinetitle))
(t
(plist-get info :beamer-outline-frame-title)))
)
(when (wholenump depth)
(format "\\setcounter{tocdepth}{%d}\n" depth))
"\\tableofcontents\n"
"\\end{frame}\n\n")))
;; Document's body.
contents
;; Creator.
(if (plist-get info :with-creator)
(concat (plist-get info :creator) "\n")
"")
;; Document end.
"\\end{document}")))
;;
:advice ((:override org-beamer-template
my:org-beamer-template))
:custom
`((org-beamer-frame-level . 2)
(org-beamer-frame-default-options . "fragile")
)
)
(leaf ox-publish
:if (file-directory-p "~/Public/cc-env")
:after (ox-jekyll org-wiki)
:commands my:org-wiki-publish
:custom
`((org-publish-timestamp-directory
. ,(expand-file-name "org-timestamps/" my:d:tmp)))
:config
(defun my:org-wiki-publish ()
(interactive)
(org-publish (org-wiki-make-org-publish-plist
'org-jekyll-publish-to-html)
t))
)
(leaf tdiary-mode
:if (and my:d:password-store
(file-directory-p (concat (getenv "HOME") "/Nextcloud/tdiary")))
:commands (tdiary-mode tdiary-replace tdiary-append)
:vc (:url "https://github.com/uwabami/tdiary-mode")
:defvar tdiary-passwd-file
:pl-setq
(tdiary-csrf-key tdiary-passwd-file)
:config
(setq tdiary-text-directory (concat (getenv "HOME") "/Nextcloud/tdiary/")
tdiary-diary-list '(("log" "https://uwabami.junkhub.org/log/"))
tdiary-style-mode 'org-mode
tdiary-text-suffix ".org"
tdiary-http-timeout 100
)
(tdiary-passwd-file-load)
)
- [ ] org2blog で tDiary を更新できないか妄想している
(leaf project
:ensure t
:custom
`((project-list-file . ,(expand-file-name "projects" my:d:tmp))
(project-switch-use-entire-map . t)
)
)
- [ ] ghq の list を追加できないかな?
できれば
--full-path
じゃない表示にしたい(my:shorten-file-path を噛ませたい).
project.el
で ghq を使うようになったら不要かもしれないけど, とりあえず.
(leaf consult-ghq
:vc (:url "https://github.com/uwabami/consult-ghq")
:bind (("C-x f" . consult-ghq-open))
:custom
`((consult-ghq-short-list . t))
)
(leaf magit
:bind (("C-x g" . magit-status))
:ensure t
:init
(leaf transient
:custom
`((transient-history-file
. ,(expand-file-name "transient-history.el" my:d:tmp))
(transient-levels-file
. ,(expand-file-name "transient-levels.el" my:d:tmp))
(transient-values-file
. ,(expand-file-name "transient-values.el" my:d:tmp))
(transient-force-fixed-pitch . t))
)
:custom
`((magit-completing-read-function . 'magit-builtin-completing-read)
(magit-refs-show-commit-count . 'all)
(magit-log-buffer-file-locked . t)
(magit-revision-show-gravatars . nil)
)
)
- japanese-latex-mode において, 幾つかのコマンドが追加/上書きされているものの, あまり使うことの無いコマンドが表示されるのが嫌なのでそれらを削除.
- コンパイルにはLatexmkを使う
と言った所.
…ただ, Beamerのクラスなんかだと勝手にdefault コマンドが LaTeX に変更されたりするので挙動がイマイチ良くわからん.
async で latexmk -pvc
を走らせておいた方が気持が良い, 気がしている….
(leaf auctex
:disabled t
:if (and (executable-find "uplatex")
(executable-find "latexmk"))
:load-path "/usr/share/emacs/site-lisp/auctex"
:init
(unless (file-directory-p (expand-file-name "auctex/auto" my:d:tmp))
(progn
(make-directory (expand-file-name "auctex/auto" my:d:tmp) t)
(make-directory (expand-file-name "auctex/style" my:d:tmp) t)))
(leaf reftex
:custom ((reftex-plug-into-AUCTeX . t)
(reftex-cite-prompt-optional-args . t)
(reftex-toc-split-windows-horizontally . t)
)
)
(leaf auctex-latexmk
:vc (:url "https://github.com/tom-tan/auctex-latexmk")
:custom
`((auctex-latexmk-inherit-TeX-PDF-mode . t))
:config
(setq TeX-command-output-list '(("LaTeXMk" ("pdf")))
TeX-command-default "LaTexMk"
japanese-LaTeX-command-default "LaTeX")
)
(load "auctex" t t)
(load "preview-latex" t t)
:hook
`((LaTeX-mode-hook
. ,(lambda ()
(turn-on-reftex)
(auctex-latexmk-setup)
(setq-default TeX-command-default "LaTexMk"
japanese-LaTeX-command-default "LaTeX")
(TeX-PDF-mode)
(TeX-source-correlate-mode)
(LaTeX-math-mode)
(outline-minor-mode)))
)
:custom
`((TeX-auto-local
. ,(expand-file-name "auctex/auto" my:d:tmp))
(TeX-style-local
. ,(expand-file-name "auctex/style" my:d:tmp))
(TeX-default-mode . 'japanese-latex-mode) ;; 🤔
(japanese-TeX-engine-default . 'uptex)
(japanese-LaTeX-default-style . "jlreq") ;; jsarticle? bxjsarticle?
(TeX-engine . 'uptex)
(TeX-PDF-from-DVI . "Dvipdfmx")
(TeX-view-program-selection . '((output-dvi "xdvi")
(output-pdf "Okular")
;; (output-pdf "Evince")
(output-html "xdg-open")))
(LaTeX-figure-label . "fig:")
(LaTeX-table-label . "tab:")
(LaTeX-section-label . "sec:")
(TeX-command-default . "LaTexMk")
(TeX-ispell-extend-skip-list . t)
(TeX-parse-self . t)
(TeX-auto-save . t)
(TeX-auto-untabify . t)
(TeX-source-correlate-mode . t)
(TeX-source-correlate-start-server . t)
(TeX-source-correlate-method . 'synctex)
(font-latex-fontify-script . nil)
(font-latex-script-display . nil)
(font-latex-fontify-sectioning . 1.0)
)
)
(leaf lua-mode :ensure t)
(leaf ssh-config-mode :ensure t)
(leaf fish-mode :ensure t :mode "\\.fish\\'")
(leaf rd-mode
:mode "\\.rd\\'"
:hook
(rd-mode-hook . rd-show-other-block-all))
(leaf scss-mode
:ensure t
:init
(leaf css-mode :custom (css-indent-offset . 2))
:mode "\\.sass\\'" "\\.scss\\'")
(leaf generic-x)
(leaf systemd :ensure t)
;; (leaf *misc-mode
;; :init
;; (leaf systemd :ensure t)
;; (leaf debian-el
;; :custom
;; `((debian-bug-download-directory . "~/Downloads"))
;; )
(leaf yaml-mode :ensure t :mode "\\.yml\\'" "\\.yaml\\'")
;; (leaf textile-mode :ensure t)
;; (leaf dpkg-dev-el)
;; (leaf sh-mode
;; :custom ((system-uses-terminfo . nil))
;; )
;; (leaf apt-sources-list
;; :custom
;; ((apt-sources-list-suites
;; . '("stable" "stable-backports"
;; "testing" "testing-backports"
;; "unstable" "experimental"
;; "jessie" "jessie-backports"
;; "stretch" "stretch-backports"
;; "buster" "buster-backports"
;; "bullseye" "bullseye-backports"
;; "sid")))
;; )
;; (leaf info-colors
;; :ensure t
;; :hook
;; (Info-selection #'info-colors-fontify-node))
;; )
;;;###autoload
(defun my:load-window-config ()
"load window-system specific settings"
(interactive)
(progn
(set-frame-parameter nil 'alpha 90)
(set-face-attribute 'default nil
:family "FSMRMP"
:height 95)
(set-face-attribute 'fixed-pitch nil
:family "FSMRMP"
:height 95)
(set-face-attribute 'variable-pitch nil
:family "FSMRMP"
:height 95)
;; Japanese
(set-fontset-font nil
'japanese-jisx0213.2004-1
(font-spec :family "FSMRMP" :height 95))
(set-fontset-font nil
'japanese-jisx0213-2
(font-spec :family "FSMRMP" :height 95))
(set-fontset-font nil
'katakana-jisx0201
(font-spec :family "FSMRMP" :height 95))
;; Latin with pronounciation annotations
(set-fontset-font nil
'(#x0080 . #x024F)
(font-spec :family "FSMRMP" :height 95))
;; Math symbols
(set-fontset-font nil
'(#x950 . #x22FF)
(font-spec :family "FSMRMP" :height 95))
;; Greek
(set-fontset-font nil
'(#x0370 . #x03FF)
(font-spec :family "FSMRMP" :height 95))
;; Some Icons
(set-fontset-font nil
'(#xE0A0 . #xEEE0)
(font-spec :family "FSMRMP" :height 95))
))
;;;###autoload
(defun my:load-side-window-config ()
"load window-system specific settings"
(interactive)
(progn
(set-face-attribute 'default nil
:family "FSMRMP"
:height 135)
(set-face-attribute 'fixed-pitch nil
:family "FSMRMP"
:height 135)
(set-face-attribute 'variable-pitch nil
:family "FSMRMP"
:height 135)
;; Japanese
(set-fontset-font nil
'japanese-jisx0213.2004-1
(font-spec :family "FSMRMP" :height 135))
(set-fontset-font nil
'japanese-jisx0213-2
(font-spec :family "FSMRMP" :height 135))
(set-fontset-font nil
'katakana-jisx0201
(font-spec :family "FSMRMP" :height 135))
;; Latin with pronounciation annotations
(set-fontset-font nil
'(#x0080 . #x024F)
(font-spec :family "FSMRMP" :height 135))
;; Math symbols
(set-fontset-font nil
'(#x2200 . #x22FF)
(font-spec :family "FSMRMP" :height 135))
;; Greek
(set-fontset-font nil
'(#x0370 . #x03FF)
(font-spec :family "FSMRMP" :height 135))
;; Some Icons
(set-fontset-font nil
'(#xE0A0 . #xEEE0)
(font-spec :family "FSMRMP" :height 135))
))
(leaf *gui
:if window-system
:config
;; (set-frame-parameter nil 'alpha 90)
(setq use-default-font-for-symbols nil)
(scroll-bar-mode -1)
;; (my:load-window-config)
)
- [ ] FSMRMP のギリシャ文字が全角にならない. 要調整
幅の確認: 絵文字は全角, 他は半角で 2:1 になっているかの確認用. GUI だと駄目だなぁ…. |abcdefghijkl| |ABCDEFGHIJKL| |'";:-+=/\~`?| |∞≤≥∏∑∫| |×±≒≡⊆⊇| |αβγδεζ| |ηθικλμ| |ΑΒΓΔΕΖ| |ΗΘΙΚΛΜ| |日本語の美観| |あいうえおか| |アイウエオカ| |アイウエオカキクケコサシ| | hoge | hogeghoe | age | |----------------------+----------+------------------| | 今日もいい天気ですね | お、 | 等幅になった👍 🍺| |----------------------+----------+------------------|デフォルトの font-lock を(好みに合わせて)入れ替えたり.
(leaf modus-themes
:ensure t
:bind ("<f5>" . modus-themes-toggle)
:commands modus-themes-load-theme
:preface
(defun my:override-face-attribute()
"CUSTOM: Override face attribute"
(modus-themes-with-colors
(custom-set-faces
`(font-lock-comment-delimiter-face ((,c :inherit font-lock-comment-face :bold t)))
`(wl-highlight-folder-closed-face ((,c :foreground ,green-cooler )))
`(wl-highlight-folder-few-face ((,c :foreground ,red-cooler )))
`(wl-highlight-folder-killed-face ((,c :foreground ,fg-alt )))
`(wl-highlight-folder-many-face ((,c :foreground ,magenta )))
`(wl-highlight-folder-opened-face ((,c :foreground ,cyan-cooler )))
`(wl-highlight-folder-unknown-face ((,c :foreground ,cyan-warmer )))
`(wl-highlight-folder-unread-face ((,c :foreground ,blue-warmer )))
`(wl-highlight-folder-zero-face ((,c :foreground ,fg-main )))
`(wl-highlight-message-citation-header ((,c :foreground ,green-warmer )))
`(wl-highlight-message-cited-text-1 ((,c :foreground ,green-intense )))
`(wl-highlight-message-cited-text-2 ((,c :foreground ,yellow-intense )))
`(wl-highlight-message-cited-text-3 ((,c :foreground ,blue-intense )))
`(wl-highlight-message-cited-text-4 ((,c :foreground ,cyan-intense )))
`(wl-highlight-message-cited-text-5 ((,c :foreground ,magenta-cooler )))
`(wl-highlight-message-cited-text-6 ((,c :foreground ,red-intense )))
`(wl-highlight-message-cited-text-7 ((,c :foreground ,green-intense )))
`(wl-highlight-message-cited-text-8 ((,c :foreground ,yellow-intense )))
`(wl-highlight-message-cited-text-9 ((,c :foreground ,blue-intense )))
`(wl-highlight-message-cited-text-10 ((,c :foreground ,cyan-intense )))
`(wl-highlight-message-header-contents ((,c :foreground ,magenta-cooler )))
`(wl-highlight-message-headers ((,c :foreground ,cyan-intense )))
`(wl-highlight-message-important-header-contents ((,c :foreground ,magenta-intense )))
`(wl-highlight-message-important-header-contents2 ((,c :foreground ,magenta-intense )))
`(wl-highlight-message-signature ((,c :foreground ,fg-dim )))
`(wl-highlight-message-unimportant-header-contents ((,c :foreground ,fg-dim )))
`(wl-highlight-summary-answered-face ((,c :foreground ,green-intense )))
`(wl-highlight-summary-deleted-face ((,c :foreground ,blue-intense )))
`(wl-highlight-summary-disposed-face ((,c :foreground ,fg-dim )))
`(wl-highlight-summary-flagged-face ((,c :foreground ,yellow-intense )))
`(wl-highlight-summary-high-unread-face ((,c :foreground ,red-intense )))
`(wl-highlight-summary-low-unread-face ((,c :foreground ,red-intense )))
`(wl-highlight-summary-normal-face ((,c :foreground ,fg-main )))
`(wl-highlight-summary-refiled-face ((,c :foreground ,blue-warmer )))
`(wl-highlight-summary-spam-face ((,c :foreground ,magenta-intense )))
`(wl-highlight-summary-thread-top-face ((,c :foreground ,fg-main )))
`(wl-highlight-summary-unread-face ((,c :foreground ,fg-main )))
`(wl-highlight-summary-new-face ((,c :foreground ,red-intense )))
`(wl-highlight-summary-displaying-face ((,c :underline t :bold t)))
`(wl-highlight-folder-path-face ((,c :underline t :bold t)))
;;
`(whitespace-trailing ((,c :foreground ,magenta-intense )))
`(whitespace-tab ((,c :foreground ,blue-intense :underline t)))
`(whitespace-space ((,c :foreground ,green-intense :bold t)))
`(whitespace-empty ((,c :background ,red-intense )))
)))
:hook
`((modus-themes-after-load-theme-hook . my:override-face-attribute))
:custom
`(
(modus-themes-custom-auto-reload . t)
(modus-themes-disable-other-themes . t)
(modus-themes-bold-constructs . nil)
(modus-themes-italic-constructs . nil)
(modus-themes-mixed-fonts . nil)
(modus-themes-prompts
. '(bold bold))
(modus-themes-completions
. '((matches . (bold))
(selection . (bold underline))))
(modus-themes-org-blocks . nil)
(modus-themes-headings . '((t . (bold))))
(modus-themes-variable-pitch-ui . nil)
(modus-vivendi-palette-overrides
. '(;;
;;; Basic color override
(green-cooler "#bfff7f")
(green-intense "#4ceea5")
(yellow "#efef00")
(yellow-warmer "#ffb347")
(yellow-intense "#ffff7f")
;;
(bg-yellow-intense "#556b2f")
;;
(bg-main 'unspecified)
(comment fg-dim)
(bg-hl-line bg-yellow-intense)
;;
;;; Code remapping
;;
(builtin blue-warmer)
(constant yellow-warmer)
(docstring green-intense)
(docmarkup green-intense)
(fnname magenta-cooler)
(keyword red-faint)
(preprocessor red-cooler)
(string cyan-cooler)
(type yellow-intense)
(variable blue)
;;
(rx-construct blue-faint)
(rx-backslash green-cooler)
;;
(fg-link cyan-warmer)
;;
(err red-intense)
(warning magenta-intense)
(info cyan-intense)
;;
;; Org Agenda view
;; (date-common fg-alt)
;; (date-deadline red-faint)
;; (date-event fg-alt)
;;
(date-common fg-alt)
(date-weekday fg-main)
;; headline
(fg-heading-0 cyan-intense)
(fg-heading-1 magenta-cooler)
(fg-heading-2 blue-cooler)
(fg-heading-3 yellow-warmer)
(fg-heading-4 green-faint)
(fg-heading-5 yellow-intense)
(fg-heading-6 red-cooler)
(fg-heading-7 magenta-warmer)
(fg-heading-8 fg-main)
))
)
:init
(modus-themes-load-theme 'modus-vivendi)
)
(leaf powerline
:ensure t
:defvar
(skk-indicator-alist
skk-hiragana-mode-string
skk-katakana-mode-string
skk-latin-mode-string
skk-jisx0208-latin-mode-string
skk-jisx0201-mode-string
skk-abbrev-mode-string
)
:init
;; (defun my:major-mode-icon (mode)
;; "Update file icon in mode-line, just display major-mode icon. not filename."
;; (let* ((icon (all-the-icons-icon-for-mode mode)))
;; (if (symbolp icon)
;; (all-the-icons-faicon "file-code-o"
;; :face 'all-the-icons-dsilver
;; :height 1.0)
;; icon)))
;;
(defun my:skk-init-modeline-input-mode ()
"Custom skkが読み込まれていなくても skk-modeline-input-mode に値を設定"
(cond
((not (boundp 'skk-modeline-input-mode))
(setq skk-modeline-input-mode "--SKK"))
(t skk-modeline-input-mode)))
;;
(defun my:skk-modeline-input-mode ()
"Custom: powerline 用に skk の indicator を準備"
(cond
((string-match "--SKK" skk-modeline-input-mode) "[--]")
((string-match skk-hiragana-mode-string skk-modeline-input-mode) "[あ]")
((string-match skk-katakana-mode-string skk-modeline-input-mode) "[ア]")
((string-match skk-latin-mode-string skk-modeline-input-mode) "[_A]")
((string-match skk-jisx0208-latin-mode-string skk-modeline-input-mode) "[A]")
((string-match skk-jisx0201-mode-string skk-modeline-input-mode) "[_ア]")
((string-match skk-abbrev-mode-string skk-modeline-input-mode) "[aA]")
(t "[--]")
)
)
;;
(defun my:skk-setup-modeline ()
"skk-setup-modeline による modeline の更新を無効化"
(setq skk-indicator-alist (skk-make-indicator-alist))
(force-mode-line-update t))
;;
:advice (:override skk-setup-modeline my:skk-setup-modeline)
:custom
`((powerline-buffer-size-suffix . nil)
(powerline-display-hud . nil)
(powerline-display-buffer-size . nil)
(powerline-text-scale-factor . 1)
(powerline-default-separator . 'utf-8)
(powerline-utf-8-separator-left . #xe0b0)
(powerline-utf-8-separator-right . #xe0b2)
)
:hook (emacs-startup-hook . my:powerline-theme)
:config
;;;###autoload
(defun my:powerline-theme ()
"Setup the default mode-line."
(interactive)
(my:skk-init-modeline-input-mode)
(setq-default
mode-line-format
'("%e"
(:eval
(let* ((active (powerline-selected-window-active))
(mode-line-buffer-id (if active 'mode-line-buffer-id 'mode-line-buffer-id-inactive))
(mode-line (if active 'mode-line 'mode-line-inactive))
(face0 (if active 'powerline-active0 'powerline-inactive0))
(face1 (if active 'powerline-active1 'powerline-inactive1))
(face2 (if active 'powerline-active2 'powerline-inactive2))
(separator-left (intern (format "powerline-%s-%s"
(powerline-current-separator)
(car powerline-default-separator-dir))))
(separator-right (intern (format "powerline-%s-%s"
(powerline-current-separator)
(cdr powerline-default-separator-dir))))
(lhs (list (powerline-raw (format "%s" (my:skk-modeline-input-mode)) mode-line 'l)
(powerline-raw "%*" mode-line 'l)
(powerline-raw mode-line-mule-info mode-line 'l)
;; (powerline-raw (my:major-mode-icon major-mode) mode-line 'l)
(powerline-buffer-id mode-line-buffer-id 'l)
(powerline-raw " ")
;; (funcall separator-left face0 face1)
))
(rhs (list (powerline-raw global-mode-string face1 'r)
;; (funcall separator-right face2 face1)
(powerline-vc face1 'r)
(powerline-raw mode-line-misc-info 'r)
(powerline-raw " ")
(powerline-raw "%6p" mode-line 'r)
)))
(concat (powerline-render lhs)
(powerline-fill face2 (powerline-width rhs))
(powerline-render rhs))))))
)
;; (my:powerline-theme)
)
(defun my:debug-on-quit-if-scratch (&rest _args)
(setq debug-on-quit (string= (buffer-name) "*scratch*")))
(add-hook 'window-selection-change-functions 'my:debug-on-quit-if-scratch)
(leaf which-key
:ensure t
:custom
`((which-key-show-early-on-C-h . t)
(which-key-idle-delay . 10000)
(which-key-idle-secondary-delay . 0.05)
(which-key-popup-type . 'minibuffer)
)
:hook (emacs-startup-hook . which-key-mode)
)
;; (leaf tree-sitter :ensure t)
;; (leaf tree-sitter-langs :ensure t)
(leaf rg
:if (executable-find "rg")
:ensure t
)
;;
;; (leaf mozc-temp
;; :init
;; (leaf mozc
;; :config
;; (setq default-input-method "japanese-mozc"))
;; :bind* ("C-j" . mozc-temp-convert)
;; :require t
;; )
;; (global-set-key (kbd "C-j") #'mozc-temp-convert)
;;(leaf emacs
;; :preface
;; (defun my-advice/window-width (fn &rest args)
;; (- (apply fn args) 1))
;; :advice (:around window-width my-advice/window-width))
;;
;; (leaf elfeed
;; :if (file-directory-p my:d:password-store)
;; :ensure t
;; :custom
;; `((elfeed-set-timeout . 36000)
;; (elfeed-db-directory . "~/.cache/elfeed"))
;; :config
;; (leaf elfeed-goodies
;; :ensure t
;; :config
;; (elfeed-goodies/setup))
;; ;;
;; (leaf elfeed-protocol
;; :ensure t
;; :config
;; (setq elfeed-feeds
;; '(("owncloud+https://[email protected]/nextcloud"
;; :password (password-store-get "Web/uwabami.junkhub.org/nextcloud")
;; )
;; ))
;; (elfeed-protocol-enable)
;; )
;; )
;;
(leaf vterm
:ensure t
:custom
`((vterm-always-compile-module . t))
:hook
(vterm-mode-hook
. (lambda () (setq-local global-hl-line-mode nil)))
)
(leaf nginx-mode :ensure t)
(leaf apache-mode :ensure t)
(leaf keg :ensure t)
(leaf keg-mode :ensure t)
(leaf esup
:ensure t
:custom
((esup-insignificant-time . 0.01)
(esup-depth . 0)) ;; 🤔
)
(leaf *show-startup-time
:hook
(emacs-startup-hook
. (lambda ()
(message "init time: %.3f sec"
(float-time (time-subtract after-init-time before-init-time)))))
)
(setq debug-on-error nil)
;; (profiler-report)
;; (profiler-stop)
(provide 'init)
;; Local Variables:
;; byte-compile-warnings: (not cl-functions free-vars docstrings unresolved)
;; End:
;; Local Variables:
;; byte-compile-warnings: (not cl-functions free-vars docstrings unresolved)
;; End:
Copyright (C) 2011--2017 Youhei SASAKI <[email protected]> . This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. . This package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. . You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.