LoginSignup
14
15

More than 1 year has passed since last update.

備忘録(init.el)- Emacs

Last updated at Posted at 2020-12-07

はじめに

最近Emacsを使い始めた初心者です。
これまでVSCodeやVimを使用しておりましたが、SpacemacsをきっかけにEmacsを始めました。
少しずつ理解を深めていきたいと思い、備忘録を作成していきます。

early-init.el

画面が表示される前に読み込まれるファイルです。
Emacs27以降で利用できます。

ここではpackage.elに関する設定と画面のUIに関する設定をしています。

init.el
;;; package --- Summary
;;; Commentary:
;;; Code:

(setq package-enable-at-startup nil) ;; package.elを使用しない

(push '(fullscreen . maximized) default-frame-alist) ;; 画面を最大化
(push '(vertical-scroll-bars) default-frame-alist) ;; スクロールバー非表示
(push '(menu-bar-lines . 0) default-frame-alist) ;; メニューバー非表示
(push '(tool-bar-lines . 0) default-frame-alist) ;; ツールバー非表示

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

init.el

初回起動時に自動生成される.emacs.dディレクトリ内にinit.elを作成します。

パッケージ管理

パッケージの管理にstraightを使用します。

straightは基本的に下記のコマンドを利用しています。

  • straight-use-package - パッケージのインストール
  • straight-pull-all - 全てのパッケージを最新の状態に更新
  • straight-freeze-versions - ロックファイルを作成
  • straight-thaw-versions - ロックファイルのバージョンでインストール
init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #straight

(defvar bootstrap-version)
(let ((bootstrap-file
	   (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
	  (bootstrap-version 5))
  (unless (file-exists-p bootstrap-file)
	(with-current-buffer
		(url-retrieve-synchronously
		 "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
		 'silent 'inhibit-cookies)
	  (goto-char (point-max))
	  (eval-print-last-sexp)))
  (load bootstrap-file nil 'nomessage))

Emacs標準機能の設定

Emacs標準パッケージの設定を行います。

  • electric-pair-mode 以外にsmartparensという括弧補完パッケージがありますが、lsp-mode と相性が良くないため、electric-pair-mode を採用しました。
  • 行番号の表示には linum-mode がありますが、こちらの記事を参考に display-line-numbers に変更しました。
init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #emacs

(setq backup-directory-alist '(("." . "~/.emacs.d/backup")) ;; バックアップファイルの作成場所を指定
      completion-ignore-case t ;; 補完時に大文字小文字を区別しない
      read-process-output-max (* 1024 1024) ;; 外部プロセスから読み取るデータ量の指定(LSP Modeのチューニング)
      use-short-answers t ;; 入力確認を「y or n」にする。Emacs27以下は (defalias 'yes-or-no-p 'y-or-n-p)
      recentf-max-saved-items 200 ;; 保存するファイルの履歴数を変更
      )

(server-mode +1) ;; デーモン起動
(savehist-mode +1) ;; コマンド履歴を保存
(save-place-mode +1) ;; 最後のカーソル位置を記録
(recentf-mode +1) ;; ファイルの閲覧履歴を保存
(show-paren-mode +1) ;; 対応括弧を強調表示(Emacs28から標準でON)
(global-auto-revert-mode +1) ;; 他プロセスの変更を常に反映する
(global-hl-line-mode +1) ;; 現在行を強調
(global-display-line-numbers-mode +1) ;; 左側に行番号を表示する
(which-function-mode +1) ;; モードラインにカーソル上の関数名等を表示する
(electric-pair-mode +1) ;; 括弧を補完する
(pixel-scroll-mode +1) ;; マウスホイールのスクロール幅を一般的なものに変更
(menu-bar-mode -1) ;; メニューバーを無効
(tool-bar-mode -1) ;; ツールバーを無効
(scroll-bar-mode -1) ;; スクロールバーを無効

文字コードの設定

文字コードの設定をOSに合わせて行います。

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #character-code

(set-language-environment "Japanese")
(prefer-coding-system 'utf-8)

;; Windows向けに細かく設定
(when (eq system-type 'windows-nt)
  ;; shift-jis より cp932 を優先させる
  (set-coding-system-priority 'utf-8
                              'euc-jp
                              'iso-2022-jp
                              'cp932))

フォントの設定

【2022/07/09 追記】フォント設定用にfontaineを導入しました。

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #font

(straight-use-package 'fontaine)

(cond ((eq system-type 'gnu/linux)
       (setq fontaine-presets
             '((regular
                :default-family "VLゴシック"
                :default-height 90
                :fixed-pitch-family "VLゴシック"
                :variable-pitch-family "VLPゴシック"
                :italic-family "VLゴシック"
                :line-spacing 1)
               (large
                :default-family "VLゴシック"
                :default-height 150
                :variable-pitch-family "VLPゴシック"
                :line-spacing 1))))

      ((eq system-type 'windows-nt)
       (setq fontaine-presets
             '((regular
                :default-family "BIZ UDゴシック"
                :default-height 90
                :fixed-pitch-family "BIZ UDゴシック"
                :variable-pitch-family "BIZ UDPゴシック"
                :italic-family "BIZ UDゴシック"
                :line-spacing 1)
               (large
                :default-family "BIZ UDゴシック"
                :default-height 150
                :variable-pitch-family "BIZ UDPゴシック"
                :line-spacing 1)))setq fontaine-presets))

;; Recover last preset or fall back to desired style from
;; `fontaine-presets'.
(fontaine-set-preset (or (fontaine-restore-latest-preset) 'regular))

;; The other side of `fontaine-restore-latest-preset'.
(add-hook 'kill-emacs-hook #'fontaine-store-latest-preset)

末尾のスペースを可視化

Emacs: whitespace で余分な空白/タブに色づけを参考に設定しました。
タブを可視化するとhighlight-indent-guidesがうまく表示されないことがあったため、末尾スペースのみの可視化にしました。

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #whitespace

(setq whitespace-style '(face trailing))

(global-whitespace-mode +1)

IME

IMEに関するパッケージです。
Windowsではtr-ime、Ubuntuではmozcを使用します。

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #ime

(straight-use-package 'tr-ime)
(straight-use-package 'mozc)

(cond ((eq system-type 'windows-nt)
       (setq default-input-method "W32-IME")
       (tr-ime-standard-install)
       (w32-ime-initialize))

      ((eq system-type 'gnu/linux)
       (setq default-input-method "japanese-mozc")))

テーマの設定

A GNU Emacs Themes Galleryに様々なテーマが載っていて参考になります。
modus-themesこちらの記事で紹介されていますが、見やすくて気に入っています。

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #theme

(straight-use-package 'modus-themes)

(defun disable-all-themes ()
  "Disable all active themes."
  (dolist (theme custom-enabled-themes)
    (disable-theme theme)))

;; load-theme 実行時に他のテーマを無効にします
(defadvice load-theme (before disable-themes-first activate)
  (disable-all-themes))

(modus-themes-load-operandi)
;; (modus-themes-load-vivendi)

モードライン

Emacsモダン化計画 -かわEmacs編-で紹介されているdoom-modelinenyan-modeを導入しました。

【Emacs入門】③モードラインについて考える(Moody / Minions)で紹介されているmoodyminions等もあります。

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #modeline

(straight-use-package 'doom-modeline)
(straight-use-package 'nyan-mode)

(setq nyan-animate-nyancat t
      nyan-bar-length 24)

(doom-modeline-mode +1)
(nyan-mode +1)

git用のパッケージ

C-x gmagitが起動します。
[Emacs] magitチュートリアルがとても参考になります。
git-gutterは変更箇所を表示してくれるパッケージです。

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #git

(straight-use-package 'magit)
(straight-use-package 'git-gutter)

(global-git-gutter-mode +1)

ショートカットキーの可視化

which-keyを導入すると、登録しているキーバインドが表示されるようになります。

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #which-key

(straight-use-package 'which-key)

(which-key-mode +1)

Vimキーバインド

Emacsキーバインドでしばらく入力していたら指が痛くなってきたので、Vimキーバインドを導入しました。

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #my-keymap

;; Spacemacsのようにスペースキーを起点にコマンド実行を行うためのキーマップ
(defvar my-intercept-mode-map (make-sparse-keymap)
  "High precedence keymap.")

;; Spacemacsのようにスペースキーを起点にコマンド実行を行うためのモード
(define-minor-mode my-intercept-mode
  "Global minor mode for higher precedence evil keybindings."
  :global t)

(my-intercept-mode)

(defvar my-quit-map (make-sparse-keymap)
  "My quit keymap.")

(defvar my-file-map (make-sparse-keymap)
  "My file keymap.")

(defvar my-buffer-map (make-sparse-keymap)
  "My buffer keymap.")

(defvar my-error-map (make-sparse-keymap)
  "My error keymap.")

(defvar my-toggle-map (make-sparse-keymap)
  "My toggle keymap.")

(defvar my-org-map (make-sparse-keymap)
  "My error keymap.")

(define-key my-quit-map (kbd "q") 'save-buffers-kill-terminal)
(define-key my-file-map (kbd "f") 'find-file)
(define-key my-file-map (kbd "b") 'bookmark-jump)
(define-key my-buffer-map (kbd "b") 'switch-to-buffer)
(define-key my-buffer-map (kbd "p") 'project-switch-to-buffer)

(my-intercept-mode)


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #evil

(straight-use-package 'evil)
(straight-use-package 'evil-collection)
(straight-use-package 'evil-commentary)
(straight-use-package 'evil-surround)
(straight-use-package 'evil-matchit)
(straight-use-package 'evil-org)

(setq evil-want-keybinding nil
      evil-symbol-word-search t     ; `*` で検索する際、 `_` や `-` を含める
      evil-kill-on-visual-paste nil ; Visualモードで貼り付けた場合、コピー内容を上書きしない
      )

(define-key my-buffer-map (kbd "d") 'kill-this-buffer)

(with-eval-after-load 'evil
  (evil-collection-init)
  (evil-commentary-mode +1)
  (global-evil-surround-mode +1)
  (global-evil-matchit-mode +1)

  ;; 定義したキーマップをEvilで使用できるようにします
  (dolist (state '(normal visual insert))
    (evil-make-intercept-map
     ;; NOTE: This requires an evil version from 2018-03-20 or later
     (evil-get-auxiliary-keymap my-intercept-mode-map state t t)
     state))

  ;; 上で定義したモード・キーマップにキーを設定しています
  ;; <leader>キーは上手くいかなかったので、直接SPCを指定しています
  (evil-define-key '(normal visual) my-intercept-mode-map
    (kbd "SPC SPC") 'execute-extended-command
    (kbd "SPC s") `("search" . ,search-map)
    (kbd "SPC g") `("goto" . ,goto-map)
    (kbd "SPC q") `("quit" . ,my-quit-map)
    (kbd "SPC f") `("file" . ,my-file-map)
    (kbd "SPC b") `("buffer" . ,my-buffer-map)
    (kbd "SPC e") `("error" . ,my-error-map)
    (kbd "SPC t") `("toggle" . ,my-toggle-map)
    (kbd "SPC o") `("org" . ,my-org-map)
    (kbd "SPC 0") #'delete-window
    (kbd "SPC 1") #'delete-other-windows
    (kbd "SPC 2") #'split-window-below
    (kbd "SPC 3") #'split-window-right
    (kbd "SPC 4") #'switch-to-buffer-other-window
    (kbd "SPC 5") #'switch-to-buffer-other-frame
    (kbd "SPC w") #'evil-window-next
    (kbd "SPC W") #'other-window))

(with-eval-after-load 'evil-org
  (require 'evil-org-agenda)
  (evil-org-set-key-theme '(navigation insert textobjects additional calendar))
  (evil-org-agenda-set-keys))

(add-hook 'org-mode-hook 'evil-org-mode)

(evil-mode +1)

入力補完

入力補完はcompanyauto-completeが有名です。

またEmacs26以降で使用できるcompany-boxを導入して、UIも強化しました。

【2022/01/27 追記】company-tabnineを追加しました。
【2022/02/10 追記】corfuの設定はこちら
【2022/06/09 追記】auto-complete から company に移行したを参考にcompany-dwimcompany-anywhereを追加しました。

基本的にはTABでワチャワチャ補完しますが、確定を明示的にするときはC-jを押下して確定します。
RETはそのまま改行として使用します。

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #company

(straight-use-package 'company)
(straight-use-package 'company-box)
(straight-use-package 'company-tabnine)
(straight-use-package '(company-dwim :type git :host github :repo "zk-phi/company-dwim"))
(straight-use-package '(company-anywhere :type git :host github :repo "zk-phi/company-anywhere"))

(setq company-minimum-prefix-length 1
      company-dabbrev-other-buffers nil ; パフォーマンスの向上
      company-dabbrev-ignore-case nil   ; パフォーマンスの向上
      company-dabbrev-downcase nil      ; パフォーマンスの向上
      company-require-match 'never      ; 補完候補に存在しない単語でも入力できるようにする
      company-auto-complete nil         ; スペースの挙動を一般的なものにする
      )

;; Tab で補完候補を表示する
(global-set-key [remap indent-for-tab-command] #'company-indent-or-complete-common)
(global-set-key [remap c-indent-line-or-region] #'company-indent-or-complete-common)

;; company-box を起動させる
(add-hook 'company-mode-hook 'company-box-mode)

(with-eval-after-load 'company
  (require 'company-dwim)
  (require 'company-anywhere)

  ;; TabNine を補完候補に追加
  (add-to-list 'company-backends '(company-capf company-yasnippet company-tabnine :separate))
  ;; company-dwim 用のフロントエンドを追加
  (add-to-list 'company-frontends 'company-dwim-frontend t)
  ;; 余分なフロントエンドを削除
  (delq 'company-preview-if-just-one-frontend company-frontends)

  ;; キーバインドの設定
  (define-key company-active-map (kbd "RET") nil)
  (define-key company-active-map (kbd "<return>") nil)
  (define-key company-active-map (kbd "TAB") #'company-dwim)
  (define-key company-active-map (kbd "<tab>") #'company-dwim)
  (define-key company-active-map (kbd "S-TAB") #'company-dwim-select-previous)
  (define-key company-active-map (kbd "<backtab>") #'company-dwim-select-previous)
  (define-key company-active-map (kbd "C-j") #'company-complete-selection))

(global-company-mode +1)

補完インターフェース

補完に関する記事ではEmacsの次世代ミニバッファ補完UIがとても参考になります。

prescientがいい感じだったので、selectrumを選択しました。

company-prescientのソート機能は便利ですが、LSPのソートも消してしまうので、lsp-modeではソート機能を無効にしています。

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #selectrum

(straight-use-package 'selectrum)

(global-set-key (kbd "C-x C-z") #'selectrum-repeat)

(with-eval-after-load 'selectrum
  (with-eval-after-load 'evil
    (evil-define-key '(normal visual) my-intercept-mode-map
      (kbd "SPC z") 'selectrum-repeat)))

(selectrum-mode +1)


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #prescient

(straight-use-package 'prescient)
(straight-use-package 'selectrum-prescient)
(straight-use-package 'company-prescient)

(setq company-prescient-sort-length-enable nil)

(with-eval-after-load 'prescient
  (prescient-persist-mode +1))

(selectrum-prescient-mode +1)
(company-prescient-mode +1)

検索パッケージ

isearch より使いやすく設計されたctrlfを導入します。
検索スタイルを fuzzy に設定することで、スペース区切りで検索することができます。
swiper系と違い、同じ行内で複数の一致があった場合でも移動できます。

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #ctrlf

(straight-use-package 'ctrlf)

(setq ctrlf-default-search-style 'fuzzy)

(define-key search-map (kbd "s") #'ctrlf-forward-default)

(ctrlf-mode +1)

詳細情報の表示

marginaliaはミニバッファの補完に傍注(追加情報)をつけてくれます。

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #marginalia

(straight-use-package 'marginalia)

(marginalia-mode +1)

便利コマンド

consultembarkverticoselectrumで利用できる便利コマンド集です。
ここで設定しているコマンド以外にも数多くの便利コマンドがあります。

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #consutl

(straight-use-package 'consult)

(require 'consult)

;; C-c bindings (mode-specific-map)
(global-set-key (kbd "C-c h") #'consult-history)
(global-set-key (kbd "C-c m") #'consult-mode-command)
(global-set-key (kbd "C-c k") #'consult-kmacro)
;; C-x bindings (ctl-x-map)
(global-set-key (kbd "C-x M-:") #'consult-complex-command) ;; orig. repeat-complex-command
(global-set-key [remap switch-to-buffer] #'consult-buffer) ;; orig. switch-to-buffer
(global-set-key [remap switch-to-buffer-other-window] #'consult-buffer-other-window) ;; orig. switch-to-buffer-other-window
(global-set-key [remap switch-to-buffer-other-frame] #'consult-buffer-other-frame) ;; orig. switch-to-buffer-other-frame
(global-set-key [remap bookmark-jump] #'consult-bookmark) ;; orig. bookmark-jump
(global-set-key [remap project-switch-to-buffer] #'consult-project-buffer) ;; orig. project-switch-to-buffer
;; Custom M-# bindings for fast register access
(global-set-key (kbd "M-#") #'consult-register-load)
(global-set-key (kbd "M-'") #'consult-register-store) ;; orig. abbrev-prefix-mark (unrelated)
(global-set-key (kbd "C-M-#") #'consult-register)
;; Other custom bindings
(global-set-key (kbd "M-y") #'consult-yank-pop) ;; orig. yank-pop
(global-set-key (kbd "<help> a") #'consult-apropos) ;; orig. apropos-command
(define-key my-buffer-map (kbd "4") #'consult-buffer-other-window)
(define-key my-buffer-map (kbd "5") #'consult-buffer-other-frame)
;; M-g bindings (goto-map)
(define-key goto-map (kbd "e") #'consult-compile-error)
(define-key goto-map (kbd "g") #'consult-goto-line) ;; orig. goto-line
(define-key goto-map (kbd "o") #'consult-outline) ;; Alternative: consult-org-heading
(define-key goto-map (kbd "m") #'consult-mark)
(define-key goto-map (kbd "k") #'consult-global-mark)
(define-key goto-map (kbd "i") #'consult-imenu)
(define-key goto-map (kbd "I") #'consult-imenu-multi)
;; M-s bindings (search-map)
(define-key search-map (kbd "d") #'consult-find)
(define-key search-map (kbd "D") #'consult-locate)
(define-key search-map (kbd "g") #'consult-grep)
(define-key search-map (kbd "G") #'consult-git-grep)
(define-key search-map (kbd "r") #'consult-ripgrep)
(define-key search-map (kbd "l") #'consult-line)
(define-key search-map (kbd "L") #'consult-line-multi)
(define-key search-map (kbd "m") #'consult-multi-occur)
(define-key search-map (kbd "k") #'consult-keep-lines)
(define-key search-map (kbd "u") #'consult-focus-lines)
;; Minibuffer history
(define-key minibuffer-local-map (kbd "M-s") #'consult-history) ;; orig. next-matching-history-element
(define-key minibuffer-local-map (kbd "M-r") #'consult-history) ;; orig. previous-matching-history-element

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

;; 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)

;; Configure other variables and modes in the :config section,
;; after lazily loading the package.
(with-eval-after-load 'consult
  ;; 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 0.5 any)
   consult-ripgrep consult-git-grep consult-grep
   consult-bookmark consult-recent-file consult-xref
   consult--source-bookmark consult--source-recent-file
   consult--source-project-recent-file
   :preview-key (kbd "M-."))

  ;; 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")))
  )


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #emabrk

(straight-use-package 'embark)
(straight-use-package 'embark-consult)

(global-set-key (kbd "C-.") #'embark-act) ;; pick some comfortable binding
(global-set-key (kbd "C-;") #'embark-dwim) ;; good alternative: M-.
(global-set-key (kbd "C-h B") #'embark-bindings) ;; alternative for `describe-bindings'

(setq prefix-help-command #'embark-prefix-help-command)

(with-eval-after-load 'embark
  (add-to-list 'display-buffer-alist
               '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
                 nil
                 (window-parameters (mode-line-format . none))))

  (with-eval-after-load 'consult
    (add-hook 'embark-collect-mode-hook 'consult-preview-at-point-mode)))

補完スタイル

補完スタイルにカスタマイズ性の高いorderlessを導入しています。selectrumは前述のselectrum-prescientを利用しているので、違いはほとんどありません。
companyではorderless-flexで曖昧に絞り込み、company-prescientで並び替えるようにしています。

現在は (add-to-list 'completion-styles 'flex t)(basic partial-completion emacs22 flex) になっています。

fussyというパッケージがとても良かったので変更しました。
Emacsで新しいFuzzy補完 - fussy -

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #fussy

(straight-use-package '(fussy :type git :host github :repo "jojojames/fussy"))

(setq completion-styles '(fussy)
      completion-category-defaults nil
      compleiton-category-overrides nil)

カッコの補完

カッコの補完にはsmartparensを使用しています。

【追記】現在はEmacs標準の electric-pair-mode を使用しています。下記はSmartparensを利用する場合の備忘録として残しています。

そのままだとxxx {|}で改行すると

xxx {
|}

となってしまうので関数を追加して、

xxx {
  |
}

となるようにしています。

init.el
(straight-use-package 'smartparens)

(with-eval-after-load 'smartparens
  (require 'smartparens-config)

  (defun indent-between-pair (&rest _ignored)
	(newline)
	(indent-according-to-mode)
	(forward-line -1)
	(indent-according-to-mode))

  (sp-local-pair 'prog-mode "{" nil :post-handlers '((indent-between-pair "RET")))
  (sp-local-pair 'prog-mode "[" nil :post-handlers '((indent-between-pair "RET")))
  (sp-local-pair 'prog-mode "(" nil :post-handlers '((indent-between-pair "RET"))))

;; (smartparens-global-mode +1)

スニペット

スニペットにはyasnippetyasnippet-snippetsを使用します。

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #yasnippet

(straight-use-package 'yasnippet)
(straight-use-package 'yasnippet-snippets)

(with-eval-after-load 'yasnippet
  (require 'yasnippet-snippets)
  (define-key yas-minor-mode-map (kbd "TAB") nil)
  (define-key yas-minor-mode-map (kbd "<tab>") nil)
  (define-key yas-keymap (kbd "C-TAB") 'yas-next-field-or-maybe-expand)
  (define-key yas-keymap (kbd "C-<tab>") 'yas-next-field-or-maybe-expand))

(yas-global-mode +1)

変更履歴のツリー表示

UndoTreeは変更履歴をツリー表示してくれるパッケージです。
こちらの記事では使い方などを簡単にまとめてくれています。

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #undo-tree

(straight-use-package 'undo-tree)

(setq undo-tree-history-directory-alist '(("." . "~/.emacs.d/undo-history")))

(with-eval-after-load 'evil
  (evil-set-undo-system 'undo-tree)
  (evil-define-key 'normal my-intercept-mode-map
    (kbd "SPC u") 'undo-tree-visualize))

(global-undo-tree-mode +1)

プロジェクトに関するパッケージ

あまり使いこなせていませんが、projectileプロジェクトレベルで動作する様々なコマンドを提供するパッケージです。
外部コマンドに依存せず利用できます。

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #projectile

(straight-use-package 'projectile)

(with-eval-after-load 'projectile
  (define-key projectile-mode-map (kbd "C-c p") #'projectile-command-map))

(with-eval-after-load 'evil
  (evil-define-key 'normal my-intercept-mode-map
    (kbd "SPC p") `("projectile" . projectile-command-map)))

(projectile-mode +1)

構文チェック

flycheckはプログラムのエラーや警告をわかりやすく表示してくれるパッケージです。
この他にEmacs標準で搭載されているflymakeなどもあります。

下記ではDoom emacsを参考にパフォーマンスが上がるように調整しています。

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #flycheck

(straight-use-package 'flycheck)
(straight-use-package 'consult-flycheck)
(straight-use-package 'flycheck-posframe)

(define-key my-error-map (kbd "l") #'flycheck-list-errors)
(define-key my-error-map (kbd "n") #'flycheck-next-error)
(define-key my-error-map (kbd "p") #'flycheck-previous-error)
(define-key my-error-map (kbd "e") #'consult-flycheck)

(with-eval-after-load 'flycheck
  ;; Rerunning checks on every newline is a mote excessive.
  (delq 'new-line flycheck-check-syntax-automatically)
  ;; And don't recheck on idle as often
  (setq flycheck-idle-change-delay 1.0)
  ;; For the above functionality, check syntax in a buffer that you switched to
  ;; only briefly. This allows "refreshing" the syntax check state for several
  ;; buffers quickly after e.g. changing a config file.
  (setq flycheck-buffer-switch-check-intermediate-buffers t)
  ;; Display errors a little quicker (default is 0.9s)
  (setq flycheck-display-errors-delay 0.25)

  (require 'flycheck-posframe)
  (add-hook 'flycheck-mode-hook #'flycheck-posframe-mode)

  (with-eval-after-load 'company
    (add-hook 'flycheck-posframe-inhibit-functions #'company--active-p)))

(global-flycheck-mode +1)

カッコをわかりやすく色付け

rainbow-delimitersは括弧の階層によって色をつけてくれるパッケージです。

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #rainbow-delimiters

(straight-use-package 'rainbow-delimiters)

(define-key my-toggle-map (kbd "r") #'rainbow-delimiters-mode)

(add-hook 'prog-mode-hook 'rainbow-delimiters-mode)

インデントの色付け

highlight-indent-guidesはインデントに色や線を引いてくれるパッケージです。
他にもパッケージが存在しますが、見た目が綺麗で動作も軽量なこのパッケージを選択しました。

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #highlight-indent-guides

(straight-use-package 'highlight-indent-guides)

(setq highlight-indent-guides-method 'character
      highlight-indent-guides-character 124
      highlight-indent-guides-responsive 'top)

(define-key my-toggle-map (kbd "h") 'highlight-indent-guides-mode)

(add-hook 'prog-mode-hook 'highlight-indent-guides-mode)

範囲選択パッケージ

expand-region.elはコマンド押下毎に選択範囲を拡張してくれるパッケージです。

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #expand-region

(straight-use-package 'expand-region)

(global-set-key (kbd "C-=") #'er/expand-region)

(with-eval-after-load 'evil
  (evil-define-key '(normal visual) my-intercept-mode-map
    (kbd "SPC v") 'er/expand-region))

カーソル位置をわかりやすくする

beaconはカーソル移動箇所をわかりやすくしてくれるパッケージです。
もっとシンプルなpulsarに変更しました。

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #pulsar

(straight-use-package 'pulsar)

(pulsar-global-mode +1)

ガベージコレクション

gcmhはEmacsがアクティブじゃない時や、しばらく操作されていない時にガベージコレクションを実行してくれるパッケージです。

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #gcmh

(straight-use-package 'gcmh)

(setq gcmh-verbose t
      gcmh-idle-delay 'auto
      gcmh-auto-idle-delay-factor 10
      gcmh-high-cons-threshold (* 128 1024 1024))

(gcmh-mode +1)

起動画面を変更

emacs-dashboardは起動画面にファイルの閲覧履歴、ブックマーク、アジェンダを表示して使いやすくしてくれます。
また、このパッケージを使用しなくてもこちらのようにカスタマイズできます。

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #dashboard

(straight-use-package 'dashboard)

(setq dashboard-center-content t
      dashboard-set-heading-icons t
      dashboard-set-file-icons t
      dashboard-set-navigator t
      dashboard-set-init-info t)

(dashboard-setup-startup-hook)

操作をわかりやすくする

ペーストやUndo、Redo等の操作をわかりやすく色付けしてくれます。

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #volatile-highlights

(straight-use-package 'volatile-highlights)

(volatile-highlights-mode +1)

Org

最近 org-mode を活用したいと思い、色々勉強中です。
org-pomodoroでEmacsでポモドーロを利用します。
alertを適切に設定すれば、ポップアップで通知してくれます。

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #org

(straight-use-package 'org-pomodoro)

(setq org-tag-alist '(("@Sample1" . nil)
                      ("@Test" . nil))
      org-directory "~/org/"
      org-default-notes-file (concat org-directory "/notes.org")
      org-capture-templates '(("t" "Todo" entry (file+headline "~/org/notes.org" "Tasks")
                               "* TODO %?\n  %i\n  %a")
                              ("j" "Journal" entry (file+datetree "~/org/journal.org")
                               "* %?\nEntered on %U\n  %i\n  %a"))
      org-agenda-files '("~/org/notes.org"
                         "~/org/journal.org"))

(global-set-key (kbd "C-c c") #'org-capture)
(global-set-key (kbd "C-c a") #'org-agenda)
(define-key my-org-map (kbd "c") #'org-capture)
(define-key my-org-map (kbd "a") #'org-agenda)
(define-key my-org-map (kbd "o") #'org-open-at-point)
(define-key my-org-map (kbd "l") #'org-link)
(define-key my-org-map (kbd "p") #'org-pomodoro)


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #alert

(straight-use-package 'alert)
(straight-use-package 'alert-toast)

(cond ((eq system-type 'gnu/linux)
       (setq alert-default-style 'libnotify))

      ((eq system-type 'windows-nt)
       (setq alert-default-style 'toast)))

valign

org-mode のテーブルを利用すると幅がずれてしまうことがあります。
このパッケージを導入すると幅を揃えてくれます。

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #valign

(straight-use-package 'valign)

(add-hook 'org-mode-hook 'valign-mode)
(add-hook 'markdown-mode-hook 'valign-mode)

ripgrepパッケージ

ripgrepを利用するパッケージは色々ありますが、私はrgを利用しています。

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #rg

(straight-use-package 'rg)

アイコンの表示

lsp-mode等で使用するアイコンなどをall-the-iconsM-x all-the-icons-install-fontsで取得します。

all-the-icons-direddired上でアイコンを表示するパッケージです。

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #all-the-icons

(straight-use-package 'all-the-icons)
(straight-use-package 'all-the-icons-dired)

(when (display-graphic-p)
  (require 'all-the-icons)
  (add-hook 'dired-mode-hook 'all-the-icons-dired-mode))

再起動用コマンド

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #restart-emacs

(straight-use-package 'restart-emacs)

(define-key my-quit-map (kbd "r") #'restart-emacs)

プログラミング

LSP

LSPに関する設定を行います。
lsp-modeeglotがありますが、lsp-modeを導入しました。

lsp-uiは画面のUI
consult-lspはLSP用のコマンド
dap-modeはデバッグ機能
lsp-javaはJava用の設定
lsp-pyrightはPython(pyright)用の設定
を提供します。

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #lsp-mode

(straight-use-package 'lsp-mode)
(straight-use-package 'lsp-ui)
(straight-use-package 'lsp-java)
(straight-use-package 'lsp-pyright)

(setq lsp-keymap-prefix "M-l"
      lsp-eldoc-enable-hover nil
      lsp-enable-folding nil
      lsp-headerline-breadcrumb-enable nil
      lsp-headerline-breadcrumb-enable-diagnostics nil
      lsp-java-vmargs '("-XX:+UseParallelGC" "-XX:GCTimeRatio=4" "-XX:AdaptiveSizePolicyWeight=90" "-Dsun.zip.disableMemoryMapping=true" "-Xmx2G" "-Xms100m"))

(add-hook 'lsp-mode-hook (lambda ()
                           (with-eval-after-load 'evil
                             (evil-local-set-key 'normal (kbd "SPC m") `("lsp" . ,lsp-command-map)))))

(add-hook 'web-mode-hook #'lsp)
(add-hook 'css-mode-hook #'lsp)
(add-hook 'rust-mode-hook #'lsp)
(add-hook 'java-mode-hook (lambda ()
                            (require 'lsp-java)
                            (lsp)))
(add-hook 'python-mode-hook (lambda ()
                              (require 'lsp-pyright)
                              (lsp)))

Java

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #java

(add-hook 'java-mode-hook (lambda ()
                            (setq-local tab-width 2
                                        c-basic-offset 2
                                        indent-tabs-mode t)))

Html/CSS

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #web

(straight-use-package 'web-mode)
(straight-use-package 'emmet-mode)
(straight-use-package 'web-beautify)

(add-to-list 'auto-mode-alist '("\\.html\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.jsp\\'" . web-mode))

(add-hook 'web-mode-hook (lambda ()
                           (setq-local tab-width 2)
                           (emmet-mode +1)))

(add-hook 'css-mode-hook (lambda ()
                           (setq-local tab-width 2)
                           (emmet-mode +1)))

Rust言語

lsp-mode起動後にlsp-install-serverコマンドを実行し、rust-analyzerを選択することで、自動的にLanguage Serverがダウンロードされます。

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #rust

(straight-use-package 'rust-mode)
(straight-use-package 'cargo)

(add-hook 'rust-mode-hook (lambda ()
                            (setq-local tab-width 4
                                        indent-tabs-mode nil)
                            (cargo-minor-mode +1)))

Python

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #python

(straight-use-package 'pyvenv)

Common Lisp

$ sudo apt sbcl
または
$ sudo apt clisp
init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #common-lisp

(straight-use-package 'slime)
(straight-use-package 'slime-company)

(setq inferior-lisp-program "sbcl")

(with-eval-after-load 'slime
  (slime-setup '(slime-fancy slime-company slime-banner)))

SQL

init.el

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; #sql

(straight-use-package 'sql-indent)
(straight-use-package 'sqlformat)

(add-hook 'sql-mode-hook 'sqlind-minor-mode)

参考

Emacsモダン化計画 -かわEmacs編-
2020年代のEmacs入門

14
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
15