GNU Emacs 27.2 for Windows で Emacs に入門したときの個人的な備忘録(3)

の続きです。
init.el が完成したら github に上げようと思いますが、いつになるやら……。

スクロール時、行を勝手にウインドウ中央に移動させる挙動をやめる

Emacs では、 C-n 押しっぱなしでスクロールをしているときなど、勝手にカーソル(ポイント)の行を画面中央に移動させる挙動をします。
これ、何気に鬱陶しいと感じる人は多いのではないでしょうか。それを止めさせるのが以下の設定です。

;; https://ayatakesi.github.io/emacs/27.2/html/Auto-Scrolling.html#Auto-Scrolling
(setq-default croll-conservatively 10000)

これにて当方の環境では、 Windows っぽくない挙動は一通り抑えることができたかなと思っております。

Windows + 絵文字 (emoji) 環境を整える

emojify をインストールしました。

(leaf emojify
  :tag "core" "font"
  :ensure t
  ;; GUI 版のみ利用
  :when window-system
  ;; グローバルで絵文字を利用する
  :hook (after-init-hook . global-emojify-mode)
  ;; 絵文字を挿入するコマンド。Vertico が効くので便利
  :bind
  ("C-x e" . emojify-insert-emoji)
  ;; ユニコード文字としての利用と、github (Slack 風でもある)のように :fuga: のように書くと絵文字に変換してくれる。 :) のように あscii で変換されるのは誤爆が多そうなので ascii は無効
  :custom
  (emojify-emoji-styles . '(unicode github))
  :config
  ;; MacOSX と Windows でフォントの指定や表示する絵文字のフォーマットを切り替え
  (cond
   ((eq system-type 'darwin)
    (progn
      (setq-default emojify-display-style 'unicode)
      (when (member "Apple Color Emoji" (font-family-list))
	(set-fontset-font t 'symbol (font-spec :family "Apple Color Emoji") nil 'prepend))))
   ((eq system-type 'windows-nt)
    (progn
      (setq-default emojify-display-style 'image)
      (when (member "Segoe UI Emoji" (font-family-list))
	(set-fontset-font t 'symbol (font-spec :family "Segoe UI Emoji") nil 'prepend)))))

Windows GUI 版 Emacs においては絵文字の利用には制限があります。ユニコードのカラー絵文字を利用できないということです。

Emacs on MS-Windowsでは、いくつかのフォントバックエンドがサポートされています。Windowsでは現在のところバックエンドとしてgdi、uniscribe、およびharfbuzzが利用可能です。

https://ayatakesi.github.io/emacs/27.2/html/Windows-Fonts.html#Windows-Fonts

和訳された方の御尽力に、深く感謝申し上げます。

Windows GDI はカラー絵文字をサポートしておらず、Emacs はその GDI を利用してフォントのレンダリングを行っていることからカラー絵文字を利用できません。そのため、通常のフォントと同じようにレダリングされる単色(モノクロ)の絵文字のみが利用可能です(と解釈しました)。
一方、MacOSX や Linux では Cairo による描画によりネイティブのような形でカラー絵文字の利用が可能とのことです。

ですが、 Windows でも何とかしてカラー絵文字を使いたいですよね。 org-mode でメモを取り始めたのですが、絵文字を使うと視認性が良く、やはり積極的に使いたいと思うようになりました。そして、カラーの方がさらに視認性も向上するというものです。
Windows でもカラー絵文字を使いたい……、そのために Emojify は「絵文字の箇所だけ、画像ファイルに差し替える」というトリックを提供してくれます。 emojify-display-style に image を指定している箇所がそうですね。この機能を理解したとき、なるほどと膝を叩きました。

png ファイルを拡大・縮小するため、見てくれは少々難があるように感じるときもありますし、プリセットの画像を他のフォントのものに差し替えるということもできません。ミニバッファでは画像は使用できないのか、 emojify-insert-emoji と Vertico で表示するときも絵文字は画像ではなく、フォントの絵文字(モノクロ)となってしまいますが、 org-mode での視認性向上という目的は達成されました。

なお、 Windows においてもネイティブでカラー絵文字を表示させるとなった場合、おそらくですが GDI から DirectWrite (Direct2D)にフォントレンダラを変更する必要があるかと思います。 Vim が過去実施したアプローチと同じですね。

ちなみに MacType などで無理やり DirectWrite にレンダラを差し替えると、カラー絵文字は表示できます。

MacType で無理やり DirectWrite だとネイティブでカラー絵文字も表示可能

MacType を常用する方は Windows でも (setq-default emojify-display-style 'unicode) としてしまってよいかもしれません。というか Emacs が ネイティブで DirectWrite をサポートしてくれるのが一番嬉しいのですが……、ニーズがないのでしょうか。ここは開発をされた方のご尽力もあり、 Vim が非常に羨しいところです。
(Windows もそろそろ、 OS として根本的に DirectWrite を利用するようにして欲しいですね)

Mac の場合 ddskk を使用するようにした

EMP 版 Emacs と AquaSKK を使っていますが、 Esc キーから x で M-x を呼び出そうと思ってもひらがなモードままで上手く動かなかったりとか、 C-h で文字を消そうとするとひらがなモードであっても問答無用に Ascii モードに切り替わってしまうなど挙動に難があり、上手い hack が見当らない・分からなかったことから、諦めて ddskk を利用することにしました。

(leaf skk
  :tag "core" "ime"
  :ensure ddskk
  :config
  ;; カスタマイズした AZIK の変換テーブルの定義を呼び出し
  (load "skk_conf")
  :bind
  ("C-x C-j" . skk-mode)
  :custom
  (skk-preload . t)
  (skk-byte-compile-init-file . t)
  ;; モードによってカーソルの色変えない
  (skk-indicator-use-cursor-color . nil)
  ;; ddskk の状態表示をするモードラインの装飾はできるだけしない
  (skk-indicator-prefix . "")
  ;; アノテーションは使わないので無効
  (skk-show-annotation . nil)
  ;; ▼モードで確定の時に改行をしない。デフォルト nil の理由はあまり分からず……
  (skk-egg-like-newline . t)
  ;; ▼モードで del したとき、候補を一つ戻す動作にする
  (skk-delete-implies-kakutei . nil)
  ;; https://github.com/skk-dev/ddskk/blob/83938788f2b1e442807745fc3b73fc9a48abe552/READMEs/NEWS.ja#L1047 が詳しい
  (skk-undo-kakutei-word-only . t)
  ;; 送り仮名の内容で変換内容が賢くなる
  (skk-henkan-strict-okuri-precedence . t)
  (default-input-method . "japanese-skk")
  (skk-show-inline . t)
  ;; Emacs ローカルの辞書ファイルを使わない
  (skk-inhibit-ja-dic-search . t)
  (skk-server-host . "localhost")
  ;; デフォルトだと skk 関連の設定やユーザ辞書は HOME 直下に置かれるので .emacs.d 以下に配置
  (skk-user-directory . "~/.emacs.d/ddskk/user")
  (skk-server-portnum . 1178))

辞書サーバは AquaSKK を利用しています。ユーザ辞書が共有できないのが難点ですが、使用感含め全く問題はなく、すこぶる快適です。もちろんキーバインドの問題も発生しません。

Face は別ファイルで theme として定義している el ファイルから、以下のように指定しています。

(let (
	;; color pallet
	(foreground #000000)
	(background "#ffffff")
	(black "#00000")
	(red "#ff0000")
	...
	
	(custom-theme-set-faces
	'my-theme
	;; ddskk
	(setq skk-inline-show-face nil)
	(setq skk-inline-show-background-color nil)
	`(skk-henkan-face-default ((t (:foreground, blue :background, background))))
	`(skk-jisyo-registration-badge-face  ((t (:foreground, blue :background, background))))
	`(skk-inline-show-background-color ((t (:foreground, brightBlue :background, background))))
	`(skk-inline-show-face ((t (:foreground, blue :background, background))))
	`(skk-treat-candidate-appearance-function ((t (:foreground, foreground :background, background))))
	`(skk-show-mode-inline-face ((t (:foreground, brightBlue :background, foreground))))
	`(skk-henkan-show-candidates-keys-face ((t (:foreground, brightBlue :weight bold))))
	`(skk-henkan-rest-indicator-face ((t (:foreground, brightRed :weight bold))))
	...

ちょっと無駄があるかもしれませんが、▽モードや▼モードをインラインで表示するときの Face を指定してます。カラフルに表示ができて、これはこれで AquaSKK の表示と趣が違って楽しいものです。
Windows の方では OS 標準の IME を使っているので、特に試してはいません。

なお、 AZIK を個人的にカスタマイズしたものを指定しております。 :config で load しているものがそれです。中身は skk-azik.el の変換テーブルをカスタマイズしたものを抜き出しただけです。

ユーザ辞書に関しては AquaSKK のものとマージをするスクリプトを cron で動かせばいいかな、と考えておりますが、本格的に困ったら実装することにします(きっとやらない)。

Projectile + Treemacs

ProjectileTreemacs を導入しました。導入だけしてまだ便利に使えていないというのが実状ですが、徐々に慣れていきたいと思います。

を拝読し参考にいたしました。

Projectile

Projectile は Project と呼ばれる特定のディレクトリ配下や、その配下のファイルを開いているバッファに対して だけ 検索など機能を実行することができるというものです。既に開かれている Project 内のディレクトリ配下が常に検索の対象となるため、 grep などをするときに対象のディレクトリを指定する必要がないというのが便利ポイントです。
Counsel の方がサポートがよく、一方 Consult では grep が実装されていないなどまだ不便なところがあります。
もっぱら M-x から呼び出しているため、bind は設定しておりません。

(leaf projectile
  :ensure t
  :config
  (leaf consult-projectile
    :ensure t
    )
  )

Treemacs

Treemacs は(語弊があるかもしれませんが)、ディレクトリ配下のファイル一覧とそれぞれの imenu-list を一つのバッファでツリー表示できる、というものですね。

Treemacs はやや挙動が個人的な思想と相反するところがあり、少々カスタマイズに悩みました。
というのも treemacs-follow-mode などはグローバルマイナーモードで動作し、 Treemacs を使用しないバッファに対しても有効になっています。特に利用のないバッファに対しても Treemacs の機能が動いているというのは考え難く(Emacs の思想として、利用していなくても積極的にグローバルで動くモードを有効にしていこう、というものがあるのでしょうか)、便利そうな機能も nil にしてしまっています。

(leaf treemacs
  :ensure t
  :bind
  (:treemacs-mode-map
   ([mouse-1] . #'treemacs-single-click-expand-action)
   )
  :custom
  (treemacs-no-png-images . t)
  (treemacs-filewatch-mode . nil)
  (treemacs-follow-mode . nil)
  (treemacs-tag-follow-mode . nil)
  (treemacs-tag-follow-cleanup . nil)
  (treemacs-expand-after-init . t)
  (treemacs-indentation . 2)
  (treemacs-missing-project-action . 'remove)
  :hook
  (treemacs-mode-hook . (lambda ()
			 (setq mode-line-format nil)
			 (display-line-numbers-mode 0))))

老後、奥さんと世界一周のための費用にします。