Configurations for GNU Emacs

Table of Contents

1. はじめに

1.1. 基本情報

2. Header

;; init.el --- My init.el -*- lexical-binding: t -*-
;; Configurations for Emacs
;;                                         Takeo Obara  <bararararatty@gmail.com>

3. Macro Utilities

3.1. when-darwin

(defmacro when-darwin (&rest body)
  (when (string= system-type "darwin")
    `(progn ,@body)))

3.2. when-darwin-not-window-system

(defmacro when-darwin-not-window-system (&rest body)
  (when (and (string= system-type "darwin")
             window-system)
    `(progn ,@body)))

4. Boot

4.1. user

(setq user-full-name "takeokunn")
(setq user-mail-address "bararararatty@gmail.com")

4.2. profile

(defconst my/enable-profile nil
  "If true, enable profile")

(when my/enable-profile
  (require 'profiler)
  (profiler-start 'cpu))

4.3. Magic File Name を一時的に無効にする

(defconst my/saved-file-name-handler-alist file-name-handler-alist)

(setq file-name-handler-alist nil)

4.4. 起動時間計測

(defconst my/before-load-init-time (current-time))

;;;###autoload
(defun my/load-init-time ()
  "Loading time of user init files including time for `after-init-hook'."
  (let ((time1 (float-time
                (time-subtract after-init-time my/before-load-init-time)))
        (time2 (float-time
                (time-subtract (current-time) my/before-load-init-time))))
    (message (concat "Loading init files: %.0f [msec], "
                     "of which %.f [msec] for `after-init-hook'.")
             (* 1000 time1) (* 1000 (- time2 time1)))))
(add-hook 'after-init-hook #'my/load-init-time t)

(defvar my/tick-previous-time my/before-load-init-time)

(defun my/emacs-init-time ()
  "Emacs booting time in msec."
  (interactive)
  (message "Emacs booting time: %.0f [msec] = `emacs-init-time'."
           (* 1000
              (float-time (time-subtract
                           after-init-time
                           before-init-time)))))

(add-hook 'after-init-hook #'my/emacs-init-time)

4.5. autoload-if-found

(defun autoload-if-found (functions file &optional docstring interactive type)
  "Set autoload iff FILE has found."
  (when (locate-library file)
    (dolist (f functions)
      (autoload f file docstring interactive type))))

5. Basic

5.1. 末尾のスペースを可視化する

(defun my/disable-show-trailing-whitespace ()
  (setq show-trailing-whitespace nil))

(with-eval-after-load 'comint
  (add-hook 'comint-mode-hook #'my/disable-show-trailing-whitespace))

(with-eval-after-load 'esh-mode
  (add-hook 'eshell-mode-hook #'my/disable-show-trailing-whitespace))

(with-eval-after-load 'minibuffer
  (add-hook 'minibuffer-inactive-mode-hook #'my/disable-show-trailing-whitespace))

(with-eval-after-load 'prog-mode
  (add-hook 'prog-mode-hook #'my/disable-show-trailing-whitespace))

(with-eval-after-load 'text-mode
  (add-hook 'text-mode-hook #'my/disable-show-trailing-whitespace))

5.2. 行番号を表示する

(autoload-if-found '(global-display-line-numbers-mode) "display-line-numbers" nil t)

(add-hook 'emacs-startup-hook #'global-display-line-numbers-mode)

(with-eval-after-load 'display-line-numbers
  (setopt display-line-numbers-grow-only t))

5.3. C-kで行削除

(with-eval-after-load 'simple
  (setopt kill-whole-line t))

5.4. カッコの中をハイライトする

(autoload-if-found '(show-paren-local-mode) "display-line-numbers" nil t)

(with-eval-after-load 'prog-mode
  (add-hook 'prog-mode-hook #'show-paren-local-mode))

(with-eval-after-load 'paren
  (setopt show-paren-style 'mixed))

5.5. カッコが自動的に作られるようにする

(add-hook 'emacs-startup-hook #'electric-pair-mode)

5.6. coding system

;; coding system
(add-hook 'emacs-startup-hook
          #'(lambda ()
              (set-default-coding-systems 'utf-8-unix)
              (prefer-coding-system 'utf-8-unix)
              (set-selection-coding-system 'utf-8-unix)))

;; prefer-coding-system take effect equally to follows
(add-hook 'emacs-startup-hook
          #'(lambda ()
              (setq locale-coding-system 'utf-8-unix)
              (set-buffer-file-coding-system 'utf-8-unix)
              (set-file-name-coding-system 'utf-8-unix)
              (set-terminal-coding-system 'utf-8-unix)
              (set-keyboard-coding-system 'utf-8-unix)))

5.7. global-auto-revert-mode

(add-hook 'emacs-startup-hook #'global-auto-revert-mode)

5.8. yes/no to y/n

(add-hook 'emacs-startup-hook
          #'(lambda ()
              (fset 'yes-or-no-p 'y-or-n-p)))

5.9. minibuffer

(with-eval-after-load 'minibuffer
  (define-key minibuffer-mode-map (kbd "C-j") #'exit-minibuffer)
  (define-key minibuffer-mode-map (kbd "M-RET") #'exit-minibuffer))

(setq enable-recursive-minibuffers t)

5.10. savehistを有効にする

(add-hook 'emacs-startup-hook #'savehist-mode)

5.11. [mac] clipboardに入るようにする

(defun my/copy-from-osx ()
  (shell-command-to-string "pbpaste"))

(defun my/paste-to-osx (text)
  (let ((process-connection-type nil))
    (let ((proc (start-process "pbcopy" "*Messages*" "pbcopy")))
      (process-send-string proc text)
      (process-send-eof proc))))

(when-darwin-not-window-system
 (setq interprogram-cut-function #'my/paste-to-osx)
 (setq interprogram-paste-function #'my/copy-from-osx))

5.12. native comp

(with-eval-after-load 'comp-run
  ;; config
  (setopt native-comp-async-jobs-number 8)
  (setopt native-comp-speed 3)
  (setopt native-comp-always-compile t))

(with-eval-after-load 'warnings
  ;; config
  (setopt warning-suppress-types '((comp))))

5.13. 同一bufferの名前を変える

(with-eval-after-load 'uniquify
  (setopt uniquify-buffer-name-style 'post-forward-angle-brackets))

5.14. killできないようにする

(add-hook 'emacs-startup-hook
          #'(lambda ()
              (with-current-buffer "*scratch*"
                (emacs-lock-mode 'kill))
              (with-current-buffer "*Messages*"
                (emacs-lock-mode 'kill))))

5.15. 日時表示

(with-eval-after-load 'time
  (setopt display-time-24hr-format t))

5.16. warning level

(with-eval-after-load 'warnings
  (setopt warning-minimum-level :error))

5.17. キーコマンド入力中に入力過程をミニバッファに反映する

(setq echo-keystrokes 0.1)

5.18. save-place-mode

(add-hook 'emacs-startup-hook #'save-place-mode)

5.19. enable-local-variables

(setq enable-local-variables :all)

5.20. password

(with-eval-after-load 'password-cache
  ;; config
  (setq password-cache t)
  (setq password-cache-expiry 3600))

5.21. 検索で大文字小文字を区別しない

(with-eval-after-load 'minibuffer
  (setopt read-file-name-completion-ignore-case t))

(setq completion-ignore-case t)
(setq read-buffer-completion-ignore-case t)

5.22. time locale

(setq system-time-locale "C")

5.23. kill-ringのサイズを変更

(setopt kill-ring-max 100000)

(custom-set-variables '(savehist-additional-variables '(kill-ring)))

5.24. 折り返ししない

(setq truncate-lines t)
(setq truncate-partial-width-windows t)

5.25. indent/tab

(add-hook 'emacs-startup-hook
        #'(lambda ()
            (indent-tabs-mode nil)))

6. Global Keybind

6.1. basic

(keymap-global-set "M-¥" #'(lambda () (interactive) (insert "\\")))
(keymap-global-set "C-a" #'back-to-indentation)
(keymap-global-set "C-z" nil)
(keymap-global-set "C-;" #'comment-dwim)
(keymap-global-set "C-M-/" #'undo-redo)
(keymap-global-set "C-c i" #'find-function)
(keymap-global-set "C-c C-o" #'org-open-at-point)
(keymap-global-set "C-x C-o" #'other-window)

(keymap-global-set "C-x l" #'next-buffer)
(keymap-global-set "C-x h" #'previous-buffer)
(keymap-global-set "C-x C-b" #'switch-to-buffer)

(keymap-global-set "C-x C-k" nil)

(keymap-global-set "M-d" #'my/delete-forward-block)

(when window-system
  (keymap-global-set "C-x C-c" nil))

7. Language

7.1. apache-mode

(autoload-if-found '(apache-mode) "apache-mode" nil t)

(add-to-list 'auto-mode-alist '("/\\.htaccess\\'" . apache-mode))
(add-to-list 'auto-mode-alist '("/\\(?:access\\|httpd\\|srm\\)\\.conf\\'" . apache-mode))
(add-to-list 'auto-mode-alist '("/apache2/.+\\.conf\\'" . apache-mode))
(add-to-list 'auto-mode-alist '("/httpd/conf/.+\\.conf\\'" . apache-mode))
(add-to-list 'auto-mode-alist '("/apache2/sites-\\(?:available\\|enabled\\)/" . apache-mode))

7.2. bazel-mode

(autoload-if-found '(bazel-mode) "bazel" nil t)

7.3. bison-mode

(autoload-if-found '(bison-mode flex-mode jison-mode) "bison-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.y\\'" . bison-mode))
(add-to-list 'auto-mode-alist '("\\.l\\'" . flex-mode))
(add-to-list 'auto-mode-alist '("\\.jison\\'" . jison-mode))

7.4. cask-mode

(autoload-if-found '(cask-mode) "cask-mode" nil t)

(add-to-list 'auto-mode-alist '("/Cask\\'" . cask-mode))

7.5. cfn-mode

(autoload-if-found '(cfn-mode) "cfn-mode" nil t)

(add-to-list 'magic-mode-alist '("\\(---\n\\)?AWSTemplateFormatVersion:" . cfn-mode))

(with-eval-after-load 'cfn-mode
  ;; hooks
  (add-hook 'cfn-mode-hook #'flycheck-mode))

7.6. clojure-mode

(autoload-if-found '(clojure-mode clojurescript-mode) "clojure-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.clj$" . clojure-mode))
(add-to-list 'auto-mode-alist '("\\.cljs$" . clojurescript-mode))

(with-eval-after-load 'clojure-mode
  ;; config
  (setopt clojure-toplevel-inside-comment-form t))

7.7. cmake-mode

(autoload-if-found '(cmake-mode) "cmake-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.cmake$" . cmake-mode))

7.8. coffee-mode

(autoload-if-found '(coffee-mode) "coffee-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.coffee$" . coffee-mode))

7.9. conf-mode

(add-to-list 'auto-mode-alist '("\\.cnf$" . conf-mode))
(add-to-list 'auto-mode-alist '("yabairc$" . conf-mode))
(add-to-list 'auto-mode-alist '("skhdrc$" . conf-mode))

7.10. crontab-mode

(autoload-if-found '(crontab-mode) "crontab-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.?cron\\(tab\\)?\\'" . crontab-mode))

7.11. csharp-mode

(autoload-if-found '(csharp-mode) "csharp-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.cs$" . csharp-mode))

7.12. csv-mode

(autoload-if-found '(csv-mode) "csv-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.csv$" . csv-mode))

7.13. cuda-mode

(autoload-if-found '(cuda-mode) "cuda-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.cu$" . cuda-mode))

7.14. crystal-mode

(autoload-if-found '(crystal-mode) "crystal-mode" nil t)

(add-to-list 'auto-mode-alist '("Projectfile$" . crystal-mode))
(add-to-list 'auto-mode-alist
             (cons (purecopy (concat "\\(?:\\."
                                     "cr"
                                     "\\)\\'")) 'crystal-mode))

7.15. dart-mode

(autoload-if-found '(dart-mode) "dart-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.dart$" . dart-mode))

7.16. dhall-mode

(autoload-if-found '(dhall-mode) "dhall-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.dhall$" . dhall-mode))

7.17. direnv-mode

(autoload-if-found '(direnv-mode direnv-envrc-mode) "direnv" nil t)

(add-to-list 'auto-mode-alist '("\\.envrc" . direnv-envrc-mode))

7.18. docker-compose-mode

(autoload-if-found '(docker-compose-mode) "docker-compose-mode" nil t)

(add-to-list 'auto-mode-alist '("\\docker-compose*" . docker-compose-mode))

7.19. dockerfile-mode

(autoload-if-found '(dockerfile-mode) "dockerfile-mode" nil t)

(add-to-list 'auto-mode-alist '("\\Dockerfile$" . dockerfile-mode))
(add-to-list 'auto-mode-alist '("\\Dockerfile_Ecs$" . dockerfile-mode))
(add-to-list 'auto-mode-alist '("\\Dockerfile_EcsDeploy" . dockerfile-mode))

(with-eval-after-load 'dockerfile-mode
  ;; hooks
  (add-hook 'dockerfile-mode-hook #'flycheck-mode))

7.20. dotenv-mode

(autoload-if-found '(dotenv-mode) "dotenv-mode" nil t)

(add-to-list 'auto-mode-alist '(".env" . dotenv-mode))
(add-to-list 'auto-mode-alist '("\\.env\\..*\\'" . dotenv-mode))

7.21. elixir-mode

(autoload-if-found '(elixir-mode) "elixir-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.elixir$" . elixir-mode))
(add-to-list 'auto-mode-alist '("\\.ex$" . elixir-mode))
(add-to-list 'auto-mode-alist '("\\.exs$" . elixir-mode))
(add-to-list 'auto-mode-alist '("mix\\.lock" . elixir-mode))

7.22. elm-mode

(autoload-if-found '(elm-mode) "elm-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.elm$" . elm-mode))

7.23. emacs-lisp-mode

(add-to-list 'auto-mode-alist '("Keg" . emacs-lisp-mode))

7.24. fish-mode

(autoload-if-found '(fish-mode) "fish-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.fish$" . fish-mode))

(with-eval-after-load 'fish-mode
  ;; config
  (setopt fish-enable-auto-indent t))

7.25. forth-mode

(autoload-if-found '(forth-mode) "forth-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.f$" . forth-mode))
(add-to-list 'auto-mode-alist '("\\.fs$" . forth-mode))
(add-to-list 'auto-mode-alist '("\\.fth$" . forth-mode))
(add-to-list 'auto-mode-alist '("\\.forth$" . forth-mode))
(add-to-list 'auto-mode-alist '("\\.4th$" . forth-mode))

7.26. fortran

(autoload-if-found '(f90-mode) "f90" nil t)

(add-to-list 'auto-mode-alist '("\\.f\\(y90\\|y?pp\\)\\'" . f90-mode))

7.27. fsharp-mode

(autoload-if-found '(fsharp-mode) "fsharp-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.fs[iylx]?$" . fsharp-mode))

7.28. git-modes

(autoload-if-found '(gitignore-mode gitconfig-mode gitattributes-mode) "git-modes" nil t)

;; gitignore-mode
(add-to-list 'auto-mode-alist '("\\.dockerignore$" . gitignore-mode))
(add-to-list 'auto-mode-alist '("\\.gitignore$" . gitignore-mode))
(add-to-list 'auto-mode-alist '("\\.prettierignore$" . gitignore-mode))
(add-to-list 'auto-mode-alist '("/git/ignore\\'" . gitignore-mode))
(add-to-list 'auto-mode-alist '("/git/ignore\\'" . gitignore-mode))
(add-to-list 'auto-mode-alist '("CODEOWNERS" . gitignore-mode))

;; gitconfig-mode
(add-to-list 'auto-mode-alist '("\\.git-pr-release$" . gitconfig-mode))
(add-to-list 'auto-mode-alist '("\\.editorconfig$" . gitconfig-mode))
(add-to-list 'auto-mode-alist '("\\.gitconfig$" . gitconfig-mode))
(add-to-list 'auto-mode-alist '("/\\.git/config\\'" . gitconfig-mode))
(add-to-list 'auto-mode-alist '("/modules/.*/config\\'" . gitconfig-mode))
(add-to-list 'auto-mode-alist '("/git/config\\'" . gitconfig-mode))
(add-to-list 'auto-mode-alist '("/\\.gitmodules\\'" . gitconfig-mode))
(add-to-list 'auto-mode-alist '("/etc/gitconfig\\'" . gitconfig-mode))

;; gitattributes
(add-to-list 'auto-mode-alist '("/\\.gitattributes\\'" . gitattributes-mode))
(add-to-list 'auto-mode-alist '("\.gitattributes$" . gitattributes-mode))
(add-to-list 'auto-mode-alist '("/info/attributes\\'" . gitattributes-mode))
(add-to-list 'auto-mode-alist '("/git/attributes\\'" . gitattributes-mode))

7.29. glsl-mode

(autoload-if-found '(glsl-mode) "glsl-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.vsh$" . glsl-mode))
(add-to-list 'auto-mode-alist '("\\.fsh$" . glsl-mode))

7.30. go-mode

(autoload-if-found '(go-mode gofmt-before-save) "go-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.go$" . go-mode))
(add-to-list 'auto-mode-alist '("^go.mod$" . go-mode))

(with-eval-after-load 'go-mode
  ;; config
  (setopt gofmt-command "goimports")

  ;; hook
  (add-hook 'before-save-hook #'gofmt-before-save))

7.31. gradle-mode

(autoload-if-found '(gradle-mode) "gradle-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.gradle$" . gradle-mode))

7.32. graphql-mode

(autoload-if-found '(graphql-mode) "graphql-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.graphql\\'" . graphql-mode))

(with-eval-after-load 'graphql-mode
  ;; config
  (setopt graphql-indent-level 4))

7.33. graphviz-dot-mode

(autoload-if-found '(graphviz-dot-mode) "graphviz-dot-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.dot\\'" . graphviz-dot-mode))
(add-to-list 'auto-mode-alist '("\\.gv\\'" . graphviz-dot-mode))

(with-eval-after-load 'graphviz-dot-mode
  ;; config
  (setopt graphviz-dot-auto-indent-on-semi nil)
  (setopt graphviz-dot-indent-width 2))

7.34. groovy-mode

(autoload-if-found '(groovy-mode) "groovy-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.g\\(?:ant\\|roovy\\|radle\\)\\'" . groovy-mode))
(add-to-list 'auto-mode-alist '("/Jenkinsfile\\'" . groovy-mode))
(add-to-list 'interpreter-mode-alist '("groovy" . groovy-mode))

7.35. hack-mode

(autoload-if-found '(hack-mode) "hack-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.hack$" . hack-mode))
(add-to-list 'auto-mode-alist '("\\.hck$" . hack-mode))
(add-to-list 'auto-mode-alist '("\\.hhi$" . hack-mode))

7.36. haskell-mode

(autoload-if-found '(haskell-mode) "haskell-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.hs$" . haskell-mode))
(add-to-list 'auto-mode-alist '("\\.cable$" . haskell-mode))

7.37. hcl-mode

(autoload-if-found '(hcl-mode) "hcl-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.hcl$" . hcl-mode))

7.38. hy-mode

(autoload-if-found '(hy-mode) "hy-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.hy$" . hy-mode))

7.39. ini-mode

(autoload-if-found '(ini-mode) "ini-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.ini$" . ini-mode))

7.40. jade-mode

(autoload-if-found '(jade-mode) "jade-mode" nil t)
(autoload-if-found '(stylus-mode) "stylus-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.jade$" . jade-mode))
(add-to-list 'auto-mode-alist '("\\.styl\\'" . stylus-mode))

7.41. java-mode

(autoload-if-found '(java-mode) "java-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.java$" . java-mode))

7.42. js2-mode

(autoload-if-found '(js2-mode) "js2-mode" nil t)

;; js2-mode
(add-to-list 'auto-mode-alist '("\\.js$" . js2-mode))
(add-to-list 'auto-mode-alist '("\\.mjs$" . js2-mode))

(with-eval-after-load 'js2-mode
  ;; config
  (setopt js2-strict-missing-semi-warning nil)
  (setopt js2-missing-semi-one-line-override nil))

7.43. json-mode

(autoload-if-found '(json-mode) "json-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.json$" . json-mode))
(add-to-list 'auto-mode-alist '("\\.textlintrc$" . json-mode))
(add-to-list 'auto-mode-alist '("\\.prettierrc$" . json-mode))
(add-to-list 'auto-mode-alist '("\\.markuplintrc$" . json-mode))

(with-eval-after-load 'json-mode
  ;; hooks
  (add-hook 'json-mode-hook #'flycheck-mode))

7.44. jsonnet-mode

(autoload-if-found '(jsonnet-mode
                     jsonnet-eval-buffer
                     jsonnet-jump
                     jsonnet-reformat-buffer) "jsonnet-mode" nil t)

(add-to-list 'auto-mode-alist (cons "\\.jsonnet\\'" 'jsonnet-mode))
(add-to-list 'auto-mode-alist (cons "\\.libsonnet\\'" 'jsonnet-mode))

(with-eval-after-load 'jsonnet-mode
  ;; config
  (setopt jsonnet-indent-level 4)

  ;; keybind
  (define-key jsonnet-mode-map (kbd "C-c C-c") #'jsonnet-eval-buffer)
  (define-key jsonnet-mode-map (kbd "C-c C-f") #'jsonnet-jump)
  (define-key jsonnet-mode-map (kbd "C-c C-r") #'jsonnet-reformat-buffer))

7.45. kotlin-mode

(autoload-if-found '(kotlin-mode) "kotlin-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.kts?\\'" . kotlin-mode))

7.46. lisp-mode

(autoload-if-found '(lisp-mode) "lisp-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.lemrc$" . lisp-mode))
(add-to-list 'auto-mode-alist '("\\.sbclrc$" . lisp-mode))

7.47. lua-mode

(autoload-if-found '(lua-mode) "lua-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.lua$" . lua-mode))

7.48. markdown-mode

(autoload-if-found '(markdown-mode) "markdown-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.md$" . markdown-mode))
(add-to-list 'auto-mode-alist '("\\.markdown$" . markdown-mode))

(with-eval-after-load 'markdown-mode
  ;; config
  (setopt markdown-code-lang-modes (append '(("diff" . diff-mode)
                                             ("hs" . haskell-mode)
                                             ("html" . web-mode)
                                             ("ini" . conf-mode)
                                             ("js" . web-mode)
                                             ("jsx" . web-mode)
                                             ("md" . markdown-mode)
                                             ("pl6" . raku-mode)
                                             ("py" . python-mode)
                                             ("rb" . ruby-mode)
                                             ("rs" . rustic-mode)
                                             ("sqlite3" . sql-mode)
                                             ("ts" . typescript-mode)
                                             ("typescript" . typescript-mode)
                                             ("tsx" . web-mode)
                                             ("yaml". yaml-mode)
                                             ("zsh" . sh-mode)
                                             ("php" . php-mode))
                                           markdown-code-lang-modes))

  ;; markdown
  (add-hook 'markdown-mode #'orgtbl-mode))

7.49. mermaid-mode

(autoload-if-found '(mermaid-mode) "mermaid-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.mmd\\'" . mermaid-mode))

7.50. makefile-mode

(autoload-if-found '(makefile-mode) "makefile-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.mk$" . makefile-mode))
(add-to-list 'auto-mode-alist '("Makefile" . makefile-mode))

(with-eval-after-load 'makefile-mode
  ;; config
  (setopt makefile-electric-keys t)

  ;; hook
  (add-hook 'makefile-mode-hook #'flycheck-mode))

7.51. nasm-mode

(autoload-if-found '(nasm-mode) "nasm-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.s$" . nasm-mode))

7.52. neon-mode

(autoload-if-found '(neon-mode) "neon-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.neon$" . neon-mode))

7.53. nim-mode

(autoload-if-found '(nim-mode) "nim-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.nim\\'" . nim-mode))

7.54. ninja-mode

(autoload-if-found '(ninja-mode) "ninja-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.ninja$" . ninja-mode))

7.55. nix-mode

(autoload-if-found '(nix-mode) "nix-mode" nil t)
(autoload-if-found '(nix-drv-mode) "nix-drv-mode" nil t)
(autoload-if-found '(nix-shell-unpack nix-shell-configure nix-shell-build) "nix-shell" nil t)
(autoload-if-found '(nix-repl) "nix-repl" nil t)
(autoload-if-found '(nix-format-before-save) "nix-format" nil t)

(add-to-list 'auto-mode-alist '("\\.nix$" . nix-mode))
(add-to-list 'auto-mode-alist '("\\.drv$" . nix-drv-mode))

(add-hook 'before-save-hook #'nix-format-before-save)

7.56. nginx-mode

(autoload-if-found '(nginx-mode) "nginx-mode" nil t)

(add-to-list 'auto-mode-alist '("nginx\\.conf\\'" . nginx-mode))
(add-to-list 'auto-mode-alist '("/nginx/.+\\.conf\\'" . nginx-mode))
(add-to-list 'auto-mode-alist '("/nginx/sites-\\(?:available\\|enabled\\)/" . nginx-mode))

(with-eval-after-load 'nginx-mode
  ;; config
  (setopt nginx-indent-tabs-mode t))

7.57. nov-mode

(autoload-if-found '(nov-mode) "nov" nil t)

(add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode))

(with-eval-after-load 'nov
  ;; hook
  (add-hook 'nov-mode-hook #'(lambda () (view-mode -1))))

7.58. pcap-mode

(autoload-if-found '(pcap-mode) "pcap" nil t)

(add-to-list 'auto-mode-alist '("\\.pcap$" . pcap-mode))

7.59. phel-mode

(define-derived-mode phel-mode clojure-mode "Phel"
  "Major mode for editing Phel language source files."
  (setq-local comment-start "#")
  ;; We disable lockfiles so that ILT evaluation works.
  ;; The lockfiles seem to modify the buffer-file-name somehow, when the buffer changes
  ;; And that is detected by the currently running Phel process.
  ;; That interferes with evaluation, as the running Phel process starts behaving badly because of that.
  (setq-local create-lockfiles nil)
  )

(add-to-list 'auto-mode-alist '("\\.phel$" . phel-mode))

7.60. php-mode

(autoload-if-found '(php-mode php-current-class php-current-namespace) "php-mode" nil t)
(autoload-if-found '(php-format-this-buffer-file
                     php-format-project
                     php-format-on-after-save-hook
                     php-format-auto-mode) "php-format" nil t)

(add-to-list 'auto-mode-alist '("\\.php$" . php-mode))

(with-eval-after-load 'php-mode
  ;; hook
  (add-hook 'php-mode-hook #'php-format-auto-mode)

  ;; keybind
  (define-key php-mode-map (kbd "C-c C--") #'php-current-class)
  (define-key php-mode-map (kbd "C-c C-=") #'php-current-namespace)
  (define-key php-mode-map (kbd "C-.") nil)

  ;; config
  (setopt php-mode-coding-style 'psr2)

  ;; phpstan
  (define-derived-mode phpstan-mode php-mode "phpstan"))

7.61. phpt-mode

(autoload-if-found '(phpt-mode) "phpt-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.phpt$" . phpt-mode))

7.62. plantuml-mode

(autoload-if-found '(plantuml-mode) "plantuml-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.pu$" . plantuml-mode))

7.63. po-mode

(autoload-if-found '(po-mode) "po-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.po$" . po-mode))

7.64. protobuf-mode

(autoload-if-found '(protobuf-mode) "protobuf-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.proto\\'" . protobuf-mode))

7.65. pug-mode

(autoload-if-found '(pug-mode) "pug-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.pug$" . pug-mode))

7.66. prisma-mode

(autoload-if-found '(prisma-mode) "prisma-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.prisma" . prisma-mode))

7.67. processing-mode

(autoload-if-found '(processing-mode) "processing-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.pde$" . processing-mode))

(with-eval-after-load 'processing-mode
  ;; config
  (setopt processing-output-dir "/tmp"))

7.68. python-mode

(autoload-if-found '(python-mode) "python-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.py$" . python-mode))

7.69. qt-pro-mode

(autoload-if-found '(qt-pro-mode) "qt-pro-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.pr[io]$" . qt-pro-mode))

7.70. robots-txt-mode

(autoload-if-found '(robots-txt-mode) "robots-txt-mode" nil t)

(add-to-list 'auto-mode-alist '("/robots\\.txt\\'" . robots-txt-mode))

7.71. ruby-mode

(autoload-if-found '(ruby-mode) "ruby-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.rb$" . ruby-mode))
(add-to-list 'auto-mode-alist '("\\.irbrc$" . ruby-mode))
(add-to-list 'auto-mode-alist '("Capfile" . ruby-mode))
(add-to-list 'auto-mode-alist '("Gemfile" . ruby-mode))
(add-to-list 'auto-mode-alist '("Schemafile" . ruby-mode))
(add-to-list 'auto-mode-alist '(".pryrc" . ruby-mode))
(add-to-list 'auto-mode-alist '("Fastfile" . ruby-mode))
(add-to-list 'auto-mode-alist '("Matchfile" . ruby-mode))
(add-to-list 'auto-mode-alist '("Procfile" . ruby-mode))
(add-to-list 'auto-mode-alist '(".git-pr-template" . ruby-mode))
(add-to-list 'auto-mode-alist '(".gemrc" . ruby-mode))
(add-to-list 'auto-mode-alist '("\\.Brewfile" . ruby-mode))

(with-eval-after-load 'ruby-mode
  ;; config
  (setopt ruby-insert-encoding-magic-comment nil))

7.72. rust-mode

(autoload-if-found '(rust-mode) "rust-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.rs$" . rust-mode))

(with-eval-after-load 'rust-rustfmt
  ;; config
  (setopt rust-format-on-save t))

7.73. scala-mode

(autoload-if-found '(scala-mode) "scala-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.scala$" . scala-mode))

7.74. scheme-mode

(add-to-list 'auto-mode-alist '("\\.scheme$" . scheme-mode))
(add-to-list 'auto-mode-alist '(".guix-channel" . scheme-mode))

(with-eval-after-load 'scheme
  ;; config
  (setopt scheme-program-name "gosh -i"))

7.75. scad-mode

(autoload-if-found '(scad-mode) "scad-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.scad\\'" . scad-mode))

7.76. scss-mode

(autoload-if-found '(scss-mode) "scss-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.scss$" . scss-mode))
(add-to-list 'auto-mode-alist '("\\.sass$" . scss-mode))

(with-eval-after-load 'scss-mode
  ;; hooks
  (add-hook 'scss-mode-hook #'flycheck-mode))

7.77. shell-mode

(autoload-if-found '(shell-mode) "shell-mode" nil t)

(define-derived-mode console-mode shell-mode "console")

7.78. slim-mode

(autoload-if-found '(slim-mode) "slim-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.slim$" . slim-mode))

7.79. solidity-mode

(autoload-if-found '(solidity-mode) "solidity-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.sol$" . solidity-mode))

7.80. ssh-config-mode

(autoload-if-found '(ssh-config-mode ssh-known-hosts-mode ssh-authorized-keys-mode) "ssh-config-mode" nil t)

(add-to-list 'auto-mode-alist '("/\\.ssh/config\\(\\.d/.*\\.conf\\)?\\'" . ssh-config-mode))
(add-to-list 'auto-mode-alist '("/sshd?_config\\(\\.d/.*\\.conf\\)?\\'" . ssh-config-mode))
(add-to-list 'auto-mode-alist '("/known_hosts\\'" . ssh-config-mode))
(add-to-list 'auto-mode-alist '("/authorized_keys2?\\'" . ssh-config-mode))

7.81. sql-mode

(with-eval-after-load 'sql
  (load-library "sql-indent")

  ;; config
  (setq sql-user "root")
  (setq sql-password "P@ssw0rd")
  (setq sql-server "127.0.0.1")
  (setq sql-port 13306)
  (setq sql-mysql-login-params '(server port user password database))

  ;; hook
  (add-hook 'sql-mode-hook #'flycheck-mode))

7.82. swift-mode

(autoload-if-found '(swift-mode) "swift-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.swift$" . swift-mode))

7.83. syslog-mode

(autoload-if-found '(syslog-mode) "syslog-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.log$" . syslog-mode))

7.84. systemd-mode

(autoload-if-found '(systemd-mode) "systemd" nil t)

(add-to-list 'auto-mode-alist '("\\.nspawn\\'" . systemd-mode))
(add-to-list 'auto-mode-alist `(,(rx (+? (any "a-zA-Z0-9-_.@\\")) "."
                                     (or "automount" "busname" "mount" "service" "slice"
                                         "socket" "swap" "target" "timer" "link" "netdev" "network")
                                     string-end)
                                . systemd-mode))
(add-to-list 'auto-mode-alist `(,(rx ".#"
                                     (or (and (+? (any "a-zA-Z0-9-_.@\\")) "."
                                              (or "automount" "busname" "mount" "service" "slice"
                                                  "socket" "swap" "target" "timer" "link" "netdev" "network"))
                                         "override.conf")
                                     (= 16 (char hex-digit)) string-end)
                                . systemd-mode))
(add-to-list 'auto-mode-alist `(,(rx "/systemd/" (+? anything) ".d/" (+? (not (any ?/))) ".conf" string-end)
                                . systemd-mode))

7.85. terraform-mode

(autoload-if-found '(terraform-mode terraform-format-on-save-mode) "terraform-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.tf$" . terraform-mode))

(with-eval-after-load 'terraform-mode
  ;; hooks
  (add-hook 'terraform-mode-hook #'terraform-format-on-save-mode)
  (add-hook 'terraform-mode-hook #'flycheck-mode))

7.86. text-mode

(autoload-if-found '(conf-space-mode) "conf-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.tigrc$" . conf-space-mode))
(add-to-list 'auto-mode-alist '("\\.editrc$" . conf-space-mode))
(add-to-list 'auto-mode-alist '("\\.inputrc$" . conf-space-mode))
(add-to-list 'auto-mode-alist '("\\.colorrc$" . conf-space-mode))
(add-to-list 'auto-mode-alist '("\\.asdfrc$" . conf-space-mode))
(add-to-list 'auto-mode-alist '("credentials$" . conf-space-mode))

7.87. toml-mode

(autoload-if-found '(toml-mode) "toml-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.toml$" . toml-mode))

(with-eval-after-load 'toml-mode
  ;; hooks
  (add-hook 'toml-mode-hook #'flycheck-mode))

7.88. tmux-mode

(autoload-if-found '(tmux-mode) "tmux-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.tmux\\.conf$" . tmux-mode))

7.89. typescript-mode

(autoload-if-found '(typescript-mode) "typescript-mode" nil t)

;; for ts/deno
(add-to-list 'auto-mode-alist '("\\.ts$" . typescript-mode))

;; for tsx
(define-derived-mode typescript-tsx-mode typescript-mode "tsx")
(add-to-list 'auto-mode-alist '("\\.jsx$" . typescript-tsx-mode))
(add-to-list 'auto-mode-alist '("\\.tsx$" . typescript-tsx-mode))

7.90. v-mode

(autoload-if-found '(v-mode v-menu v-format-buffer) "v-mode" nil t)

(add-to-list 'auto-mode-alist '("\\(\\.v?v\\|\\.vsh\\)$" . v-mode))

(with-eval-after-load 'v-mode
  ;; keybind
  (define-key v-mode-map (kbd "M-z") #'v-menu)
  (define-key v-mode-map (kbd "C-c C-f") #'v-format-buffer))

7.91. vue-mode

(autoload-if-found '(vue-mode) "vue-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.vue$" . vue-mode))

(with-eval-after-load 'vue-html-mode
  ;; config
  (setopt vue-html-extra-indent 4))

7.92. vimrc-mode

(autoload-if-found '(vimrc-mode) "vimrc-mode" nil t)

(add-to-list 'auto-mode-alist '("vimrc" . vimrc-mode))
(add-to-list 'auto-mode-alist '("\\.vim\\(rc\\)?\\'" . vimrc-mode))

7.93. wat-mode

(autoload-if-found '(wat-mode) "wat-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.wat?\\'" . wat-mode))

7.94. web-mode

(autoload-if-found '(web-mode) "web-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.html$" . web-mode))
(add-to-list 'auto-mode-alist '("\\.erb$" . web-mode))
(add-to-list 'auto-mode-alist '("\\.gsp$" . web-mode))
(add-to-list 'auto-mode-alist '("\\.svg$" . web-mode))
(add-to-list 'auto-mode-alist '("\\.tpl$" . web-mode))
(add-to-list 'auto-mode-alist '("\\.liquid$" . web-mode))

(with-eval-after-load 'web-mode
  ;; config
  (setopt web-mode-comment-style 2)
  (setopt web-mode-enable-auto-pairing nil)
  (setopt web-mode-enable-auto-indentation nil))

7.95. web-php-blade-mode

(autoload-if-found '(web-php-blade-mode) "web-php-blade-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.blade\\.php$" . web-php-blade-mode))

7.96. wolfram-mode

(autoload-if-found '(wolfram-mode run-wolfram) "wolfram-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.m$" . wolfram-mode))
(add-to-list 'auto-mode-alist '("\\.nb$" . wolfram-mode))
(add-to-list 'auto-mode-alist '("\\.cbf$" . wolfram-mode))

(with-eval-after-load 'wolfram-mode
  ;; config
  (setopt wolfram-path "path-to-dir"))

7.97. yaml-mode

(autoload-if-found '(yaml-mode) "yaml-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.ya?ml$" . yaml-mode))
(add-to-list 'auto-mode-alist '("\\.aclpolicy$" . yaml-mode))

(with-eval-after-load 'yaml-mode
  ;; hooks
  (add-hook 'yaml-mode-hook #'flycheck-mode))

7.98. yarn-mode

(autoload-if-found '(yarn-mode) "yarn-mode" nil t)

(add-to-list 'auto-mode-alist '("yarn\\.lock\\'" . yarn-mode))

7.99. zig-mode

(autoload-if-found '(zig-mode) "zig-mode" nil t)

(add-to-list 'auto-mode-alist '("\\.zig$" . zig-mode))

8. IME

8.1. ddskk

(autoload-if-found '(skk-mode) "ddskk-autoloads" nil t)

(keymap-global-set "C-x C-j" #'skk-mode)

(defun my/skk-C-j-key (arg)
  (interactive "P")
  (cond
   ((and (null (skk-in-minibuffer-p))
         (null skk-henkan-mode))
    (skk-emulate-original-map arg))
   (t
    (skk-kakutei arg))))

(with-eval-after-load 'skk
  ;; config
  (setq skk-preload t)
  (setq default-input-method "japanese-skk"))

(with-eval-after-load 'skk-vars
  ;; use skkserv
  (when-darwin
   (setq skk-server-host "localhost")
   (setq skk-server-portnum 1178))

  ;; guix
  (setq skk-byte-compile-init-file t)
  (setq skk-isearch-mode-enable 'always)
  (setq skk-egg-like-newline t)
  (setq skk-show-annotation nil)
  (setq skk-auto-insert-paren t)

  ;; azik
  (setq skk-use-azik t)
  (setq skk-azik-keyboard-type 'jp106)

  ;; ref: https://github.com/skk-dev/ddskk/blob/master/etc/dot.skk#L752-L768
  (add-to-list 'skk-rom-kana-rule-list '(skk-kakutei-key nil my/skk-C-j-key)))

8.2. ddskk-posframe

(autoload-if-found '(ddskk-posframe-mode) "ddskk-posframe" nil t)

(with-eval-after-load 'skk
  ;; hooks
  (add-hook 'skk-mode-hook #'ddskk-posframe-mode))

9. Coding

9.1. Check

9.1.1. flycheck

(autoload-if-found '(flycheck-mode flycheck-define-checker) "flycheck" nil t)

9.1.2. TODO flycheck-textlint

;; (add-hook 'emacs-startup-hook
;;           #'(lambda ()
;;               (flycheck-define-checker textlint
;;                 "A linter for prose."
;;                 :command ("npx" "textlint" "--format" "unix" source-inplace)
;;                 :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 (org-mode))

;;               (with-eval-after-load 'flycheck
;;                 (add-to-list 'flycheck-checkers 'textlint))))

9.1.3. flycheck-elsa

(autoload-if-found '(flycheck-elsa-setup) "flycheck-elsa" nil t)

(with-eval-after-load 'elisp-mode
  ;; hooks
  (add-hook 'emacs-lisp-mode-hook #'flycheck-elsa-setup))

9.1.4. flycheck-projectile

(autoload-if-found '(flycheck-projectile-list-errors) "flycheck-projectile" nil t)

9.1.5. flycheck-cfn

(autoload-if-found '(flycheck-cfn-setup) "flycheck-cfn" nil t)

(with-eval-after-load 'cfn-mode
  ;; hooks
  (add-hook 'cfn-mode-hook #'flycheck-elsa-setup))

9.2. Completion

9.2.1. corfu

(autoload-if-found '(global-corfu-mode) "corfu" nil t)

(add-hook 'emacs-startup-hook #'global-corfu-mode)

(with-eval-after-load 'corfu
  ;; config
  (setopt corfu-auto t)
  (setopt corfu-auto-delay 0.2)
  (setopt corfu-cycle t)
  (setopt corfu-on-exact-match nil))

(with-eval-after-load 'indent
  ;; config
  (setopt tab-always-indent 'complete))

9.2.2. cape

(autoload-if-found '(cape-file
                     cape-dabbrev
                     cape-elisp-block
                     cape-history
                     cape-keyword) "cape" nil t)

(with-eval-after-load 'minibuffer
  (add-to-list 'completion-at-point-functions #'cape-dabbrev)
  (add-to-list 'completion-at-point-functions #'cape-file)
  (add-to-list 'completion-at-point-functions #'cape-elisp-block)
  (add-to-list 'completion-at-point-functions #'cape-history))

9.2.3. prescient

(autoload-if-found '(prescient-persist-mode) "prescient" nil t)

(add-hook 'emacs-startup-hook #'prescient-persist-mode)

(with-eval-after-load 'prescient
  ;; config
  (setopt prescient-aggressive-file-save t))

9.2.4. kind-icon

(autoload-if-found '(kind-icon-margin-formatter) "kind-icon" nil t)

(with-eval-after-load 'corfu
  (add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter))

9.3. Git

9.3.1. magit

(autoload-if-found '(global-git-commit-mode) "git-commit" nil t)
(autoload-if-found '(magit-status magit-blame) "magit")

(add-hook 'emacs-startup-hook #'global-git-commit-mode)

(keymap-global-set "C-x g" #'my/magit-status)
(keymap-global-set "C-x G" #'magit-blame)

(defun my/magit-status ()
  (interactive)
  (let ((default-directory (locate-dominating-file default-directory ".git")))
    (magit-status)))

(with-eval-after-load 'magit
  ;; config
  (setopt magit-refresh-status-buffer nil))

(with-eval-after-load 'magit-status
  ;; config
  (setopt magit-status-sections-hook
          '(magit-insert-status-headers
            ;; magit-insert-merge-log
            ;; magit-insert-rebase-sequence
            ;; magit-insert-am-sequence
            ;; magit-insert-sequencer-sequence
            ;; magit-insert-bisect-output
            ;; magit-insert-bisect-rest
            ;; magit-insert-bisect-log
            magit-insert-untracked-files
            magit-insert-unstaged-changes
            magit-insert-staged-changes
            ;; magit-insert-stashes
            magit-insert-unpushed-to-pushremote
            magit-insert-unpushed-to-upstream-or-recent
            magit-insert-unpulled-from-pushremote
            magit-insert-unpulled-from-upstream))


  ;; keybinds
  (define-key magit-status-mode-map (kbd "C-j") #'magit-visit-thing))

(with-eval-after-load 'magit-log
  ;; keybinds
  (define-key magit-log-mode-map (kbd "C-j") #'magit-visit-thing))

9.3.2. magit-file-icons

(autoload-if-found '(magit-file-icons-mode) "magit-file-icons" nil t)

;; (with-eval-after-load 'magit
;;   (add-hook 'magit-mode-hook #'magit-file-icons-mode))

9.3.3. magit-gptcommit

(autoload-if-found '(magit-gptcommit-status-buffer-setup
                     magit-gptcommit-mode
                     magit-gptcommit-commit-accept) "magit-gptcommit" nil t)

;; (magit-gptcommit-status-buffer-setup)

(with-eval-after-load 'magit
  ;; hooks
  (add-hook 'magit-mode #'magit-gptcommit-mode))

(with-eval-after-load 'git-commit
  ;; keybinds
  (define-key git-commit-mode-map (kbd "C-c C-g") #'magit-gptcommit-commit-accept))

9.3.4. magit-forge

;; (add-hook 'magit-mode-hook #'(lambda () (require 'forge)))

9.3.5. git-gutter

(autoload-if-found '(git-gutter-mode) "git-gutter" nil t)

(with-eval-after-load 'git-gutter
  ;; config
  (setopt git-gutter:update-hooks '(after-save-hook after-revert-hook)))

9.3.6. git-gutter-fringe

(autoload-if-found '(git-gutter-fr:init
                     git-gutter-fr:view-diff-infos
                     git-gutter-fr:clear) "git-gutter-fringe" nil t)

(with-eval-after-load 'git-gutter
  ;; config
  (setopt git-gutter-fr:side 'right-fringe)
  (setopt git-gutter:window-width -1)
  (setopt git-gutter:init-function #'git-gutter-fr:init)
  (setopt git-gutter:view-diff-function #'git-gutter-fr:view-diff-infos)
  (setopt git-gutter:clear-function #'git-gutter-fr:clear))

9.3.7. git-timemachine

(autoload-if-found '(git-timemachine) "git-timemachine" nil t)

9.3.8. gist

(autoload-if-found '(gist-mode) "gist" nil t)

9.3.9. blamer

(autoload-if-found '(blamer-mode) "blamer" nil t)

9.3.10. git-auto-commit-mode

(autoload-if-found '(git-auto-commit-mode) "git-auto-commit-mode" nil t)

(with-eval-after-load 'git-auto-commit-mode
  ;; config
  (setopt gac-automatically-push-p t)
  (setopt gac-silent-message-p t)
  (setopt gac-debounce-interval (* 60 60 3))
  (setopt gac-default-message "Update"))

9.4. Keyboard

9.4.1. key-chord

(autoload-if-found '(key-chord-mode key-chord-define-global) "key-chord" nil t)

(add-hook 'emacs-startup-hook #'key-chord-mode)
(add-hook 'emacs-startup-hook #'(lambda ()
                               (key-chord-define-global "fj" #'view-mode)
                               (key-chord-define-global "jf" #'view-mode)))

9.4.2. key-combo

(autoload-if-found '(key-combo-mode key-combo-define-local) "key-combo" nil t)

;; for php-mode
(with-eval-after-load 'php-mode
  ;; (add-hook 'php-mode-hook
  ;;           #'(lambda ()
  ;;               (key-combo-mode)
  ;;               (when (window-system)
  ;;                 (key-combo-define-local (kbd ",>") " => "))
  ;;               ;; (key-combo-define-local (kbd "+") '("+" " + " "++" " ++ "))
  ;;               ;; (key-combo-define-local (kbd "-") '("-" " - " "--" " -- "))
  ;;               ;; (key-combo-define-local (kbd "*") '("*" "**" " * "))
  ;;               ;; (key-combo-define-local (kbd "=") '("=" " = " "==" "==="))
  ;;               ))
  )

;; for typescript-tsx-mode
(with-eval-after-load 'typescript-tsx-mode
  ;; hooks
  (add-hook 'typescript-tsx-mode
            #'(lambda ()
                (key-combo-mode)
                (key-combo-define-local (kbd "</") #'web-mode-element-close))))

9.4.3. which-key

(autoload-if-found '(which-key-mode) "which-key" nil t)

(add-hook 'emacs-startup-hook #'which-key-mode)

9.4.4. dmacro

(autoload-if-found '(global-dmacro-mode) "dmacro" nil t)

(add-hook 'emacs-startup-hook #'global-dmacro-mode)

9.4.5. god-mode

(autoload-if-found '(god-mode) "god-mode" nil t)

9.5. Refactor

9.5.1. emr

(autoload-if-found '(emr-show-refactor-menu) "emr" nil t)

(with-eval-after-load 'prog-mode
  ;; keybinds
  (define-key prog-mode-map (kbd "M-RET") #'emr-show-refactor-menu))

9.6. Snippet

9.6.1. yasnippet

(autoload-if-found '(yas-global-mode) "yasnippet" nil t)

(add-hook 'emacs-startup-hook #'yas-global-mode)

9.6.2. consult-yasnippet

(autoload-if-found '(consult-yasnippet) "consult-yasnippet" nil t)

(keymap-global-set "C-c y" #'consult-yasnippet)
(keymap-global-set "C-c C-y" #'consult-yasnippet)

9.7. Narrowing

9.7.1. fancy-narrow

(autoload-if-found '(fancy-narrow-mode) "fancy-narrow" nil t)

;; (with-eval-after-load 'org
;;   (add-hook 'org-mode-hook #'fancy-narrow-mode))

;; (with-eval-after-load 'elisp-mode
;;   (add-hook 'emacs-lisp-mode-hook #'fancy-narrow-mode))

;; (with-eval-after-load 'lisp-mode
;;   (add-hook 'lisp-mode-hook #'fancy-narrow-mode))

;; (with-eval-after-load 'clojure-mode
;;   (add-hook 'clojure-mode-hook #'fancy-narrow-mode))

9.7.2. origami

(autoload-if-found '(global-origami-mode origami-recursively-toggle-node origami-recursively-toggle-node) "origami" nil t)

(keymap-global-set "C-c t" #'origami-recursively-toggle-node)
(keymap-global-set "C-c C-t" #'origami-recursively-toggle-node)

(add-hook 'emacs-startup-hook #'global-origami-mode)

9.8. LSP

9.8.1. eglot

(autoload-if-found '(eglot) "eglot" nil t)

(with-eval-after-load 'eglot
  ;; config
  (setopt eglot-events-buffer-size nil)
  (setopt eglot-autoshutdown t)
  (setopt eglot-extend-to-xref t))

9.8.2. lsp-mode

(autoload-if-found '(lsp lsp-deferred lsp-org lsp-register-client make-lsp-client) "lsp-mode" nil t)
(autoload-if-found '(lsp-lens-mode lsp-lens-refresh lsp-lens--enable) "lsp-lens" nil t)
(autoload-if-found '(lsp-modeline-workspace-status-mode) "lsp-modeline" nil t)
(autoload-if-found '(lsp-headerline-breadcrumb-mode) "lsp-headerline" nil t)
(autoload-if-found '(lsp-diagnostics-mode) "lsp-diagnostics" nil t)

(with-eval-after-load 'lsp-mode
  (add-to-list 'lsp-language-id-configuration '("php-ts-mode" . "php"))

  ;; ignore path
  (add-to-list 'lsp-file-watch-ignored-directories "[/\\\\]vendor")
  (add-to-list 'lsp-file-watch-ignored-directories "[/\\\\]storage")
  (add-to-list 'lsp-file-watch-ignored-directories "[/\\\\]docs")
  (add-to-list 'lsp-file-watch-ignored-directories "[/\\\\]target")
  (add-to-list 'lsp-file-watch-ignored-directories "[/\\\\].calva")
  (add-to-list 'lsp-file-watch-ignored-directories "[/\\\\].clj-kondo")
  (add-to-list 'lsp-file-watch-ignored-directories "[/\\\\].direnv")

  ;; enable flycheck
  (add-hook 'lsp-mode-hook #'flycheck-mode)

  ;; enable diagnostics
  (add-hook 'lsp-configure-hook #'lsp-diagnostics-mode)

  ;; config
  (setopt lsp-idle-delay 0.8)
  (setopt lsp-enable-links nil)
  (setopt lsp-log-io nil)
  (setopt lsp-file-watch-threshold 20000))

(with-eval-after-load 'lsp-rename
  (advice-add 'lsp-rename :before #'(lambda (&rest _) (remove-hook 'find-file-hooks #'view-mode)))
  (advice-add 'lsp-rename :after #'(lambda (&rest _) (add-hook 'find-file-hooks #'view-mode))))

(with-eval-after-load 'lsp-diagnostics
  ;; config
  (setopt lsp-diagnostics-flycheck-default-level 'info))

(with-eval-after-load 'lsp-completion
  ;; config
  (setopt lsp-completion-no-cache t)
  (setopt lsp-prefer-capf t))

(with-eval-after-load 'lsp-php
  ;; for intelephense
  (setopt lsp-intelephense-telemetry-enabled t)
  (setopt lsp-intelephense-files-exclude ["**/.git/**" "**/.svn/**" "**/.hg/**" "**/CVS/**" "**/.DS_Store/**"
                                          "**/node_modules/**" "**/bower_components/**" "**/vendor/**/{Test,test,Tests,tests}/**"
                                          "**/.direnv/**"]))

(with-eval-after-load 'lsp-javascript
  ;; for typescript-language-server
  (setopt lsp-clients-typescript-log-verbosity "info")
  (setopt lsp-typescript-references-code-lens-enabled t)
  (setopt lsp-typescript-implementations-code-lens-enabled t)
  (setopt lsp-javascript-display-return-type-hints t)
  (setopt lsp-javascript-display-parameter-type-hints t)
  (setopt lsp-javascript-display-parameter-name-hints-when-argument-matches-name t)
  (setopt lsp-javascript-display-property-declaration-type-hints t)
  (setopt lsp-javascript-display-variable-type-hints t))

(with-eval-after-load 'lsp-completion
  ;; config
  (setopt lsp-completion-provider :none))

(with-eval-after-load 'lsp-ruby
  ;; config
  (setopt lsp-solargraph-autoformat t)
  (setopt lsp-solargraph-multi-root nil))

(with-eval-after-load 'lsp-nil
  ;; config
  (setopt lsp-nix-nil-max-mem 100000))

9.8.3. TODO emacs-ccls

;; (with-eval-after-load 'lsp-mode
;;   (add-hook 'lsp-mode-hook #'(lambda () (require 'ccls))))

9.8.4. lsp-php-key

(with-eval-after-load 'lsp-php
  (setopt lsp-intelephense-licence-key "00OXTX8OROOJH9P"))

9.8.5. consult-lsp

(autoload-if-found '(consult-lsp-symbols) "consult-lsp" nil t)

(with-eval-after-load 'lsp-mode
  (define-key lsp-mode-map [remap xref-find-apropos] #'consult-lsp-symbols))

9.8.6. lsp-treemacs

(autoload-if-found '(lsp-treemacs-sync-mode) "lsp-treemacs" nil t)

(with-eval-after-load 'lsp-mode
  ;; hooks
  (add-hook 'lsp-mode-hook #'lsp-treemacs-sync-mode))

(with-eval-after-load 'lsp-treemacs
  ;; config
  (setopt lsp-treemacs-error-list-severity 1)
  (setopt lsp-treemacs-error-list-current-project-only t))

9.8.7. lsp-docker

(autoload-if-found '(lsp-docker-start) "lsp-docker" nil t)

9.8.8. dap-mode

(autoload-if-found '(dap-debug) "dap-mode" nil t)
(autoload-if-found '(dap-hydra) "dap-hydra" nil t)
(autoload-if-found '(dap-ui-mode dap-ui-controls-mode) "dap-ui" nil t)
(autoload-if-found '(dap-tooltip-mode) "dap-mouse" nil t)
(autoload-if-found '(dap-php-setup) "dap-php" nil t)
(autoload-if-found '(dap-node-setup) "dap-node" nil t)
(autoload-if-found '(dap-go-setup) "dap-go" nil t)
(autoload-if-found '(dap-ruby-setup) "dap-ruby" nil t)

(with-eval-after-load 'dap-mode
  ;; keybind
  (define-key dap-mode-map (kbd "C-c d") #'dap-breakpoint-toggle)

  ;; hooks
  (add-hook 'dap-mode-hook #'dap-ui-mode)
  (add-hook 'dap-mode-hook #'dap-ui-controls-mode)
  (add-hook 'dap-mode-hook #'tooltip-mode)
  (add-hook 'dap-mode-hook #'dap-tooltip-mode)
  (add-hook 'dap-stopped-hook #'(lambda (arg) (call-interactively #'dap-hydra))))

(with-eval-after-load 'php-mode
  ;; hooks
  (add-hook 'php-mode-hook #'dap-php-setup))

(with-eval-after-load 'dap-php
  ;; config
  (setopt dap-php-debug-path `,(expand-file-name "xdebug/vscode-php-debug" dap-utils-extension-path))

  ;; register
  (dap-register-debug-template "Laravel Run Configuration"
                               (list :type "php"
                                     :request "launch"
                                     :mode "remote"
                                     :host "localhost"
                                     :port 9003)))

;; (with-eval-after-load 'js2-mode
;;   (add-hook 'js2-mode-hook #'dap-node-setup))

(with-eval-after-load 'go-mode
  ;; hooks
  (add-hook 'go-mode-hook #'dap-go-setup))

(with-eval-after-load 'ruby-mode
  ;; hooks
  (add-hook 'ruby-mode-hook #'dap-ruby-setup))

9.8.9. lsp-ui

(autoload-if-found '(lsp-ui-mode) "lsp-ui" nil t)

;; hook
(with-eval-after-load 'lsp-mode
  ;; hooks
  (add-hook 'lsp-mode-hook #'lsp-ui-mode))

;; lsp-ui-doc
(with-eval-after-load 'lsp-ui-doc
  ;; config
  (setopt lsp-ui-doc-enable t)
  (setopt lsp-ui-doc-show-with-cursor t)
  (setopt lsp-ui-doc-use-webkit t)
  (setopt lsp-ui-doc-include-signature t)
  (setopt lsp-ui-doc-delay 1)
  (setopt lsp-ui-doc-max-height 30))

;; lsp-ui-peek
(autoload-if-found '(lsp-ui-peek-find-references lsp-ui-peek-find-definitions lsp-ui-peek-find-implementation) "lsp-ui-peek" nil t)
(with-eval-after-load 'lsp-ui-peek
  ;; config
  (setopt lsp-ui-peek-enable nil)
  (setopt lsp-ui-peek-peek-height 30)
  (setopt lsp-ui-peek-list-width 60)
  (setopt lsp-ui-peek-fontify 'on-demand))

;; lsp-ui-imenu
(autoload-if-found '(lsp-ui-imenu) "lsp-ui-imenu" nil t)
(with-eval-after-load 'lsp-ui-imenu
  ;; config
  (setopt lsp-ui-imenu-enable nil)
  (setopt lsp-ui-imenu-kind-position 'top))

;; lsp-ui-sideline
(autoload-if-found '(lsp-ui-sideline-mode) "lsp-ui-sideline" nil t)
(with-eval-after-load 'lsp-ui-sideline
  ;; config
  (setopt lsp-ui-sideline-enable nil)
  (setopt lsp-ui-sideline-show-hover t))

;; keybind
(with-eval-after-load 'lsp-mode
  ;; hooks
  (define-key lsp-mode-map (kbd "C-c C-r") #'lsp-ui-peek-find-references)
  (define-key lsp-mode-map (kbd "C-c C-j") #'lsp-ui-peek-find-definitions)
  (define-key lsp-mode-map (kbd "C-c C-i") #'lsp-ui-peek-find-implementation)
  (define-key lsp-mode-map (kbd "C-c C-m") #'lsp-ui-imenu)
  (define-key lsp-mode-map (kbd "C-c C-s") #'lsp-ui-sideline-mode)
  (define-key lsp-mode-map (kbd "C-c C-d") #'lsp-ui-doc-mode))

9.8.10. lsp-scheme

(autoload-if-found '(lsp-scheme) "lsp-scheme" nil t)

(with-eval-after-load 'scheme
  ;; (add-hook 'scheme-mode-hook #'lsp-scheme)
  )

(with-eval-after-load 'lsp-scheme
  (setopt lsp-scheme-implementation "guile"))

9.8.11. TODO lsp-haskell

(autoload-if-found '(lsp) "lsp-haskell" nil t)

9.8.12. TODO lsp-pyright

;; (eval-when-compile
;;   (el-clone :repo "emacs-lsp/lsp-pyright"))

;; (with-delayed-execution
;;   (message "Install lsp-pyright...")
;;   (add-to-list 'load-path (locate-user-emacs-file "el-clone/lsp-pyright"))

;;   ;; (with-eval-after-load 'python-mode
;;   ;;   (add-hook 'python-mode-hook #'(lambda ()
;;   ;;                                   (require 'lsp-pyright)
;;   ;;                                   (lsp))))
;;   )

9.8.13. TODO lsp-bridge

;; (eval-when-compile
;;   (el-clone :repo "manateelazycat/lsp-bridge"))

;; (with-delayed-execution
;;   (message "Install lsp-bridge...")
;;   (add-to-list 'load-path (locate-user-emacs-file "el-clone/lsp-bridge"))

;;   (autoload-if-found '(lsp-bridge-mode) "lsp-bridge" nil t)

;;   (with-eval-after-load 'lsp-bridge
;;     ;; config
;;     (setopt lsp-bridge-php-lsp-server "phpactor")

;;     ;; keybind
;;     (define-key lsp-bridge-mode-map (kbd "M-.") #'lsp-bridge-find-impl)
;;     (define-key lsp-bridge-mode-map (kbd "C-c C-r") #'lsp-bridge-find-references)))

9.9. Syntax

9.9.1. syntax-subword

(autoload-if-found '(global-syntax-subword-mode) "syntax-subword" nil t)

(add-hook 'emacs-startup-hook #'global-syntax-subword-mode)

9.10. Undo

9.10.1. undo-tree

(autoload-if-found '(global-undo-tree-mode) "undo-tree" nil t)

(add-hook 'emacs-startup-hook #'global-undo-tree-mode)

(with-eval-after-load 'undo-tree
  (setopt undo-tree-auto-save-history nil))

9.11. Template

9.11.1. auto-insert

(autoload-if-found '(auto-insert-mode) "autoinsert" nil t)

;; (add-hook 'emacs-startup-hook #'auto-insert-mode)

(with-eval-after-load 'autoinsert
  (setopt auto-insert-directory "~/.emacs.d/auto-insert"))

9.12. View Mode

9.12.1. view-mode

(with-eval-after-load 'files
  (add-hook 'find-file-hooks #'view-mode))

(with-eval-after-load 'view
  ;; hooks
  (add-hook 'view-mode-hook #'my/enable-view-mode-automatically)

  ;; keybind
  (define-key view-mode-map (kbd "f") #'forward-char)
  (define-key view-mode-map (kbd "b") #'backward-char)
  (define-key view-mode-map (kbd "n") #'my/org-view-next-heading)
  (define-key view-mode-map (kbd "p") #'my/org-view-previous-heading)
  (define-key view-mode-map (kbd "@") #'set-mark-command)
  (define-key view-mode-map (kbd "C-c '") #'my/org-edit-special)
  (define-key view-mode-map (kbd "C-c C-C") #'my/org-ctrl-c-ctrl-c)
  (define-key view-mode-map (kbd "e") nil)
  (define-key view-mode-map (kbd "C-j") nil)
  (define-key view-mode-map (kbd "C-i") #'my/view-tab)
  (define-key view-mode-map (kbd "S-C-i") #'my/view-shifttab)

  ;; functions
  (defun my/org-view-next-heading ()
    (interactive)
    (if (and (derived-mode-p 'org-mode)
             (org-at-heading-p))
        (org-next-visible-heading 1)
      (next-line)))

  (defun my/org-view-previous-heading ()
    (interactive)
    (if (and (derived-mode-p 'org-mode)
             (org-at-heading-p))
        (org-previous-visible-heading 1)
      (previous-line)))

  (defun my/view-tab ()
    (interactive)
    (when (and (derived-mode-p 'org-mode)
               (or (org-at-heading-p)
                   (org-at-property-drawer-p)))
      (let ((view-mode nil))
        (org-cycle))))

  (defun my/view-shifttab ()
    (interactive)
    (when (derived-mode-p 'org-mode)
      (let ((view-mode nil))
        (org-shifttab))))

  (defun my/org-edit-special ()
    (interactive)
    (when (derived-mode-p 'org-mode)
      (view-mode -1)
      (org-edit-special)))

  (defun my/org-ctrl-c-ctrl-c ()
    (interactive)
    (when (derived-mode-p 'org-mode)
      (view-mode -1)
      (org-ctrl-c-ctrl-c)))

  (defvar my/view-mode-timer nil)
  (defun my/enable-view-mode-automatically ()
    (if view-mode
        (when my/view-mode-timer
          (cancel-timer my/view-mode-timer))
      (setopt my/view-mode-timer (run-with-idle-timer (* 60 10) nil #'view-mode))))

  ;; advices
  (advice-add 'view--disable :before #'(lambda (&rest _) (view-lock-mode -1))))

9.12.2. view-lock-mode

(autoload-if-found '(view-lock-timer-start view-lock-quit) "view-lock-mode" nil t)

(with-eval-after-load 'view
  (add-hook 'view-mode-hook #'view-lock-timer-start))

(with-eval-after-load 'view-lock-mode
  (setopt view-lock-start-time (* 30 60)))

9.13. Utility

9.13.1. comint

(with-eval-after-load 'comint
  (setopt comint-buffer-maximum-size 100000)
  (setopt comint-prompt-read-only t)
  (setopt comint-terminfo-terminal "eterm-256color"))

9.13.2. crux

(autoload-if-found '(crux-open-with
                     crux-smart-open-line-above
                     crux-cleanup-buffer-or-region
                     crux-view-url
                     crux-transpose-windows
                     crux-duplicate-current-line-or-region
                     crux-duplicate-and-comment-current-line-or-region
                     crux-rename-file-and-buffer
                     crux-visit-term-buffer
                     crux-kill-other-buffers
                     crux-indent-defun
                     crux-top-join-lines
                     crux-kill-line-backwards) "crux" nil t)

;; keybind
(keymap-global-set "C-c o" #'crux-open-with)
(keymap-global-set "C-S-o" #'crux-smart-open-line-above)
(keymap-global-set "C-c u" #'crux-view-url)
(keymap-global-set "C-x 4 t" #'crux-transpose-windows)
(keymap-global-set "C-c d" #'crux-duplicate-current-line-or-region)
(keymap-global-set "C-c M-d" #'crux-duplicate-and-comment-current-line-or-region)
(keymap-global-set "C-c r" #'crux-rename-file-and-buffer)
(keymap-global-set "C-c M-t" #'crux-visit-term-buffer)
(keymap-global-set "C-c k" #'crux-kill-other-buffers)
(keymap-global-set "C-M-z" #'crux-indent-defun)
(keymap-global-set "C-^" #'crux-top-join-lines)
(keymap-global-set "C-DEL" #'crux-kill-line-backwards)

9.13.3. delsel

(autoload-if-found '(delete-selection-mode) "delsel" nil t)

(add-hook 'emacs-startup-hook #'delete-selection-mode)

9.13.4. dogears

(autoload-if-found '(dogears-go
                     dogears-back
                     dogears-forward
                     dogears-list
                     dogears-sidebar) "dogears" nil t)

;; keybind
(keymap-global-set "M-g d" #'dogears-go)
(keymap-global-set "M-g M-b" #'dogears-back)
(keymap-global-set "M-g M-f" #'dogears-forward)
(keymap-global-set "M-g M-d" #'dogears-list)
(keymap-global-set "M-g M-D" #'dogears-sidebar)

9.13.5. goto-addr

(autoload-if-found '(goto-address-prog-mode goto-address-mode) "goto-address" nil t)

(with-eval-after-load 'prog-mode
  (add-hook 'prog-mode-hook #'goto-address-prog-mode))

(with-eval-after-load 'text-mode
  (add-hook 'text-mode-hook #'goto-address-mode))

9.13.6. minimap

(autoload-if-found '(minimap-mode) "minimap" nil t)

(keymap-global-set "C-c m" #'minimap-mode)

(with-eval-after-load 'minimap
  (setopt minimap-window-location 'right)
  (setopt minimap-update-delay 0.2)
  (setopt minimap-minimum-width 20)
  (setopt minimap-major-modes '(prog-mode org-mode)))

9.13.7. puni

(autoload-if-found '(puni-global-mode puni-disable-puni-mode) "puni" nil t)

(add-hook 'emacs-startup-hook #'puni-global-mode)

(with-eval-after-load 'lisp-mode
  (add-hook 'lisp-mode-hook #'puni-disable-puni-mode))

(with-eval-after-load 'emacs-lisp-mode
  (add-hook 'emacs-lisp-mode-hook #'puni-disable-puni-mode))

(with-eval-after-load 'clojure-mode
  (add-hook 'clojure-mode-hook #'puni-disable-puni-mode))

(with-eval-after-load 'lisp-interaction-mode
  (add-hook 'lisp-interacton-mode-hook #'puni-disable-puni-mode))

(with-eval-after-load 'scheme
  (add-hook 'scheme-mode-hook #'puni-disable-puni-mode))

(with-eval-after-load 'simple
  (add-hook 'eval-expression-minibuffer-setup-hook #'puni-disable-puni-mode))

(with-eval-after-load 'ielm
  (add-hook 'inferior-emacs-lisp-mode-hook #'puni-disable-puni-mode))

(with-eval-after-load 'minibuffer
  (add-hook 'minibuffer-mode-hook #'puni-disable-puni-mode))

9.13.8. quickrun

(autoload-if-found '(quickrun) "quickrun" nil t)

9.13.9. restclient

(autoload-if-found '(restclient-mode) "restclient" nil t)

9.13.10. smartparens

(with-eval-after-load 'smartparens)

9.13.11. smart-jump

(with-eval-after-load 'smart-jump)

9.13.12. string-inflection

(autoload-if-found '(string-inflection-all-cycle) "string-inflection" nil t)

9.13.13. uuid

(autoload-if-found '(uuid-string) "uuid" nil t)

(defun my/uuid ()
  (interactive)
  (insert (uuid-string)))

(defalias 'uuid #'my/uuid)

9.13.14. woman

(autoload-if-found '(woman woman-find-file) "woman" nil t)

10. Remote Access

10.1. docker-tramp

(autoload-if-found '(docker-tramp-add-method) "docker-tramp" nil t)

;; (add-hook 'emacs-startup-hook #'docker-tramp-add-method)

;; (with-eval-after-load 'tramp
;;   (tramp-set-completion-function docker-tramp-method docker-tramp-completion-function-alist))

10.2. consult-tramp

(autoload-if-found '(consult-tramp) "consult-tramp" nil t)

11. Monitor

11.1. Process

11.1.1. proced

(autoload-if-found '(proced) "proced" nil t)

(with-eval-after-load 'proced
  ;; hooks
  (add-hook 'proced-mode-hook #'proced-toggle-auto-update)

  ;; config
  (setopt proced-auto-update-interval 10)
  (setopt proced-tree-flag t)
  (setopt proced-format 'long))

11.1.2. proced-narrow

(autoload-if-found '(proced-narrow) "proced-narrow" nil t)

(with-eval-after-load 'proced
  ;; keybinds
  (define-key proced-mode-map (kbd "/") #'proced-narrow))

11.2. System

11.2.1. symon

(autoload-if-found '(symon-mode) "symon" nil t)

11.3. Minor Modes

11.3.1. command-log-mode

(autoload-if-found '(clm/toggle-command-log-buffer) "command-log-mode" nil t)

(defalias 'command-log #'clm/toggle-command-log-buffer)

11.4. Statistics

11.4.1. esup

(autoload-if-found '(esup) "esup" nil t)

11.4.2. explain-pause-mode

(autoload-if-found '(explain-pause-mode) "explain-pause-mode" nil t)

11.4.3. disk-usage

(autoload-if-found '(disk-usage disk-usage-here) "disk-usage" nil t)

11.4.4. keyfreq

(autoload-if-found '(keyfreq-mode keyfreq-autosave-mode) "keyfreq" nil t)

(add-hook 'emacs-startup-hook #'keyfreq-mode)
(add-hook 'emacs-startup-hook #'keyfreq-autosave-mode)

11.4.5. uptimes

(autoload-if-found '(uptimes) "uptimes" nil t)

12. EWW

12.1. basic

(defun my/eww-rename-buffer ()
  "Rename the name of current EWW buffer."
  (let* ((title (plist-get eww-data :title))
         (url (file-name-base (eww-current-url)))
         (buffer-name (or (if (and title (> (length title) 0))
                              title
                            nil)
                          url "")))
    (rename-buffer (format "eww: %s" buffer-name) t)))

(with-eval-after-load 'eww
  ;; config
  (setopt eww-header-line-format nil)
  (setopt eww-search-prefix "http://www.google.co.jp/search?q="))

(with-eval-after-load 'eww
  ;; keybind
  (define-key eww-mode-map (kbd "C") #'eww-set-character-encoding)
  (define-key eww-mode-map (kbd "C-j") #'eww-follow-link)
  (define-key eww-mode-map (kbd "T") #'eww-goto-title-heading)
  (define-key eww-mode-map (kbd "T") #'eww-goto-title-heading))

(with-eval-after-load 'eww
  ;; hooks
  (add-hook 'eww-after-render #'my/eww-rename-buffer))

12.2. eww-lnum

(autoload-if-found '(eww-lnum-follow eww-lnum-universal) "eww-lnum" nil t)

(with-eval-after-load 'eww
  ;; keybinds
  (define-key eww-mode-map "f" #'eww-lnum-follow)
  (define-key eww-mode-map "F" #'eww-lnum-universal))

13. Dired

13.1. basic

(with-eval-after-load 'dired
  ;; config
  (setopt dired-dwim-target nil)
  (setopt dired-hide-details-hide-symlink-targets nil)
  (setopt dired-listing-switches "-alh")
  (setopt dired-recursive-copies 'always)
  (setopt dired-use-ls-dired nil)

  ;; hook
  (add-hook 'dired-mode-hook #'(lambda () (display-line-numbers-mode -1))))

13.2. dired-collapse

(autoload-if-found '(dired-collapse-mode) "dired-collapse" nil t)

(with-eval-after-load 'dired
  ;; hooks
  (add-hook 'dired-mode #'dired-collapse-mode))

13.3. dired-filter

(autoload-if-found '(dired-filter-mode) "dired-filter" nil t)

(with-eval-after-load 'dired
  ;; hooks
  (add-hook 'dired-mode #'dired-filter-mode))

13.4. dired-narrow

(autoload-if-found '(dired-narrow-mode) "dired-narrow" nil t)

(with-eval-after-load 'dired
  ;; hooks
  (add-hook 'dired-mode-hook #'dired-narrow-mode))

13.5. dired-open

(autoload-if-found '(dired-open-file) "dired-open" nil t)

(with-eval-after-load 'dired
  ;; keybind
  (define-key dired-mode-map [remap dired-find-file] #'dired-open-file))

13.6. dired-ranger

(autoload-if-found '() "dired-ranger" nil t)

13.7. dired-quick-sort

(autoload-if-found '(dired-quick-sort-setup) "dired-quick-sort" nil t)

(with-eval-after-load 'dired
  ;; hooks
  (add-hook 'dired-mode-hook #'dired-quick-sort-setup))

13.8. dired-subtree

(autoload-if-found '(dired-subtree-apply-filter) "dired-subtree" nil t)

13.9. diredfl

(autoload-if-found '(diredfl-global-mode) "diredfl" nil t)

(with-eval-after-load 'dired
  ;; hooks
  (add-hook 'dired-mode-hook #'diredfl-global-mode))

14. Search

14.1. wgrep

(autoload-if-found '(wgrep-setup) "wgrep" nil t)

(with-eval-after-load 'grep
  ;; hooks
  (add-hook 'grep-setup-hook 'wgrep-setup))

14.2. consult

(autoload-if-found '(consult-bookmark
                     consult-buffer
                     consult-buffer-other-frame
                     consult-buffer-other-tab
                     consult-buffer-other-window
                     consult-complex-command
                     consult-find
                     consult-flycheck
                     consult-focus-lines
                     consult-git-grep
                     consult-global-mark
                     consult-goto-line
                     consult-grep
                     consult-history
                     consult-isearch-history
                     consult-keep-lines
                     consult-line
                     consult-line-multi
                     consult-locate
                     consult-man
                     consult-mark
                     consult-outline
                     consult-project-buffer
                     consult-register
                     consult-register-load
                     consult-register-store
                     consult-ripgrep
                     consult-yank-pop
                     consult-mode-command

                     ;; other
                   consult-completion-in-region
                     consult-preview-at-point-mode
                     consult-register-window) "consult" nil t)

(autoload-if-found '(consult-compile-error) "consult-compile" nil t)
(autoload-if-found '(consult-org-heading consult-org-agenda) "consult-org" nil t)
(autoload-if-found '(consult-imenu consult-imenu-multi) "consult-imenu" nil t)
(autoload-if-found '(consult-kmacro) "consult-kmacro" nil t)
(autoload-if-found '(consult-xref) "consult-xref" nil t)

;; keybind
;; C-c bindings in `mode-specific-map'
(keymap-global-set "C-c M-x" #'consult-mode-command)
(keymap-global-set "C-c h" #'consult-history)

;; C-x bindings in `ctl-x-map'
(keymap-global-set "C-x M-:" #'consult-complex-command)
(keymap-global-set "C-x b" #'consult-buffer)
(keymap-global-set "C-x 4 b" #'consult-buffer-other-window)
(keymap-global-set "C-x 5 b" #'consult-buffer-other-frame)

;; Other custom bindings
(keymap-global-set "M-y" #'consult-yank-pop)

;; M-g bindings in `goto-map'
(keymap-global-set "M-g e" #'consult-compile-error)
(keymap-global-set "M-g f" #'consult-flycheck)
(keymap-global-set "M-g g" #'consult-goto-line)
(keymap-global-set "M-g M-g" #'consult-goto-line)
(keymap-global-set "M-g o" #'consult-outline)
(keymap-global-set "M-g m" #'consult-mark)
(keymap-global-set "M-g k" #'consult-global-mark)
(keymap-global-set "M-g i" #'consult-imenu)
(keymap-global-set "M-g I" #'consult-imenu-multi)

;; C-o bindings in `search-map'
(keymap-global-set "C-o" #'(lambda ()
                             (interactive)
                             (let ((word (thing-at-point 'symbol 'no-properties)))
                               (consult-line word))))

;; Isearch integration
(with-eval-after-load 'isearch
  (define-key isearch-mode-map (kbd "M-e") #'consult-isearch-history))

;; Minibuffer history
(with-eval-after-load 'minibuffer
  ;; config
  (setopt completion-in-region-function #'consult-completion-in-region)

  ;; keybinds
  (define-key minibuffer-local-map (kbd "M-s") #'consult-history)
  (define-key minibuffer-local-map (kbd "M-r") #'consult-history))

(with-eval-after-load 'simple
  (add-hook 'completion-list-mode #'consult-preview-at-point-mode))

(with-eval-after-load 'register
  (advice-add #'register-preview :override #'consult-register-window))

(with-eval-after-load 'xref
  (setopt xref-show-xrefs-function #'consult-xref)
  (setopt xref-show-definitions-function #'consult-xref))

14.3. affe

(autoload-if-found '(affe-grep) "affe" nil t)

(with-eval-after-load 'affe
  ;; config
  (setopt affe-highlight-function 'orderless-highlight-matches)
  (setopt affe-find-command "fd --color=never --full-path")
  (setopt affe-regexp-function 'orderless-pattern-compiler))

14.4. TODO embark

(autoload-if-found '(embark-act embark-dwim embark-prefix-help-command) "embark" nil t)

(keymap-global-set "C-." #'embark-act)
(keymap-global-set "C-h B" #'embark-prefix-help-command)

(with-eval-after-load 'embark
  ;; macros
  ;; (defmacro my/embark-ace-action (fn)
  ;;   `(defun ,(intern (concat "my/embark-ace-" (symbol-name fn))) ()
  ;;      (interactive)
  ;;      (with-demoted-errors "%s"
  ;;        (aw-switch-to-window (aw-select nil))
  ;;        (call-interactively (symbol-function ',fn)))))

  ;; (defmacro my/embark-split-action (fn split-type)
  ;;   `(defun ,(intern (concat "my/embark-"
  ;;                            (symbol-name fn)
  ;;                            "-"
  ;;                            (car (last (split-string
  ;;                                        (symbol-name split-type) "-"))))) ()
  ;;      (interactive)
  ;;      (funcall #',split-type)
  ;;      (call-interactively #',fn)))

  ;; (defun my/sudo-find-file (file)
  ;;   "Open FILE as root."
  ;;   (interactive "FOpen file as root: ")
  ;;   (when (file-writable-p file)
  ;;     (user-error "File is user writeable, aborting sudo"))
  ;;   (find-file (if (file-remote-p file)
  ;;                  (concat "/" (file-remote-p file 'method) ":"
  ;;                          (file-remote-p file 'user) "@" (file-remote-p file 'host)
  ;;                          "|sudo:root@"
  ;;                          (file-remote-p file 'host) ":" (file-remote-p file 'localname))
  ;;                (concat "/sudo:root@localhost:" file))))

  ;; config
  (setopt embark-mixed-indicator-delay 0.1)
  (setopt prefix-help-command #'embark-prefix-help-command)

  ;; ace-window
  ;; (define-key embark-file-map     (kbd "o") (my/embark-ace-action find-file))
  ;; (define-key embark-buffer-map   (kbd "o") (my/embark-ace-action switch-to-buffer))
  ;; (define-key embark-bookmark-map (kbd "o") (my/embark-ace-action bookmark-jump))

  ;; split window(2)
  ;; (define-key embark-file-map     (kbd "2") (my/embark-split-action find-file split-window-below))
  ;; (define-key embark-buffer-map   (kbd "2") (my/embark-split-action switch-to-buffer split-window-below))
  ;; (define-key embark-bookmark-map (kbd "2") (my/embark-split-action bookmark-jump split-window-below))

  ;; split window(3)
  ;; (define-key embark-file-map     (kbd "3") (my/embark-split-action find-file split-window-right))
  ;; (define-key embark-buffer-map   (kbd "3") (my/embark-split-action switch-to-buffer split-window-right))
  ;; (define-key embark-bookmark-map (kbd "3") (my/embark-split-action bookmark-jump split-window-right))

  ;; sudo
  ;; (define-key embark-file-map (kbd "S") #'my/sudo-find-file)

  ;; hooks
  (add-hook 'embark-collect-mode-hook #'consult-preview-at-point-mode))

14.5. TODO embark-consult

;; (autoload-if-found '(embark-consult-outline-candidates
;;                      embark-consult-imenu-candidates
;;                      embark-consult-imenu-or-outline-candidates) "embark-consult" nil t)

14.6. compile-multi

(autoload-if-found '(compile-multi) "compile-multi" nil t)
(autoload-if-found '(consult-compile-multi-mode) "consult-compile-multi" nil t)
(autoload-if-found '(compile-multi-embark-mode) "compile-multi-embark" nil t)

(keymap-global-set "C-x m" #'compile-multi)

;; (add-hook emacs-startup-hook #'consult-compile-multi-mode)
;; (add-hook emacs-startup-hook #'compile-multi-embark-mode)

14.7. vertico

(autoload-if-found '(vertico-mode) "vertico-autoloads" nil t)
(autoload-if-found '(vertico-flat-mode) "vertico-flat" nil t)

(add-hook 'emacs-startup-hook #'vertico-mode)

(with-eval-after-load 'vertico
  ;; config
  (setopt vertico-count 8)
  (setopt vertico-cycle t))

14.8. marginalia

(autoload-if-found '(marginalia-mode marginalia-cycle) "marginalia" nil t)

(with-eval-after-load 'minibuffer
  ;; hooks
  (define-key minibuffer-local-map (kbd "M-A") #'marginalia-cycle))

14.9. orderless

(autoload-if-found '(orderless-all-completions orderless-try-completion) "orderless" nil t)

(with-eval-after-load 'minibuffer
  ;; config
  (setopt completion-styles '(orderless basic))
  (setopt completion-category-overrides '((file (styles basic partial-completion))))
  (add-to-list 'completion-styles-alist '(orderless orderless-try-completion orderless-all-completions
                                                    "Completion of multiple components, in any order.")))

15. Buffer

15.1. auto-save-buffers-enhanced

(autoload-if-found '(auto-save-buffers-enhanced) "auto-save-buffers-enhanced" nil t)

;; (add-hook 'emacs-startup-hook #'auto-save-buffers-enhanced)

(with-eval-after-load 'auto-save-buffers-enhanced
  (setopt auto-save-buffers-enhanced-interval 10))

15.2. editorconfig

(autoload-if-found '(editorconfig-mode) "editorconfig" nil t)

(add-hook 'emacs-startup-hook #'editorconfig-mode)

15.3. persistent-scratch

(autoload-if-found '(persistent-scratch-setup-default) "persistent-scratch" nil t)

(add-hook 'emacs-startup-hook #'persistent-scratch-setup-default)

(with-eval-after-load 'persistent-scratch
  ;; config
  (setopt persistent-scratch-autosave-interval 100))

15.4. popwin

(autoload-if-found '(popwin-mode) "popwin" nil t)

(add-hook 'emacs-startup-hook #'popwin-mode)

15.5. whitespace

(autoload-if-found '(global-whitespace-mode) "whitespace" nil t)

(when window-system
  (add-hook 'emacs-startup-hook #'global-whitespace-mode))

(with-eval-after-load 'whitespace
  ;; config
  (setopt whitespace-style '(face tabs tab-mark spaces space-mark))
  (setopt whitespace-display-mappings '((space-mark ?\u3000 [?\u25a1])
                                        (tab-mark ?\t [?\xBB ?\t] [?\\ ?\t]))))

16. File

16.1. recentf

(autoload-if-found '(recentf-mode) "recentf" nil t)

(add-hook 'emacs-startup-hook #'recentf-mode)

(with-eval-after-load 'recentf
  ;; config
  (setopt recentf-auto-cleanup 'never)
  (setopt recentf-max-menu-items 10000)
  (setopt recentf-max-saved-items 10000)
  (setopt recentf-save-file  "~/.emacs.d/.recentf")
  (setopt recentf-exclude '(".recentf" "\\.gpg\\")))

16.2. open-junk-file

(autoload-if-found '(open-junk-file) "open-junk-file" nil t)

(keymap-global-set "C-x j" #'open-junk-file)

(with-eval-after-load 'open-junk-file
  ;; config
  (setopt open-junk-file-format "~/.emacs.d/.junk/%Y-%m-%d-%H%M%S."))

16.3. vlf

(autoload-if-found '(vlf-disable-for-function) "vlf-setup" t)

(with-eval-after-load 'dired
  ;; hooks
  (define-key dired-mode-map (kbd "V") #'dired-vlf))

16.4. sudo-edit

(autoload-if-found '(sudo-edit-current-file) "sudo-edit" nil t)

17. Project

17.1. projectile

(autoload-if-found '(projectile-mode
                   projectile-clear-known-projects
                   projectile-cleanup-known-projects) "projectile" nil t)

(add-hook 'emacs-startup-hook #'projectile-mode)

(with-eval-after-load 'projectile
  ;; keybind
  (keymap-global-set "M-p" #'projectile-command-map)
  (keymap-global-set "C-c p" #'projectile-command-map)

  ;; hooks
  (add-hook 'projectile-mode-hook #'my/update-projectile-known-projects)

  ;; function
  (defun my/update-projectile-known-projects ()
    (interactive)
    (projectile-clear-known-projects)
    (projectile-cleanup-known-projects)
    (setopt projectile-known-projects (mapcar
                                     (lambda (x)
                                       (abbreviate-file-name (concat x "/")))
                                     (split-string (shell-command-to-string "ghq list --full-path")))))

  ;; config
  (setopt projectile-switch-project-action 'projectile-dired)
  (setopt projectile-enable-caching t)
  (setopt projectile-use-git-grep t))

17.2. consult-projectile

(autoload-if-found '(consult-projectile-switch-to-buffer
                     consult-projectile-switch-to-buffer-other-window
                     consult-projectile-switch-to-buffer-other-frame
                     consult-projectile-find-dir
                     consult-projectile-find-file
                     consult-projectile-find-file-other-window
                     consult-projectile-find-file-other-frame
                     consult-projectile-recentf
                     consult-projectile-switch-project) "consult-projectile" nil t)

(with-eval-after-load 'projectile
  ;; advice
  (advice-add 'projectile-switch-to-buffer :override #'consult-projectile-switch-to-buffer)
  (advice-add 'projectile-switch-to-buffer-other-window :override #'consult-projectile-switch-to-buffer-other-window)
  (advice-add 'projectile-switch-to-buffer-other-frame :override #'consult-projectile-switch-to-buffer-other-frame)
  (advice-add 'projectile-find-dir :override #'consult-projectile-find-dir)
  (advice-add 'projectile-find-file :override #'consult-projectile-find-file)
  (advice-add 'projectile-find-file-other-window :override #'consult-projectile-find-file-other-window)
  (advice-add 'projectile-find-file-other-frame :override #'consult-projectile-find-file-other-frame)
  (advice-add 'projectile-recentf :override #'consult-projectile-recentf)
  (advice-add 'projectile-switch-project :override #'consult-projectile-switch-project)

  ;; keybind
  (keymap-global-set "C-x B" #'consult-projectile-switch-to-buffer))

18. Window

18.1. ace-window

(autoload-if-found '(ace-window) "ace-window" nil t)

(keymap-global-set "C-x o" #'ace-window)

(with-eval-after-load 'ace-window
  ;; config
  (setopt aw-dispatch-always t)
  (setopt aw-scope 'frame)
  (setopt aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l))
  (setopt aw-minibuffer-flag t))

18.2. writeroom-mode

(autoload-if-found '(writeroom-mode
                     writeroom-decrease-width
                     writeroom-increase-width
                     writeroom-adjust-width
                     writeroom-width)
                   "writeroom-mode" nil t)

(with-eval-after-load 'writeroom-mode
  ;; keybind
  (define-key writeroom-mode-map (kbd "C-M-<") #'writeroom-decrease-width)
  (define-key writeroom-mode-map (kbd "C-M->") #'writeroom-increase-width)
  (define-key writeroom-mode-map (kbd "C-M-=") #'writeroom-adjust-width)

  ;; config
  (setq writeroom-width 150))

18.3. zoom-window

(autoload-if-found '(zoom-window-zoom) "zoom-window" nil t)

(keymap-global-set "C-c C-z" #'zoom-window-zoom)

18.4. tab-bar

(autoload-if-found '(tab-bar-mode
                     tab-bar-history-mode
                     tab-previous
                     tab-next) "tab-bar" nil t)

(add-hook 'emacs-startup-hook #'tab-bar-history-mode)

(keymap-global-set "C-x C-t" tab-prefix-map)
(keymap-global-set "M-[" #'tab-previous)
(keymap-global-set "M-]" #'tab-next)


(with-eval-after-load 'tab-bar
  ;; rename tab-bar with projectile
  (define-key tab-prefix-map (kbd "r") #'my/tab-bar-rename-tab)

  ;; config
  (setq tab-bar-close-button-show nil)
  (setq tab-bar-close-last-tab-choice nil)
  (setq tab-bar-close-tab-select 'left)
  (setq tab-bar-history-mode nil)
  (setq tab-bar-new-tab-choice "*scratch*")
  (setq tab-bar-new-button-show nil)
  (setq tab-bar-tab-name-truncated-max 12)
  (setq tab-bar-separator " | ")

  ;; advice
  ;; close neotree when tab bar action
  ;; (advice-add 'tab-new :before #'(lambda (&rest _) (neotree-hide)))
  ;; (advice-add 'tab-next :before #'(lambda (&rest _) (neotree-hide)))
  ;; (advice-add 'tab-bar-switch-to-tab :before #'(lambda (&rest _) (neotree-hide)))

  ;; function
  (defun my/tab-bar-rename-tab ()
    (interactive)
    (let ((proj-name (projectile-project-name)))
      (tab-bar-rename-tab proj-name)))

  ;; hook
  (add-hook 'tab-bar-mode-hook #'(lambda () (display-line-numbers-mode -1))))

19. Cursor

19.1. avy

(autoload-if-found '(avy-goto-word-1) "avy" nil t)

(keymap-global-set "C-:" #'avy-goto-word-1)

(with-eval-after-load 'avy
  ;; config
  (setopt avy-all-windows nil)
  (setopt avy-background t))

19.2. avy-zap

(autoload-if-found '(avy-zap-up-to-char-dwim) "avy-zap" nil t)

(keymap-global-set "M-z" #'avy-zap-up-to-char-dwim)

19.3. expand-region

(autoload-if-found '(er/expand-region) "expand-region" nil t)

(add-hook 'emacs-startup-hook #'transient-mark-mode)

(keymap-global-set "C-M-@" #'er/expand-region)

19.4. multiple-cursors

(autoload-if-found '(mc/mark-next-like-this mc/mark-previous-like-this mc/mark-all-like-this) "multiple-cursors" nil t)

(keymap-global-set "C->" #'mc/mark-next-like-this)
(keymap-global-set "C-<" #'mc/mark-previous-like-this)
(keymap-global-set "C-c C-<" #'mc/mark-all-like-this)

20. Client

20.1. Mail

20.1.1. mu4e

(autoload-if-found '(mu4e) "mu4e" nil t)

(keymap-global-set "C-x C-w" #'mu4e)

(with-eval-after-load 'mu4e
  ;; config
  (setopt mail-user-agent 'mu4e-user-agent))

(with-eval-after-load 'mu4e-update
  ;; config
  (setopt mu4e-get-mail-command "offlineimap")
  (setopt mu4e-update-interval (* 5 60))
  (setopt mu4e-index-cleanup nil)
  (setopt mu4e-index-lazy-check t))

(with-eval-after-load 'mu4e-view
  ;; config
  (setopt mu4e-split-view 'horizontal))

(with-eval-after-load 'mu4e-folders
  ;; config
  (setopt mu4e-maildir-shortcuts '((:maildir "/INBOX" :key ?i)
                                   (:maildir "/Redmine" :key ?r)
                                   (:maildir "/GitHub" :key ?g)
                                   (:maildir "/Emacs" :key ?e)
                                   (:maildir "/Guix" :key ?u))))

(with-eval-after-load 'mm-decode
  (add-to-list 'mm-discouraged-alternatives "text/html")
  (add-to-list 'mm-discouraged-alternatives "text/richtext"))

20.1.2. TODO mu4e-views

;; (eval-when-compile
;;   (el-clone :repo "lordpretzel/mu4e-views"))

;; (with-delayed-execution
;; (message "Install mu4e-views...")
;;   (add-to-list 'load-path (locate-user-emacs-file "el-clone/mu4e-views"))

20.1.3. TODO mu4e-dashboard

;; (autoload-if-found '() "mu4e-dashboard" nil t)

20.2. Googling

20.2.1. google-this

(autoload-if-found '(google-this) "google-this" nil t)

20.2.2. google-translate

(autoload-if-found '(google-translate-at-point) "google-translate" nil t)

20.3. Client

20.3.1. md4rd

(autoload-if-found '(md4rd
                     md4rd-login
                     md4rd-visit
                     md4rd-widget-expand-all
                     md4rd-widget-collapse-all
                     md4rd-reply
                     md4rd-upvote
                     md4rd-downvote
                     md4rd-widget-toggle-line
                     md4rd-refresh-login
                     md4rd-indent-all-the-lines) "md4rd" nil t)

(with-eval-after-load 'md4rd
  (add-hook 'md4rd-mode-hook #'md4rd-indent-all-the-lines)
  (run-with-timer 0 3540 #'md4rd-refresh-login)

  ;; config
  (setopt md4rd-subs-active '(emacs lisp+Common_Lisp prolog clojure))
  ;; (setopt md4rd--oauth-access-token "your-access-token-here")
  ;; (setopt md4rd--oauth-refresh-token "your-refresh-token-here")

  ;; keymap
  (define-key md4rd-mode-map (kbd "u") 'tree-mode-goto-parent)
  (define-key md4rd-mode-map (kbd "o") 'md4rd-open)
  (define-key md4rd-mode-map (kbd "v") 'md4rd-visit)
  (define-key md4rd-mode-map (kbd "e") 'tree-mode-toggle-expand)
  (define-key md4rd-mode-map (kbd "E") 'md4rd-widget-expand-all)
  (define-key md4rd-mode-map (kbd "C") 'md4rd-widget-collapse-all)
  (define-key md4rd-mode-map (kbd "n") 'widget-forward)
  (define-key md4rd-mode-map (kbd "j") 'widget-forward)
  (define-key md4rd-mode-map (kbd "h") 'backward-button)
  (define-key md4rd-mode-map (kbd "p") 'widget-backward)
  (define-key md4rd-mode-map (kbd "k") 'widget-backward)
  (define-key md4rd-mode-map (kbd "l") 'forward-button)
  (define-key md4rd-mode-map (kbd "q") 'kill-current-buffer)
  (define-key md4rd-mode-map (kbd "r") 'md4rd-reply)
  (define-key md4rd-mode-map (kbd "u") 'md4rd-upvote)
  (define-key md4rd-mode-map (kbd "d") 'md4rd-downvote)
  (define-key md4rd-mode-map (kbd "t") 'md4rd-widget-toggle-line))

21. Theme

21.1. Font

21.1.1. fontset

(defconst my/enable-warning-log nil)

(defun set-fontset-font:around (set-fontset-font name target font-spec &optional frame add)
  "Warn if specified font is not installed."
  (if (stringp font-spec)
      (setopt font-spec (font-spec :family font-spec)))
  (if (and (fontp font-spec)
           (null (find-font font-spec))
           my/enable-warning-log)
      (warn "set-fontset-font: font %s is not found." (font-get font-spec :family))
    (ignore-errors
      (funcall set-fontset-font name target font-spec frame add))))

;; reset all settings in default fontset
(add-hook 'emacs-startup-hook
          #'(lambda ()
              (advice-add 'set-fontset-font :around #'set-fontset-font:around)

              (when (functionp 'set-fontset-font)
                (if (find-font (font-spec :family "Noto Sans"))
                    (set-fontset-font t '(0 . #x3fffff) "Noto Sans"))

                ;; multiple platform
                (set-fontset-font t 'latin "Noto Sans")
                (set-fontset-font t 'greek "Noto Sans")
                (set-fontset-font t 'phonetic "Noto Sans")
                (set-fontset-font t 'coptic "Noto Sans Coptic")
                (set-fontset-font t 'coptic "Noto Sans Symbols2" nil 'append)
                (set-fontset-font t 'cyrillic "Noto Sans")
                (set-fontset-font t 'armenian "Noto Sans Armenian")
                (set-fontset-font t 'hebrew "Noto Sans Hebrew")
                (set-fontset-font t 'arabic "Noto Sans Arabic")
                (set-fontset-font t 'syriac "Noto Sans Syriac")
                (set-fontset-font t 'thaana "Noto Sans Thaana")
                (set-fontset-font t 'nko "Noto Sans N'Ko")
                (set-fontset-font t 'samaritan "Noto Sans Samaritan")
                (set-fontset-font t 'mandaic "Noto Sans Mandaic")
                (set-fontset-font t 'devanagari "Noto Sans Devanagari")
                (set-fontset-font t 'bengali "Noto Sans Bengali")
                (set-fontset-font t 'gurmukhi "Noto Sans Gurmukhi")
                (set-fontset-font t 'gujarati "Noto Sans Gujanrati")
                (set-fontset-font t 'oriya "Noto Sans Oriya")
                (set-fontset-font t 'tamil "Noto Sans Tamil")
                (set-fontset-font t 'tamil "Noto Sans Tamil Supplement" nil 'append)
                (set-fontset-font t 'telugu "Noto Sans Telugu")
                (set-fontset-font t 'kannada "Noto Sans Kannada")
                (set-fontset-font t 'malayalam "Noto Sans Malayalam")
                (set-fontset-font t 'sinhala "Noto Sans Sinhala")
                (set-fontset-font t 'thai "Noto Sans Thai")
                (set-fontset-font t 'lao "Noto Sans Lao")
                (set-fontset-font t 'tibetan "Noto Sans Tibetan")
                (set-fontset-font t 'burmese "Noto Sans Myanmar")
                (set-fontset-font t 'georgian "Noto Sans Georgian")
                (set-fontset-font t 'hangul "Noto Sans CJK KR")
                (set-fontset-font t 'ethiopic "Noto Sans Ethiopic")
                (set-fontset-font t 'cherokee "Noto Sans Cherokee")
                (set-fontset-font t 'canadian-aboriginal "Noto Sans Canadian Aboriginal")
                (set-fontset-font t 'ogham "Noto Sans Ogham")
                (set-fontset-font t 'runic "Noto Sans Runic")
                (set-fontset-font t 'tagalog "Noto Sans Tagalog")
                (set-fontset-font t 'hanunoo "Noto Sans Hanunoo")
                (set-fontset-font t 'buhid "Noto Sans Buhid")
                (set-fontset-font t 'tagbanwa "Noto Sans Tagbanwa")
                (set-fontset-font t 'khmer "Noto Sans Khmer")
                (set-fontset-font t 'mongolian "Noto Sans Mongolian")
                (set-fontset-font t 'limbu "Noto Sans Limbu")
                (set-fontset-font t 'tai-le "Noto Sans Tai Le")
                (set-fontset-font t 'tai-lue "Noto Sans NewTaiLue")
                (set-fontset-font t 'buginese "Noto Sans Buginese")
                (set-fontset-font t 'tai-tham "Noto Sans Tai Tham")
                (set-fontset-font t 'balinese "Noto Sans Balinese")
                (set-fontset-font t 'sundanese "Noto Sans Sundanese")
                (set-fontset-font t 'vedic "Noto Sans Devanagari")
                (set-fontset-font t 'symbol "Noto Sans CJK JP")
                (set-fontset-font t 'symbol "Noto Sans Symbols2" nil 'append)
                (set-fontset-font t 'symbol "Noto Sans" nil 'append)
                (set-fontset-font t 'symbol "Noto Sans Math" nil 'append)
                (set-fontset-font t 'symbol "Noto Emoji" nil 'append)
                (set-fontset-font t 'symbol "Noto Sans Symbols" nil 'append)
                (set-fontset-font t 'braille "Noto Sans Symbols2")
                (set-fontset-font t 'batak "Noto Sans Batak")
                (set-fontset-font t 'lepcha "Noto Sans Lepcha")
                (set-fontset-font t 'ol-chiki "Noto Sans Ol Chiki")
                (set-fontset-font t 'glagolitic "Noto Sans Glagolitic")
                (set-fontset-font t 'tifinagh "Noto Sans Tifinagh")
                (set-fontset-font t 'han "Noto Sans CJK JP")
                (set-fontset-font t 'ideographic-description "Noto Sans CJK JP")
                (set-fontset-font t 'cjk-misc "Noto Sans CJK JP")
                (set-fontset-font t 'kana "Noto Sans CJK JP")
                (set-fontset-font t 'bopomofo "Noto Sans CJK TC")
                (set-fontset-font t 'kanbun "Noto Sans CJK JP")
                (set-fontset-font t 'yi "Noto Sans Yi")
                (set-fontset-font t 'lisu "Noto Sans Lisu")
                (set-fontset-font t 'vai "Noto Sans Vai")
                (set-fontset-font t 'bamum "Noto Sans Bamum")
                (set-fontset-font t 'syloti-nagri "Noto Sans Syloti Nagri")
                (set-fontset-font t 'north-indic-number "Noto Sans Devanagari")
                (set-fontset-font t 'phags-pa "Noto Sans Phags Pa")
                (set-fontset-font t 'saurashtra "Noto Sans Saurashtra")
                (set-fontset-font t 'kayah-li "Noto Sans Kayah Li")
                (set-fontset-font t 'rejang "Noto Sans Rejang")
                (set-fontset-font t 'javanese "Noto Sans Javanese")
                (set-fontset-font t 'cham "Noto Sans Cham")
                (set-fontset-font t 'tai-viet "Noto Sans Tai Viet")
                (set-fontset-font t 'meetei-mayek "Noto Sans Meetei Mayek")
                (set-fontset-font t 'vertical-form "Noto Sans CJK JP")
                (set-fontset-font t '(#xfe50 . #xfe6b) "Noto Sans CJK JP") ; symbol
                (set-fontset-font t '(#xfff9 . #xfffb) "Noto Sans Symbols2") ; nil
                (set-fontset-font t 'linear-b "Noto Sans Linear B")
                (set-fontset-font t 'aegean-number "Noto Sans Linear B")
                (set-fontset-font t 'ancient-greek-number "Noto Sans Symbols2")
                (set-fontset-font t 'ancient-symbol "Noto Sans Symbols2")
                (set-fontset-font t 'phaistos-disc "Noto Sans Symbols2")
                (set-fontset-font t 'lycian "Noto Sans Lycian")
                (set-fontset-font t 'carian "Noto Sans Carian")
                (set-fontset-font t 'old-italic "Noto Sans Old Italic")
                (set-fontset-font t 'gothic "Noto Sans Gothic")
                (set-fontset-font t 'old-permic "Noto Sans Old Permic")
                (set-fontset-font t 'ugaritic "Noto Sans Ugaritic")
                (set-fontset-font t 'old-persian "Noto Sans OldPersian")
                (set-fontset-font t 'deseret "Noto Sans Deseret")
                (set-fontset-font t 'shavian "Noto Sans Shavian")
                (set-fontset-font t 'osmanya "Noto Sans Osmanya")
                (set-fontset-font t 'osage "Noto Sans Osage")
                (set-fontset-font t 'elbasan "Noto Sans Elbasan")
                (set-fontset-font t 'caucasian-albanian "Noto Sans CaucAlban")
                (set-fontset-font t 'linear-a "Noto Sans Linear A")
                (set-fontset-font t 'cypriot-syllabary "Noto Sans Cypriot")
                (set-fontset-font t 'aramaic "Noto Sans ImpAramaic")
                (set-fontset-font t 'palmyrene "Noto Sans Palmyrene")
                (set-fontset-font t 'nabataean "Noto Sans Nabataean")
                (set-fontset-font t 'hatran "Noto Sans Hatran")
                (set-fontset-font t 'phoenician "Noto Sans Phoenician")
                (set-fontset-font t 'lydian "Noto Sans Lydian")
                (set-fontset-font t 'meroitic "Noto Sans Meroitic")
                (set-fontset-font t 'kharoshthi "Noto Sans Kharoshthi")
                (set-fontset-font t 'old-south-arabian "Noto Sans OldSouArab")
                (set-fontset-font t 'old-north-arabian "Noto Sans OldNorArab")
                (set-fontset-font t 'manichaean "Noto Sans Manichaean")
                (set-fontset-font t 'avestan "Noto Sans Avestan")
                (set-fontset-font t 'inscriptional-parthian "Noto Sans Inscriptional Parthian")
                (set-fontset-font t 'inscriptional-pahlavi "Noto Sans Inscriptional Pahlavi")
                (set-fontset-font t 'psalter-pahlavi "Noto Sans PsaPahlavi")
                (set-fontset-font t 'old-turkic "Noto Sans Old Turkic")
                (set-fontset-font t 'old-hungarian "Noto Sans OldHung")
                (set-fontset-font t 'hanifi-rohingya "Noto Sans HanifiRohg")
                (set-fontset-font t 'rumi-number "Noto Sans Symbols2")
                (set-fontset-font t 'old-sogdian "Noto Sans OldSogdian")
                (set-fontset-font t 'sogdian "Noto Sans Sogdian")
                (set-fontset-font t 'elymaic "Noto Sans Elymaic")
                (set-fontset-font t 'brahmi "Noto Sans Brahmi")
                (set-fontset-font t 'kaithi "Noto Sans Kaithi")
                (set-fontset-font t 'sora-sompeng "Noto Sans SoraSomp")
                (set-fontset-font t 'chakma "Noto Sans Chakma")
                (set-fontset-font t 'mahajani "Noto Sans Mahajani")
                (set-fontset-font t 'sharada "Noto Sans Sharada")
                (set-fontset-font t 'sinhala-archaic-number "Noto Sans Sinhala")
                (set-fontset-font t 'khojki "Noto Sans Khojki")
                (set-fontset-font t 'multani "Noto Sans Multani")
                (set-fontset-font t 'khudawadi "Noto Sans Khudawadi")
                (set-fontset-font t 'grantha "Noto Sans Grantha")
                (set-fontset-font t 'newa "Noto Sans Newa")
                (set-fontset-font t 'tirhuta "Noto Sans Tirhuta")
                (set-fontset-font t 'siddham "Noto Sans Siddham")
                (set-fontset-font t 'modi "Noto Sans Modi")
                (set-fontset-font t 'takri "Noto Sans Takri")
                (set-fontset-font t 'ahom "Noto Serif Ahom")
                (set-fontset-font t 'dogra "Noto Serif Dogra")
                (set-fontset-font t 'warang-citi "Noto Sans WarangCiti")
                (set-fontset-font t 'zanabazar-square "Noto Sans Zanabazar")
                (set-fontset-font t 'soyombo "Noto Sans Soyombo")
                (set-fontset-font t 'pau-cin-hau "Noto Sans PauCinHau")
                (set-fontset-font t 'bhaiksuki "Noto Sans Bhaiksuki")
                (set-fontset-font t 'marchen "Noto Sans Marchen")
                (set-fontset-font t 'masaram-gondi "Noto Sans Masaram Gondi")
                (set-fontset-font t 'gunjala-gondi "Noto Sans Gunjala Gondi")
                (set-fontset-font t 'cuneiform "Noto Sans Cuneiform")
                (set-fontset-font t 'cuneiform-numbers-and-punctuation "Noto Sans Cuneiform")
                (set-fontset-font t 'egyptian "Noto Sans EgyptHiero")
                (set-fontset-font t 'anatolian "Noto Sans AnatoHiero")
                (set-fontset-font t 'mro "Noto Sans Mro")
                (set-fontset-font t 'bassa-vah "Noto Sans Bassa Vah")
                (set-fontset-font t 'pahawh-hmong "Noto Sans Pahawh Hmong")
                (set-fontset-font t 'miao "Noto Sans Miao")
                (set-fontset-font t 'tangut "Noto Serif Tangut")
                (set-fontset-font t 'tangut-components "Noto Serif Tangut")
                (set-fontset-font t '(#x16fe0 . #x16fe0) "Noto Serif Tangut")
                (set-fontset-font t 'duployan-shorthand "Noto Sans Duployan")
                (set-fontset-font t 'byzantine-musical-symbol "Noto Music")
                (set-fontset-font t 'musical-symbol "Noto Music")
                (set-fontset-font t 'ancient-greek-musical-notation "Noto Music")
                (set-fontset-font t 'mayan-numeral "Noto Sans Mayan Numerals")
                (set-fontset-font t 'tai-xuan-jing-symbol "Noto Sans Symbols2")
                (set-fontset-font t 'counting-rod-numeral "Noto Sans Symbols2")
                (set-fontset-font t 'mathematical "Noto Sans Math")
                (set-fontset-font t 'wancho "Noto Sans Wancho")
                (set-fontset-font t 'mende-kikakui "Noto Sans Mende Kikakui")
                (set-fontset-font t 'adlam "Noto Sans Adlam")
                (set-fontset-font t 'indic-siyaq-number "Noto Sans Indic Siyaq Numbers")
                (set-fontset-font t '(#x1ee00 . #x1eeff) "Noto Sans Math") ; arabic
                (set-fontset-font t 'mahjong-tile "Noto Sans Symbols2")
                (set-fontset-font t 'domino-tile "Noto Sans Symbols2")
                (set-fontset-font t 'playing-cards "Noto Sans Symbols2")

                ;; non Noto fonts
                (set-fontset-font t 'kana "UniHentaiKana" nil 'append)
                (set-fontset-font t 'latin "Iosevka" nil 'append)
                (set-fontset-font t 'symbol "Iosevka" nil 'append)

                ;; Nerd Font (defined thru -#xfd46)
                (set-fontset-font t '( #xe000 .  #xf136) "Inconsolata Nerd Font"))))

21.1.2. font-lock-studio

(autoload-if-found '(font-lock-studio) "font-lock-studio" nil t)

21.2. Color

21.2.1. ansi-color

(autoload-if-found '(ansi-color-for-comint-mode-on) "ansi-color" nil t)

(with-eval-after-load 'shell-mode
  ;; hooks
  (add-hook 'shell-mode-hook #'ansi-color-for-comint-mode-on))

(with-eval-after-load 'compile
  ;; hooks
  (add-hook 'compilation-filter-hook
            #'(lambda ()
                (ansi-color-apply-on-region (point-min) (point-max)))))

21.2.2. highlight-indent-guides

(autoload-if-found '(highlight-indent-guides-mode) "highlight-indent-guides" nil t)

(with-eval-after-load 'yaml-mode
  ;; hooks
  (add-hook 'yaml-mode-hook 'highlight-indent-guides-mode))

(with-eval-after-load 'highlight-indent-guides
  ;; config
  (setopt highlight-indent-guides-responsive 'stack)
  (setopt highlight-indent-guides-method 'bitmap))

21.2.3. hl-todo

(autoload-if-found '(global-hl-todo-mode) "hl-todo" nil t)

(add-hook 'emacs-startup-hook #'global-hl-todo-mode)

(with-eval-after-load 'hl-todo
  ;; config
  (setopt hl-todo-keyword-faces
          '(("HOLD" . "#d0bf8f")
            ("TODO" . "#cc9393")
            ("NOW" . "#dca3a3")
            ("SOMEDAY" . "#dc8cc3")
            ("WAIT" . "#7cb8bb")
            ("DONE" . "#afd8af")
            ("FIXME" . "#cc9393"))))

21.2.4. xterm-color

(autoload-if-found '(xterm-color-filter) "xterm-color" nil t)

(add-hook 'emacs-startup-hook
          #'(lambda () (setenv "TERM" "xterm-256color")))

(with-eval-after-load 'xterm-color
  ;; config
  (setopt xterm-color-preserve-properties t))

21.3. Icon

21.3.1. emojify

(autoload-if-found '(global-emojify-mode) "emojify" nil t)

(add-hook 'emacs-startup-hook #'global-emojify-mode)

21.3.2. nerd-icons-dired

(autoload-if-found '(nerd-icons-dired-mode) "nerd-icons-dired" nil t)

(with-eval-after-load 'dired-mode
  (add-hook 'dired-mode-hook #'nerd-icons-dired-mode))

21.3.3. nerd-icons-completion

(autoload-if-found '(nerd-icons-completion-marginalia-setup) "nerd-icons-completion" nil t)

(with-eval-after-load 'marginalia
  (add-hook 'marginalia-mode-hook #'nerd-icons-completion-marginalia-setup))

21.4. Dashboard

(autoload-if-found '(dashboard-refresh-buffer) "dashboard" nil t)

(with-eval-after-load 'dashboard
  (setopt dashboard-startup-banner 'logo)
  (setopt dashboard-set-file-icons t)
  (setopt dashboard-startup-banner 4)
  (setopt dashboard-items '((recents . 10))))

21.5. Dimmer

(autoload-if-found '(dimmer-mode) "dimmer" nil t)

(add-hook 'emacs-startup-hook #'dimmer-mode)

(with-eval-after-load 'dimmer
  ;; config
  (setopt dimmer-fraction 0.05))

21.6. Doom

21.6.1. doom-themes

(add-hook 'emacs-startup-hook
          #'(lambda ()
              (when (require 'doom-themes)
                (load-theme 'doom-dracula t))))

(with-eval-after-load 'doom-themes
  ;; config
  (setopt doom-themes-padded-modeline t)
  (setopt doom-themes-enable-bold t)
  (setopt doom-themes-enable-italic t))

21.6.2. doom-modeline

(autoload-if-found '(doom-modeline-mode) "doom-modeline" nil t)

(add-hook 'emacs-startup-hook #'doom-modeline-mode)
(add-hook 'emacs-startup-hook #'(lambda () (line-number-mode 0)))
(add-hook 'emacs-startup-hook #'(lambda () (column-number-mode 0)))

(with-eval-after-load 'doom-modeline
  ;; config
  (setopt doom-modeline-buffer-file-name-style 'truncate-with-project)
  (setopt doom-modeline-icon `,(display-graphic-p))
  (setopt doom-modeline-major-mode-icon `,(display-graphic-p))
  (setopt doom-modeline-minor-modes nil)
  (setopt doom-modeline-check-icon nil))

21.7. hl-line

(autoload-if-found '(global-hl-line-mode) "hl-line-mode" nil t)

(add-hook 'emacs-startup-hook
          #'(lambda ()
              (when (not window-system)
                (global-hl-line-mode))))

(with-eval-after-load 'hl-line
  (set-face-attribute 'hl-line nil :inherit nil)
  (set-face-background 'hl-line "#444642"))

21.8. idle-highlight-mode

(autoload-if-found '(idle-highlight-mode) "idle-highlight-mode" nil t)

(with-eval-after-load 'idle-highlight-mode
  (setopt idle-highlight-idle-time 0.1))

(with-eval-after-load 'prog-mode
  (add-hook 'prog-mode-hook #'idle-highlight-mode))

21.9. neotree

(autoload-if-found '(neotree-hide neotree-dir neotree-make-executor neo-open-file neo-open-dir) "neotree" nil t)

(defun my/neotree-toggle ()
  (interactive)
  (let ((default-directory (or (locate-dominating-file default-directory ".neotree")
                               (locate-dominating-file default-directory ".git"))))
    (if (and (fboundp 'neo-global--window-exists-p)
             (neo-global--window-exists-p))
        (neotree-hide)
      (neotree-dir default-directory))))

(keymap-global-set "C-q" #'my/neotree-toggle)

(with-eval-after-load 'neotree
  ;; config
  (setopt neo-theme 'ascii)
  (setopt neo-show-hidden-files t)

  ;; hook
  (add-hook 'neotree-mode-hook #'(lambda () (display-line-numbers-mode -1)))

  ;; keybind
  ;; (define-key neotree-mode-map (kbd "C-j") (neotree-make-executor
  ;;                                           :file-fn #'neo-open-file
  ;;                                           :dir-fn  #'neo-open-dir))
  )

21.10. nyan-mode

(autoload-if-found '(nyan-mode) "nyan-mode" nil t)

(add-hook 'emacs-startup-hook #'nyan-mode)

(with-eval-after-load 'nyan-mode
  ;; config
  (setopt nyan-cat-face-number 5)
  (setopt nyan-animate-nyancat t))

21.11. volatile-highlights

(autoload-if-found '(volatile-highlights-mode) "volatile-highlights" nil t)

(add-hook 'emacs-startup-hook #'volatile-highlights-mode)

21.12. topsy

(autoload-if-found '(topsy-mode) "topsy" nil t)

(with-eval-after-load 'yaml-mode
  (add-hook 'yaml-mode-hook #'topsy-mode))

21.13. idle-highlight-mode

(autoload-if-found '(idle-highlight-mode) "idle-highlight-mode" nil t)

(with-eval-after-load 'prog-mode
  (add-hook 'prog-mode-hook #'idle-highlight-mode))

(with-eval-after-load 'idle-highlight-mode
  (setopt idle-highlight-idle-time 0.1))

22. Awesome Package

22.1. Joke

22.1.1. hacker-typer

(autoload-if-found '(hacker-typer) "hacker-typer" nil t)

22.1.2. power-mode

(autoload-if-found '(power-mode) "power-mode" nil t)

22.1.3. sudden-death

(autoload-if-found '(sudden-death) "sudden-death" nil t)

22.1.4. redacted

(autoload-if-found '(redacted-mode) "redacted" nil t)

(defun my/redacted-mode ()
  (interactive)
  (read-only-mode (if redacted-mode -1 1))
  (redacted-mode (if redacted-mode -1 1)))

22.1.5. lorem ipsum

(autoload-if-found '(lorem-ipsum-insert-sentences
                     lorem-ipsum-insert-paragraphs
                     lorem-ipsum-insert-list) "lorem-ipsum" nil t)

(keymap-global-set "C-c C-l s" #'lorem-ipsum-insert-sentences)
(keymap-global-set "C-c C-l p" #'lorem-ipsum-insert-paragraphs)
(keymap-global-set "C-c C-l l" #'lorem-ipsum-insert-list)

22.1.6. zalgo-mode

(autoload-if-found '(zalgo-transform-word
                   zalgo-mode
                   zalgo-transform-region) "zalgo-mode" nil t)

22.2. Password

22.2.1. pass

(autoload-if-found '(pass pass-view-mode) "pass" nil t)

(add-to-list 'auto-mode-alist (cons (substitute-in-file-name "$HOME/ghq/github.com/takeokunn/private/password-store/.*\\.gpg") 'pass-view-mode))

(with-eval-after-load 'pass
  (setopt pass-suppress-confirmations t))

22.3. Dictionary

22.3.1. define-word

(defun my/define-word ()
  (interactive)
  (if (use-region-p)
      (call-interactively #'define-word-at-point)
    (call-interactively #'define-word)))

(with-eval-after-load 'define-word
  (setopt define-word-displayfn-alist
          '((wordnik . takeokunn/define-word--display-in-buffer)
            (openthesaurus . takeokunn/define-word--display-in-buffer)
            (webster . takeokunn/define-word--display-in-buffer)
            (weblio . takeokunn/define-word--display-in-buffer))))

22.4. GC

22.4.1. gcmh

(autoload-if-found '(gcmh-mode) "gcmh" nil t)

(add-hook 'emacs-startup-hook #'gcmh-mode)

(with-eval-after-load 'gcmh
  ;; config
  (setopt gcmh-verbose nil)

  ;; hooks
  (defvar my/gcmh-status nil)
  (advice-add #'garbage-collect
              :before
              (defun my/gcmh-log-start (&rest _)
                (when gcmh-verbose
                  (setopt my/gcmh-status "Running GC..."))))

  (advice-add #'gcmh-message
              :override
              (defun my/gcmh-message (format-string &rest args)
                (setopt my/gcmh-status
                      (apply #'format-message format-string args))
                (run-with-timer 2 nil
                                (lambda ()
                                  (setopt my/gcmh-status nil))))))

22.5. Command

22.5.1. amx

(autoload-if-found '(amx-mode) "amx" nil t)

(add-hook 'emacs-startup-hook #'amx-mode)

(with-eval-after-load 'amx
  ;; config
  (setopt amx-history-length 100))

22.6. GPG

22.6.1. epa-file

(autoload-if-found '(epa-file-enable) "epa-file" nil t)

(add-hook 'emacs-startup-hook #'epa-file-enable)

(with-eval-after-load 'epa-file
  ;; config
  (setopt epa-file-encrypt-to '("bararararatty@gmail.com"))
  (setopt epa-file-select-keys 'silent)
  (setopt epa-file-cache-passphrase-for-symmetric-encryption t)
  (setopt epg-pinentry-mode 'loopback)

  ;; fset
  (fset 'epg-wait-for-status 'ignore))

22.6.2. pinentry

https://github.com/ch11ng/exwm/wiki#gpg-pinentry

(autoload-if-found '(pinentry-start) "pinentry" nil t)

22.7. Help

22.7.1. helpful

(autoload-if-found '(helpful-callable
                     helpful-function
                     helpful-macro
                     helpful-command
                     helpful-key
                     helpful-variable
                     helpful-at-point) "helpful" nil t)

(keymap-global-set "C-h f" #'helpful-callable)
(keymap-global-set "C-h v" #'helpful-variable)
(keymap-global-set "C-h k" #'helpful-key)
(keymap-global-set "C-c C-d" #'helpful-at-point)
(keymap-global-set "C-h F" #'helpful-function)
(keymap-global-set "C-h C" #'helpful-command)

22.8. Shell

22.8.1. exec-path-from-shell

(autoload-if-found '(exec-path-from-shell-initialize) "exec-path-from-shell")

(add-hook 'emacs-startup-hook #'exec-path-from-shell-initialize)

(with-eval-after-load 'exec-path-from-shell
  (setopt exec-path-from-shell-variables '("PATH"
                                         "GEM_HOME"
                                         "GOROOT"
                                         "GOPATH"
                                         "LSP_USE_PLISTS"
                                         "TERM"
                                         "SSH_AUTH_SOCK"
                                         "NATIVE_FULL_AOT"
                                         "GPG_TTY")))

22.9. Utility

22.9.1. htmlize

(with-eval-after-load 'htmlize
  (setopt htmlize-html-charset 'utf-8))

22.9.2. midnight

(autoload-if-found '(midnight-mode) "midnight" nil t)

(add-hook 'emacs-startup-hook #'midnight-mode)

(with-eval-after-load 'midnight
  (setopt clean-buffer-list-delay-general 1))

23. Language Specific

23.1. Basic Lisp

23.1.1. paredit

(autoload-if-found '(enable-paredit-mode
                     paredit-forward-slurp-sexp
                     paredit-splice-sexp
                     paredit-define-keys)
                   "paredit" nil t)

(keymap-global-set "C-c f" #'paredit-forward-slurp-sexp)
(keymap-global-set "M-s" #'paredit-splice-sexp)

(with-eval-after-load 'paredit
  ;; hooks
  (add-hook 'paredit-mode-hook #'paredit-define-keys))

(with-eval-after-load 'lisp-mode
  ;; hooks
  (add-hook 'lisp-mode-hook #'enable-paredit-mode)
  (add-hook 'lisp-data-mode-hook #'enable-paredit-mode))

(with-eval-after-load 'emacs-lisp-mode
  ;; hooks
  (add-hook 'emacs-lisp-mode-hook #'enable-paredit-mode))

(with-eval-after-load 'clojure-mode
  ;; hooks
  (add-hook 'clojure-mode-hook #'enable-paredit-mode))

(with-eval-after-load 'lisp-interaction-mode
  ;; hooks
  (add-hook 'lisp-interacton-mode-hook #'enable-paredit-mode))

(with-eval-after-load 'scheme
  ;; hooks
  (add-hook 'scheme-mode-hook #'enable-paredit-mode))

(with-eval-after-load 'simple
  ;; hooks
  (add-hook 'eval-expression-minibuffer-setup-hook #'enable-paredit-mode))

(with-eval-after-load 'ielm
  ;; hooks
  (add-hook 'inferior-emacs-lisp-mode-hook #'enable-paredit-mode))

23.1.2. rainbow-delimiter

(autoload-if-found '(rainbow-delimiters-mode-enable) "rainbow-delimiters" nil t)

(with-eval-after-load 'lisp-mode
  ;; hooks
  (add-hook 'lisp-mode-hook #'rainbow-delimiters-mode-enable))

(with-eval-after-load 'emacs-lisp-mode
  ;; hooks
  (add-hook 'emacs-lisp-mode-hook #'rainbow-delimiters-mode-enable))

(with-eval-after-load 'clojure-mode
  ;; hooks
  (add-hook 'clojure-mode-hook #'rainbow-delimiters-mode-enable))

(with-eval-after-load 'scheme
  ;; hooks
  (add-hook 'scheme-mode-hook #'rainbow-delimiters-mode-enable))

23.2. Common Lisp

23.2.1. slime

(with-eval-after-load 'lisp-mode
  ;; hooks
  (add-hook 'lisp-mode-hook
            #'(lambda ()
                (require 'slime)
                (require 'slime-autoloads)

                (defun my/slime-history ()
                  (interactive)
                  (if (and (fboundp '-distinct)
                           (fboundp 'f-read-text))
                      (insert
                       (completing-read
                        "choice history: "
                        (-distinct (read (f-read-text "~/.slime-history.eld"))))))))))

(with-eval-after-load 'slime
  ;; config
  (setopt slime-net-coding-system 'utf-8-unix)
  (setopt inferior-lisp-program "ros run -Q"))

(with-eval-after-load 'slime-repl
  ;; keybinds
  (define-key slime-repl-mode-map (kbd "C-c C-r") #'my/slime-history))

23.2.2. hyperspec

(autoload-if-found '(hyperspec-lookup) "hyperspec" nil t)

(with-eval-after-load 'lisp-mode
  ;; keybinds
  (define-key lisp-mode-map (kbd "C-c h") #'hyperspec-lookup))

23.3. Emacs Lisp

23.3.1. eros

(autoload-if-found '(eros-mode) "eros" nil t)

(with-eval-after-load 'emacs-lisp
  ;; hooks
  (add-hook 'emacs-lisp-mode-hook #'eros-mode))

23.3.2. eldoc

(autoload-if-found '(turn-on-eldoc-mode) "eldoc" nil t)

(with-eval-after-load 'elisp-mode
  ;; hooks
  (add-hook 'emacs-lisp-mode-hook #'turn-on-eldoc-mode)
  (add-hook 'lisp-interaction-mode-hook #'turn-on-eldoc-mode))

(with-eval-after-load 'ielm
  ;; hooks
  (add-hook 'ielm-mode-hook #'turn-on-eldoc-mode))

23.3.3. trinary

(autoload-if-found '() "trinary" nil t)

23.3.4. elsa

(autoload-if-found '(elsa-run) "elsa" nil t)

23.3.5. lispxmp

(autoload-if-found '(lispxmp) "lispxmp" nil t)

23.3.6. macrostep

(autoload-if-found '(macrostep-expand macrostep-mode) "macrostep" nil t)

(with-eval-after-load 'elisp-mode
  ;; keybinds
  (define-key emacs-lisp-mode-map (kbd "C-c e") #'macrostep-expand))

23.3.7. elisp-slime-nav

(autoload-if-found '(elisp-slime-nav-mode) "elisp-slime-nav" nil t)

(with-eval-after-load 'elisp-mode
  ;; hooks
  (add-hook 'emacs-lisp-mode-hook #'elisp-slime-nav-mode))

(with-eval-after-load 'ielm
  ;; hooks
  (add-hook 'ielm-mode-hook #'elisp-slime-nav-mode))

23.3.8. nameless

(autoload-if-found '(nameless-mode) "nameless" nil t)

(with-eval-after-load 'elisp-mode
  ;; hooks
  (add-hook 'emacs-lisp-mode-hook #'nameless-mode))

(with-eval-after-load 'ielm
  ;; hooks
  (add-hook 'ielm-mode-hook #'nameless-mode))

23.3.9. elisp-refs

(autoload-if-found '(elisp-refs-function
                     elisp-refs-macro
                     elisp-refs-variable
                     elisp-refs-special
                     elisp-refs-symbol) "elisp-refs" nil t)

23.3.10. highlight-quoted

(autoload-if-found '(highlight-quoted-mode) "highlight-quoted" nil t)

(with-eval-after-load 'elisp-mode
  ;; hooks
  (add-hook 'emacs-lisp-mode-hook #'highlight-quoted-mode))

23.3.11. highlight-defined

(autoload-if-found '(highlight-defined-mode) "highlight-defined" nil t)

(with-eval-after-load 'elisp-mode
  ;; hooks
  (add-hook 'emacs-lisp-mode-hook #'highlight-defined-mode))

23.3.12. my/ielm-history

(autoload-if-found '(my/ielm-history) "ielm" nil t)

(defun my/ielm-history ()
  (interactive)
  (insert
   (completing-read
    "choice history: "
    (progn
      (let ((history nil)
            (comint-input-ring nil))
        (dotimes (index (ring-length comint-input-ring))
          (push (ring-ref comint-input-ring index) history))
        history)))))

23.4. Clojure

23.4.1. anakondo

(autoload-if-found '(anakondo-minor-mode) "anakondo" nil t)

;; (with-eval-after-load 'clojure-mode
;;   (add-hook 'clojure-mode-hook #'anakondo-minor-mode)
;;   (add-hook 'clojurescript-mode-hook #'anakondo-minor-mode)
;;   (add-hook 'clojurec-mode-hook #'anakondo-minor-mode))

23.4.2. cider

(autoload-if-found '(cider cider-format-buffer cider-switch-to-last-clojure-buffer) "cider" nil t)
(autoload-if-found '(cider-doc) "cider-doc" nil t)

;; (add-hook 'before-save-hook #'cider-format-buffer t t)

(with-eval-after-load 'cider-common
  ;; config
  (setopt cider-special-mode-truncate-lines nil))

(with-eval-after-load 'cider-mode
  ;; config
  (setopt cider-font-lock-reader-conditionals nil)
  (setopt cider-font-lock-dynamically '(macro core function var)))

(with-eval-after-load 'cider-repl
  ;; config
  (setopt cider-repl-buffer-size-limit 1000000)
  (setopt cider-repl-wrap-history t)
  (setopt cider-repl-history-size 10000)
  (setopt cider-repl-tab-command #'indent-for-tab-command)
  (setopt cider-repl-display-in-current-window t))

(with-eval-after-load 'nrepl-client
  ;; config
  (setopt nrepl-use-ssh-fallback-for-remote-hosts t)
  (setopt nrepl-hide-special-buffers t))

(with-eval-after-load 'cider-eval
  ;; config
  (setopt cider-show-error-buffer nil)
  (setopt cider-auto-select-error-buffer nil))

(with-eval-after-load 'clojure-mode
  ;; keybinds
  (define-key clojure-mode-map (kbd "C-c h") #'cider-doc))

23.4.3. kibit-helper

(autoload-if-found '(kibit kibit-current-file kibit-accept-proposed-change) "kibit-helper" nil t)

23.4.4. clj-refactor

;; (autoload-if-found '(clj-refactor-mode cljr-add-keybindings-with-prefix) "clj-refactor" nil t)

;; (add-hook 'clojure-mode-hook #'clj-refactor-mode)
;; (cljr-add-keybindings-with-prefix "C-c C-m")

;; (with-eval-after-load 'clj-refactor
;;   (setopt cljr-suppress-middleware-warnings t)
;;   (setopt cljr-hotload-dependencies t))

23.4.5. inf-clojure

(autoload-if-found '(inf-clojure) "inf-clojure" nil t)

23.5. C/C++

23.5.1. clang-format

(autoload-if-found '(clang-format-buffer) "clang-format" nil t)

(add-hook 'before-save-hook
          #'(lambda ()
              (when (member major-mode '(c-mode c++-mode))
                (clang-format-buffer))))

23.6. Csv

23.6.1. rainbow-csv

;; (autoload-if-found '(rainbow-csv-mode) "rainbow-csv" nil t)

;; (with-eval-after-load 'csv-mode
;;   (add-hook 'csv-mode-hook #'rainbow-csv-mode))

23.7. JavaScript/TypeScript

23.7.1. nodejs-repl

(autoload-if-found '(nodejs-repl
                     nodejs-repl-send-last-expression
                     nodejs-repl-send-line
                     nodejs-repl-send-region
                     nodejs-repl-send-buffer
                     nodejs-repl-load-file
                     nodejs-repl-switch-to-repl) "nodejs-repl" nil t)

(with-eval-after-load 'js2-mode
  ;; keyinds
  (define-key js2-mode-map (kbd "C-x C-e") #'nodejs-repl-send-last-expression)
  (define-key js2-mode-map (kbd "C-c C-j") #'nodejs-repl-send-line)
  (define-key js2-mode-map (kbd "C-c C-r") #'nodejs-repl-send-region)
  (define-key js2-mode-map (kbd "C-c C-c") #'nodejs-repl-send-buffer)
  (define-key js2-mode-map (kbd "C-c C-l") #'nodejs-repl-load-file)
  (define-key js2-mode-map (kbd "C-c C-z") #'nodejs-repl-switch-to-repl))

23.7.2. js2-refactor

(autoload-if-found '(js2-refactor-mode) "js2-refactor" nil t)

(with-eval-after-load 'js2-refactor
  ;; config
  (setopt js2r-use-strict t))

(with-eval-after-load 'js2-mode
  ;; hooks
  (add-hook 'js2-mode-hook #'js2-refactor-mode))

(with-eval-after-load 'typescript-mode
  ;; hooks
  (add-hook 'typescript-mode-hook #'js2-refactor-mode))

23.7.3. jest

(autoload-if-found '(jest
                     jest-file
                     jest-file-dwim
                     jest-function
                     jest-last-failed
                     jest-repeat
                     jest-minor-mode) "jest" nil t)

(with-eval-after-load 'typescript-mode
  ;; hooks
  (add-hook 'typescript-mode-hook #'jest-minor-mode)

  ;; config
  (setopt jest-executable "npx jest"))

(with-eval-after-load 'typescript-mode
  (add-hook 'typescript-mode-hook
            #'(lambda ()
                (projectile-register-project-type 'npx '("package.json" "yarn.lock")
                                                  :project-file "package.json"
                                                  :test "npx jest"
                                                  :test-suffix ".spec"))))

23.8. Ruby

23.8.1. robe

(autoload-if-found '(robe-mode inf-ruby-console-auto) "robe" nil t)

23.8.2. rubocop

(autoload-if-found '(rubocop-mode) "rubocop" nil t)

(with-eval-after-load 'ruby-mode
  ;; config
  (setopt rubocop-keymap-prefix "C-c C-x")

  ;; hooks
  (add-hook 'ruby-mode-hook #'rubocop-mode))

23.8.3. ruby-refactor

(autoload-if-found '(ruby-refactor-mode-launch) "ruby-refactor" nil t)

(with-eval-after-load 'ruby-mode
  ;; hooks
  (add-hook 'ruby-mode-hook #'ruby-refactor-mode-launch))

23.8.4. inf-ruby

(autoload-if-found '(inf-ruby inf-ruby-minor-mode) "inf-ruby" nil t)

(defun my/irb-history ()
  (interactive)
  (when (and (fboundp '-distinct)
             (fboundp 's-lines)
             (fboundp 'f-read-text))
    (insert
     (completing-read
      "choose history: "
      (mapcar #'list (-distinct (s-lines (f-read-text "~/.irb_history"))))))))

(with-eval-after-load 'ruby-mode
  ;; hooks
  (add-hook 'ruby-mode-hook #'inf-ruby-minor-mode))

23.8.5. yard-mode

(autoload-if-found '(yard-mode) "yard-mode" nil t)

(with-eval-after-load 'ruby-mode
  ;; hooks
  (add-hook 'ruby-mode-hook #'yard-mode))

23.9. SQL

23.9.1. sql-indent

(autoload-if-found '(sqlind-setup sqlind-minor-mode) "sql-indent" nil t)

(with-eval-after-load 'sql
  ;; hooks
  (add-hook 'sql-mode-hook #'sqlind-setup)
  (add-hook 'sql-mode-hook #'sqlind-minor-mode))

23.10. PHP

23.10.1. composer

(autoload-if-found '() "composer" nil t)

23.10.2. php-runtime

(autoload-if-found '(php-runtime-expr php-runtime-eval) "php-runtime" nil t)

23.10.3. psysh

(autoload-if-found '(psysh psysh-doc) "psysh" nil t)

(with-eval-after-load 'php-mode
  ;; keybinds
  (define-key php-mode-map (kbd "C-c h") #'psysh-doc))

23.10.4. laravel-tinker-repl

;; (autoload-if-found '(laravel-tinker-repl) "laravel-tinker-repl" nil t)

;; (with-eval-after-load 'php-mode
;;   (define-key php-mode-map (kbd "C-c C-c") #'laravel-tinker-repl-send-line)
;;   (define-key php-mode-map (kbd "C-c C-z") #'laravel-tinker-repl-switch-to-repl))

23.10.5. emacs-php-doc-block

(autoload-if-found '(php-doc-block) "php-doc-block" nil t)

23.10.6. phpstan

(autoload-if-found '(phpstan-analyze-file phpstan-analyze-this-file) "phpstan" nil t)

(with-eval-after-load 'phpstan
  ;; config
  (setopt phpstan-memory-limit "4G"))

23.10.7. phpunit

(autoload-if-found '(phpunit-current-test
                     phpunit-current-class
                     phpunit-current-project
                     phpunit-group) "phpunit" nil t)

23.11. Markdown

23.11.1. poly-markdown

(autoload-if-found '(poly-markdown-mode) "poly-markdown" nil t)

(add-to-list 'auto-mode-alist '("\\.md" . poly-markdown-mode))

23.11.2. markdown-preview-mode

(autoload-if-found '(markdown-preview-open-browser markdown-preview-mode) "markdown-preview-mode" nil t)

(with-eval-after-load 'markdown-preview-mode
  ;; config
  (setopt markdown-preview-stylesheets (list "http://thomasf.github.io/solarized-css/solarized-light.min.css")))

23.12. Fish

23.12.1. fish-repl

(autoload-if-found '(fish-repl) "fish-repl" nil t)

23.13. Haskell

23.13.1. hindent

(autoload-if-found '(hindent-mode) "hindent" nil t)

(with-eval-after-load 'haskell-mode
  ;; hooks
  (add-hook 'haskell-mode-hook #'hindent-mode))

23.14. Web

23.14.1. emmet-mode

(autoload-if-found '(emmet-mode) "emmet-mode" nil t)

(with-eval-after-load 'html-mode
  ;; hooks
  (add-hook 'html-mode-hook #'emmet-mode))

(with-eval-after-load 'web-mode
  ;; hooks
  (add-hook 'web-mode-hook #'emmet-mode))

(with-eval-after-load 'css-mode
  ;; hooks
  (add-hook 'css-mode-hook #'emmet-mode))

(with-eval-after-load 'nxml-mode
  ;; hooks
  (add-hook 'nxml-mode-hook #'emmet-mode))

(with-eval-after-load 'web-php-blade-mode
  ;; hooks
  (add-hook 'web-php-blade-mode #'emmet-mode))

(with-eval-after-load 'typescript-mode
  ;; hooks
  (add-hook 'typescript-tsx-mode-hook #'emmet-mode))

(with-eval-after-load 'vue-mode
  ;; hooks
  (add-hook 'vue-mode-hook #'emmet-mode))

(with-eval-after-load 'emmet-mode
  ;; keybinds
  (define-key emmet-mode-keymap (kbd "C-j") nil)
  (define-key emmet-mode-keymap (kbd "M-j") #'emmet-expand-line)

  ;; config
  (setopt emmet-self-closing-tag-style "")
  (setopt emmet-indent-after-insert nil))

23.15. JSON

23.15.1. jq-mode

(autoload-if-found '(jq-interactively) "jq-mode" nil t)

(with-eval-after-load 'json-mode
  ;; keybinds
  (define-key json-mode-map (kbd "C-c C-j") #'jq-interactively))

23.15.2. json-reformat

(autoload-if-found '(json-reformat-region) "json-reformat" nil t)

23.16. Python

23.16.1. py-isort

(autoload-if-found '(py-isort-region
                     py-isort-buffer
                     py-isort-before-save) "py-isort" nil t)

24. Elfeed

24.1. elfeed

(autoload-if-found '(elfeed) "elfeed" nil t)

(with-eval-after-load 'elfeed-show
  ;; config
  (setopt elfeed-show-entry-switch #'display-buffer))

(with-eval-after-load 'elfeed-db
  ;; config
  (setopt elfeed-db-directory "~/.cache/elfeed"))

(with-eval-after-load 'elfeed-search
  ;; config
  (setopt elfeed-search-filter "@2-week-ago"))

(with-eval-after-load 'elfeed-curl
  ;; config
  (setopt elfeed-curl-max-connections 32))

24.2. elfeed-org

(autoload-if-found '(elfeed-org) "elfeed-org" nil t)

(with-eval-after-load 'elfeed-search
  ;; hooks
  (add-hook 'elfeed-search-mode-hook #'elfeed-org))

(with-eval-after-load 'elfeed-org
  ;; config
  (setopt rmh-elfeed-org-files '("~/.ghq/github.com/takeokunn/private/elfeed.org"))
  (setopt rmh-elfeed-org-auto-ignore-invalid-feeds t))

24.3. elfeed-dashboard

(autoload-if-found '(elfeed-dashboard) "elfeed-dashboard" nil t)

(keymap-global-set "C-x w" #'elfeed-dashboard)

(with-eval-after-load 'elfeed-dashboard
  ;; config
  (setopt elfeed-dashboard-file (locate-user-emacs-file "elfeed-dashboard.org")))

24.4. elfeed-goodies

(autoload-if-found '(elfeed-goodies/setup) "elfeed-goodies" nil t)

(with-eval-after-load 'elfeed-dashboard
  (add-hook 'elfeed-dashboard-mode-hook #'elfeed-goodies/setup))

(with-eval-after-load 'elfeed-goodies
  (setopt elfeed-goodies/entry-pane-size 0.6))

25. Org Mode

25.1. Basic

25.1.1. org

(keymap-global-set "C-c l" #'org-store-link)
(keymap-global-set "C-c a" #'org-agenda)

(with-eval-after-load 'org
  ;; keybind
  (define-key org-mode-map (kbd "C-c ,") #'org-insert-structure-template)
  (define-key org-mode-map (kbd "C-c C-,") #'org-insert-structure-template)

  ;; directory
  (setq org-directory "~/.ghq/github.com/takeokunn/private")

  ;; todo
  (setq org-todo-keywords '((sequence "TODO(t)" "SOMEDAY(s)" "WAIT(w)" "|" "DONE(d)")))

  ;; startup
  (setq org-startup-folded 'show3levels)
  (setq org-startup-truncated nil)

  (defvar my/org-agenda-files `(,(concat org-directory "/agenda")
                                ,(concat org-directory "/archive/2023")
                                ,(concat org-directory "/archive/2024")))

  (setq org-agenda-files my/org-agenda-files)
  (setq org-archive-location `,(format (expand-file-name "archive/%s/%s.org::* Archived Tasks" org-directory)
                                         (format-time-string "%Y" (current-time))
                                         (format-time-string "%Y-%m-%d" (current-time))))

  ;; log
  (setq org-log-into-drawer t)
  (setq org-log-done 'time)

  (defun my/update-org-agenda-files ()
    (interactive)
    (setq org-agenda-files my/org-agenda-files)))

(with-eval-after-load 'org-src
  ;; config
  (setq org-src-window-setup 'current-window))

(with-eval-after-load 'org-archive
  ;; archive
  (advice-add 'org-archive-subtree :before #'(lambda (&rest _) (remove-hook 'find-file-hooks #'view-mode)))
  (advice-add 'org-archive-subtree :after #'(lambda (&rest _) (add-hook 'find-file-hooks #'view-mode))))

25.1.2. org-clock

(autoload-if-found '(org-clock-load org-clock-save) "org-clock" nil t)

(with-eval-after-load 'org
  ;; hooks
  (add-hook 'org-mode-hook #'org-clock-load))

(with-eval-after-load 'org-clock
  ;; config
  (setq org-clock-out-remove-zero-time-clocks t)
  (setq org-clock-clocked-in-display 'mode-line))

25.1.3. org-list

(with-eval-after-load 'org-list
  (setq org-list-allow-alphabetical t))

25.1.4. org-keys

(with-eval-after-load 'org-keys
  ;; config
  (setq org-use-extra-keys t)
  (setq org-use-speed-commands t)

  ;; keybind
  (add-to-list 'org-speed-commands '("d" org-todo "DONE"))
  (add-to-list 'org-speed-commands '("j" call-interactively #'consult-org-heading)))

25.1.5. org-capture

(autoload-if-found '(org-capture) "org-capture" nil t)

(keymap-global-set "C-c c" #'org-capture)

(with-eval-after-load 'org-capture
  ;; advice
  (advice-add 'org-capture :before #'(lambda (&rest _) (remove-hook 'find-file-hooks #'view-mode)))
  (advice-add 'org-capture :after #'(lambda (&rest _) (add-hook 'find-file-hooks #'view-mode)))

  ;; config
  (setq org-capture-use-agenda-date t)
  (setq org-capture-bookmark nil)
  (setq org-capture-templates `(("t" "Todo" entry (file ,(expand-file-name "todo.org" org-directory))
                                   "* %?")
                                  ("m" "Memo" entry (file ,(expand-file-name "memo.org" org-directory))
                                   "* %?")
                                  ("j" "Journal" entry (file+olp+datetree ,(expand-file-name "journal.org" org-directory))
                                   "* %U\n%?\n%i\n"))))

25.1.6. org-duration

(with-eval-after-load 'org-duration
  ;; config
  (setq org-duration-format (quote h:mm)))

25.1.7. org-id

(autoload-if-found '(org-id-store-link) "org-id" nil t)

(with-eval-after-load 'org-id
  ;; config
  (setq org-id-locations-file (expand-file-name ".org-id-locations" org-directory))
  (setq org-id-extra-files (append org-agenda-text-search-extra-files)))

25.1.8. org-crypt

(autoload-if-found '(org-encrypt-entry org-decrypt-entry org-crypt-use-before-save-magic) "org-crypt" nil t)

(with-eval-after-load 'org
  ;; hooks
  (add-hook 'org-mode-hook #'org-crypt-use-before-save-magic))

(with-eval-after-load 'org-crypt
  ;; config
  (setq org-crypt-key nil)
  (setq org-tags-exclude-from-inheritance '("crypt")))

25.1.9. org-table

(autoload-if-found '(orgtbl-mode org-table-begin org-table-end) "org-table" nil t)

(with-eval-after-load 'org-table
  (defun my/org-table-align-markdown ()
    "Replace \"+\" sign with \"|\" in org-table."
    (when (member major-mode '(markdown-mode))
      (save-excursion
        (save-restriction
          (narrow-to-region (org-table-begin) (org-table-end))
          (goto-char (point-min))
          (while (search-forward "-+-" nil t)
            (replace-match "-|-"))))))

  (advice-add 'org-table-align :before #'my/org-table-align-markdown))

25.1.10. org-journal

(with-eval-after-load 'org-journal
  ;; config
  (setq org-journal-dir (expand-file-name "journal" org-directory))
  (setq org-journal-start-on-weekday 7)
  (setq org-journal-prefix-key "C-c j"))

25.1.11. org-generate

(autoload-if-found '(org-generate) "org-generate" nil t)

25.1.12. org-pomodoro

(autoload-if-found '(org-pomodoro) "org-pomodoro" nil t)

25.1.13. org-view-mode

(autoload-if-found '(org-view-mode) "org-view-mode" nil t)

25.1.14. org-random-todo

(autoload-if-found '(org-random-todo org-random-todo-goto-current) "org-random-todo" nil t)

25.1.15. org-projectile

(autoload-if-found '(org-projectile-todo-files
                     org-projectile-project-todo-completing-read)
                   "org-projectile" nil t)

(keymap-global-set "C-c n p" #'org-projectile-project-todo-completing-read)

(with-eval-after-load 'org
  (setq org-agenda-files (append org-agenda-files (org-projectile-todo-files))))

25.1.16. org-dashboard

(autoload-if-found '(org-dashboard-display) "org-dashboard" nil t)

25.1.17. org-volume

(autoload-if-found '(org-volume-update-entry-from-dblock) "org-volume" nil t)

25.1.18. org-ql

(autoload-if-found '(org-ql-query org-ql-select) "org-ql" nil t)

25.2. Theme

25.2.1. org-faces

(with-eval-after-load 'org-faces
  ;; config
  (setq org-link '(t (:foreground "#ebe087" :underline t))))

25.2.2. org-superstar

(autoload-if-found '(org-superstar-mode) "org-superstar")

(with-eval-after-load 'org
  ;; hooks
  (add-hook 'org-mode-hook #'org-superstar-mode))

(with-eval-after-load 'org-superstar
  ;; config
  (setopt org-superstar-headline-bullets-list '("◉" "○" "✸" "✿"))
  (setopt org-superstar-leading-bullet " "))

25.3. Content

25.3.1. toc-org

(autoload-if-found '(toc-org-mode) "toc-org" nil t)

(with-eval-after-load 'org
  ;; hooks
  (add-hook 'org-mode-hook #'toc-org-mode))

25.4. Presentation

25.4.1. org-tree-slide

(autoload-if-found '(org-tree-slide-mode org-tree-slide-skip-done-toggle) "org-tree-slide" nil t)

(with-eval-after-load 'org-tree-slide
  ;; config
  (setopt org-tree-slide-skip-outline-level 4))

25.5. Org Link

25.5.1. org-link

(autoload-if-found '(org-store-link) "ol" nil t)

(with-eval-after-load 'ol
  ;; config
  (setq org-link-file-path-type 'relative))

25.5.2. org-link-beautify

(autoload-if-found '(org-link-beautify-mode) "org-link-beautify" nil t)

;; (with-eval-after-load 'org
;;   ;; hooks
;;   (add-hook 'org-mode-hook #'org-link-beautify-mode))

25.5.3. TODO orgit

(autoload-if-found '(orgit-store-link) "orgit" nil t)

;; (with-eval-after-load 'magit
;;   (define-key magit-mode-map [remap org-store-link] #'orgit-store-link))

25.6. Org Agenda

25.6.1. Basic

(autoload-if-found '(org-agenda) "org-agenda" nil t)

(with-eval-after-load 'org-agenda
  ;; config
  (setq org-agenda-span 'day)
  (setq org-agenda-start-on-weekday 1)
  (setq org-agenda-todo-ignore-with-date t))

25.6.2. org-super-agenda

(autoload-if-found '(org-super-agenda-mode) "org-super-agenda" nil t)

(add-hook 'emacs-startup-hook #'org-super-agenda-mode)

(with-eval-after-load 'org-super-agenda
  ;; config
  (setopt org-super-agenda-groups '((:log t)
                                    (:auto-group t)
                                    (:name "Today List..." :scheduled today)
                                    (:name "Due Today List..." :deadline today)
                                    (:name "Overdue List..." :deadline past)
                                    (:name "Due Soon List" :deadline future)
                                    (:name "TODO List..." :todo "TODO")
                                    (:name "WAIT List..." :todo "WAIT")
                                    (:name "DONE List..." :todo "DONE")
                                    (:name "SOMEDAY List..." :todo "SOMEDAY"))))

25.6.3. org-hyperscheduler

(autoload-if-found '(org-hyperscheduler-open) "org-hyperscheduler" nil t)

25.6.4. org-timeblock

(autoload-if-found '(org-timeblock-list org-timeblock-mode) "org-timeblock" nil t)

25.7. Org External Tools

25.7.1. org-redmine

(autoload-if-found '(org-redmine-get-issue) "org-redmine" nil t)

(with-eval-after-load 'org-redmine
  ;; config
  (setopt org-redmine-template-header "[#%i%] %s%")
  (setopt org-redmine-template-property '(("project_name" . "%p_n%"))))

25.7.2. org-ai

(autoload-if-found '(org-ai-mode) "org-ai" nil t)

(with-eval-after-load 'org
  ;; config
  (add-to-list 'org-structure-template-alist '("A" . "ai"))

  ;; hooks
  (add-hook 'org-mode-hook #'org-ai-mode))

(with-eval-after-load 'org-ai
  ;; config
  (setopt org-ai-default-chat-model "gpt-3.5-turbo"))

25.8. Org Babel

25.8.1. basic

(autoload-if-found '(org-babel-do-load-languages) "org" nil t)

(with-eval-after-load 'org
  (add-hook 'org-mode-hook
            #'(lambda ()
                (org-babel-do-load-languages 'org-babel-load-languages
                                             '((awk . t)
                                               (C . t)
                                               (R . t)
                                               (clojure . t)
                                               (emacs-lisp . t)
                                               (haskell . t)
                                               (java . t)
                                               (js . t)
                                               (lisp . t)
                                               (makefile . t)
                                               (perl . t)
                                               (plantuml . t)
                                               (python . t)
                                               (ruby . t)
                                               (scheme . t)
                                               (shell . t)
                                               (sql . t)
                                               (shell . t))))))

(with-eval-after-load 'ob-core
  ;; config
  (setq org-confirm-babel-evaluate nil)
  (add-to-list 'org-babel-default-header-args '(:results . "output")))

(with-eval-after-load 'ob-eval
  ;; advice
  (advice-add #'org-babel-eval-error-notify
              :around #'(lambda (old-func &rest args)
                          (when (not (string= (nth 1 args)
                                              "mysql: [Warning] Using a password on the command line interface can be insecure.\n"))
                            (apply old-func args)))))

25.8.2. ob-async

(autoload-if-found '(ob-async-org-babel-execute-src-block) "ob-async" nil t)

;; (advice-add 'org-babel-execute-src-block :around #'ob-async-org-babel-execute-src-block)

25.8.3. ob-fish

;; (autoload-if-found '(org-babel-execute:fish) "ob-fish" nil t)

;; (with-eval-after-load 'org-src
;;   (add-to-list 'org-src-lang-modes '("fish" . fish)))

25.8.4. ob-rust

(autoload-if-found '(org-babel-execute:rust) "ob-rust" nil t)

(with-eval-after-load 'org-src
  (add-to-list 'org-src-lang-modes '("rust" . rust)))

25.8.5. ob-go

(autoload-if-found '(org-babel-execute:go) "ob-go" nil t)

(with-eval-after-load 'org-src
  (add-to-list 'org-src-lang-modes '("go" . go)))

25.8.6. ob-translate

(autoload-if-found '(ob-translate:google-translate) "ob-translate" nil t)

(with-eval-after-load 'text-mode
  (define-derived-mode translate-mode text-mode "translate"))

(with-eval-after-load 'org-src
  (add-to-list 'org-src-lang-modes '("translate" . translate)))

25.8.7. ob-typescript

(autoload-if-found '(org-babel-execute:typescript) "ob-typescript" nil t)

(with-eval-after-load 'org-src
  (add-to-list 'org-src-lang-modes '("typescript" . typescript)))

25.8.8. ob-php

(autoload-if-found '(org-babel-execute:php) "ob-php" nil t)

(with-eval-after-load 'org-src
  (add-to-list 'org-src-lang-modes '("php" . php)))

25.8.9. ob-phpstan

(autoload-if-found '(org-babel-execute:phpstan) "ob-phpstan" nil t)

(with-eval-after-load 'org-src
  (add-to-list 'org-src-lang-modes '("phpstan" . phpstan)))

25.8.10. ob-http

(autoload-if-found '(org-babel-execute:http) "ob-http" nil t)
(autoload-if-found '(ob-http-mode) "ob-http-mode" nil t)

(with-eval-after-load 'org-src
  (add-to-list 'org-src-lang-modes '("http" . ob-http)))

25.8.11. ob-mermaid

(autoload-if-found '(org-babel-execute:mermaid) "ob-mermaid" nil t)

(with-eval-after-load 'org-src
  (add-to-list 'org-src-lang-modes '("mermaid" . mermaid)))

25.8.12. ob-graphql

(autoload-if-found '(org-babel-execute:graphql) "ob-graphql" nil t)

(with-eval-after-load 'org-src
  (add-to-list 'org-src-lang-modes '("graphql" . graphql)))

25.8.13. ob-rust

(autoload-if-found '(org-babel-execute:rust) "ob-rust" nil t)

(with-eval-after-load 'org-src
  (add-to-list 'org-src-lang-modes '("rust" . rust)))

25.8.14. ob-swift

(autoload-if-found '(org-babel-execute:swift) "ob-swift" nil t)

(with-eval-after-load 'org-src
  (add-to-list 'org-src-lang-modes '("swift" . swift)))

25.8.15. ob-elixir

(autoload-if-found '(org-babel-execute:elixir) "ob-elixir" nil t)

(with-eval-after-load 'org-src
  (add-to-list 'org-src-lang-modes '("elixir" . elixir)))

25.8.16. ob-dart

(autoload-if-found '(org-babel-execute:dart) "ob-dart" nil t)

(with-eval-after-load 'org-src
  (add-to-list 'org-src-lang-modes '("dart" . dart)))

25.8.17. ob-fsharp

(autoload-if-found '(org-babel-execute:fsharp) "ob-fsharp" nil t)

(with-eval-after-load 'org-src
  (add-to-list 'org-src-lang-modes '("fsharp" . fsharp)))

25.8.18. ob-treesitter

(autoload-if-found '(org-babel-execute:treesitter) "ob-treesitter" nil t)

(with-eval-after-load 'prog-mode
  (define-derived-mode treesitter-mode prog-mode "treesitter"))

(with-eval-after-load 'org-src
  (add-to-list 'org-src-lang-modes '("treesitter" . treesitter)))

25.8.19. ob-base64

(autoload-if-found '(org-babel-execute:base64) "ob-base64" nil t)

(with-eval-after-load 'org-src
  (add-to-list 'org-src-lang-modes '("base64" . base64)))

25.8.20. ob-lisp

(with-eval-after-load 'ob-lisp
  (defalias 'org-babel-execute:common-lisp 'org-babel-execute:lisp))

25.8.21. org-nix-shell

(autoload-if-found '(org-nix-shell-mode) "org-nix-shell" nil t)

(with-eval-after-load 'org
  (add-hook 'org-mode-hook #'org-nix-shell-mode))

25.9. Org Publish

25.9.1. ox-html

(with-eval-after-load 'ox-html
  ;; config
  (setopt org-html-head-include-default-style nil)
  (setopt org-html-head-include-scripts nil)
  (setopt org-html-doctype "html5")
  (setopt org-html-coding-system 'utf-8-unix))

25.9.2. ox-gfm

(autoload-if-found '(org-gfm-export-as-markdown
                       org-gfm-convert-region-to-md
                       org-gfm-export-to-markdown
                       org-gfm-publish-to-gfm) "ox-gfm" nil t)

25.9.3. ox-zenn

(autoload-if-found '(org-zenn-export-as-markdown
                     org-zenn-export-to-markdown
                     org-zenn-publish-to-markdown
                     org-zenn-convert-region-to-md) "ox-zenn" nil t)

25.9.4. ox-hatena

(autoload-if-found '(org-hatena-export-as-hatena
                     org-hatena-export-to-hatena
                     org-hatena-export-to-hatena-and-open) "ox-hatena" nil t)

25.9.5. ox-qmd

(autoload-if-found '(org-qmd-export-as-markdown
                     org-qmd-convert-region-to-md
                     org-qmd-export-to-markdown) "ox-qmd" nil t)

25.9.6. ox-hugo

(autoload-if-found '(org-hugo-export-as-md
                     org-hugo-export-to-md
                     org-hugo-export-wim-to-md
                     org-hugo-debug-info) "ox-hugo" nil t)

(with-eval-after-load 'ox-hugo
  ;; config
  (setopt org-hugo-auto-set-lastmod t))

25.10. Org Roam

25.10.1. basic

(autoload-if-found '(org-roam-graph) "org-roam" nil t)

(keymap-global-set "C-c n g" #'org-roam-graph)
(keymap-global-set "C-c n l" #'org-roam-buffer-toggle)
(keymap-global-set "C-c n f" #'org-roam-node-find)
(keymap-global-set "C-c n i" #'org-roam-node-insert)
(keymap-global-set "C-c n c" #'org-roam-capture)
(keymap-global-set "C-c n d" #'org-roam-dailies-map)
(keymap-global-set "C-c n j" #'org-roam-dailies-goto-today)

(with-eval-after-load 'org-roam
  ;; config
  (setopt org-roam-directory `,(concat (s-trim-right (shell-command-to-string "ghq root"))
                                       "/github.com/takeokunn/blog")))

25.10.2. org-roam-mode

(autoload-if-found '(org-roam-buffer-toggle) "org-roam-mode" nil t)

25.10.3. org-roam-node

(autoload-if-found '(org-roam-node-find org-roam-node-insert) "org-roam-node" nil t)

(with-eval-after-load 'org-roam-node
  (setopt org-roam-completion-everywhere nil))

25.10.4. org-roam-db

(autoload-if-found '(org-roam-db-autosync-enable) "org-roam-db" nil t)

(with-eval-after-load 'org
  (add-hook 'org-mode-hook #'org-roam-db-autosync-enable))

(with-eval-after-load 'org-roam-db
  ;; config
  (setopt org-roam-database-connector 'sqlite)
  (setq org-roam-db-gc-threshold (* 4 gc-cons-threshold)))

25.10.5. org-roam-capture

(autoload-if-found '(org-roam-capture) "org-roam-capture" nil t)

(with-eval-after-load 'org-roam-capture
  ;; config
  (setopt org-roam-capture-templates '(("f" "Fleeting(一時メモ)" plain "%?"
                                        :target (file+head "org/fleeting/%<%Y%m%d%H%M%S>-${slug}.org" "#+TITLE: ${title}\n")
                                        :unnarrowed t)
                                       ("l" "Literature(文献)" plain "%?"
                                        :target (file+head "org/literature/%<%Y%m%d%H%M%S>-${slug}.org" "#+TITLE: ${title}\n")
                                        :unnarrowed t)
                                       ("p" "Permanent(記事)" plain "%?"
                                        :target (file+head "org/permanent/%<%Y%m%d%H%M%S>-${slug}.org" "#+TITLE: ${title}\n")
                                        :unnarrowed t)
                                       ("d" "Diary(日記)" plain "%?"
                                        :target (file+head "org/diary/%<%Y%m%d%H%M%S>-${slug}.org" "#+TITLE: ${title}\n")
                                        :unnarrowed t)
                                       ("z" "Zenn" plain "%?"
                                        :target (file+head "org/zenn/%<%Y%m%d%H%M%S>.org" "#+TITLE: ${title}\n")
                                        :unnarrowed t)
                                       ("m" "Private" plain "%?"
                                        :target (file+head "org/private/%<%Y%m%d%H%M%S>.org.gpg" "#+TITLE: ${title}\n")
                                        :unnarrowed t)
                                       ("o" "Poem" plain "%?"
                                        :target (file+head "org/poem/%<%Y%m%d%H%M%S>-${slug}.org" "#+TITLE: ${title}\n")
                                        :unnarrowed t))))

25.10.6. org-roam-dailies

(autoload-if-found '(org-roam-dailies-map
                     org-roam-dailies-goto-today
                     org-roam-dailies-goto-yesterday
                     org-roam-dailies-goto-tomorrow
                     org-roam-dailies-capture-today
                     org-roam-dailies-goto-next-note
                     org-roam-dailies-goto-previous-note
                     org-roam-dailies-goto-date
                     org-roam-dailies-capture-date
                     org-roam-dailies-find-directory) "org-roam-dailies" nil t)

(with-eval-after-load 'org-roam-dailies
  ;; config
  (setopt org-roam-dailies-directory "org/daily/")

  ;; keybind
  (define-key org-roam-dailies-map (kbd "d") #'org-roam-dailies-goto-today)
  (define-key org-roam-dailies-map (kbd "y") #'org-roam-dailies-goto-yesterday)
  (define-key org-roam-dailies-map (kbd "t") #'org-roam-dailies-goto-tomorrow)
  (define-key org-roam-dailies-map (kbd "n") #'org-roam-dailies-capture-today)
  (define-key org-roam-dailies-map (kbd "f") #'org-roam-dailies-goto-next-note)
  (define-key org-roam-dailies-map (kbd "b") #'org-roam-dailies-goto-previous-note)
  (define-key org-roam-dailies-map (kbd "c") #'org-roam-dailies-goto-date)
  (define-key org-roam-dailies-map (kbd "v") #'org-roam-dailies-capture-date)
  (define-key org-roam-dailies-map (kbd ".") #'org-roam-dailies-find-directory))

25.10.7. org-roam-export

(autoload-if-found '(org-roam-export--org-html--reference) "org-roam-export" nil t)

(with-eval-after-load 'ox-html
  (advice-add 'org-html--reference :override #'org-roam-export--org-html--reference))

25.10.8. org-roam-graph

(autoload-if-found '(org-roam-graph org-roam-graph--open) "org-roam-graph" nil t)

25.10.9. org-roam-overlay

(autoload-if-found '(org-roam-overlay-mode) "org-roam-overlay" nil t)

(with-eval-after-load 'org-roam-mode
  (add-hook 'org-roam-mode-hook #'org-roam-overlay-mode))

25.10.10. org-roam-protocol

(autoload-if-found '(org-roam-protocol-open-ref org-roam-protocol-open-node) "org-roam-protocol" nil t)

(with-eval-after-load 'org-roam-protocol
  ;; alist
  (add-to-list 'org-protocol-protocol-alist '("org-roam-ref" :protocol "roam-ref" :function org-roam-protocol-open-ref))
  (add-to-list 'org-protocol-protocol-alist '("org-roam-node" :protocol "roam-node" :function org-roam-protocol-open-node))

  ;; config
  (setopt org-roam-protocol-store-links t))

25.10.11. consult-org-roam

(autoload-if-found '(consult-org-roam-mode
                   consult-org-roam-file-find
                   consult-org-roam-backlinks
                   consult-org-roam-backlinks-recursive
                   consult-org-roam-forward-links
                   consult-org-roam-search) "consult-org-roam" nil t)

(keymap-global-set "C-c n e" #'consult-org-roam-file-find)
(keymap-global-set "C-c n b" #'consult-org-roam-backlinks)
(keymap-global-set "C-c n B" #'consult-org-roam-backlinks-recursive)
(keymap-global-set "C-c n l" #'consult-org-roam-forward-links)
(keymap-global-set "C-c n r" #'consult-org-roam-search)

(with-eval-after-load 'org
  ;; hooks
  (add-hook 'org-mode-hook #'consult-org-roam-mode))

(with-eval-after-load 'consult-org-roam
  ;; config
  (setq consult-org-roam-grep-func #'consult-ripgrep)
  (setq consult-org-roam-buffer-narrow-key ?r)
  (setq consult-org-roam-buffer-after-buffers t))

25.10.12. org-roam-ui

(autoload-if-found '(org-roam-ui-mode) "org-roam-ui" nil t)

(with-eval-after-load 'org-roam-mode
  ;; hooks
  (add-hook 'org-roam-mode-hook #'org-roam-ui-mode))

(with-eval-after-load 'org-roam-ui
  ;; config
  (setopt org-roam-ui-sync-theme t)
  (setopt org-roam-ui-follow t)
  (setopt org-roam-ui-update-on-save t)
  (setopt org-roam-ui-open-on-start t))

25.10.13. org-roam-timestamps

(autoload-if-found '(org-roam-timestamps-mode) "org-roam-timestamps" nil t)

(with-eval-after-load 'org-roam-mode
  ;; hooks
  (add-hook 'org-roam-mode #'org-roam-timestamps-mode))

(with-eval-after-load 'org-roam-timestamps
  ;; config
  (setopt org-roam-timestamps-remember-timestamps nil))

25.10.14. org-roam-search-node-insert

(autoload-if-found '() "org-roam-search-node-insert" nil t)

25.10.15. TODO org-roam-ql

;; (autoload-if-found '(org-roam-ql-nodes
;;                      org-roam-ql-search
;;                      org-roam-ql-defpred
;;                      org-roam-ql-agenda-buffer-from-roam-buffer
;;                      org-roam-ql-refresh-buffer
;;                      org-dblock-write:org-roam-ql) "org-roam-ql" nil t)
;; (autoload-if-found '(org-roam-ql-ql-init) "org-roam-ql-ql" nil t)

;; (add-hook 'emacs-startup-hook #'org-roam-ql-ql-init)

26. EXWM

26.1. TODO exwm

;; (eval-when-compile
;;   (el-clone :repo "ch11ng/exwm"))

26.2. TODO exwm-edit

;; (eval-when-compile
;;   (el-clone :repo "agzam/exwm-edit"))

;; (when (string= system-type "gnu/linux")
;;   (with-delayed-execution
;;     (message "Install exwm-edit...")
;;     (add-to-list 'load-path (locate-user-emacs-file "el-clone/exwm-edit"))

;;     (autoload-if-found '(exwm-edit--compose-minibuffer) "exwm-edit" nil t)

;;     (exwm-input-set-key (kbd "C-c '") #'exwm-edit--compose-minibuffer)
;;     (exwm-input-set-key (kbd "C-c C-'") #'exwm-edit--compose-minibuffer)

;;     (with-eval-after-load 'exwm-edit
;;       (setq exwm-edit-bind-default-keys nil))))

26.3. TODO exwm-modeline

;; (eval-when-compile
;;   (el-clone :repo "SqrtMinusOne/exwm-modeline"))

;; (when (string= system-type "gnu/linux")
;;   (with-delayed-execution
;;     (message "Install exwm-modeline...")
;;     (add-to-list 'load-path (locate-user-emacs-file "el-clone/exwm-modeline"))

;;     (autoload-if-found '(exwm-modeline-mode) "exwm-modeline")

;;     (with-eval-after-load 'exwm-core
;;       (add-hook 'exwm-mode-hook #'exwm-modeline-mode))

;;     (with-eval-after-load 'exwm-modeline
;;       (setq exwm-modeline-short t))))

27. AI

27.1. copilot.el

(autoload-if-found '(copilot-login
                     copilot-mode
                     global-copilot-mode) "copilot" nil t)

(with-eval-after-load 'copilot
  ;; config
  (setopt copilot-log-max 100000)

  ;; keymap
  (define-key copilot-mode-map (kbd "C-c # i") #'copilot-complete)
  (define-key copilot-mode-map (kbd "C-c # a") #'copilot-accept-completion))

27.2. llm

(autoload-if-found '(make-llm-ollama) "llm-ollama" nil t)

(with-eval-after-load 'llm
  ;; config
  (setopt llm-warn-on-nonfree nil))

27.3. ellama

(autoload-if-found '(ellama-chat
                     ellama-ask-about
                     ellama-ask-line
                     ellama-complete
                     ellama-translate
                     ellama-define-word
                     ellama-summarize
                     ellama-code-review
                     ellama-change
                     ellama-enhance-grammar-spelling
                     ellama-enhance-wording
                     ellama-make-concise
                     ellama-change-code
                     ellama-enhance-code
                     ellama-complete-code
                     ellama-add-code
                     ellama-render
                     ellama-make-list
                     ellama-make-table
                     ellama-summarize-webpage
                     ellama-provider-select
                     ellama-code-complete
                     ellama-code-add
                     ellama-code-edit
                     ellama-code-improve
                     ellama-improve-wording
                     ellama-improve-grammar
                     ellama-improve-conciseness
                     ellama-make-format
                     ellama-ask-interactive)
                   "ellama" nil t)

(with-eval-after-load 'ellama
  (setopt ellama-language "日本語")
  (setopt ellama-translation-template "
Translate this text to %s.

Original text:
%s

Translation to %s:


以下のフォーマットで出力してください。

元テキスト:

<ここに元テキストを出力する>

翻訳後テキスト:

<ここに翻訳後テキストを出力する>

英語構文解説:

<ここに英語の構文解説を日本語でする>
")
  (setopt ellama-provider (progn
                            (make-llm-ollama :chat-model "gemma2:27b" :embedding-model "gemma2:27b"))))

28. MyFunc

28.1. my/beginning-of-intendation

(defun my/beginning-of-intendation ()
  "move to beginning of line, or indentation"
  (interactive)
  (back-to-indentation))

28.2. my/copy-buffer

(defun my/copy-buffer ()
  (interactive)
  (save-excursion
    (mark-whole-buffer)
    (copy-region-as-kill (region-beginning) (region-end))))

(defalias 'copy-buffer 'my/copy-buffer)

28.3. my/ghq-get

(defun my/ghq-get ()
  (interactive)
  (let ((url (read-string "url > ")))
    (message
     (shell-command-to-string
      (mapconcat #'shell-quote-argument
                 (list "ghq" "get" url)
                 " ")))))

(defalias 'ghq-get 'my/ghq-get)

28.4. my/gh-browse

(defun my/gh-browse ()
  (interactive)
  (message
   (shell-command-to-string
    (mapconcat #'shell-quote-argument
               (list "gh" "browse")
               " "))))

(defalias 'gh-browse 'my/gh-browse)

28.5. my/indent-all

(defun my/indent-buffer ()
  (interactive)
  (save-excursion
    (mark-whole-buffer)
    (untabify (region-beginning) (region-end))
    (indent-region (region-beginning) (region-end))))

(defalias 'indent-buffer 'my/indent-buffer)

28.6. my/move-line

(defun my/move-line (arg)
  (interactive)
  (let ((col (current-column)))
    (unless (eq col 0)
      (move-to-column 0))
    (save-excursion
      (forward-line)
      (transpose-lines arg))
    (forward-line arg)))

(defun my/move-line-down ()
  (interactive)
  (my/move-line 1))

(defun my/move-line-up ()
  (interactive)
  (my/move-line -1))

(keymap-global-set "M-N" #'my/move-line-down)
(keymap-global-set "M-P" #'my/move-line-up)

28.7. my/reload-major-mode

(defun my/reload-major-mode ()
  "Reload current major mode."
  (interactive)
  (let ((current-mode major-mode))
    (fundamental-mode)
    (funcall current-mode)
    current-mode))

28.8. my/toggle-kill-emacs

(defvar my/kill-emacs-keybind-p t)

(defun my/toggle-kill-emacs ()
  (interactive)
  (if my/kill-emacs-keybind-p
      (progn
        (message "C-x C-c save-buffers-kill-emacs OFF")
        (setq my/kill-emacs-keybind-p nil)
        (keymap-global-set "C-x C-c" nil))
    (progn
      (message "C-x C-c save-buffers-kill-emacs ON")
      (setq my/kill-emacs-keybind-p t)
      (keymap-global-set "C-x C-c" 'save-buffers-kill-emacs))))

28.9. my/get-class-name-by-file-name

(defun my/get-class-name-by-file-name ()
  (interactive)
  (insert
   (file-name-nondirectory
    (file-name-sans-extension (or (buffer-file-name)
                                  (buffer-name (current-buffer)))))))

28.10. my/insert-clipboard

(defun my/insert-clipboard (arg)
  (interactive "sstring: ")
  (kill-new arg))

28.11. my/actionlint

(defun my/actionlint ()
  (interactive)
  (shell-command-to-string "actionlint"))

(defalias 'actionlint 'my/actionlint)

28.12. my/build-info

(defun my/build-info ()
  "Display build information in a buffer."
  (interactive)
  (switch-to-buffer (get-buffer-create "*Build info*"))
  (setq tab-width 4)
  (let ((buffer-read-only nil))
    (erase-buffer)
    (insert (format "GNU Emacs %s\nCommit:\t\t%s\nBranch:\t\t%s\n"
                    emacs-version
                    emacs-repository-version
                    emacs-repository-branch))
    (insert (format "System:\t\t%s\nDate:\t\t%s\n"
                    system-configuration
                    (format-time-string "%Y-%m-%d %T (%Z)" emacs-build-time)))
    (insert (format "Patch:\t\t%s ns-inline.patch\n"
                    (if (boundp 'mac-ime--cursor-type) "with" "without")))
    (insert (format "Features:\t%s\n" system-configuration-features))
    (view-mode)))

28.13. my/current-ip-address

(defun my/current-ip-address ()
  (interactive)
  (insert
   (shell-command-to-string "curl -s ifconfig.me")))

28.14. my/today

(defun my/today ()
  (interactive)
  (insert
   (format-time-string "%Y-%m-%d %a" (current-time))))

(defalias 'today 'my/today)

28.15. my/subword

(defun my/delete-forward-block ()
  (interactive)
  (if (eobp)
      (message "End of buffer")
    (let* ((syntax-move-point
            (save-excursion
              (skip-syntax-forward (string (char-syntax (char-after))))
              (point)))
           (subword-move-point
            (save-excursion
              (subword-forward)
              (point))))
      (kill-region (point) (min syntax-move-point subword-move-point)))))

29. Footer

29.1. Magic File Name を有効にする

(setq file-name-handler-alist my/saved-file-name-handler-alist)

29.2. profilerを終了する

(when my/enable-profile
  (profiler-report)
  (profiler-stop))

Author: takeokunn

Created: 2024-10-14 Mon 02:39

Validate