Emacs備忘録（２０２４年版）

# 追記

【2024/06/24】ガベージコレクション・flxの設定を修正しました。
【2024/08/26】native-compile-prune-cacheの設定は不要なので、削除しました。
【2024/11/03】tabnine、capeの設定を修正しました。
【2024/11/13】meow、org-modern、diff-hl、corfuの設定を修正
【2025/05/31】package.elに自動リトライ機能を追加

# 背景

[こちら](https://qiita.com/nobuyuki86/items/6b7aa2f17faa63b6a900)の記事を書いてから１年半ほど経過しましたが、設定やパッケージが大きく変わってきたので、振り返りも兼ねて備忘録を投稿します。

設定の管理はorgファイルで`orb-babel-load-file`コマンドを使用してelファイルを生成・ロードするようにしています。
パッケージの選定基準はシンプルでemacs組み込み機能を活用しているものをなるべく選んでいます。

最終的な見た目は下記のような感じです。

- org-modern + perfect-margin + spacious-padding

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696232/fb4cbabd-d4ce-3b57-d610-3533d256a1b0.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696232/1657652a-4860-e19d-9077-1c5c1e37ac10.png)

- vertico (vertico-buffer)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696232/ad2c46f4-25e6-eb30-31e5-d29f97a1cf93.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696232/7e76c1c1-d11e-93bb-425d-645eeb4a1335.png)

- corfu

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696232/2e4571d0-73dd-723a-20ba-4fe892dd7e04.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696232/f2c13e70-39a7-da53-6248-21990fd5bd59.png)

- vundo

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696232/f9fd21d8-b2e0-a1eb-b4cd-c257bcb8aa95.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696232/889a400d-0cbd-eb2c-388c-ac75e5941310.png)

- imenu-list

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696232/4b0404e2-d4e4-2697-8dc7-9602cdd58017.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696232/6ef3b30c-7583-4c72-fa12-aac059f1c18e.png)

- magit

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696232/40cf8ed4-557e-3274-de4a-68f036361bfc.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696232/66c492bf-65ea-1b94-d2b4-0c7111d2ebda.png)

- difftastic

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696232/3c3f8c0d-7d9e-8b52-dfcf-7d0902d03dee.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696232/81d7129b-83f4-22e6-3e0a-2249f4a8eced.png)


下記はorgファイルの設定をmarkdownに変換してそのまま貼り付けてます。
Emacs29以上が対象です。

# 注意点

builtinパッケージはそのままではアップデートされないので、
`list-packages`で`U`、`x`を入力してアップデートを行います。

`auto-compile`を導入するとインストールが上手くいかない場合がありましたので、削除しました。

初回インストール時に全てのパッケージがインストールされない場合があります。その場合、Emacsを何度か再起動して全てのパッケージをインストールしてください。

# early-init.el


## header

```el
;;; package --- Summary
;;; Commentary:
;;; Code:
```


## custom変数の保存先を変更

```el
(setq custom-file (locate-user-emacs-file "custom.el"))
(when (file-exists-p (expand-file-name custom-file))
  (load-file (expand-file-name custom-file)))
```


## [protesilaos](https://protesilaos.com/emacs/dotemacs#h:a1288a07-93f6-4e14-894e-707d5ad8b6dc)を参考


### ファイル選択ウィンドウを使用しない

```el
(setq use-file-dialog nil)
```


### Xリソースを使用しない

```el
(setq inhibit-x-resources t)
```


### バッファメニューの使用を抑制

```el
(setq inhibit-startup-buffer-menu t)
```


## 画面最大化

```el
(push '(fullscreen . maximized) default-frame-alist)
```


## スクロール非表示

```el
(scroll-bar-mode -1)
```


## メニューバー非表示

```el
(menu-bar-mode -1)
```


## ツールバー非表示

```el
(tool-bar-mode -1)
```


## footer

```el
(provide 'early-init)
;;; early-init.el ends here
```



# init.el


## header

```el
;;; package --- Summary
;;; Commentary:
;;; Code:
```


## OS判定用定数

```el
(defconst IS-MAC (eq system-type 'darwin))
(defconst IS-LINUX (memq system-type '(gnu gnu/linux gnu/kfreebsd berkeley-unix)))
(defconst IS-WINDOWS (memq system-type '(cygwin windows-nt ms-dos)))
```


## 文字コード

slack emacs-jpのwindowsチャンネルを参考にしています。`default-process-coding-system` が重要。

```el
(when IS-WINDOWS
  (setq-default default-process-coding-system '(utf-8-unix . japanese-cp932-dos)))
```


## package.el

