Doom Emacs config

メモ のためだけに emacs をつかっています。Doom は emacs を使いやすくするためのプラグイン群のコンピレーション。

まず、emacs のインストール、mac の場合は、

brew tap d12frosted/emacs-plus

brew install emacs-plus@29 --with-native-comp --with-xwidgets --with-no-frame-refocus --with-modern-black-gnu-head-icon --with-imagemagick

<2023-09-08 Fri> –with-no-frame-refocus やめる?

が一番いい。linux は普通に入れれば OK。(29 に合せたほうがいいかも)

doomのインストール

emacs/doom の設定ファイルは init.el, packages.el, config.el, の三つで ~/.config/doom/ の中に保存。下の項目は、軽い順。

tangle: このファイルを編集したら、 <C-c> <C-v> t で書き出し。

packages.el

packages.el
;; -*- no-byte-compile: t; -*-
;;; $DOOMDIR/packages.el

;; THIS IS AN AUTOGENERATED FILE

;; To install a package with Doom you must declare them here and run 'doom sync'
;; on the command line, then restart Emacs for the changes to take effect -- or
;; use 'M-x doom/reload'.

;; To install SOME-PACKAGE from MELPA, ELPA or emacsmirror:
;(package! some-package)

;; To install a package directly from a remote git repo, you must specify a
;; `:recipe'. You'll find documentation on what `:recipe' accepts here:
;; https://github.com/raxod502/straight.el#the-recipe-format
;(package! another-package
;  :recipe (:host github :repo "username/repo"))

;; If the package you are trying to install does not contain a PACKAGENAME.el
;; file, or is located in a subdirectory of the repo, you'll need to specify
;; `:files' in the `:recipe':
;(package! this-package
;  :recipe (:host github :repo "username/repo"
;           :files ("some-file.el" "src/lisp/*.el")))

;; If you'd like to disable a package included with Doom, you can do so here
;; with the `:disable' property:
;(package! builtin-package :disable t)

;; You can override the recipe of a built in package without having to specify
;; all the properties for `:recipe'. These will inherit the rest of its recipe
;; from Doom or MELPA/ELPA/Emacsmirror:
;(package! builtin-package :recipe (:nonrecursive t))
;(package! builtin-package-2 :recipe (:repo "myfork/package"))

;; Specify a `:branch' to install a package from a particular branch or tag.
;; This is required for some packages whose default branch isn't 'master' (which
;; our package manager can't deal with; see raxod502/straight.el#279)
;(package! builtin-package :recipe (:branch "develop"))

;; Use `:pin' to specify a particular commit to install.
;(package! builtin-package :pin "1a2b3c4d5e")

;; (use-package! mixed-pitch
;;   :hook
;;   ;; If you want it in all text modes:
;;   (org-mode . mixed-pitch-mode))

