エディタは、主に Emacs を使っていて、 メモ作業(TODO、予定を含む)は org-mode(now 9.6) に依存している。
年末なので、その使い方と設定を棚卸ししてみる。 使い始めた頃の設定も残っていたりする。環境は以下。
- Debian GNU/Linux 11 (bullseye)
- emacs 27.1
- org 9.6
隠居老人なので、使い方はシンプルな方だと思う。 仕事がらみが無いし。
私のメモ作業は、基本的にひとつのファイル(memos.org)で行っている。
中身を、アウトラインでテーマ毎に分けてあって、 量が増えたり、完了した項目は、サブファイルを作成したり、 既ファイルのサブツリーへ移動させ、必要なら link を張る。 不要なものは、org-archive でアーカイブディレクトリへ移動。 更に、その後をどうするか、は未定。
TODO、予定を纏めた org-agenda は、 memos.org とサブファイル群を対象に作成させている。
ルールはこれだけ。
この時に重要なのがアイテムの移動手段で、 avy の avy-org-refile-as-child を使っている。
これを知るまでは、 org-refile を使っていて、 outline が整ってないと、気持ち悪い質なので、 refile 後の手間にイライラがあった。
当然だが、例外がある。
-
org-agenda の対象外だが、org-mode を使っているもの。
- hugo 専用ディレクトリ
- dropbox に置いてあるメモファイル。定期的に同期。
- org-journal (1日1ファイル。在宅介護の見守り記録に使っている)
-
org-mode を使ってないメモ。
-
terminal で vim と共通で使っている。
Markdown のファイル。1メモ1ファイル。emacs から deft で扱えるようにしている。 コマンド関連のメモが多いかな。
-
具体的な org-mode の設定は以下。 コピペ主体で作り込んできたものなので、 使ってない機能が含まれたりしするし、 動作を保証するものでもない。
(leaf org :ensure t :require t
:bind (("C-c c" . org-capture)
(org-mode-map
("C-c a" . org-agenda)
("C-c l" . org-store-link)
;; ("C-c c-l" . org-insert-link)
;; ("C-c C-z" . org-add-note) ;; note は使ってない
("<tab>" . org-cycle)
;;
;; timestamp は頻繁に使う。heading しなくても日時が必要な場合がある
("C-c (" . my-insert-todays) ;; 今日の日付挿入
("C-u C-c (" . my-timestamp) ;; 現在の日時挿入
("C-c )" . org-time-stamp-inactive) ;; カレンダーから日付挿入
("C-u C-c C-a" . my-org-toggle-time-stamp-activity) ;; active inactive の toggle
;; リストの toggle が未完だけど、使わなくなってるので、止めてる。
("C-u C-c C-c" . my-org-toggle-list-checkbox) ;; リストに checkbox を付ける。
("C-u C-c C-t" . my-org-toggle-list-timestamp)
;;
("M-;" . org-comment-dwim-2) ;; babel の中で使う
))
:mode ("\\.org\\'" "\\.org$")
;; :init
;; (push '("\\.txt$" . org-mode)
;; auto-mode-alist) ;; txt ファイルをorg-modeで開くようにする。
:custom (
(org-directory . "~/Documents/ownCloud")
;; このディレクトリは、Nextcloud のシンク対象にしてある。
)
:config
(setq org-default-notes-file (concat org-directory "/captured.org")
org-archive-dir (concat org-directory "/archive")
org-archive-location (concat org-archive-dir "/archive-" (format-time-string "%Y%m" (current-time)) ".org_archive::")) ;;月単位でまとめる。
(setq org-log-done 'time ;; DONEにした時、時刻追記
org-startup-folded 'content ;; defaultの折り畳み表示方法
org-startup-truncated nil ;; 右端で折り返すか
org-hide-leading-stars t ;; 見出しの余分な*を消すか nil t
org-list-allow-alphabetical t ;; listに a. を使う。exportに反映してない
org-return-follows-link t ;; return でリンクを追う
org-startup-indented t ;; 見出しをインデント original nil
org-startup-with-inline-images nil ;; inline imageの表示
org-image-actual-width nil ;; original t width of inline image
org-enforce-todo-dependencies t ;; タスク依存関係で、子の全完済、要
)
(require 'org-protocol)
(setq org-link-frame-setup '((gnus . org-gnus-other-frame)
(file . find-file-other-window)))
;; agenda
;; ディレクトリの全ファイルではなく、必要なものだけを対象にする
(setq org-agenda-files `("~/Documents/ownCloud/memos.org"
"~/Documents/ownCloud/khal.org" ;; ほぼ、read only.
"~/Documents/ownCloud/todo.org"
"~/Documents/ownCloud/bike_memo.org"
"~/Documents/ownCloud/pc_memo.org"
"~/Documents/ownCloud/emacs_memo.org"
"~/Documents/ownCloud/private.org"
))
;;
(setq org-agenda-dim-blocked-tasks 'invisible)
(setq org-agenda-include-diary nil) ;; 使ってない
(setq org-agenda-current-time-string "← now")
(setq org-agenda-time-grid '((daily today require-timed)
(500 900 1200 1500 1800 2100 2400)
"...." "--------"))
(setq org-agenda-start-day "-1d")
(setq org-agenda-start-on-weekday nil)
(setq org-agenda-span 'fortnight) ;; 2週間分を表示
;;don't show tasks as scheduled if they are already shown as a deadline
(setq org-agenda-skip-scheduled-if-deadline-is-shown nil)
;;don't give awarning colour to tasks with impending deadlines
;;if they are scheduled to be done
(setq org-agenda-skip-deadline-if-done nil)
(setq org-agenda-skip-scheduled-if-done t)
(setq org-agenda-include-inactive-timestamp nil)
;; (setq org-agenda-skip-deadline-prewarning-if-scheduled 'pre-scheduled)
(setq org-agenda-skip-deadline-prewarning-if-scheduled t)
;; warn me of any deadlines in next 7 days nil, t, pre-scheduled
(setq org-deadline-warning-days 7)
(setq org-agenda-todo-ignore-deadlines 'all)
(setq org-agenda-todo-ignore-scheduled 'all)
(setq org-agenda-window-setup 'reorganize-frame)
;; tag で agenda を絞り込むメニュを追加
(setq org-agenda-custom-commands '(("h" "Home-related tasks"
((agenda)
(tags-todo "pubs")
(tags "pubs"
((org-agenda-sorting-strategy
'(priority-up)))))
((org-agenda-sorting-strategy
'(priority-down))))
("o" "work agenda"
((agenda)
(tags-todo "work")
(tags "work")))))
;; task(todo)
;; todo-keyword は、これでいいかんじ。
(setq org-todo-keywords '((sequence "TODO(t)" "WAIT(w)" "INPROGRESS(p)" "IDLE(i)" "VERIFY(v)" "|" "DONE(d)" "SOMEDAY(s)" "CANCEL(c)")))
;; (setq org-enforce-todo-dependencies t)
(setq org-todo-keyword-faces '(("TODO" :foreground "cyan2" :weight bold)
("INPROGRESS" :foreground "firebrick1" :weight bold)
("DONE" :foreground "dark olive green" :weight bold)
("WAIT" :foreground "orange" :weight bold)
("SOMEDAY" :foreground "indian red" :weight normal)
("CANCEL" :foreground "dark sea green" :weight bold)
("VERIFY" :foreground "OliveDrab1" :weight bold)
("IDLE" :foreground "burlywood" :weight bold)))
;; tags
;; グループ化は便利だが、分類が細かすぎたと反省。もっとラフでいい
(setq org-group-tags nil) ; enable group tags
(setq org-tags-column -60) ; The default value is -77
(setq org-tag-alist '((:startgroup)
("@HOME" . 72) ("@WORK" . 87) ("@EDC" . 101) ("@Duty" . 68) ("@Pubs" . 80)
(:endgroup)
(:startgroup)
("Get" . 71) ("Talk" . 84) ("Listen" . 76) ("Read" . 82)
("Serch" . 83) ("Exert" . 88) ("Care" . 99)
(:endgroup)
("unix" . 117) ("emacs" . 65) ("lang" . 108)
("pcpda" . 99) ("python" . 112)
("tour" . 116) ("gpxs" . 103) ("bikes" . 98)
("others" . 111)))
;; org-refile
;; avy の avy-org-refile-as-child を使うようになった。
;; org-refile より楽だと思う。
(setq org-refile-use-outline-path 'file)
(setq org-refile-use-cache nil)
(setq org-outline-path-complete-in-steps nil)
(setq org-refile-targets '((nil :maxlevel . 3)
("~/Documents/ownCloud/todo.org" :level . 1)
("/home/QNAP/clouds/dropbox_ayageman/org/dropmemo.org" :level . 1)
("~/Documents/ownCloud/bicycle_memo.org" :level . 1)
("~/Documents/ownCloud/pc_memo.org" :level . 1)
("~/Documents/ownCloud/python.org" :level . 1)
("~/Documents/ownCloud/memos.org" :level . 1)
("~/Documents/ownCloud/hugo/blogger_hugo.org" :level . 1)))
(setq org-refile-allow-creating-parent-nodes 'confirm)
;; When the value of this variable is ‘confirm’, new node
;; creation must be confirmed by the user (recommended). When nil,
;; the completion must match an existing entry.
;; org-src
(setq org-src-window-setup 'reorganize-frame)
(setq org-src-tab-acts-natively nil)
(setq org-src-fontify-natively t)
(setq org-src-preserve-indentation nil)
(setq org-edit-src-content-indentation 0) ;; インデントを残す
(setq electric-quote-mode nil)
:defer-config
;; org-table
(leaf org-table :ensure nil
:config
(setq org-table-formula-evaluate-inline nil) ;; Default = t
(leaf org-table-sticky-header :ensure nil :disabled t)
)
;; org-ox
(leaf ox :ensure nil
:config
(setq org-export-with-timestamps nil) ;; heading timestamp
(leaf ox-pandoc :ensure t :require t)
;; pandoc は優秀だと思う。重複するメニューを消したいが、わからないので放置。
(leaf ox-md :ensure nil :require t) ;; markdown
(leaf ox-hugo :ensure t :require t
:config
(setq org-hugo-default-section-directory "posts")
(setq org-hugo-export-with-section-numbers t)
)
(leaf ox-rst :ensure t :disabled t)
)
;; file が大きくなると、すごく遅いので、使わなくなった。
(leaf ox-publish :ensure nil :disabled t
;; 設定は削除
)
;; org-babel
(leaf ob-async :ensure t :require t
:commands (ob-async-org-babel-execute-src-block)
:config
(setq ob-async-no-async-languages-alist '("ipython" "python"))
)
(leaf ob :ensure nil
:defer-config
(setq org-confirm-babel-evaluate t) ;; 実行時に確認する。
;;
;; = blockdiag
(leaf ob-blockdiag :ensure t
:url "https://github.com/corpix/ob-blockdiag.el"
)
;; = mermaid
(leaf ob-mermaid :ensure t
:url "https://github.com/arnm/ob-mermaid"
:mode ("\\.mmd\\'")
:config
(setq ob-mermaid-cli-path "/home/hoge/.yarn/bin/mmdc")
;;(setq ob-mermaid-cli-path "/home/hoge/.yarn/bin/mmdc -p ~/.config/puppeteer-config.json")
;; ob-mermaid.el で対応済み
)
;; = ditta
(setq org-ditaa-jar-path (expand-file-name "/usr/share/ditaa/ditaa.jar"))
;; = plantuml
(leaf ob-plantuml :ensure nil
:custom
(org-plantuml-exec-mode . 'jar)
(org-plantuml-jar-path . "/usr/share/plantuml/plantuml.jar")
)
;; = gnuplot これが無いと動かない。 [2019-08-13]
;; (leaf gnuplot :ensure t)
;;
;;active Babel languages
(org-babel-do-load-languages
'org-babel-load-languages
'((R . t)
(emacs-lisp . t) ;; elisp
(lisp . t) ;; lisp
(awk . t) ;; awk
(shell . t) ;; shell
(python . t) ;; python
(perl . t) ;; perl
(dot . t) ;; graphviz
(gnuplot . t) ;; gnuplot
(blockdiag . t) ;; blockdiag
(css . t) ;; css
(mermaid . t) ;; mermaid
(plantuml . t) ;; plantuml
(sqlite . t) ;; sqlite
))
;;
(add-to-list 'org-src-lang-modes '("dot" . graphviz-dot))
;; (add-to-list 'org-src-lang-modes '("diag" . blockdiag)) ;; 対応してない?
(add-to-list 'org-src-lang-modes '("mermaid" . mermaid))
(add-to-list 'org-src-lang-modes '("plantuml" . plantuml))
(add-to-list 'org-src-lang-modes '("gnuplot" . gnuplot))
)
(leaf org-cliplink :ensure t :require t
:doc "クリップボードがurlのみなら、アクセスして、org-linkにしてくれる。"
:url "https://github.com/rexim/org-cliplink"
:bind (org-mode-map ("C-c M-l" . org-cliplink)))
;; alart by org-mode (使ってない)
(leaf org-wild-notifier :ensure t
:doc "alart by org-mode"
:url "https://github.com/akhramov/org-wild-notifier.el"
:init (setf alert-default-style 'wild)
:config
(org-wild-notifier-mode))
;; id は使ってない
(leaf org-id-cleanup :ensure t)
;; jorunal
(leaf org-journal :ensure t
;; :commands org-journal-new-entry
:bind (
("C-c j" . nil)
("C-c j" . org-journal-new-entry) ;; open today and start new entry
(org-journal-mode-map (("C-c f" . org-journal-next-entry)
("C-c b" . org-journal-previous-entry)))
)
:hook (
(org-journal-mode-hook . (lambda() (setq-local truncate-lines t)))
)
:custom (
(org-journal-file-type . 'weekly)
(org-journal-date-format . "%A, %d %B %Y")
(org-journal-date-prefix . "* ")
(org-journal-time-prefix . "** ")
(org-journal-time-format . "%H:%M ")
;;(org-journal-enable-agenda-integration . t)
;; agenda には含めてない。
)
:config
(customize-set-variable 'org-journal-dir (concat org-directory "/journal/"))
)
;; org-bullet
(leaf org-bullets :ensure t :disabled nil
:url "https://github.com/emacsorphanage/org-bullets"
:custom (org-bullets-bullet-list . '("➽" "◉" "" "" "" "" "" "" "" "" ""))
:commands org-bullets-mode
:init
(add-hook 'org-mode-hook (lambda () (org-bullets-mode 1)))
:require t
)
;; org-capture
(leaf org-capture :ensure nil
:config
(defun org-journal-find-location ()
;; Open today's journal, but specify a non-nil prefix argument in order to
;; inhibit inserting the heading; org-capture will insert the heading.
(org-journal-new-entry t)
;; Position point on the journal's top-level heading so that org-capture
;; will add the new entry as a child entry.
(goto-char (point-min)))
(defun my/generate-md-memo-name ()
(setq my-org-note--name (read-string "Name: "))
(setq my-org-note--date (format-time-string "%Y-%m-%d"))
(setq my-org-note--dtime (format-time-string "%Y-%m-%d %H:%M"))
(expand-file-name (format "%s-%s.md" my-org-note--date my-org-note--name) "~/Documents/ownCloud/_posts"))
(defun my/generate-post-name ()
(setq my-org-note--name (read-string "Name: "))
(setq my-org-note--dtime (format-time-string "%Y%m%d-%H%M"))
(format "%s_%s.md" my-org-note--dtime my-org-note--name))
(defun my/generate-blogger-name-m () ;; post markdown
(setq my-blogger-post--name-m (read-string "Name: "))
(setq my-blogger-post--time (format-time-string "%Y%m%d"))
(expand-file-name (format "%s-%s.mkd" my-blogger-post--time my-blogger-post--name-m) "~/Documents/mup/blogg/content"))
(defun my/generate-blogger-name-r () ;; post restructuredtext
(setq my-blogger-post--name-r (read-string "Name: "))
(setq my-blogger-post--time (format-time-string "%Y%m%d"))
(expand-file-name (format "%s-%s.rst" my-blogger-post--time my-blogger-post--name-r) "~/Documents/mup/blogg/content"))
(defun org-hugo-new-subtree-post-capture-template ()
(let* ((title (read-from-minibuffer "Post Title: " )) ;; Prompt to enter the post title
(hugo-post-time (format-time-string "%Y-%m-%d" ))
(fname (org-hugo-slug title)))
(mapconcat #'identity
`(
,(concat "* TODO " title " \t:@Cars:")
":PROPERTIES:"
,(concat ":EXPORT_FILE_NAME: " hugo-post-time "-" fname)
":EXPORT_HUGO_CUSTOM_FRONT_MATTER: :description \"summary\""
":EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :toc true"
":END:"
"%?\n") ;; Place the cursor here finally
"\n")
)
)
;; org capture templates
(setq org-capture-templates '(
("t" "TODO(sch/nosch)")
("tt" "Todo(no)" entry
(file+headline "~/Documents/ownCloud/memos.org" "Task")
"* TODO %?\n %i\n %a\nEntered on %U\n")
("ts" "Todo(sch)" entry
(file+headline "~/Documents/ownCloud/memos.org" "Task(scheduled)")
"* TODO %?\n %i\nSCHEDULED: <%<%Y-%m-%d %a %H:%M>>\nEntered on %U\n" :empty-lines 1)
("td" "Todo(dropbox)" entry
(file+headline "/home/QNAP/clouds/dropbox/org/dropmemo.org" "todo_dropbox")
"* TODO %?\n %i\nSCHEDULED: <%<%Y-%m-%d %a %H:%M>>\nEntered on %U\n" :empty-lines 1)
("m" "Memo" entry
(file+headline "~/Documents/ownCloud/memos.org" "Memos")
"* %?\n %U\n %i")
("n" "note(deft for vi)" plain
(file my/generate-md-memo-name)
"%(format \"---\ntitle: %s\ndate: %s\n---\n\n# \" my-org-note--name my-org-note--dtime)%?")
;;
("b" "Bike memos") ;; 各自転車毎にエントリー
("bm" "Marine" entry
(file+headline "~/Documents/ownCloud/bike_memo.org" "Marine")
"* %?\n %U\n %i")
("bs" "Sutra" entry
(file+headline "~/Documents/ownCloud/bike_memo.org" "Sutra")
"* %?\n %U\n %i")
("br" "Rouvaix" entry
(file+headline "~/Documents/ownCloud/bike_memo.org" "Rouvaix")
"* %?\n %U\n %i")
("bo" "Others" entry
(file+headline "~/Documents/ownCloud/bike_memo.org" "Others")
"* %?\n %U\n %i")
;;
("p" "Post for Blogger")
("pp" "blogger(pelican mkd)" plain ;; pelican 用のキャプチャ。今は使ってない。
(file my/generate-blogger-name-m)
"Title: %?\nDate: %<%Y-%m-%d %H:%M>\nTags:\nCategory:\nAuthors: AYAGE\nSummary: \nStatus: draft\n\n\n ")
("ps" "blogger(pelican rst)" plain ;; pelican 用のキャプチャ。今は使ってない。
(file my/generate-blogger-name-r)
"%?\n###################\n\n:date: %<%Y-%m-%d %H:%M>\n:tags:\n:category:\n:authors: AYAGE\n:summary: \n:status: draft\n\n\n ")
;;
("pa" "blogger(hugo) page" entry ;; hugo 用のキャプチャ。page.
(file+olp "hugo/blogger_hugo.org" "pages")
"** TODO %? \t:@debian:\n:PROPERTIES:\n:EXPORT_FILE_NAME: %(my/generate-post-name)\n\
:EXPORT_HUGO_FRONT_MATTER_FORMAT: toml\n\
:EXPORT_HUGO_SECTION: pages\n\
:EXPORT_HUGO_CUSTOM_FRONT_MATTER: :description false\n\
:EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :archives %<%Y\/%m>\n\
:EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :series [debian python emacs]\n\
:EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :toc 2 :num t\n\
:END:\n\n")
("ph" "blogger(hugo) post" entry ;; hugo 用のキャプチャ。post.
(file+olp "hugo/blogger_hugo.org" "posts")
"** TODO %? \t:@debian:\n:PROPERTIES:\n:EXPORT_FILE_NAME: %(my/generate-post-name)\n\
:EXPORT_HUGO_FRONT_MATTER_FORMAT: toml\n\
:EXPORT_HUGO_SECTION: posts\n\
:EXPORT_HUGO_CUSTOM_FRONT_MATTER: :description false\n\
:EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :archives %<%Y\/%m>\n\
:EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :series [debian python emacs]\n\
:EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :toc 2 :num t\n\
:END:\n\n\n")
;;
("j" "org-journal(Default)" entry (function org-journal-find-location)
"** %(format-time-string org-journal-time-format)%^{Title}\n %i%?")
;; datetree のファイルに追記してゆく
("J" "journal.org(agenda)" entry (file+datetree "~/Documents/ownCloud/journal/journal.org")
"* %?\nSCHEDULED:<%<%Y-%m-%d %a %H:%M>>\nEntered on %U\n\n%i\n")
;;
("h" "Hugo Yasa") ;; 別のテーマの hugo. 今は使ってない
("hp" "Hugo Yasa post for Cars" entry
(file+olp "hugo/hugo_post.org" "Blog Posts")
"** TODO %? \t:@Cars:\n:PROPERTIES:\n:EXPORT_FILE_NAME: %<%Y-%m-%d>-post_name.md\n\
:EXPORT_HUGO_FRONT_MATTER_FORMAT: yaml\n\
:EXPORT_HUGO_CUSTOM_FRONT_MATTER: :comments false\n\
:EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :image \"/ox-hugo/rimg.jpg\"\n\
:END:\n\n")
("ht" "Hugo post page" entry
(file "~/Documents/ownCloud/hugo/hugo_page.org")
(function org-hugo-new-subtree-post-capture-template))
;;
))
)
(setq flycheck-mode nil) ;; デフォでは動かさない。
)
ゆるい縛りで、 使い散らかしているという思いはあるが、 まあ、なんとか使っている、というところか。仕事の縛りが無いので気楽だ。
暗号化したファイルでメモを管理したいけど、それは未挑戦。
やっぱ、在宅介護オンリーで、外出は病院と近所のコンビニだけ、 という生活では、もひとつ使い甲斐が無い。 まあ、org-journal は活躍しているから、よしとする。