modus-themesの作者 [Protesilaos Stavrouのブログ](https://protesilaos.com/emacs/dotemacs) を参考にしています。

```el
(require 'package)

(add-to-list 'package-archives '("gnu-elpa-devel" . "https://elpa.gnu.org/devel/"))
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))

;; インストールする優先順位を指定
(setq package-archive-priorities
      '(("gnu-elpa-devel" . 3)
        ("melpa" . 2)
        ("nongnu" . 1)))

(setq package-install-upgrade-built-in t ; built-inパッケージも更新対象にする
      package-native-compile t           ; インストール時にnative compileする
      )
```

### リトライ処理を導入

以下のコードを設定ファイルに追加することで、`package-install`に自動リトライ機能を追加できます。

```el
  (setq package-retry-max-attempts 5)
  (setq package-retry-delay 3)

  (defun package-install-advice (orig-fun package &rest args)
    "Advice to add retry functionality to package-install."
    (let ((retry-count 0)
          (max-retries package-retry-max-attempts)
          (delay package-retry-delay)
          success result)
      (while (and (< retry-count max-retries) (not success))
        (condition-case err
            (progn
              (when (> retry-count 0)
                (message "Retrying package installation (%d/%d): %s" 
                         retry-count max-retries 
                         (if (package-desc-p package)
                             (package-desc-name package)
                           package))
                (sleep-for delay))
              (setq result (apply orig-fun package args))
              (setq success t))
          (error
           (setq retry-count (1+ retry-count))
           (if (>= retry-count max-retries)
               (signal (car err) (cdr err))
             (message "Package installation failed (attempt %d/%d): %s" 
                      retry-count max-retries (error-message-string err))))))
      result))

  ;; アドバイスを適用
  (advice-add 'package-install :around #'package-install-advice)
```

### use-package

Emacsパッケージの設定や管理を簡単にしてくれます。Emacs29からbuiltinされました。

```el
(use-package use-package
  :config
  (setq use-package-always-ensure t))
```

1.  [vc-use-package](https://github.com/slotThe/vc-use-package)

    use-packageとvcを統合します。Windows版Emacsではbuiltinされていないのでインストールします。
    
    ```el
    (unless (package-installed-p 'vc-use-package)
      (package-vc-install "https://github.com/slotThe/vc-use-package"))
    (require 'vc-use-package)
    ```


### [auto-package-update](https://github.com/rranelli/auto-package-update.el)

パッケージを自動的に更新してくれます。最新のEmacsでは `package-upgrade-all` 機能が搭載されていますが、高頻度でエラーが発生するためこちらのパッケージで更新します。

```el
(use-package auto-package-update
  :config
  (setq auto-package-update-interval 1)
  (auto-package-update-maybe))
```


## keymap

後述のmeowで設定するキーマップを作成します。こちらによく使うコマンドを登録し、利便性を向上させます。

```el
(defvar my-toggle-map (make-keymap))
(defvar my-quit-map (make-keymap))
(defvar my-error-map (make-keymap))
```


## Emacs標準機能の設定


### yes-or-noをy-or-nに変更

```el
(setq use-short-answers t)
```


### バックアップファイルを作成しない

```el
(setq make-backup-files nil)
(setq backup-inhibited nil)
(setq create-lockfiles nil)
```


### ビープ音を無効化

```el
(setq ring-bell-function 'ignore)
```


### auto-save-visited

一定時間経過しても操作がない場合、バッファを自動保存します。

```el
(use-package files
  :ensure nil
  :config
  (setq auto-save-visited-interval 30)
  (auto-save-visited-mode +1))
```


### フォーカスアウト時に全バッファを保存

```el
(defun my/save-all-buffers ()
  (save-some-buffers "!"))

(add-hook 'focus-out-hook #'my/save-all-buffers)
```


### デーモン起動

`emacsclient` コマンドで高速にファイルが開けます。

```el
(use-package server
  :config
  (unless (server-running-p)
    (server-start)))
```


### 最後のカーソル位置を保存する

```el
(use-package saveplace
  :init
  (save-place-mode +1))
```


### ファイルの閲覧履歴を保存する

```el
(use-package recentf
  :init
  (setq recentf-max-saved-items 100)
  (recentf-mode +1))
```


### コマンドの履歴を保存

```el
(use-package savehist
  :init
  (savehist-mode +1))
```


### 対応括弧を強調表示

```el
(use-package paren
  :init
  (show-paren-mode +1))
```


### 対応括弧を自動補完

```el
(use-package elec-pair
  :config
  (electric-pair-mode +1))
```


### 現在行を強調表示

```el
(use-package hl-line
  :init
  (global-hl-line-mode +1))
```


### 他プロセスの編集をバッファに反映

```el
(use-package autorevert
  :init
  (global-auto-revert-mode +1))
```


### camelCase単位で移動する

```el
(use-package subword
  :init
  (global-subword-mode +1))
```


### 削除したファイルをゴミ箱に移動させる

```el
(setq delete-by-moving-to-trash t)
```


### native-compの警告を表示しない

```el
(setq native-comp-async-report-warnings-errors 'silent)
```


### 終了コマンドをキーマップに設定

```el
(use-package files
  :ensure nil
  :bind ( :map my-quit-map
          ("q" . save-buffers-kill-terminal)))
```


### インデントの基本をスペースに変更

```el
(use-package simple
  :ensure nil
  :init
  (setq-default indent-tabs-mode nil))
```


### ガベージコレクション

デフォルトの設定ではガベージコレクションが頻発する為調整しています。前は[gcmh](https://github.com/emacsmirror/gcmh)を使用していましたがタイマーによるごみが多く生成されてしまうようで、[こちら](https://emacsconf.org/2023/talks/gc/)の記事で推奨されているように`gc-cons-percentage` を0.2にするように変更しました。

```el
(setq gc-cons-percentage 0.2
      gc-cons-threshold (* 128 1024 1024))
(add-hook 'focus-out-hook #'garbage-collect)
```

1.  ガベージコレクションのメッセージを表示

    ```el
    (setq garbage-collection-messages t)
    ```


### 長い行を含むファイルの最適化

```el
(use-package so-long
  :init
  (global-so-long-mode +1))
```


### flymake

Emacs標準に組み込まれているシンタックスチェック用のパッケージです。他の有名なパッケージに[flycheck](https://github.com/flycheck/flycheck)があります。

```el
(use-package flymake
  :hook ((prog-mode
          conf-mode) . flymake-mode)
  :bind ( :map my-error-map
          ("l" . flymake-show-buffer-diagnostics)
          ("L" . flymake-show-project-diagnostics)
          ("n" . flymake-goto-next-error)
          ("p" . flymake-goto-prev-error))
  :init
  (setq-default flymake-no-changes-timeout 1.0)

  :config
  (with-eval-after-load 'meow
    (meow-leader-define-key
     `("e" . ("error" . ,my-error-map)))))
```

1.  [flymake-collection](https://github.com/mohkale/flymake-collection)

    flymake-collectionはflymakeの各言語の設定を簡単にしてくれるパッケージです。typescriptでeglotと併用する際に、そのままだとeslintの設定が上書きされてしまうので、eglotのflymake設定を後から追加するようにしています。
    
    ```el
    (use-package flymake-collection
      :hook ((after-init . flymake-collection-hook-setup)
             ((tsx-ts-mode
               jsx-ts-mode
               jtsx-jsx-mode
               jtsx-tsx-mode
               jtsx-typescript-mode) . (lambda () (add-to-list 'flymake-diagnostic-functions #'flymake-collection-eslint)))
             (eglot-managed-mode . (lambda () (add-to-list 'flymake-diagnostic-functions #'eglot-flymake-backend)))))
    ```


### 末尾のスペースやタブを可視化

```el
(setq-default show-trailing-whitespace t)
```


### delsel

選択している状態で入力したときに、regionを削除して挿入するようにします。

```el
(use-package delsel
  :config
  (delete-selection-mode +1))
```


### パフォーマンスの向上

<https://ayatakesi.github.io/lispref/25.2/html/Output-from-Processes.html>

```el
(setq process-adaptive-read-buffering t)
```

1.  [protesilaos](https://protesilaos.com/emacs/dotemacs)

    1.  閉じ括弧を入力しても点滅させない
    
        ```el
        (setq blink-matching-paren nil)
        ```
    
    2.  vcのバックエンドをGitのみに変更
    
        ```el
        (setq vc-handled-backends '(Git))
        ```

2.  [doomemacs](https://github.com/doomemacs/doomemacs/blob/master/lisp/doom-start.el)

    1.  ファイル検索を2回行わないようにする
    
        ```el
        (setq auto-mode-case-fold nil)
        ```
    
    2.  双方向の並び替えを抑制する
    
        ```el
        (setq-default bidi-display-reordering 'left-to-right)
        ```
    
    3.  長い行の双方向スキャン
    
        ```el
        (setq bidi-inhibit-bpa t)
        ```
    
    4.  フォーカスされていないウィンドウのカーソルを削除
    
        ```el
        (setq-default cursor-in-non-selected-windows nil)
        (setq highlight-nonselected-windows nil)
        ```
    
    5.  高速なスクロール
    
        ```el
        (setq fast-but-imprecise-scrolling t)
        ```
    
    6.  ドメインにpingを送信しない
    
        ```el
        (setq ffap-machine-p-known 'reject)
        ```
    
    7.  UIの更新頻度を下げる
    
        ```el
        (setq idle-update-delay 1.0)
        ```
    
    8.  不要なフォント表示化を抑制
    
        ```el
        (setq redisplay-skip-fontification-on-input t)
        ```
    
    9.  Windowsの最適化
    
        ```el
        (when IS-WINDOWS
          (setq w32-get-true-file-attributes nil
                w32-pipe-read-delay 0
                w32-pipe-buffer-size (* 64 1024)))
        ```

3.  [Centaur Emacs](https://github.com/seagle0128/.emacs.d)

    1.  各OSの最適化
    
        ```el
        (when IS-WINDOWS
          (setq w32-use-native-image-API t))
        
        (unless IS-MAC
          (setq command-line-ns-option-alist nil))
        
        (unless IS-LINUX
          (setq command-line-x-option-alist nil))
        ```


## [meow](https://github.com/meow-edit/meow)

meow は vi/vim に代表される modal editing を提供するパッケージで、Normal ModeやInsert Modeのような移動や編集に特化したモードを提供します。Emacsで最も有名なものは[evil](https://github.com/emacs-evil/evil)ですが、シンプルでEmacsによく統合されているmeowに乗り換えてみました。[デフォルトのQWERTYキーバインド](https://github.com/meow-edit/meow/blob/master/KEYBINDING_QWERTY.org)ではVimの操作と乖離が大きいので、近づけるようにキーバインドを変更しています。

また、meowではEmacsのショートカットを下記のような入力で実行できます。

-   M-x → `SPC m x`
-   C-x C-f → `SPC x f`
-   C-x b → `SPC x SPC b`
-   C-c C-c → `SPC c c`

※ 上のコマンドは `evil` + `god-mode` でも同様のことができるみたいです。

```el
(use-package meow
  :config
  (setopt meow-use-clipboard t
          meow-expand-hint-counts nil)

  (defun meow-setup ()
    (setopt meow-cheatsheet-layout meow-cheatsheet-layout-qwerty)

    (meow-thing-register 'angle
                         '(pair ("<") (">"))
                         '(pair ("<") (">")))
    (add-to-list 'meow-char-thing-table '(?a . angle))

    (meow-motion-overwrite-define-key
     '("j" . meow-next)
     '("k" . meow-prev)
     '("<escape>" . ignore))
    (meow-leader-define-key
     ;; SPC j/k will run the original command in MOTION state.
     '("j" . "H-j")
     '("k" . "H-k")
     ;; Use SPC (0-9) for digit arguments.
     '("0" . delete-window)
     '("1" . delete-other-windows)
     '("2" . split-window-below)
     '("3" . split-window-right)
     '("4" . switch-to-buffer-other-frame)
     '("5" . meow-digit-argument)
     '("6" . meow-digit-argument)
     '("7" . meow-digit-argument)
     '("8" . meow-digit-argument)
     '("9" . meow-digit-argument)
     '("/" . meow-keypad-describe-key)
     '("?" . meow-cheatsheet)
     '("w" . other-window)
     `("s" . ("search" . ,search-map))
     `("p" . ("project" . ,project-prefix-map))
     `("t" . ("toggle" . ,my-toggle-map))
     `("q" . ("quit" . ,my-quit-map)))
    (meow-normal-define-key
     '("$" . move-end-of-line)
     '("0" . move-beginning-of-line)
     '("^" . back-to-indentation)
     '("9" . meow-expand-9)
     '("8" . meow-expand-8)
     '("7" . meow-expand-7)
     '("6" . meow-expand-6)
     '("5" . meow-expand-5)
     '("4" . meow-expand-4)
     '("3" . meow-expand-3)
     '("2" . meow-expand-2)
     '("1" . meow-expand-1)
     '("-" . negative-argument)
     '(";" . repeat)
     '(":" . meow-reverse)
     '("," . meow-inner-of-thing)
     '("." . meow-bounds-of-thing)
     '("<" . meow-beginning-of-thing)
     '(">" . meow-end-of-thing)
     '("[" . scroll-down-command)
     '("]" . scroll-up-command)
     '("{" . backward-paragraph)
     '("}" . forward-paragraph)
     '("a" . meow-append)
     '("A" . meow-open-below)
     '("b" . meow-back-word)
     '("B" . meow-back-symbol)
     '("c" . meow-change)
     '("d" . meow-kill)
     '("D" . meow-kill-whole-line)
     '("e" . meow-next-word)
     '("E" . meow-next-symbol)
     '("f" . meow-find)
     '("g" . meow-cancel-selection)
     '("G" . meow-grab)
     '("h" . meow-left)
     '("H" . meow-left-expand)
     '("i" . meow-insert)
     '("I" . meow-open-above)
     '("j" . meow-next)
     '("J" . meow-next-expand)
     '("k" . meow-prev)
     '("K" . meow-prev-expand)
     '("l" . meow-right)
     '("L" . meow-right-expand)
     '("m" . meow-join)
     '("o" . meow-block)
     '("O" . meow-to-block)
     '("p" . yank)
     '("q" . meow-quit)
     '("Q" . meow-goto-line)
     '("r" . meow-replace)
     '("R" . meow-swap-grab)
     '("s" . meow-change)
     '("t" . meow-till)
     '("u" . meow-undo)
     '("U" . meow-undo-in-selection)
     '("v" . set-mark-command)
     '("V" . meow-line)
     '("w" . meow-mark-word)
     '("W" . meow-mark-symbol)
     '("x" . meow-delete)
     '("y" . meow-save)
     '("Y" . meow-sync-grab)
     '("z" . meow-pop-selection)
     '("'" . meow-reverse)
     '("/" . isearch-forward)
     '("n" . isearch-repeat-forward)
     '("N" . isearch-repeat-backward)
     '("*" . isearch-forward-symbol-at-point)
     '("=" . indent-region)
     '("<escape>" . ignore)))

  (meow-setup)
  (meow-global-mode +1)

  ;; ノーマルモードに戻る際、日本語入力を解除する
  (add-hook 'meow-insert-exit-hook #'deactivate-input-method))
```


## org

`org-mode` に関する基本的な設定をしています。

```el
(use-package org
  :init
  (setq org-return-follows-link t  ; Returnキーでリンク先を開く
        org-mouse-1-follows-link t ; マウスクリックでリンク先を開く
        ))
```


### アンダースコアを入力しても下付き文字にならないようにする

```el
(setq org-use-sub-superscripts '{}
      org-export-with-sub-superscripts nil)
```


### org-agenda

`org-agenda` のディレクトリを指定しています。

```el
(use-package org-agenda
  :ensure nil
  :after org
  :config
  (setq org-agenda-files (file-expand-wildcards (concat org-directory "/*.org"))))
```


### org-indent-mode

インデント機能を有効にしています。

```el
(use-package org-indent
  :ensure nil
  :hook (org-mode . org-indent-mode))
```


### [org-pomodoro](https://github.com/marcinkoziej/org-pomodoro)

カーソル上のタスクでポモドーロタイマーを設定してくれます。

```el
(use-package org-pomodoro
  :after org)
```


### [ox-qmd](https://github.com/0x60df/ox-qmd) (qiita投稿用)

orgファイルをmarkdownファイルに変換してくれます。

```el
(use-package ox-qmd
  :defer t)
```


### [denote](https://protesilaos.com/emacs/denote)

org用のシンプルなメモ取りツールとして愛用しています。

```el
(use-package denote
  :init
  (with-eval-after-load 'org
    (setq denote-directory org-directory))

  :config
  (with-eval-after-load 'meow
    (meow-leader-define-key
     '("d" . denote-open-or-create)))

  (add-hook 'find-file-hook #'denote-link-buttonize-buffer)
  (add-hook 'dired-mode-hook #'denote-dired-mode-in-directories)
  (add-hook 'context-menu-functions #'denote-context-menu)

  (denote-rename-buffer-mode +1))
```


### [org-modern](https://github.com/minad/org-modern)

org-modeの見た目をリッチなものにしてくれます。

```el
(use-package org-modern
  :config
  (setopt
   ;; Edit settings
   org-auto-align-tags nil
   org-tags-column 0
   org-catch-invisible-edits 'show-and-error
   org-special-ctrl-a/e t
   org-insert-heading-respect-content t

   ;; Org styling, hide markup etc.
   org-hide-emphasis-markers t
   org-pretty-entities t

   ;; Agenda styling
   org-agenda-tags-column 0
   org-agenda-block-separator ?─
   org-agenda-time-grid
   '((daily today require-timed)
     (800 1000 1200 1400 1600 1800 2000)
     " ┄┄┄┄┄ " "┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄")
   org-agenda-current-time-string
   "◀── now ─────────────────────────────────────────────────")

  ;; Ellipsis styling
  (setopt org-ellipsis "…")
  (set-face-attribute 'org-ellipsis nil :inherit 'default :box nil)

  (global-org-modern-mode))
```

1.  [org-modern-indent](https://github.com/jdtsmith/org-modern-indent)

    `org-indent + org-modern` を有効にするとsrcブロックの「bracket」と呼ばれる表示が無効になります。このパッケージは `org-indent + org-modern` でも「bracket」を再現します。
    
    ```el
    (use-package org-modern-indent
      :vc ( :fetcher github :repo "jdtsmith/org-modern-indent")
      :config
      (add-hook 'org-mode-hook #'org-modern-indent-mode 90))
    ```


## IME

Emacsは~C-\\~で日本語入力を切り替えることができますが、デフォルトだとあまり補完が賢くないのでOSに合わせて導入します。


### [tr-ime](https://github.com/trueroad/tr-emacs-ime-module)

```el
(use-package tr-ime
  :if IS-WINDOWS
  :config
  (setq default-input-method "W32-IME")
  (tr-ime-standard-install)
  (w32-ime-initialize))
```


### mozc

[日本語変換 Mozc の設定，emacs 用の Mozc の設定（Ubuntu 上）](https://www.kkaneko.jp/tools/server/mozc.html) を参考にしています。

1.  必要なパッケージを導入

    ```shell
    sudo apt install fcitx-libs-dev
    sudo apt install emacs-mozc
    fcitx-config-gtk
    ```

2.  Emacs側の設定

    ```el
    (use-package mozc
      :unless IS-WINDOWS
      :init
      (setq default-input-method "japanese-mozc"))
    ```


## フォントの設定

私は [fontaine](https://github.com/protesilaos/fontaine) を使用してフォントを設定しています。

```el
(use-package fontaine
  :config
  (cond (IS-LINUX
         (setq fontaine-presets
               '((regular
                  :default-family "PlemolJP HS"
                  :fixed-pitch-family "PlemolJP HS"
                  :variable-pitch-family "IBM Plex Sans JP"
                  :italic-family "PlemolJP HS")
                 (large
                  :default-family "PlemolJP HS"
                  :variable-pitch-family "IBM Plex Sans JP"))))

        (IS-WINDOWS
         (setq fontaine-presets
               '((regular
                  :default-family "PlemolJP Console NF"
                  :fixed-pitch-family "PlemolJP Console NF"
                  :variable-pitch-family "IBM Plex Sans JP"
                  :italic-family "PlemolJP Console NF")
                 (large
                  :default-family "PlemolJP Console NF"
                  :variable-pitch-family "IBM Plex Sans JP")))))

  (fontaine-set-preset (or (fontaine-restore-latest-preset) 'regular))
  (add-hook 'kill-emacs-hook #'fontaine-store-latest-preset))
```


## アイコン


### [nerd-icons](https://github.com/rainstormstudio/nerd-icons.el)

アイコンにはnerd-iconsを使用しています。他に[all-the-icons](https://github.com/domtronn/all-the-icons.el)というパッケージもあります。

```el
(use-package nerd-icons)
```

1.  [nerd-icons-completion](https://github.com/rainstormstudio/nerd-icons-completion)

    vertico等の補完パッケージでアイコンが表示されるようにします。
    
    ```el
    (use-package nerd-icons-completion
      :hook (after-init . nerd-icons-completion-mode))
    ```

2.  [nerd-icons-dired](https://github.com/rainstormstudio/nerd-icons-dired)

    diredでアイコンが表示されるようにします。
    
    ```el
    (use-package nerd-icons-dired
      :hook (dired-mode . nerd-icons-dired-mode))
    ```

3.  [nerd-icons-corfu](https://github.com/LuigiPiucco/nerd-icons-corfu)

    corfuでアイコンが表示されるようになります。
    
    ```el
    (use-package nerd-icons-corfu
      :vc ( :fetcher github :repo "LuigiPiucco/nerd-icons-corfu")
      :after corfu nerd-icons
      :config
      (add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter))
    ```


## modeline


### [nyan-mode](https://github.com/TeMPOraL/nyan-mode)

バッファー上での位置をニャンキャットが教えてくれるパッケージです。マウスでクリックすると大体の位置にジャンプもできます。

```el
(use-package nyan-mode
  :init
  (setq nyan-bar-length 24)
  (nyan-mode +1))
```


### [minions](https://github.com/tarsius/minions)

デフォルトのモードラインでは各言語のメジャーモードやマイナーモードが全て表示されますが、こちらのパッケージを導入することで、マイナーモードがハンバーガーメニューで表示され、マウスクリックで表示されるようになります。

```el
(use-package minions
  :init
  (minions-mode +1))
```


## [corfu](https://github.com/minad/corfu)

corfuはEmacsの補完パッケージです。他に有名な補完パッケージに[company](https://github.com/company-mode/company-mode)と[auto-complete](https://github.com/auto-complete/auto-complete)がありますが、corfuが最もEmacsの組み込み機能と統合されています。

最新のcorfuは特に設定を記述しなくてもminibuffer上で補完が表示されるので設定を削除しました。

```el
(use-package corfu
  :demand t
  :hook (prog-mode . (lambda ()
                       (global-set-key [remap c-indent-line-or-region] #'indent-for-tab-command)))
  :config
  (setopt corfu-cycle t
          corfu-auto t
          corfu-auto-delay 0.0
          corfu-auto-prefix 2
          corfu-on-exact-match 'show)

  (global-corfu-mode +1)

  (with-eval-after-load 'meow
    (define-key corfu-map (kbd "<escape>")
                (lambda ()
                  (interactive)
                  (corfu-quit)
                  (meow-normal-mode))))

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

  (with-eval-after-load 'orderless
    (defun my/orderless-for-corfu ()
      (setq-local orderless-matching-styles '(orderless-flex)))

    (add-hook 'corfu-mode-hook #'my/orderless-for-corfu)))
```


### corfu-popupinfo

補完候補の横に説明用のポップアップが表示されるようになります。

```el
(use-package corfu-popupinfo
  :ensure nil
  :hook (corfu-mode . corfu-popupinfo-mode))
```


### corfu-magic

[evil-collection](https://github.com/emacs-evil/evil-collection/blob/master/modes/corfu/evil-collection-corfu.el)の設定を元にキーバインドを設定しています。補完候補未選択時にRETを押下すると改行が挿入され、補完候補選択時にRETを押下すると補完候補を選択します。

```el
(with-eval-after-load 'corfu
  (setq corfu-preselect 'prompt)

  (define-key corfu-map (kbd "TAB") 'corfu-next)
  (define-key corfu-map (kbd "<tab>") 'corfu-next)
  (define-key corfu-map (kbd "S-TAB") 'corfu-previous)
  (define-key corfu-map (kbd "<backtab>") 'corfu-previous)

  (defvar corfu--index)
  (defvar corfu-magic-insert-or-next-line
    `(menu-item "" nil :filter ,(lambda (&optional _)
                                  (when (>= corfu--index 0)
                                    'corfu-insert)))
    "If we made a selection during `corfu' completion, select it.")
  (define-key corfu-map (kbd "RET") corfu-magic-insert-or-next-line)

  (defvar corfu-magic-cancel-or-backspace
    `(menu-item "" nil :filter ,(lambda (&optional _)
                                  (when (>= corfu--index 0)
                                    'corfu-reset)))
    "If we made a selection during `corfu' completion, cancel it.")
  (define-key corfu-map (kbd "DEL") corfu-magic-cancel-or-backspace)
  (define-key corfu-map (kbd "<backspace") corfu-magic-cancel-or-backspace)
  )
```


### [cape](https://github.com/minad/cape)

capeは `completion-at-point（capf）` と呼ばれるEmacsの組み込み補完機能を拡張するパッケージです。capfはcorfuやcompanyで使用されており、補完候補の候補をカスタマイズできます。
~~※`cape-capf-super`内で`cape-capf-buster`を使用すると、`eglot`使用時に補完の上書き開始・終了位置が正しくない不具合があったので、`cape-capf-buster`の位置を変更しました。~~
※パフォーマンス上の問題やcape-capf-buster + tabnineの主張が激しいので、シンプルな設定にしました。

```el
(use-package tabnine
  :hook (kill-emacs . tabnine-kill-process)
  :bind ( :map tabnine-completion-map
          ("TAB" . nil)
          ("<tab>" . nil))
  :init
  (global-tabnine-mode +1))

(use-package cape
  :config
  (advice-add 'eglot-completion-at-point :around #'cape-wrap-buster)
  (advice-add 'eglot-completion-at-point :around #'cape-wrap-nonexclusive)
  (advice-add 'lsp-completion-at-point :around #'cape-wrap-buster)
  (advice-add 'lsp-completion-at-point :around #'cape-wrap-nonexclusive)
  (advice-add 'lsp-completion-at-point :around #'cape-wrap-noninterruptible)

  (add-hook 'completion-at-point-functions #'tempel-complete)
  (add-hook 'completion-at-point-functions #'cape-dabbrev)
  (add-hook 'completion-at-point-functions #'cape-file)
  (add-hook 'completion-at-point-functions #'cape-elisp-block)
  (with-eval-after-load 'tabnine
    (advice-add 'tabnine-completion-at-point #'cape-wrap-buster)
    (add-hook 'completion-at-point-functions #'tabnine-completion-at-point)))
```

1.  dabbrevのサイズを制限

    ```el
    (setq dabbrev-friend-buffer-function (lambda (other-buffer)
                                           (< (buffer-size other-buffer) (* 1024 1024))))
    ```


### [corfu-terminal](https://codeberg.org/akib/emacs-corfu-terminal)

corfuはデフォルトではターミナルに対応していません。こちらのパッケージを導入することでターミナルでもcorfuが使用できるようになります。

```el
(use-package corfu-terminal
  :unless (display-graphic-p)
  :config
  (corfu-terminal-mode +1))
```


### TABで補完を表示する

```el
(setq tab-always-indent 'complete)
```


## [vertico](https://github.com/minad/vertico)

`helm` や `ivy` よりも補完インタフェース新しくシンプルな補完パッケージです。

```el
(use-package vertico
  :init
  (setq vertico-cycle t)
  (vertico-mode +1))
```


### vertico-repeat

`verito` の拡張機能の一つで直前のコマンドを再度表示します。

```el
(use-package vertico-repeat
  :ensure nil
  :after vertico
  :hook (minibuffer-setup . vertico-repeat-save)
  :init
  (with-eval-after-load 'meow
    (meow-leader-define-key
     '("z" . vertico-repeat))))
```


### vertico-directory

`verito` の拡張機能の一つで `find-file` のファイル・ディレクトリ操作時の操作性を向上させる拡張機能です。

```el
(use-package vertico-directory
  :ensure nil
  :after vertico
  :bind ( :map vertico-map
          ("<backspace>" . vertico-directory-delete-char)))
```


### vertico-buffer

verticoはデフォルトではミニバッファを使用して表示しますが、縦長のディスプレイを使用した際に視線の移動が大きいため、helmのようにバッファを使用するようにしています。

```el
(use-package vertico-buffer
  :ensure nil
  :config
  (setq vertico-buffer-display-action '(display-buffer-at-bottom))
  (vertico-buffer-mode +1))
```


### Prefix current candidate with arrow

verticoの選択行のアイコンを追加します。[vertico wiki](https://github.com/minad/vertico/wiki#prefix-current-candidate-with-arrow)で紹介されています。

```el
(defvar +vertico-current-arrow t)

(cl-defmethod vertico--format-candidate :around
  (cand prefix suffix index start &context ((and +vertico-current-arrow
                                                 (not (bound-and-true-p vertico-flat-mode)))
                                            (eql t)))
  (setq cand (cl-call-next-method cand prefix suffix index start))
  (let ((arrow (nerd-icons-faicon "nf-fa-hand_o_right")))
    (if (bound-and-true-p vertico-grid-mode)
        (if (= vertico--index index)
            (concat arrow " " cand)
          (concat #("_" 0 1 (display " ")) cand))
      (if (= vertico--index index)
          (concat " " arrow " " cand)
        (concat "    " cand)))))
```


### [vertico-truncate](https://github.com/jdtsmith/vertico-truncate)

補完候補に非常に長い候補が存在するとパフォーマンス上の問題があるそうで、こちらのパッケージがそれを解消してくれます。

```el
(use-package vertico-truncate
  :vc ( :fetcher github :repo "jdtsmith/vertico-truncate")
  :config
  (vertico-truncate-mode +1))
```


## [orderless](https://github.com/oantolin/orderless)

orderlessは柔軟な補完スタイルを提供するパッケージです。パフォーマンスも良く、高度にカスタマイズ可能です。

```el
(use-package orderless
  :config
  (setq completion-styles '(orderless basic)
        completion-category-defaults nil
        completion-category-overrides nil)

  (with-eval-after-load 'migemo
    ;; orderlessをmigemo対応
    (defun orderless-migemo (component)
      (let ((pattern (downcase (migemo-get-pattern component))))
        (condition-case nil
            (progn (string-match-p pattern "") pattern)
          (invalid-regexp nil))))
    (add-to-list 'orderless-matching-styles 'orderless-migemo))

  (with-eval-after-load 'corfu
    (defun orderless-fast-dispatch (word index total)
      (and (= index 0) (= total 1) (length< word 4)
           'orderless-literal-prefix))

    (orderless-define-completion-style orderless-fast
      (orderless-style-dispatchers '(orderless-fast-dispatch))
      (orderless-matching-styles '(orderless-flex)))

    (defun my/setup-corfu-for-orderless ()
      (setq-local corfu-auto-delay 0
                  corfu-auto-prefix 1
                  completion-styles '(orderless-fast)))

    (add-hook 'corfu-mode-hook #'my/setup-corfu-for-orderless)))
```


## [prescient](https://github.com/radian-software/prescient.el)

prescientは補完候補の並び替えやフィルター機能を提供します。フィルター機能はorderlessの方が優れているので、並び替えのみを使用します。

```el
(use-package prescient
  :config
  (setq prescient-aggressive-file-save t)
  (prescient-persist-mode +1))
```


### vertico-prescient

prescientをverticoに適用します。

```el
(use-package vertico-prescient
  :config
  (setq vertico-prescient-enable-filtering nil)
  (vertico-prescient-mode +1))
```


### corfu-prescient

prescientをcorfuに適用します。

```el
(use-package corfu-prescient
  :config
  (setq corfu-prescient-enable-filtering nil)
  (corfu-prescient-mode +1))
```


### [flx](https://github.com/lewang/flx)

flxは補完候補にスコアリングを適用するパッケージです。prescientのtiebreakerに利用しています。

```el
(use-package flx
  :config
  (with-eval-after-load 'prescient
    ;; 入力文字を抽出
    (defvar-local my/input-query nil)
    (defun my/store-input-query (string &rest _args)
      "Store the current completion query in `my/input-query'."
      (setq my/input-query (replace-regexp-in-string " " "" string)))
    (advice-add 'completion-all-completions :before #'my/store-input-query)

    ;; ローカル変数を使用できるように再定義
    (defvar vertico--total nil)
    (defvar corfu--total nil)

    ;; スコアのキャッシュ
    (defvar my/flx-cache (make-hash-table :test 'equal :size 1000))

    (defun my/get-flx-score (str query)
      (or (gethash (cons str query) my/flx-cache)
          (let ((score (condition-case nil
                           (car (flx-score str query flx-file-cache))
                         (error nil))))
            (puthash (cons str query) score my/flx-cache)
            score)))

    (defun my/flx-tiebreaker (c1 c2)
      (let ((total (or vertico--total corfu--total 0))
            (query-length (length my/input-query)))
        (if (and (< total 3000)
                 (> query-length 2)
                 (< (length c1) 100)
                 (< (length c2) 100))
            (let ((score1 (my/get-flx-score c1 my/input-query))
                  (score2 (my/get-flx-score c2 my/input-query)))
              (cond ((and (integerp score1) (integerp score2))
                     (cond ((> score1 score2) -1)
                           ((< score1 score2) 1)
                           (t (- (length c1) (length c2)))))
                    (t 0)))
          (- (length c1) (length c2)))))

    (setq prescient-tiebreaker #'my/flx-tiebreaker)

    (defun my/clear-flx-cache ()
      (clrhash my/flx-cache))

    ;; キャッシュを1時間ごとにクリア
    (defvar my/flx-cache-timer nil)
    (setq my/flx-cache-timer
          (run-with-timer 3600 3600 #'my/clear-flx-cache))))
```


## [consult](https://github.com/minad/consult)

`vertico` や `selectrum` で利用できる便利なコマンドを提供してくれます。

```el
;; Example configuration for Consult
(use-package consult
  ;; Replace bindings. Lazily loaded due by `use-package'.
  :bind (;; C-c bindings (mode-specific-map)
         ("C-c h" . consult-history)
         ("C-c m" . consult-mode-command)
         ("C-c k" . consult-kmacro)
         ;; C-x bindings (ctl-x-map)
         ("C-x M-:" . consult-complex-command)     ;; orig. repeat-complex-command
         ([remap switch-to-buffer] . consult-buffer)                ;; orig. switch-to-buffer
         ([remap switch-to-buffer-other-window] . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window
         ([remap switch-to-buffer-other-frame] . consult-buffer-other-frame)  ;; orig. switch-to-buffer-other-frame
         ([remap bookmark-jump] . consult-bookmark)            ;; orig. bookmark-jump
         ([remap project-switch-to-buffer] . consult-project-buffer)      ;; orig. project-switch-to-buffer
         ;; Custom M-# bindings for fast register access
         ("M-#" . consult-register-load)
         ("M-'" . consult-register-store)          ;; orig. abbrev-prefix-mark (unrelated)
         ("C-M-#" . consult-register)
         ;; Other custom bindings
         ("M-y" . consult-yank-pop)                ;; orig. yank-pop
         ("<help> a" . consult-apropos)            ;; orig. apropos-command
         :map goto-map
         ("e" . consult-compile-error)
         ("f" . consult-flymake)               ;; Alternative: consult-flycheck
         ("g" . consult-goto-line)             ;; orig. goto-line
         ("M-g" . consult-goto-line)           ;; orig. goto-line
         ("o" . consult-outline)               ;; Alternative: consult-org-heading
         ("m" . consult-mark)
         ("k" . consult-global-mark)
         ("i" . consult-imenu)
         ("I" . consult-imenu-multi)
         :map search-map
         ("d" . consult-fd)
         ("D" . consult-locate)
         ("g" . consult-grep)
         ("G" . consult-git-grep)
         ("r" . consult-ripgrep)
         ("l" . consult-line)
         ("L" . consult-line-multi)
         ("m" . consult-multi-occsur)
         ("k" . consult-keep-lines)
         ("u" . consult-focus-lines)
         ("e" . consult-isearch-history)
         :map isearch-mode-map
         ("M-e" . consult-isearch-history)         ;; orig. isearch-edit-string
         ("M-s e" . consult-isearch-hisstory)       ;; orig. isearch-edit-string
         ("M-s l" . consult-line)                  ;; needed by consult-line to detect isearch
         ("M-s L" . consult-line-multi)            ;; needed by consult-line to detect isearch
         ;; Minibuffer history
         :map minibuffer-local-map
         ("M-s" . consult-history)                 ;; orig. next-matching-history-element
         ("M-r" . consult-history)
         :map my-error-map
         ("e" . consult-flymake))                ;; orig. previous-matching-history-element

  ;; Enable automatic preview at point in the *Completions* buffer. This is
  ;; relevant when you use the default completion UI.
  :hook (completion-list-mode . consult-preview-at-point-mode)

  ;; The :init configuration is always executed (Not lazy)
  :init

  ;; Optionally configure the register formatting. This improves the register
  ;; preview for `consult-register', `consult-register-load',
  ;; `consult-register-store' and the Emacs built-ins.
  (setq register-preview-delay 0.5
        register-preview-function #'consult-register-format)

  ;; Optionally tweak the register preview window.
  ;; This adds thin lines, sorting and hides the mode line of the window.
  (advice-add #'register-preview :override #'consult-register-window)

  ;; Use Consult to select xref locations with preview
  (setq xref-show-xrefs-function #'consult-xref
        xref-show-definitions-function #'consult-xref)

  (with-eval-after-load 'meow
    (meow-leader-define-key
     '("b" . consult-buffer)))

  ;; Configure other variables and modes in the :config section,
  ;; after lazily loading the package.
  :config

  ;; Optionally configure preview. The default value
  ;; is 'any, such that any key triggers the preview.
  ;; (setq consult-preview-key 'any)
  ;; (setq consult-preview-key (kbd "M-."))
  ;; (setq consult-preview-key (list (kbd "<S-down>") (kbd "<S-up>")))
  ;; For some commands and buffer sources it is useful to configure the
  ;; :preview-key on a per-command basis using the `consult-customize' macro.
  (consult-customize
   consult-theme :preview-key '(:debounce 1.0 any)
   consult-ripgrep consult-git-grep consult-grep
   consult-bookmark consult-recent-file consult-xref
   consult--source-bookmark consult--source-file-register
   consult--source-recent-file consult--source-project-recent-file
   ;; :preview-key "M-."
   :preview-key '(:debounce 0.4 any))

  ;; Optionally configure the narrowing key.
  ;; Both < and C-+ work reasonably well.
  (setq consult-narrow-key "<") ;; (kbd "C-+")

  ;; Optionally make narrowing help available in the minibuffer.
  ;; You may want to use `embark-prefix-help-command' or which-key instead.
  (define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help)

  ;; By default `consult-project-function' uses `project-root' from project.el.
  ;; Optionally configure a different project root function.
  ;; There are multiple reasonable alternatives to chose from.
    ;;;; 1. project.el (the default)
  ;; (setq consult-project-function #'consult--default-project--function)
    ;;;; 2. projectile.el (projectile-project-root)
  ;; (autoload 'projectile-project-root "projectile")
  ;; (setq consult-project-function (lambda (_) (projectile-project-root)))
    ;;;; 3. vc.el (vc-root-dir)
  ;; (setq consult-project-function (lambda (_) (vc-root-dir)))
    ;;;; 4. locate-dominating-file
  ;; (setq consult-project-function (lambda (_) (locate-dominating-file "." ".git")))
  )
```


### その他

現在のディレクトリのみripgrepで検索するコマンドを定義しています。

```el
(defun consult-ripgrep-current-directory ()
  (interactive)
  (consult-ripgrep default-directory))

(define-key search-map (kbd "R") #'consult-ripgrep-current-directory)
```


## [marginalia](https://github.com/minad/marginalia)

`vertico` の候補に情報を追加してくれます。

```el
(use-package marginalia
  :init
  (marginalia-mode +1))
```


## [embark](https://github.com/oantolin/embark)

vertico の候補等に様々なアクションを提供してくれます。

```el
(use-package embark
  :bind (("C-." . embark-act)         ;; pick some comfortable binding
         ("C-;" . embark-dwim)        ;; good alternative: M-.
         ("C-h B" . embark-bindings)) ;; alternative for `describe-bindings'
  :init
  (setq prefix-help-command #'embark-prefix-help-command)

  :config
  ;; Hide the mode line of the Embark live/completions buffers
  (add-to-list 'display-buffer-alist
               '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
                 nil
                 (window-parameters (mode-line-format . none)))))
```


### embark-consult

`embark` と `consult` を連動させます。

```el
(use-package embark-consult
  :hook (embark-collect-mode . consult-preview-at-point-mode))
```


## [tempel](https://github.com/minad/tempel)

tempelはEmacs用のテンプレートパッケージです。有名なものに[yasnippet](https://github.com/joaotavora/yasnippet)がありますが、こちらの方がシンプルな実装になっています。

```el
(use-package tempel
  :demand t
  :bind (("M-+" . tempel-complete) ;; Alternative tempel-expand
         ("M-*" . tempel-insert)))
```


### [tempel-collection](https://github.com/Crandel/tempel-collection)

tempel用のテンプレートを集めているパッケージです。

```el
(use-package tempel-collection
  :after tempel)
```


## git


### [magit](https://magit.vc/)

Emacs上でGitを快適に操作できるようにしてくれます。

```el
(use-package magit
  :config
  (when IS-WINDOWS
    (setq magit-refresh-status-buffer nil)
    (setq auto-revert-buffer-list-filter
          'magit-auto-revert-repository-buffer-p)
    (remove-hook 'magit-refs-sections-hook 'magit-insert-tags)
    (remove-hook 'server-switch-hook 'magit-commit-diff)
    (remove-hook 'with-editor-filter-visit-hook 'magit-commit-diff)))
```


### [diff-hl](https://github.com/dgutov/diff-hl)

ウィンドウの左側にコミットされていない箇所を強調表示してくれます。

```el
(use-package diff-hl
  :hook ((magit-pre-refresh . diff-hl-magit-pre-refresh)
         (magit-post-refresh . diff-hl-magit-post-refresh)
         (dired-mode . diff-hl-dired-mode))
  :init
  (global-diff-hl-mode +1)
  (global-diff-hl-show-hunk-mouse-mode +1)
  (diff-hl-margin-mode +1))
```


### [difftastic.el](https://github.com/pkryger/difftastic.el)

Emacsで[difftastic](https://github.com/wilfred/difftastic)を使用できるようにします。通常のコマンドとしても使用でき、magitにも統合させています。

```el
(use-package difftastic
  :demand t
  :bind (:map magit-blame-read-only-mode-map
              ("D" . difftastic-magit-show)
              ("S" . difftastic-magit-show))
  :config
  (eval-after-load 'magit-diff
    '(transient-append-suffix 'magit-diff '(-1 -1)
       [("D" "Difftastic diff (dwim)" difftastic-magit-diff)
        ("S" "Difftastic show" difftastic-magit-show)])))
```


## [which-key](https://github.com/justbur/emacs-which-key)

キーバインドを可視化してくれます。

```el
(use-package which-key
  :config
  (which-key-mode +1))
```


## undo


### [undo-fu](https://github.com/emacsmirror/undo-fu)

Emacsのundoとredoを強化するパッケージです

```el
(use-package undo-fu
  :config
  (with-eval-after-load 'evil
    (setq evil-undo-system 'undo-fu)))
```


### [undo-fu-session](https://github.com/emacsmirror/undo-fu-session)

undo情報をEmacs終了後も保持してくれるようになります。

```el
(use-package undo-fu-session
  :config
  (undo-fu-session-global-mode +1))
```


### [vundo](https://github.com/casouri/vundo)

undo履歴を視覚的に分かりやすく表示してくれます。代表的なものにundo-treeがありますが、vundoはundo-treeよりもシンプルな実装になっています。

```el
(use-package vundo
  :config
  (with-eval-after-load 'meow
    (meow-leader-define-key
     '("u" . vundo))))
```


## [rg](https://github.com/dajva/rg.el)

`ripgrep` を利用してGrep検索してくれます。

```el
(use-package rg
  :defer t)
```


## [apheleia](https://github.com/radian-software/apheleia)

フォーマットを実行してくれるパッケージです。そのままではWindows環境でprettierが実行できなかったので、修正しています。

```el
(use-package apheleia
  :config
  (when IS-WINDOWS
    (add-to-list 'apheleia-formatters
                 '(prettier-css
                   . (npx "prettier" "--stdin-filepath" filepath "--parser=css"
                          (apheleia-formatters-js-indent "--use-tabs" "--tab-width"))))
    (add-to-list 'apheleia-formatters
                 '(prettier-html
                   . (npx "prettier" "--stdin-filepath" filepath "--parser=html"
                          (apheleia-formatters-js-indent "--use-tabs" "--tab-width"))))
    (add-to-list 'apheleia-formatters
                 '(prettier-json
                   . (npx "prettier" "--stdin-filepath" filepath "--parser=json"
                          (apheleia-formatters-js-indent "--use-tabs" "--tab-width"))))
    (add-to-list 'apheleia-formatters
                 '(prettier-typescript
                   . (npx "prettier" "--stdin-filepath" filepath "--parser=typescript"
                          (apheleia-formatters-js-indent "--use-tabs" "--tab-width")))))

  (apheleia-global-mode +1))
```


## theme


### [ef-themes](https://github.com/protesilaos/ef-themes)

```el
(use-package ef-themes
  :config
  (setq ef-themes-mixed-fonts t
        ef-themes-variable-pitch-ui t)
  (load-theme 'ef-melissa-light t))
```


### [modus-themes](https://github.com/protesilaos/modus-themes)

```el
(use-package modus-themes
  :config
  (setq modus-themes-italic-constructs t
        modus-themes-bold-constructs nil
        modus-themes-mixed-fonts t
        modus-themes-variable-pitch-ui t
        modus-themes-disable-other-themes t)

  (setq modus-themes-completions
        '((t . (underline))))

  (setq modus-themes-common-palette-overrides
        '((fg-completion-match-0 blue)
          (fg-completion-match-1 magenta-warmer)
          (fg-completion-match-2 cyan)
          (fg-completion-match-3 red)
          (bg-completion-match-0 bg-blue-nuanced)
          (bg-completion-match-1 bg-magenta-nuanced)
          (bg-completion-match-2 bg-cyan-nuanced)
          (bg-completion-match-3 bg-red-nuanced)))

  ;; (load-theme 'modus-operandi-tinted t)
  )
```


## [restart-emacs](https://github.com/iqbalansari/restart-emacs)

Emacsを再起動してくれます。

```el
(use-package restart-emacs
  :ensure nil
  :bind ( :map my-quit-map
          ("r" . restart-emacs)))
```


## [expreg](https://github.com/casouri/expreg)

選択範囲を拡張するパッケージです。有名なものに[expand-region](https://github.com/magnars/expand-region.el)がありますが、expregの方がシンプルな実装になっています。

```el
(use-package expreg
  :config
  (with-eval-after-load 'meow
    (meow-leader-define-key
     '("v" . expreg-expand))))
```


## [puni](https://github.com/AmaiKinono/puni)

括弧等の構造を操作するパッケージです。[こちら](https://qiita.com/akirak/items/11dafdf89e32d34f3fc9#puni)の記事でも紹介されています。他に有名なパッケージとして[smartparens](https://github.com/Fuco1/smartparens)があります。

```el
(use-package puni
  :config
  (puni-global-mode +1))
```


## [alert](https://github.com/jwiegley/alert)

通知機能を利用できるようにします。主に `org-pomodoro` で使用します。

```el
(use-package alert
  :init
  (setq alert-default-style 'libnotify))
```


### [alert-toast](https://github.com/gkowzan/alert-toast)

Windows用の設定です。

```el
(use-package alert-toast
  :if IS-WINDOWS
  :init
  (setq alert-default-style 'toast))
```


## treesit

`tree-sitter` をEmacsで利用できるようにします。


### [treesit-auto](https://github.com/renzmann/treesit-auto)

treesiterの自動インストールやセットアップをしてくれます。

```el
(use-package treesit-auto
  :config
  (setq treesit-auto-install 'prompt)
  (treesit-auto-add-to-auto-mode-alist 'all)
  (global-treesit-auto-mode +1))
```


## [string-inflection](https://github.com/akicho8/string-inflection)

こちらのパッケージはカーソル直下の単語をunderscore -> UPCASE -> CamelCase に変換してくれます。

```el
(use-package string-inflection
  :bind ( :map my-string-inflection-map
          ("a" . string-inflection-all-cycle)
          ("_" . string-inflection-underscore)
          ("p" . string-inflection-pascal-case)
          ("c" . string-inflection-camelcase)
          ("u" . string-inflection-upcase)
          ("k" . string-inflection-kebab-case)
          ("C" . string-inflection-capital-underscore))
  :init
  (defvar my-string-inflection-map (make-keymap))
  (with-eval-after-load 'meow
    (meow-leader-define-key
     `("i" . ("inflection" . ,my-string-inflection-map)))))
```


## [go-translate](https://github.com/lorniu/go-translate)

Emacs内で翻訳してくれるようになります。

```el
(use-package go-translate
  :init
  (setq gts-translate-list '(("en" "ja")))
  :config
  (with-eval-after-load 'meow
    (meow-leader-define-key
     '("T" . gts-do-translate))))
```


## [avy](https://github.com/abo-abo/avy)

画面上の文字にジャンプできるようになります。別ウィンドウにもジャンプできるので重宝しています。

```el
(use-package avy
  :config
  (with-eval-after-load 'meow
    (meow-leader-define-key
     '("a" . avy-goto-char))))
```


## [ace-window](https://github.com/abo-abo/ace-window)

[Emacsモダン化計画 -かわEmacs編-](https://qiita.com/Ladicle/items/feb5f9dce9adf89652cf#tmux%E3%81%A3%E3%81%BD%E3%81%8F%E3%82%A6%E3%82%A3%E3%83%B3%E3%83%89%E3%82%A6%E3%82%92%E7%A7%BB%E5%8B%95%E3%81%99%E3%82%8B----ace-window)を参考に設定しています。ウィンドウの移動が楽になります。

```el
(use-package ace-window
  :config
  (with-eval-after-load 'meow
    (meow-leader-define-key
     '("w" . ace-window)))
  (custom-set-faces
   '(aw-leading-char-face ((t (:foreground "red" :height 4.0))))))
```


## [migemo](https://github.com/emacs-jp/migemo)

ローマ字で日本語を検索できるようにしてくれます。WindowsではScoopを使用してcmigemoをダウンロードしています。

```el
(use-package migemo
  :init
  ;; cmigemo(default)
  (setq migemo-command "cmigemo")
  (setq migemo-options '("-q" "--emacs"))

  ;; Set your installed path
  (when IS-WINDOWS
    (setq migemo-dictionary
          "C:/Users/u396/scoop/apps/cmigemo/current/cmigemo-mingw64/share/migemo/utf-8/migemo-dict"))

  (setq migemo-user-dictionary nil)
  (setq migemo-regex-dictionary nil)
  (setq migemo-coding-system 'utf-8-unix)

  :config
  (migemo-init))
```


## [lin](https://protesilaos.com/emacs/lin)

`hl-line-mode` を強化するパッケージです。

```el
(use-package lin
  :init
  (setq lin-face 'lin-red)
  (lin-global-mode +1))
```


## [pulsar](https://protesilaos.com/emacs/pulsar)

カーソルの移動を視覚的に分かりやすくしてくれます。[beacon](https://github.com/Malabarba/beacon)よりもシンプルな実装になっています。

```el
(use-package pulsar
  :config
  (pulsar-global-mode +1))
```


## [goggles](https://github.com/minad/goggles)

```el
(use-package goggles
  :hook ((prog-mode text-mode) . goggles-mode)
  :config
  (setq-default goggles-pulse t)) ;; set to nil to disable pulsing
```


## [spacious-padding](https://protesilaos.com/emacs/spacious-padding)

画面の余白を付けてくれます。カスタマイズ変数を調整することでモードラインも良い感じにしてくれます。

```el
(use-package spacious-padding
  :config
  (setq spacious-padding-widths
        '( :internal-border-width 15
           :header-line-width 4
           :mode-line-width 6
           :tab-width 4
           :right-divider-width 30
           :scroll-bar-width 8))

  ;; Read the doc string of `spacious-padding-subtle-mode-line' as it
  ;; is very flexible and provides several examples.
  (setq spacious-padding-subtle-mode-line
        `( :mode-line-active 'default
           :mode-line-inactive vertical-border))

  (spacious-padding-mode +1))
```


## [beframe](https://protesilaos.com/emacs/beframe)

あまり使い方を理解していませんが、consult-bufferに適用しています。

```el
(use-package beframe
  :config
  (defvar consult-buffer-sources)
  (declare-function consult--buffer-state "consult")

  (with-eval-after-load 'consult
    (defface beframe-buffer
      '((t :inherit font-lock-string-face))
      "Face for `consult' framed buffers.")

    (defvar beframe-consult-source
      `( :name     "Frame-specific buffers (current frame)"
         :narrow   ?F
         :category buffer
         :face     beframe-buffer
         :history  beframe-history
         :items    ,#'beframe-buffer-names
         :action   ,#'switch-to-buffer
         :state    ,#'consult--buffer-state))

    (add-to-list 'consult-buffer-sources 'beframe-consult-source))

  (beframe-mode +1))
```


## [aggressive-indent](https://github.com/Malabarba/aggressive-indent-mode)

インデントを自動的に整えてくれるパッケージです。elispを書いているときに重宝します。

```el
(use-package aggressive-indent
  :hook (emacs-lisp-mode . aggressive-indent-mode))
```


## [perfect-mergin](https://github.com/mpwang/perfect-margin)

バッファが1つの時に中央寄せしてくれます。同様のパッケージに[sublimity](https://github.com/zk-phi/sublimity)があります。

```el
(use-package perfect-margin
  :config
  (setq perfect-margin-ignore-filters nil)
  (perfect-margin-mode +1))
```


## [dashboard](https://github.com/emacs-dashboard/emacs-dashboard)

起動画面を良い感じにしてくれます。

```el
(use-package dashboard
  :config
  (setq dashboard-center-content t)
  (dashboard-setup-startup-hook))
```


## [page-break-lines](https://github.com/purcell/page-break-lines)

^Lの改ページ文字の表示を良くします。

```el
(use-package page-break-lines
  :config
  (page-break-lines-mode +1))
```


## [breadcrumb](https://github.com/joaotavora/breadcrumb)

バッファ上部にパンくずリストを表示してくれます。

```el
(use-package breadcrumb
  :vc ( :fetcher github :repo "joaotavora/breadcrumb")
  :config
  (breadcrumb-mode +1))
```


## [rainbow-delimiters](https://github.com/Fanael/rainbow-delimiters)

括弧の深さに応じて色付けをしてくれます。

```el
(use-package rainbow-delimiters
  :hook (prog-mode . rainbow-delimiters-mode))
```


## [imenu-list](https://github.com/bmag/imenu-list)

imenuを一覧表示してくれます。

```el
(use-package imenu-list
  :bind ( :map my-toggle-map
          ("i" . imenu-list-smart-toggle))
  :init
  (setq imenu-list-position 'left))
```


## eglot

emacsに標準で組み込まれているlspクライアントです。lsp-modeよりもEmacsの標準機能と良く統合されています。lsp-modeにはlanguage serverのインストール機能が備わっていますので、lsp-modeでインストールしたlanguage serverを利用できるようにパスを通しています。

```el
(use-package eglot
  :bind ( :map eglot-mode-map
          ("C-c r" . eglot-rename)
          ("C-c o" . eglot-code-action-organize-imports)
          ("C-c a" . eglot-code-actions)
          ("C-c h" . eldoc)
          ("<f6>" . xref-find-definitions))
  :init
  (setq eglot-events-buffer-config '(:size 0  :format short)
        eglot-ignored-server-capabilities '(:documentHighlightProvider)
        eglot-stay-out-of '(flymake)
        eglot-send-changes-idle-time 1.0)

  (defun my/add-directory-to-exec-path-recursively (dir)
    "Recursively add directories and their subdirectories to `exec-path`."
    (add-to-list 'exec-path dir)
    (dolist (entry (directory-files dir t "^[^.]" t))
      (when (file-directory-p entry)
        (my/add-directory-to-exec-path-recursively entry))))

  (defun my/load-lsp-exec-path ()
    (interactive)
    (my/add-directory-to-exec-path-recursively "~/.emacs.d/.cache/"))

  (my/load-lsp-exec-path))
```


### [eglot-tempel](https://github.com/fejfighter/eglot-tempel)

スニペットパッケージのtempelとeglotと統合するパッケージです。

```el
(use-package eglot-tempel
  :after (eglot tempel)
  :hook (eglot-managed-mode . eglot-tempel-mode))
```


### [consult-eglot](https://github.com/mohkale/consult-eglot)

consultとeglotを統合するパッケージです。シンボルの検索が行えるようになります。

```el
(use-package consult-eglot
  :after eglot
  :bind ( :map eglot-mode-map
          ("C-c s" . consult-eglot-symbols)))
```


### jsonrpc

jsonrpcはjsonを扱うEmacsの標準パッケージです。デフォルトのタイムアウト時間が短いため、タイムアウトしないように時間を延ばしています。また、ログを無視するように設定することでパフォーマンスを向上させています。

```el
(use-package jsonrpc
  :config
  (setq jsonrpc-default-request-timeout 3000)
  (fset #'jsonrpc--log-event #'ignore))
```


### [eglot-booster](https://github.com/jdtsmith/eglot-booster)

lsp-boosterはlspのパフォーマンスを向上させるパッケージです。Windowsでは上手く動作が確認できませんでした&#x2026;

```el
(use-package eglot-booster
  :after eglot
  :vc ( :fetcher github :repo "jdtsmith/eglot-booster")
  :config
  (eglot-booster-mode +1))
```


### [eglot-x](https://github.com/nemethf/eglot-x)

eglotは標準的な機能しかサポートしていませんが、こちらのパッケージを導入することでサポートされる機能が増えます。

```el
(use-package eglot-x
  :vc ( :fetcher github :repo "nemethf/eglot-x")
  :after eglot
  :config
  (eglot-x-setup))
```


### [eldoc-box](https://github.com/casouri/eldoc-box)

ミニバッファのeldocをposframeで表示してくれます。

```el
(use-package eldoc-box
  :hook (eglot-managed-mode . eldoc-box-hover-mode))
```


### [eglot-signature-eldoc-talkative](https://codeberg.org/mekeor/emacs-eglot-signature-eldoc-talkative)

eldocの情報を追加します。

```el
(use-package eglot-signature-eldoc-talkative
  :after eldoc-box
  :config
  (advice-add #'eglot-signature-eldoc-function
              :override #'eglot-signature-eldoc-talkative))
```


## [lsp-mode](https://github.com/emacs-lsp/lsp-mode)

lsp-modeはeglotよりも多機能で開発が活発です。全ての機能を有効にすると、パフォーマンスが悪くなる可能性があるので、必要のない機能は無効にします。

```el
(use-package lsp-mode
  ;; :hook (((typescript-ts-mode
  ;;          tsx-ts-mode
  ;;          html-ts-mode
  ;;          css-ts-mode
  ;;          json-ts-mode) . lsp))
  :init
  (setq read-process-output-max (* 1024 1024)) ;; 1mb
  (setq lsp-keymap-prefix "M-l")
  (setq lsp-headerline-breadcrumb-enable nil
        lsp-enable-file-watchers nil
        lsp-enable-folding nil
        lsp-enable-symbol-highlighting nil
        lsp-enable-text-document-color nil
        lsp-enable-indentation nil
        lsp-enable-on-type-formatting nil
        lsp-auto-execute-action nil
        lsp-before-save-edits nil))
```


### [lsp-java](https://github.com/emacs-lsp/lsp-java)

JavaのLSは特殊なため、専用の拡張パッケージをインストールします。

最新のバージョンは[ここ](https:download.eclipse.org/jdtls/milestones/?d)を参照します。※1.13以降はJava17が必要

```el
(use-package lsp-java
  :after (lsp-mode java-mode))
```


### [lsp-pyright](https://github.com/emacs-lsp/lsp-pyright)

`pyright` を利用したい場合、こちらのパッケージをインストールします。

```el
(use-package lsp-pyright
  :after (lsp-mode python-mode))
```


### [symbol-overlay](https://github.com/wolray/symbol-overlay)

emacsの組み込み関数を利用してシンボルをハイライトしてくれます。

```el
(use-package symbol-overlay
  :hook (prog-mode . symbol-overlay-mode))
```


### [lsp-snippet](https://github.com/svaante/lsp-snippet)

tempelとlsp-modeを統合するパッケージです。

```el
(use-package lsp-snippet
  :vc ( :fetcher github :repo "svaante/lsp-snippet")
  :config
  (when (featurep 'lsp)
    (lsp-snippet-tempel-lsp-mode-init)))
```


### [emacs-lsp-booster](https://github.com/blahgeek/emacs-lsp-booster)

lsp-boosterはlspのパフォーマンスを向上させるパッケージです。Windowsでは上手く動作が確認できませんでした&#x2026;

```el
(progn
  (defun lsp-booster--advice-json-parse (old-fn &rest args)
    "Try to parse bytecode instead of json."
    (or
     (when (equal (following-char) ?#)
       (let ((bytecode (read (current-buffer))))
         (when (byte-code-function-p bytecode)
           (funcall bytecode))))
     (apply old-fn args)))
  (advice-add (if (progn (require 'json)
                         (fboundp 'json-parse-buffer))
                  'json-parse-buffer
                'json-read)
              :around
              #'lsp-booster--advice-json-parse)

  (defun lsp-booster--advice-final-command (old-fn cmd &optional test?)
    "Prepend emacs-lsp-booster command to lsp CMD."
    (let ((orig-result (funcall old-fn cmd test?)))
      (if (and (not test?)                             ;; for check lsp-server-present?
               (not (file-remote-p default-directory)) ;; see lsp-resolve-final-command, it would add extra shell wrapper
               lsp-use-plists
               (not (functionp 'json-rpc-connection))  ;; native json-rpc
               (executable-find "emacs-lsp-booster"))
          (progn
            (message "Using emacs-lsp-booster for %s!" orig-result)
            (cons "emacs-lsp-booster" orig-result))
        orig-result)))
  (advice-add 'lsp-resolve-final-command :around #'lsp-booster--advice-final-command))
```


## language

各言語のインデントの設定や専用のパッケージを設定しています。


### elisp

1.  [highlight-defined](https://github.com/Fanael/highlight-defined)

    既知のシンボルに色を付けてくれます。
    
    ```el
    (use-package highlight-defined
      :hook (emacs-lisp-mode . highlight-defined-mode))
    ```

2.  [highlight-quoted](https://github.com/Fanael/highlight-quoted)

    引用符と引用記号を色付けしてくれます。
    
    ```el
    (use-package highlight-quoted
      :hook (emacs-lisp-mode . highlight-quoted-mode))
    ```


### web

1.  typescript-mode

    ```el
    (use-package typescript-mode)
    ```

2.  [jtsx](https://github.com/llemaitre19/jtsx)

    tsxやjsxファイルの編集を強化してくれます。
    
    ```el
    (use-package jtsx
      :ensure t
      :mode (("\\.jsx?\\'" . jtsx-jsx-mode)
             ("\\.tsx\\'" . jtsx-tsx-mode)
             ("\\.ts\\'" . jtsx-typescript-mode))
      :commands jtsx-install-treesit-language
      :hook ((jtsx-jsx-mode . hs-minor-mode)
             (jtsx-tsx-mode . hs-minor-mode)
             (jtsx-typescript-mode . hs-minor-mode))
      :custom
      ;; Optional customizations
      ;; (js-indent-level 2)
      ;; (typescript-ts-mode-indent-offset 2)
      ;; (jtsx-switch-indent-offset 0)
      (jtsx-indent-statement-block-regarding-standalone-parent nil)
      (jtsx-jsx-element-move-allow-step-out t)
      (jtsx-enable-jsx-electric-closing-element t)
      (jtsx-enable-electric-open-newline-between-jsx-element-tags t)
      (jtsx-enable-jsx-element-tags-auto-sync t)
      (jtsx-enable-all-syntax-highlighting-features t)
      :config
      (defun jtsx-bind-keys-to-mode-map (mode-map)
        "Bind keys to MODE-MAP."
        (define-key mode-map (kbd "C-c C-j") 'jtsx-jump-jsx-element-tag-dwim)
        (define-key mode-map (kbd "C-c j o") 'jtsx-jump-jsx-opening-tag)
        (define-key mode-map (kbd "C-c j c") 'jtsx-jump-jsx-closing-tag)
        (define-key mode-map (kbd "C-c j r") 'jtsx-rename-jsx-element)
        (define-key mode-map (kbd "C-c <down>") 'jtsx-move-jsx-element-tag-forward)
        (define-key mode-map (kbd "C-c <up>") 'jtsx-move-jsx-element-tag-backward)
        (define-key mode-map (kbd "C-c C-<down>") 'jtsx-move-jsx-element-forward)
        (define-key mode-map (kbd "C-c C-<up>") 'jtsx-move-jsx-element-backward)
        (define-key mode-map (kbd "C-c C-S-<down>") 'jtsx-move-jsx-element-step-in-forward)
        (define-key mode-map (kbd "C-c C-S-<up>") 'jtsx-move-jsx-element-step-in-backward)
        (define-key mode-map (kbd "C-c j w") 'jtsx-wrap-in-jsx-element)
        (define-key mode-map (kbd "C-c j u") 'jtsx-unwrap-jsx)
        (define-key mode-map (kbd "C-c j d") 'jtsx-delete-jsx-node))
    
      (defun jtsx-bind-keys-to-jtsx-jsx-mode-map ()
        (jtsx-bind-keys-to-mode-map jtsx-jsx-mode-map))
    
      (defun jtsx-bind-keys-to-jtsx-tsx-mode-map ()
        (jtsx-bind-keys-to-mode-map jtsx-tsx-mode-map))
    
      (add-hook 'jtsx-jsx-mode-hook 'jtsx-bind-keys-to-jtsx-jsx-mode-map)
      (add-hook 'jtsx-tsx-mode-hook 'jtsx-bind-keys-to-jtsx-tsx-mode-map))
    ```

3.  [emmet-mode](https://github.com/smihica/emmet-mode)

    `Emmet` を導入します。
    
    ```el
    (use-package emmet-mode
      :hook ((html-mode
              css-mode
              js-mode
              typescript-mode) . emmet-mode))
    ```

4.  [web-beautify](https://github.com/yasuyk/web-beautify)

    `web-beautify` を導入します。
    
    ```el
    (use-package web-beautify
      :defer t)
    ```


### [rust-mode](https://github.com/rust-lang/rust-mode)

```el
(use-package rust-mode
  :hook (rust-mode . (lambda ()
                       (setq-local tab-width 4))))
```

1.  [cargo](https://github.com/kwrooijen/cargo.el)

    ```el
    (use-package cargo
      :hook (rust-mode . cargo-minor-mode))
    ```


### python

1.  [pyvenv](https://github.com/jorgenschaefer/pyvenv)

    ```el
    (use-package pyvenv
      :defer t)
    ```


### common lisp

1.  [slime](https://slime.common-lisp.dev/)

    ```el
    (use-package slime
      :defer t
      :init
      (setq inferior-lisp-program "sbcl"))
    ```

2.  [slime-company](https://github.com/anwyn/slime-company)

    ```el
    (use-package slime-company
      :after (slime company)
      :config
      (setq slime-company-completion 'fuzzy
            slime-company-after-completion 'slime-company-just-one-space))
    ```


### sql

1.  [sql-indent](https://github.com/alex-hhh/emacs-sql-indent)

    ```el
    (use-package sql-indent
      :hook (sql-mode . sqlind-minor-mode))
    ```

2.  sql-format

    ```el
    (use-package sqlformat
      :init
      (setq sqlformat-command "sqlfluff"))
    ```


## footer

```el
(provide 'init)
;;; init.el ends here
```