GNU Emacs 26で日本語入力(Microsoft Windows 11, Ubuntu 20.04 & WSL2 GUI, X11: X Windows System利用)

　標記の環境を使っている人がどれほどいるか知らないが、ついカッとなってしまったので投稿する。
# はじめに
　目指したのは **安定した環境で `org-mode` が使いたい** ということである。[mhatta](https://twitter.com/mhatta)氏の[Windows用Emacs日本語パッチ](https://github.com/mhatta/emacs-27-x86_64-win-ime)は素晴らしいのだが突然ウィンドウが消えるなど困ったことなる。
　UNIX環境を使い始めたのは1990年代前後なので古参のエンジニアである。一番馴染んでいるGNU Emacsの「たまご」環境(Wnn Egg)を主に好んで使っていた。
　Microsoft Windows 11のWSL2 GUIでUbuntu-20.04を運用すれば近い環境が得られると思いいろいろと設定したが結局かなりの時間を費やしてしまった。この環境にどれだけのニーズがあるかわからないがまとめることにした。

# 用意するもの
　抜け漏れはあるかとは思うが主に準備したものインストールしたものは以下になる。

- Microsoft Windows 11
- Ricty Diminished Discord (等幅フォント)
- WSL2
- WSLg ( `|` , `C-\` などをセンスしない)
- VcXsrv (仕方ないのでX11経由でEmacsを使う)
- Ubuntu-20.04
- mozc
- Emacs 26 (当然Emacs 27としたいところだがGoogle検索したものでやってもうまくいかないのでUbuntu-20.04のデフォルトの26のままにしている)

# Emacsでよく使っているもの
　スケジュールや To-Do の管理に使っている。簡単なメモも `Markdown` ではなく `org-mode` で書く。 `markdown` や `html` にはエキスポートしてやれば良い。作ったドキュメントとスケジュールと To-Do が相互リンクできるというのは非常に都合が良い。使っていない人は一度使ってみることをオススメしたい。(その前にEmacsに慣れずに悶絶すると思われるが…)

- org-mode

# WSL2を日本語化
　参考にしたのはこちらの記事([Win11のWSL2 (WSLg)を日本語化 & Mozcで日本語入力](https://astherier.com/blog/2021/07/windows11-wsl2-wslg-japanese/))である。
　` .profile`  や ` .bashrc`  なんかも自動で設定される。
　なおEmacsの `Set-Mark` コマンドである `CTRL+Space` ( `C-SPC` )が `fcitx` にもっていかれているはずなので、 `fcitx-config-gtk3` (GUIツール)を使って別のキーバインド(例えば `Shift+Space` `S-SPC` )に変更しておく。

# Windows Terminalでの C-V C-C
　GUIがうまくいかないので `emacs -nw` で作業したいところだがどうも様子がおかしい。 `Windows Terminal` の余計なお世話^H^H^H^H^H^H親切のおかげで `C-C` (CTRL+C) 、 `C-V` (CTRL+V) にそれぞれコピー、ペーストが割り振られているではないか。
　これも記事([Windows Terminal で Ctrl+Shift+C, V | 壁にでも話してろ](https://www.yo1000.com/windows-terminal-keybindings))を参考にして修正しておく。

# ~/.Xresources
　Googleで検索すると `*` でワイルドカードが使えたり `:` の代わりが `=` になっている例があるのだがすべてうまくいかない。以下の様に設定する。

```
! ~/.Xresources
! Emacs XIMを無効化
emacs.useXIM:false
emacs24.useXIM:false
emacs25.useXIM:false
emacs26.useXIM:false
emacs27.useXIM:false
```

# ~/.emacs.d/init.el
　今回の日本語に関係しないところも入っている。様々なサイトからの情報を入れたキメラ設定となっている。当然だが自分で使いやすい様にカスタマイズもしている。

```emacs-lisp
;; ~/.emacs.d/init.el - 2021/08/01 13:00 - @ujisakaeru

;; https://emacs-jp.github.io/packages/package-management/package-el

(require 'package)

;; package-archivesを上書き
(setq package-archives
      '(("melpa" . "https://melpa.org/packages/")
        ;; ("melpa-stable" . "https://stable.melpa.org/packages/")
        ("org" . "https://orgmode.org/elpa/")
        ("gnu" . "https://elpa.gnu.org/packages/")))

;; 初期化
(package-initialize)

;;; Emacs における日本語文字コードの設定 | プログラマーズ雑記帳
;;; http://yohshiy.blog.fc2.com/blog-entry-273.html

;; ベースは Shift-JIS のまま
(set-language-environment "Japanese")
;; ファイルのデフォルトを HTML や C++ 用に BOM 付き UTF-8
(set-default 'buffer-file-coding-system 'utf-8-with-signature)

(modify-coding-system-alist 'file "\\.java\\'" 'utf-8)              ; Java
(modify-coding-system-alist 'file "\\.clj\\'" 'utf-8)               ; Clojure
(modify-coding-system-alist 'file "\\.\\(scala\\|sbt\\)\\'" 'utf-8) ; Scala
(modify-coding-system-alist 'file "\\.[eh]rl\\'" 'utf-8)            ; Erlang
(modify-coding-system-alist 'file "\\.exs?\\'" 'utf-8)              ; Elixir

;; emacsでVB6のコードを見る。そのままでも見れるけど、やっぱり白黒ではあじけないのでvisual-basic-mode.elを入れてみる。 - 風待ち
;; http://kawadome.hatenablog.com/entry/2018/02/05/213355

(add-to-list 'load-path "~/.emacs.d/elisp")

;;; VB mode
(require 'visual-basic-mode)
(add-to-list 'auto-mode-alist
             '("\\.\\(frm\\|bas\\|cls\\|vbs\\)$" . visual-basic-mode))
;;; coding system
(modify-coding-system-alist 'file
                            "\\.\\(frm\\|bas\\|cls\\|vbs\\)\\'" 'utf-8)

;; Markdown Mode for Emacs
;; https://jblevins.org/projects/markdown-mode/

(autoload 'markdown-mode "markdown-mode"
  "Major mode for editing Markdown files" t)
(add-to-list 'auto-mode-alist '("\\.markdown\\'" . markdown-mode))
(add-to-list 'auto-mode-alist '("\\.md\\'" . markdown-mode))

(autoload 'gfm-mode "markdown-mode"
  "Major mode for editing GitHub Flavored Markdown files" t)
(add-to-list 'auto-mode-alist '("README\\.md\\'" . gfm-mode))

;;; Emacs "ことはじめ" 私の事例 | TECHSCORE BLOG
;;; https://www.techscore.com/blog/2016/12/25/emacs-%E3%81%93%E3%81%A8%E3%81%AF%E3%81%98%E3%82%81-%E7%A7%81%E3%81%AE%E4%BA%8B%E4%BE%8B/

;; mini buffer 内も含めて C-h を Backspace へ割当てる
(define-key key-translation-map (kbd "C-h") (kbd "<DEL>"))

;; toggle-trancate-lines関数を作って、トグル動作させる。
;; (global-set-key (kbd "C-c l") 'toggle-truncate-lines) ; ON/OFF
(global-set-key (kbd "C-c t") 'toggle-truncate-lines) ; ON/OFF
(defun toggle-truncate-lines ()
  (interactive)
  (if truncate-lines
      (setq truncate-lines nil)
    (setq truncate-lines t))
  (recenter))

;; 標準で利用可能な linum-mode をオンにする
(require 'linum)
(global-linum-mode t)
(setq linum-format "%3d")

;; 以下はお好みで設定してください
;; 全てバッファ内で日本語入力中に特定のコマンドを実行した際の日本語入力無効化処理です

;; ミニバッファに移動した際は最初に日本語入力が無効な状態にする
(add-hook 'minibuffer-setup-hook 'deactivate-input-method)

;; Emacs設定ファイル - Qiita
;; https://qiita.com/osada/items/3f2e586d120e0d6d778c

(require 'time-stamp)

;; 日本語で日付を入れたくないのでlocaleをCにする
(defun time-stamp-with-locale-c ()
  (let ((system-time-locale "C"))
    (time-stamp)
    nil))

;; org-mode - opentfc @ ウィキ - アットウィキ
;; https://w.atwiki.jp/opentfc/pages/116.html

(add-hook 'org-mode-hook
          (lambda ()
            (set (make-local-variable 'system-time-locale) "C")))

;; One More Duo: EmacsのOrg-modeで、思考を加速させてみよう(2)
;; https://onemoreduo.blogspot.com/2012/11/emacsorg-mode2.html

(add-to-list 'auto-mode-alist '("\\.\\(org\\|org_archive\\|txt\\)$" . org-mode))

(define-key global-map "\C-cl" 'org-store-link)
(define-key global-map "\C-ca" 'org-agenda)
;; (global-set-key "\C-cb" 'org-iswitchb)
(define-key global-map "\C-cb" 'org-iswitchb)

;; org-captureをカスタマイズして、すばやくメモを取る方法 | 趣味に生きる。
;; https://www.5ing-myway.com/org-capture/

;; org-capture
;; キーバインドの設定
(global-set-key (kbd "C-c c") 'org-capture)

;; ファイルパスの設定
;; (setq work-directory "/d/work/")
;; (setq work-directory "~/../../Dropbox/Share/Org/")
(setq work-directory "~/Dropbox/Share/Org/")
(setq taskfile (concat work-directory "tasks.org"))
(setq listfile (concat work-directory "lists.org"))

;; モーレツ! Org mode 教室 その5: TODOを管理する - mhatta's mumbo jumbo
;; http://www.mhatta.org/wp/2018/08/27/org-mode-101-5/

(setq org-enforce-todo-dependencies t)
(setq org-log-done 'time)

(setq notefile (concat work-directory "notes.org"))

;; Org-modeで、ライフログを録ろう - Qiita
;; https://qiita.com/takushi1969/items/1653235191c0d1538a84

(setq journalfile (concat work-directory "journal.org"))

;;

(setq org-capture-templates
      '(
        ;; タスク（スケジュールなし）
        ;;   ("t" "タスク（スケジュールなし）" entry (file+headline taskfile "Tasks")
        ;;    "** TODO %? \n")
        ;;   ;; タスク（スケジュールあり）
        ;;   ("s" "タスク（スケジュールあり）" entry (file+headline taskfile "Tasks")
        ;;    "** TODO %? \n  SCHEDULED: %^t \n")
        ;;
        ("t" "Todo" entry (file+headline taskfile "INBOX")
          "** TODO %?\n  %i\n  %a")
        ("s" "Todo(w/Date)" entry (file+headline taskfile "INBOX")
          "** TODO %?\n  SCHEDULED: %^t\n  %i\n  %a")
        ("n" "Note" entry (file+headline taskfile "Notes")
          "** %?\n  Entered on %U\n  %i\n  %a")
        ;;
        ("j" "Journal" entry (file+datetree journalfile "Journal")
          "** %?\n  Entered on %U\n  %i\n  %a")
        ;;
        ("d" "やりたいこと" checkitem (file+headline listfile "やりたいこと")
          "[ ] %? \n")
        ("b" "欲しいもの" checkitem (file+headline listfile "欲しいもの")
          "[ ] %? \n")
        ("g" "行きたいところ" checkitem (file+headline listfile "行きたいところ")
          "[ ] %? \n")))

;; EmacsとOrg-modeで簡単TODO管理のススメ
;; http://www.swlab.cs.okayama-u.ac.jp/lab/nom/articles/okada-20141207-184858

;; (setq org-agenda-files (list "~/Dropbox/org"))
;; (setq org-agenda-files (list "~/../../Dropbox/Share/Org"))
;; (setq org-agenda-files (list work-directory))
(setq org-agenda-files (list "~/Dropbox/Share/Org"))

;; Emacs org-modeを使ってみる: (6) アジェンダ表示 - 屯遁のパズルとプログラミングの日記
;; https://tamura70.hatenadiary.org/entry/20100208/org

;; (global-set-key (kbd "C-c a") 'org-agenda)

;; アジェンダ表示の対象ファイル
;; (setq org-agenda-files (list org-directory))
;; アジェンダ表示で下線を用いる
(add-hook 'org-agenda-mode-hook '(lambda () (hl-line-mode 1)))
(setq hl-line-face 'underline)
;; 標準の祝日を利用しない
(setq calendar-holidays nil)

;; emacs の org-mode と google calendar を連携させる org-gcal - Qiita
;; https://qiita.com/clothoid/items/73a937a22eeeb82c3ee7#fn.1

(require 'org-gcal)
(setq
 org-gcal-client-id "195187265684-qe864aledhfneeo52ahfrosi99pbih5v.apps.googleusercontent.com"
 org-gcal-client-secret "hUvcbNbMvpxtCJtFsVP7wcZ9"
 ;; ID が sample@foo.google.com のカレンダーと ~/calendar.org を同期
 org-gcal-file-alist '(
                       ("sample@foo.hoge" .  "~/Dropbox/Share/Org/gcal.org")
                       ;; ("sample2@foo.google.com" .  "~/calendar2.org")
                       ))
;; token の保存場所を変更
(setq org-gcal-dir "~/Dropbox/.emacs.d/local-lisp/org-gcal")

;; 日本語入力

;; mozc.elを変換/無変換キーでOn/Off: ふるきのガベージコレクション
;; http://kenedori.moe-nifty.com/fgc/2016/08/1604.html

;----------------------------------<mozc>
;; mozc
;; (require 'mozc)
(require 'mozc-im)

;; この設定はLEIM用。
;; 無変換キーのバグ動作があるため使用しない
;; (setq default-input-method "japanese-mozc")
(setq default-input-method "japanese-mozc-im")
;; 変換候補を mini buffer に表示
;; (変換時は、カーソル位置しか見ていない。
;;       候補が出てこない時に視線を移動する使い方)
(setq mozc-candidate-style 'echo-area)
;; (setq mozc-candidate-style 'overlay)

;; 全角半角キーで on/off
;; (global-set-key [zenkaku-hankaku] 'toggle-input-method)

;; mozc 変換/無変換キーでOn/Off
(global-set-key (kbd "<henkan>") '(lambda ()
                    (interactive)
                    (mozc-mode 1)
;;                    (setq mozc-on-off "[mozc]")
;;                    (force-mode-line-update)
                    (mozc-mode-line-indicator-update)
                    ))
(global-set-key (kbd "<muhenkan>") '(lambda ()
                      (interactive)
                      (mozc-mode 0)
;;                      (setq mozc-on-off "")
;;                      (force-mode-line-update)
                      (mozc-mode-line-indicator-update)
                      ))

;; mozc-mode有効時にmultiple-cursorsが使えないので - あじーん-0.0.2-SNAPSHOT
;; https://nishikawasasaki.hatenablog.com/entry/2019/01/22/222914

;; 変換キーでon
;; (global-set-key [henkan]
;;              (lambda () (interactive)
;;                (mozc-mode 1)
;;                (when (null current-input-method) (toggle-input-method))))
;; 無変換キーでoff
;; (global-set-key [muhenkan]
;;              (lambda () (interactive)
;;                (deactivate-input-method)))

;; mozcオンでも無変換キーはEmacsにわたすようにキーイベントを横取りする
(defadvice mozc-handle-event (around intercept-keys (event))
  (if (member event (list 'zenkaku-hankaku 'muhenkan))
      (progn
        (mozc-clean-up-session)
        ;; (toggle-input-method)
        (mozc-mode nil)
        (deactivate-input-method))
    (progn ;; (message "%s" event) ;debug
      ad-do-it)))
(ad-activate 'mozc-handle-event)

;; Mozcの情報まとめ的な - Qiita
;; https://qiita.com/ballforest/items/063a7fb4d0661c2bcf07

(require 'mozc-mode-line-indicator)

;; GitHub - HKey/mozc-temp: Use mozc temporarily
;; https://github.com/HKey/mozc-temp

(global-set-key (kbd "M-n") #'mozc-temp-convert)

;;

(global-set-key (kbd "C-\\") #'mozc-mode)
(global-set-key (kbd "<zenkaku-hankaku>") #'mozc-mode)

;; Emacs24に最初から同梱されているテーマ - AOEの日記
;; https://aoe-tk.hatenablog.com/entry/20130210/1360506829

;; (load-theme 'tango-dark t)
(load-theme 'wheatgrass t)
;; (load-theme 'deeper-blue t)
;; (load-theme 'tsdh-dark t)
;; (load-theme 'manoj-dark t)

;; emacsで全角スペースを見やすくする。 - うめすこんぶ
;; https://konbu13.hatenablog.com/entry/2014/04/01/203857

(require 'whitespace)

(set-face-foreground 'whitespace-space "DarkGoldenrod1")
(set-face-background 'whitespace-space nil)
(set-face-bold-p 'whitespace-space t)
(set-face-foreground 'whitespace-tab "DarkOliveGreen1")
(set-face-background 'whitespace-tab nil)
(set-face-underline  'whitespace-tab t)

(setq whitespace-style '(face tabs tab-mark spaces space-mark))
(setq whitespace-space-regexp "\\(\x3000+\\)")
(setq whitespace-display-mappings
      '((space-mark ?\x3000 [?\□])
        (tab-mark   ?\t   [?\xBB ?\t])
        ))

(global-whitespace-mode 1) ; 全角スペース("　")を常に表示
(global-set-key (kbd "C-x w") 'global-whitespace-mode) ; 全角スペース表示の切替

;; プログラミング向けフォント「Ricty Diminished」をDebian testing(Buster)環境にインストールしEmacs25に設定する
;; https://emacs.tsutomuonoda.com/install-the-programming-font-ricty-diminished-in-the-debian-testing-buster-environment-and-set-it-to-emacs-25/

(set-face-attribute 'default nil
                    :family "Ricty Diminished Discord"
                    :height 136)
(set-fontset-font (frame-parameter nil 'font)
                  'japanese-jisx0208
                  (cons "Ricty Diminished Discord" "iso10646-1"))
(set-fontset-font (frame-parameter nil 'font)
                  'japanese-jisx0212
                  (cons "Ricty Diminished Discord" "iso10646-1"))
(set-fontset-font (frame-parameter nil 'font)
                  'katakana-jisx0201
                  (cons "Ricty Diminished Discord" "iso10646-1"))

;; 自分の.emacs.elです · GitHub
;; https://gist.github.com/kazekyo/2637273/e99fefb29c011a7a04df2ed3b33c8a8612f7bd31

                                        ;起動時のフレームサイズを設定する
(setq initial-frame-alist
      (append (list
               '(width . 100)
               '(height . 46)
               '(top . 31)          ;; Y 表示位置
               '(left . 961)        ;; X 表示位置
               '(font . "Ricty Diminished Discord 14")
               )
              initial-frame-alist))
(setq default-frame-alist initial-frame-alist)

;; WSL で Emacs を使うための設定 - NTEmacs @ ウィキ【6/25更新】 - atwiki（アットウィキ）
;; https://w.atwiki.jp/ntemacs/pages/69.html

;; shell の設定

(setq shell-file-name "/bin/bash")
(setq shell-command-switch "-c")
(setq explicit-shell-file-name shell-file-name)

;;
;;
(custom-set-variables
 ;; custom-set-variables was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(column-number-mode t)
 '(current-language-environment "Japanese")
 '(package-selected-packages
   (quote
    (mozc-temp w3m use-package recentf-ext org-gcal neotree mozc-popup mozc-im migemo markdown-mode hiwin golden-ratio gitter elscreen dired-toggle diminish auto-complete)))
 '(show-paren-mode t))
(custom-set-faces
 ;; custom-set-faces was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 )

```

# ポイント
　今回のポイントをまとめると以下になる。

- WSLg(WSL2 GUI)にはEmacsの日本語入力やShellのパイプで必ず使う `￥`(当然半角)、`|` が刻印された `Backspace` (BS)の隣のキーが使えない。
- X11の他のアプリで日本語入力できるように設定してあると日本語に割り当てられたキーが使えなくて困るのだがキャンセルの方法はGoogle検索したものではだめだった。
- `mozc-mode` を入れてもまともな日本語入力はできないのでカスタマイズが必要だった。