動機
Emacsのカスタマイズをした。Blogを書くときは自作のEditorモードを用いて いる。これは書いた内容を特定のディレクトリに配置してGitに登録するツー ルだ。使ってくと2つのパターンでファイルを作成したくなることに気づいた。 今回はそれぞれのパターンに対応できるようにEmacsをカスタマイズした。
2つのパターン
ファイルスタイル
今までのスタイルでXXXX.orgのようにURLとして用いられるファイル名に直接 拡張子がついたものである。これを便宜的にファイルスタイルと呼ぶことにす る。
例えば短文のコメントであったり、複数のファイルを作る必要のないようなシ ンプルな記事の場合に用いられる。
ディレクトリスタイル
これはXXXX/index.orgのようにURLとして用いられる部分がディレクトリ名に なっており、その配下にindex.orgというファイルを作成するものである。こ れを便宜的にディレクトリスタイルと呼ぶことにする。
例えばサンプルコードとして別ファイルを作成したり、画像を配置したりする 場合に用いられる。
2つのパターンに対応する
主にeditor-save-as-kill関数を修正しeditor-file-path-directory-styleの 値で挙動を変更できるようにした。コマンドUIとしてtransientを用いている ので、fでファイルスタイル、dでディレクトリスタイル、sでデフォルトのス タイルとして保存できるように修正した。
全文を載せておく。
(defvar editor-buffer-name "*EDITOR*") (defvar editor-map (make-sparse-keymap)) (defun editor-refresh-export-option-date () "DATEエクスポートオプションの更新" (interactive) (let* ((timestamp (format-time-string "%+FT%T%z")) (pattern (format "s/^\#+DATE:.*$/#+DATE: %s/g" timestamp))) (call-process-region (point-min) (point-max) "sed" t t t "-e" pattern))) (defun editor-create-buffer () (interactive) (let ((buf-name editor-buffer-name)) (with-current-buffer (get-buffer-create buf-name) (if (= 0 (buffer-size)) (progn ;; エクスポートオプションの追加 (save-excursion (goto-char 0) (insert "#+DATE:\n#+TAGS[]: comment\n\n")) (editor-refresh-export-option-date))) (kill-all-local-variables) (use-local-map editor-map) (editor-mode)) (switch-to-buffer buf-name))) (define-derived-mode editor-mode org-mode "Editor mode" nil) (defun editor-make-new-file-path () "エディターモードの保存先ファイルのパス返す。 通常ではファイルスタイルorgファイル (XXXX.org) のパスを返す。 `editor-file-path-directory-style` をNONE NILにするとディレクトリスタ イルのパス(XXXX/index.org)を返す。 " (let ((file-style-path (concat (directory-file-name editor-base-directory) (format "/%s.org" (truncate (float-time)))))) (if editor-file-path-directory-style (concat (directory-file-name (file-name-sans-extension file-style-path)) "/index.org") file-style-path))) (defcustom editor-base-directory "/ng/symdon/pages/posts") (defcustom editor-file-path-directory-style nil) (defcustom editor-new-file-path #'editor-make-new-file-path) (defun editor-save-as-kill () "エディターバッファの内容をファイルに保存してgit commitする" (interactive) (let ((new-file-path (funcall editor-new-file-path))) ;; Create parent directory. (make-directory (file-name-directory new-file-path) t) ;; Copy buffer content (switch-to-buffer (with-current-buffer (find-file-noselect new-file-path) (insert-buffer-substring (get-buffer editor-buffer-name)) (save-buffer) (current-buffer))) ;; Git commit (let ((default-directory (file-name-directory new-file-path))) (shell-command (format "git add %s" new-file-path)) (shell-command (format "git commit -m 'Add comment.' %s" new-file-path)))) (kill-buffer editor-buffer-name)) (defun editor-save-as-kill-file-style () "ファイルスタイルでエディターバッファの内容を保存する" (interactive) (let ((editor-file-path-directory-style nil)) (editor-save-as-kill))) (defun editor-save-as-kill-directory-style () "ディレクトリスタイルでエディターバッファの内容を保存する" (interactive) (let ((editor-file-path-directory-style t)) (editor-save-as-kill))) (transient-define-prefix editor-save-as () "Editor mode save as..." ["Save as" ("f" "Save as file style" editor-save-as-kill-file-style) ("d" "Save as directory style" editor-save-as-kill-directory-style) ("s" "Save as default" editor-save-as-kill) ]) (bind-keys :map editor-mode-map ("C-x C-s" . editor-save-as)) (bind-key* "C-t C-w" 'editor-create-buffer)