;; Doom's packages are pinned to a specific commit and updated from release to
;; release. The `unpin!' macro allows you to unpin single packages...
;(unpin! pinned-package)
;; ...or multiple packages
;(unpin! pinned-package another-pinned-package)
;; ...Or *all* packages (NOT RECOMMENDED; will likely break things)
;(unpin! t)
(package! doom-modeline :pin "918730eff72e")

init.el

それぞれの module のフラグはこちらを参照する。不要なものを全てけずっているので、追加したくなったら、こちらを参照。

init.el
;;;; init.el -*- lexical-binding: t; -*-

;; This file controls what Doom modules are enabled and what order they load
;; in. Remember to run 'doom sync' after modifying it!

;; NOTE Press 'SPC h d h' (or 'C-h d h' for non-vim users) to access Doom's
;;      documentation. There you'll find a link to Doom's Module Index where all
;;      of our modules are listed, including what flags they support.

;; NOTE Move your cursor over a module's name (or its flags) and press 'K' (or
;;      'C-c c k' for non-vim users) to view its documentation. This works on
;;      flags as well (those symbols that start with a plus).
;;
;;      Alternatively, press 'gd' (or 'C-c c d') on a module to browse its
;;      directory (for easy access to its source code).

(doom! :input
       japanese
       :completion
       company           ; the ultimate code completion backend
       vertico           ; the search engine of the future
       :ui
       doom              ; what makes DOOM look the way it does
       doom-dashboard    ; a nifty splash screen for Emacs
       hl-todo           ; highlight TODO/FIXME/NOTE/DEPRECATED/HACK/REVIEW
       modeline          ; snazzy, Atom-inspired modeline, plus API
       ophints           ; highlight the region an operation acts on
       (popup +defaults)   ; tame sudden yet inevitable temporary windows
       (vc-gutter +pretty) ; vcs diff in the fringe
       vi-tilde-fringe   ; fringe tildes to mark beyond EOB
       workspaces        ; tab emulation, persistence & separate workspaces
       :editor
       (evil +everywhere); come to the dark side, we have cookies
       file-templates    ; auto-snippets for empty files
       ;fold              ; (nigh) universal code folding
       snippets          ; my elves. They type so I don't have to
       :emacs
       dired             ; making dired pretty [functional]
       electric          ; smarter, keyword-based electric-indent
       undo              ; persistent, smarter undo for your inevitable mistakes
       vc                ; version-control and Emacs, sitting in a tree
       :term
       vterm             ; the best terminal emulation in Emacs
       :checkers
       syntax              ; tasing you for every semicolon you forget
       (spell +flyspell) ; tasing you for misspelling mispelling
       :tools
       biblio            ; Writes a PhD for you (citation needed)
       (eval +overlay)     ; run code, run (also, repls)
       lookup              ; navigate your code and its documentation
       lsp               ; M-x vscode
       magit             ; a git porcelain for Emacs
       pdf               ; pdf enhancements
       tree-sitter       ; syntax and parsing, sitting in a tree...
       :os
       (:if IS-MAC macos)  ; improve compatibility with macOS
       :lang
       (latex +lsp
              +latexmk)
       emacs-lisp        ; drown in parentheses
       markdown          ; writing docs for people to ignore
       (org
        +pandoc
        +roam2
        +pretty)              ; organize your plain life in plain text
       (lua
        +tree-sitter
        +lsp)
       (python
        +pyright
        +tree-sitter)            ; beautiful is better than ugly
       (go
        +lsp
        +tree-sitter)
       (rust
        +lsp
        +tree-sitter)       ; Fe2O3.unwrap().unwrap().unwrap().unwrap()
       (elixir
        +lsp
        +tree-sitter)
       sh                ; she sells {ba,z,fi}sh shells on the C xor
       (zig
        +lsp
        +tree-sitter)
       :email
       :app
       calendar
       :config
       (default +bindings +smartparens))

(add-to-list 'default-frame-alist '(undecorated-round . t))

;; inoremap j gj
(setq evil-respect-visual-line-mode t)

config.el

もともとの config.el ファイルはこちらから

config.el (header)
;   ;; $DOOMDIR/config.el -*- lexical-binding: t; -*-

;; THIS IS AN AUTOGENERATED FILE
config.el

general

(setq user-full-name "Yasushi Sakai"
      user-mail-address "yasushi.accounts@fastmail.com")


;; specify zls path for zig
(setq lsp-zig-zls-executable "/Users/yasushi/zig/tools/zls/zig-out/bin/zls")

theme

(setq doom-theme 'doom-one)
(setq pdf-view-midnight-minor-mode t)

fonts

部分的にフォントやみてくれを変更したい場合は、 hl-line-mode を disable してから、 describe-face(SPC h F) 経由で、custom できる。 custom.el に書き出されるので、こちらに手動で持ってくれば良い。

(setq fixed_font "HackGen35 Console NF")

;; fonts
(setq doom-font (font-spec :family fixed_font :size 14)
      doom-variable-pitch-font (font-spec :family "Hiragino Sans" :size 16)
      doom-big-font-increment 6)

;; mixed pitch is disabled
;; (add-hook! 'org-mode-hook #'mixed-pitch-mode)
;; (setq mixed-pitch-variable-pitch-cursor nil)

;; FIXME: redundant literals
(custom-set-faces
 '(org-block ((t (:extend t :background "#212430" :height 0.9 :family "HackGen35 Console NF"))))
 '(org-block-begin-line ((t (:extend t :background "#212430" :foreground "#51587a" :family "HackGen35 Console NF"))))
 '(org-code ((t (:inherit org-block :foreground "#ff9e64" :height 0.9 :family "HackGen35 Console NF"))))
 '(org-document-title ((t (:foreground "#f7768e" :family "Hackgen35 Console NF" :weight extrabold :height 3.0))))
 '(org-level-1 ((t (:foreground "#EBBCBA" :family "HackGen35 Console NF" :height 2.0 :weight extrabold))))
 '(org-level-2 ((t (:foreground "#F6c177" :weight bold :height 1.8 :family "HackGen35 Console NF\12"))))
 '(org-level-3 ((t (:foreground "#31748f" :weight bold :height 1.5 :family "HackGen35 Console NF"))))
 '(org-level-4 ((t (:height 1.25 :weight bold))))
 '(org-meta-line ((t (:inherit org-block-begin-line))))
 '(org-special-keyword ((t (:family "HackGen35 Console NF"))))
 '(org-table ((t (:foreground "#9aa5ce" :family "HackGen35 Console NF"))))
 '(shadow ((t (:foreground "#9099c0" :height 0.8 :family "HackGen35 Console NF")))))

snipe

(setq evil-snipe-scope 'visible)

unfill-paragraph

;;; Stefan Monnier <foo at acm.org>. It is the opposite of fill-paragraph
(defun unfill-paragraph (&optional region)
  "Takes a multi-line paragraph and makes it into a single line of text."
  (interactive (progn (barf-if-buffer-read-only) '(t)))
  (let ((fill-column (point-max))
        ;; This would override `fill-column' if it's an integer.
        (emacs-lisp-docstring-fill-column t))
    (fill-paragraph nil region)))

(define-key global-map "\M-Q" 'unfill-paragraph)

projectile

(setq projectile-project-search-path '("~/code/"))

org

この org-mode で書いたメモをどこでもみたいとなると、同期問題が出てくるんだけど、それを git でやってたけど、いまいち。

そもそも版管理するのは、プログラムや法律 1 のように、その版で必要なスナップショット的な情報が完結している前提で、連結リストでプロセスを保存する目的がある。プログラムに前まで動いていた箇所をコメントアウトして保存しておく事があるけど、原理主義的には、その時間を超えた情報はコミット、すなわち git 側のメタデータとして保存されるべき。原理主義だから、日々のコーディングで多少はあってもいいと思う。

そうゆう意味で、そのメディアがスナップショットでかつ、変更の履歴をおう仕組みが別々に必要なものを通時的なメディアとすると、別の時間に起こったことがあってもいい、メディアは経時的なメディアと言えるのだろう。メモはたぶん、こっちの方で、昔の試行錯誤の形跡が少しあったほうが良い。

ので、git やめて、syncthing にしてみてる。ios だと同期のタイミングが読めない(プロセスの生死は O S の独断)ので、あんまり使えるのかどうかわからない。メモとインターフェースするタイミングについてもう少し考える必要がある。

(use-package! org
  :custom
  (org-directory "~/notes")
  (org-id-locations-file (expand-file-name ".orgids" org-directory))
  :config
  (setq org-hide-block-startup t)
  (setq org-todo-keywords
      '((sequence "TODO" "HOLD" "NEXT" "WAITING" "MEETING" "|" "DONE" "CANCELLED"))))

(add-hook! org-mode :append
           #'visual-line-mode)
           ; #'variable-pitch-mode)
           ;; #'(lambda() (set (make-local-variable 'display-line-numbers-mode) nil)))
;; (add-hook 'term-mode-hook '(lambda() (set (make-local-variable 'global-hl-line-mode) nil)))

(add-hook 'org-mode-hook
          (lambda (&rest _) (display-line-numbers-mode -1)))

(add-hook 'org-mode-hook 'variable-pitch-mode)

org-roam

(use-package! org-roam
  :custom
  (org-roam-directory org-directory)
  (org-roam-db-autosync-mode)
  (org-roam-capture-templates
    '(("d" "default" plain "%?"
      ;; :if-new (file+head "~/Dropbox/org/notes/${slug}.org" "${title}
      :if-new (file+head "~/notes/${slug}.org" "${title}
#+date: %U
:DRAWER:
#+options: title:nil
#+LATEX_CLASS: article
#+LATEX_HEADER: \\newcommand{\\headauthor}{Yasushi Sakai}
#+LATEX_HEADER: \\newcommand{\\headtitle}{${title}}
#+LATEX_HEADER: \\newcommand{\\headsubtitle}{${title}}
#+setupfile: ./setup.org
:END:")
     :unarrowed t))))

citation

(setq! citar-bibliography '("~/notes/bib/main.bib"))

org-agenda

(setq org-agenda-files (list org-directory))

(setq org-agenda-sorting-strategy '((tags category-up)))

(setq org-agenda-custom-commands
      '(("c" "Simple agenda view" (
                                   (agenda "" ((org-agenda-span 8)
                                               (org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done))
                                               (org-agenda-start-day "-1d")
                                               (org-deadline-warning-days 0)
                                               (org-agenda-start-on-weekday nil)
                                               (org-habit-show-habits-only-for-today t)
                                               (org-agenda-overriding-header "\nThis weeks tasks\n")
                                               ))
                                    (alltodo "" ((org-agenda-skip-function '(org-agenda-skip-entry-if 'nottodo '("NEXT")))
                                                    (org-agenda-overriding-header "\nNEXT tasks\n")))
                                    (alltodo "" ((org-agenda-overriding-header "\nALL TODO\n")))
))))

(setq org-capture-templates
      '(("t" "TODO item" entry (file+headline "~/notes/tasks.org" "Tasks")
         "*** TODO %?\n %i\n %a\n %T")
        ("m" "small memo / journal" entry (file+datetree "~/notes/small_memo.org")
         "*** %? :noexport:\nEntered on %U\n %i\n %a")
        ))

publish

Blog Publish

(after! python
 (setq python-shell-interpreter "/opt/homebrew/bin/python3"))

;; no need to evaluate when exporting..
(setq org-export-babel-evaluate nil)

(require 'ox-publish)

(setq org-publish-project-alist
      '(("main"
             :recursive t
             :base-directory "~/notes"
             :publishing-directory "/tmp/www"
             :publishing-function org-html-publish-to-html
             :with-author nil
             :with-creator nil
             :with-toc nil
                 :with-timestamps t
             :with-broken-links 'mark
             :section-numbers nil
             :time-stamp-file nil)
        ("images"
             :base-directory "~/notes/images"
             :base-extension "png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg"
             :publishing-directory "/tmp/www/images"
             :recursive t
             :publishing-function org-publish-attachment)
        ("static"
             :base-directory "~/notes/static"
             :base-extension "js\\|css\\|html"
             :publishing-directory "/tmp/www/static"
             :recursive t
             :publishing-function org-publish-attachment)))

(setq org-html-validation-link nil
      org-html-head-include-scripts nil
      org-html-head-include-default-style nil
      ;org-html-doctype "html5"
      org-html-head "<link rel=\"stylesheet\" type=\"text/css\" href=\"/static/style.css\" /><meta name=\"apple-mobile-web-app-capable\" content=\"yes\">
")

calendar

https://github.com/kidd/org-gcal.el#installation

https://github.com/kidd/org-gcal.el/issues/238#issuecomment-1715495148

https://gist.githubusercontent.com/sankalp-khare/94fee1727ec5d199018be225127510d2/raw/215c60351a1b1154b2dc622fbeec57479ef3acb2/switch-gnupg.sh

(setq org-gcal-client-id "your-id-foo.apps.googleusercontent.com"
      org-gcal-client-secret "your-secret"
      org-gcal-fetch-file-alist '(("your-mail@gmail.com" .  "~/schedule.org")
                                  ("another-mail@gmail.com" .  "~/task.org")))

(require 'org-gcal)
(setq plstore-cache-passphrase-for-symmetric-encryption t)

(require 'epa-file)
(setq epg-pinentry-mode 'loopback)
(epa-file-enable)
(setq epg-gpg-program "/opt/homebrew/bin/gpg") ; replace with actual path to gpg if different
(setq plstore-cache-passphrase-for-symmetric-encryption t)

org-tree-slide

;; this may go away if you update
;; (setq org-fold-core-style 'overlay)

migemo

;; (setq! migemo-dictionary "/opt/homebrew/Cellar/cmigemo/20110227/share/migemo/utf-8/migemo-dict")

Footnotes:

1

他には、料理のレシピ、 図面(特に設計契約の設計図書について)各種契約書類があるかしら。プログラムも普通は changelog として、何がどう変わったかの変更履歴を書いているものはたくさんある。ほんとうはそのまま git のコミット記録が changelog として機能すればいいので、コミットメッセージはプログラマーの内的な変更の説明ともに、それを使う外部の人間のレファレンスになる様にしたほうが良いという当たりまえのアドバイスに行き着く。

Date: 2022-03-29 Tue 19:07