= [[emacs]] / LM: [2025-01-13 01:28:49]
~~NOCACHE~~
====== - 各種 mode/パッケージ ======
===== - migemo =====
[2023-11-05]
migemo は,emacs 上で日本語をインクリメンタルサーチするための仕組み.デフォルトだと(かな漢字変換の) skk 由来の辞書をベースに,ローマ字を内部的に漢字に変換しつつ,バッファ内を検索する.大変便利.migemo の実装はいくつか存在していて,本メモを書いた時点では cmigemo がメジャーな模様.ruby や python での実装をしている人なども見かけた.検索アルゴリズムや辞書データのありかたなど,弄べる部分が多いに違いない.
利用方法は,まず,OS のネイティブに cmigemo をインストールする.
# FreeBSD
% sudo portmaster -D japanese/cmigemo
# Ubuntu
% sudo apt-get install migemo
emacs 側の設定は,use-package を使うなら以下のような形.起動を速くしたいと言う人のブログを参考にしたので,遅延読み込みを意識した設定になっている.
(use-package migemo
:ensure t
:if (executable-find "cmigemo")
:commands (migemo-init)
:defer t
:config
(setq migemo-command "cmigemo")
(setq migemo-options '("-q" "--emacs"))
(cond
((string= os-type "bsd")
(setq migemo-dictionary "/usr/local/share/cmigemo/utf-8/migemo-dict"))
((string= os-type "linux")
(setq migemo-dictionary "/usr/share/cmigemo/utf-8/migemo-dict"))
)
(setq migemo-user-dictionary nil)
(setq migemo-regex-dictionary nil)
(setq migemo-coding-system 'utf-8-unix)
:hook
(emacs-startup . migemo-init)
)
パッケージ管理の仕組みを使わないなら,以下のような形かもしれない.
(require 'migemo)
(setq migemo-command "cmigemo")
(setq migemo-options '("-q" "--emacs"))
(cond
((string= os-type "bsd")
(setq migemo-dictionary "/usr/local/share/cmigemo/utf-8/migemo-dict"))
((string= os-type "linux")
(setq migemo-dictionary "/usr/share/cmigemo/utf-8/migemo-dict"))
)
(setq migemo-user-dictionary nil)
(setq migemo-regex-dictionary nil)
(setq migemo-coding-system 'utf-8-unix)
(migemo-init)
os-type の部分は,事前に以下のような形で OS を取得している.事前に取得している意味はあまりないので,そのうちリファクタしてしまいたい.
(setq os-type nil)
(cond ((string-match "apple-darwin" system-configuration) ;; Mac
(setq os-type "mac"))
((string-match "linux" system-configuration) ;; Linux
(setq os-type "linux"))
((string-match "freebsd" system-configuration) ;; FreeBSD
(setq os-type "bsd"))
((string-match "mingw" system-configuration) ;; Windows
(setq os-type "win")))
==== - 雑記 ====
[2023-11-06]
そういえば,pure lisp な migemo 実装は存在しないのかな…?軽く調べても見つからなかった.
また,ローマ字変換を利用していると言うことで,例えば漢語のような文字については検索できないのでは…?という気もしている.
検索してたら,[[https://ipsj.ixsq.nii.ac.jp/ej/index.php?action=pages_view_main&active_action=repository_action_common_download&item_id=11380&item_no=1&attribute_id=1&file_no=1&page_id=13&block_id=8|情報処理学会の論文]]を発見.高林さんが最初に開発,というブログは見かけていたが,増井さんがソニーの研究所にいる時の成果の一つなんすね..
===== - vc =====
[2023-11-05]
<TBD>
バージョンコントールのための統合的な機能.svn も扱えている気がする.
| キーバインド | コマンド | 説明 | Subversionのコマンド |
| C-x v = | vc-diff | 差分を表示 | diff |
| C-x v l | vc-print-log | 履歴を表示 | log |
| C-x v g | vc-annotate | 注釈を表示 | blame |
| C-x v ~ | vc-revision-other-window | 過去のバージョンを表示 | cat |
| C-x v + | vc-update | 更新 | update |
| C-x v v | vc-next-action | コミット | commit |
| C-x v i | vc-register | ファイルの追加 | add |
| C-x v u | vc-revert | 修正の破棄 | revert |
| C-x v d | vc-dir | 状態の表示 | status |
| | ediff-revision | Ediffで差分を表示 | |
メモ:
''C-x v v'' すると,コメント入力を求められる.入力が終わったら,''C-c C-c'' したら commit された.
参考:
* https://dev.ariel-networks.com/articles/emacs/part7/ :もうすぐ消え去りそう…
==== - vc-svn 利用時の svn コマンドへの引数指定 ====
[2023-11-06]
どうしても svn コマンドに引数を渡して実行したいケースがある.ドキュメントには書いてなかったが,vc-svn.el の中に,以下のような変数が設定されているのを発見した.
;; Might be nice if svn defaulted to non-interactive if stdin not tty.
;; https://svn.haxx.se/dev/archive-2008-05/0762.shtml
;; https://svn.haxx.se/dev/archive-2009-04/0094.shtml
;; Maybe newer ones do?
(defcustom vc-svn-global-switches (unless (eq system-type 'darwin) ; bug#13513
'("--non-interactive"))
"Global switches to pass to any SVN command.
The option \"--non-interactive\" is often needed to prevent SVN
hanging while prompting for authorization."
:type '(choice (const :tag "None" nil)
(string :tag "Argument String")
(repeat :tag "Argument List"
:value ("")
string))
:version "24.4")
良く分からないが,MacOS 以外では ''--non-intereractive'' という引数を svn コマンドに渡している模様.リストになっているので,以下のように add-to-list すればコマンドライン引数を追加できた.
(use-package vc
:after vc-svn
:config
(add-to-list 'vc-svn-global-switches "--hogehoge=hogehoge"))
===== - recentf =====
[2023-11-05]
今まで開いたことのあるファイル一覧を保存しておいてくれる機能.emacs 25 くらい?からは,mode を有効するのに,その mode にたいして non-nil を指定すれば良いっぽい.
(recentf-mode 1)
保存情報は,''~/.emacs.d/recentf'' ファイルに以下のように保存されている.
;;; Automatically generated by ‘recentf’ on Thu Nov 2 15:57:51 2023.
(setq recentf-list
'(
"/mnt/c/Users/skk/svn/.elisp/.emacs-29"
"/mnt/c/Users/skk/svn/howm/2023/10/2023-10-19-200323.howm"
))
(setq recentf-filter-changer-current 'nil)
^L
;; Local Variables:
;; coding: utf-8-emacs
;; End:
保存しておくパスの件数は以下のように設定する.
(setq recentf-max-menu-items 100)
保存しておいて欲しくないファイルについては,以下のように exclude リストを ''recentf-exclude'' に追加する.
(add-to-list 'recentf-exclude
(recentf-expand-file-name "\\.\\*AppData/Local/Temp/\\.\\*"))
emacs を起動している間は,除外したファイルも一覧に入っているが,起動時(?)に ''(recentf-cleanup)'' が呼ばれて,ファイル内から指定されたファイルが除外される模様.
recentf-cleanup で,M-x describe-function したら以下のように書いてあった.
Cleanup the recent list.
That is, remove duplicates, non-kept, and excluded files.
[2023-12-13]
recentf が増えてくると,検索したくなる.そのような時は,''M-x recentf-open-files'' と打つと,今までの履歴が一覧で出てきて,''C-s'' などで検索して探しやすくなる.
参考:
* https://emacs.stackexchange.com/questions/27139/ignoring-specific-files-in-recentf-mode
===== - color theme =====
[2023-11-05]
markdown モードのコメント,org の階層,など,一つ一つの要素の色を設定していくのはとても大変なので,一気に色の指定をしてくれる色のセット.
いつから使えるようになったのか分からないが,https://www.nongnu.org/color-theme/ ここら辺を見ていると,2009 年頃にはある程度使われるようになってきていたように思われる.
検索してみると,https://emacsthemes.com/ ここのサイトに情報が多く載っている模様.Vim と同じ配色の Zenburn theme というものが Top Themes を見ると一位にランクしている.
M-x package-list-pagckages から該当の theme をダウンロードし,''(load-theme 'abyss-theme t)''としても良いし,以下のように use-package を利用してもよい.僕は,.emacs 内にいろいろな残骸が残っているので,''after-init-hook'' で load-theme しているが,余計な設定が無い人ならば,単に :config の中で load-theme するだけで動作すると思われる.
(use-package
se-package
;; darktooth-theme
abyss-theme
;; darkmine-theme
;; doom-themes
:ensure t
:defer nil
:if (window-system)
:config
;; 多分 after-init の前に色々設定してるから,終わってから更に上書きする.
(add-hook 'after-init-hook
(lambda ()
(load-theme 'abyss t)))))
===== - use-package =====
==== - 概要 ====
[2023-11-01] 2000 年中盤ころはまだ,emacs でパッケージ管理という概念はあんまりなかった気がする.そういえば,最近は新しい機能を入れる時に ''M-x packge-list-packages'' してるな,と思ったので調べてみたら,パッケージ管理機能がかなり充実してきているのに気づいた.
少しぐぐってみると,leaf.el というのが流行っているのに気づいたのだが,検索している時に英語の情報が全然出てこないので,英語だけで調べてみたところ,leaf.el は全然出てこなかった.一度設定すると,下手すると 10 年単位で放置する可能性があるので,単に流行ってるだけのものは使いたくない.leaf.el ってなんなんだ?と調べてみたところ,日本人が作っている use-package のラッパーみたいなものだということが分かった.(なるほど,だから日本語の情報が大量にあるのか...)英語方面で調べてみると use-package + straight というのが良く引っかかる.straight というのはまだ良く分かってないが,少なくとも use-package を使うと,
* パッケージが入ってなかったら勝手に入れてくれる(emacs デフォルトのパッケージの設定も同じ記法で管理可能)
* setq で指定していたパッケージ毎の設定を見やすく記述できる
という利点があることが分かった.また,登場してからすでに 10 年近く経っているのに,まだ現役で設定している人がいたので,まだまだ寿命が長そうだな,ということで,.emacs の色々を use-package にしてみることにした.
use-package は,package.el のマクロということで,package.el を使い倒すための仕組みらしい.
==== - 初期設定 ====
まず,package でオンラインで取得できる設定をした後に,use-package が入ってなくてもインストールされるようにする.
;------------------------------------------------------------------------
; melpa 設定 (package manager)
;------------------------------------------------------------------------
(require 'package)
(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/") t)
(add-to-list 'package-archives '("org" . "https://orgmode.org/elpa/") t)
;; (package-initialize) ;; from version 27, no need.
;;------------------------------------------------------------------------
;; use-package 設定
;;------------------------------------------------------------------------
;; もし,use-package が入ってなかったら,インストールする.
;; これ以外は,use-package を使って自動でインストールして貰う.
(unless (package-installed-p 'use-package)
(package-install 'use-package))
==== - use-package 基本利用方法 ====
最も良いドキュメントは,use-package の github の [[https://github.com/jwiegley/use-package|README.md]] になる.
基本の使いかたは,以下のように書くことで,''(require 'package-name)'' と同様のことをする.
(use-package package-name)
require と load は少し意味が違っていて,require は遅延ロードで,load は即座にロードする,という意味らしい.遅延ロードにすることで,emacs の起動が早くなり,利用する際に該当のパッケージの本体が読み込まれることになる模様.ここの理解はまだ浅いので,そのうち調べたい.
例えば,''emacs-lisp-mode'' を利用する際に hook でいくつかの mode を起動する場合,use-package を使わないと,
(add-hook 'emacs-lisp-mode-hook 'action-lock-mode)
(add-hook 'emacs-lisp-mode-hook 'auto-complete-mode)
のように書いていたが,use-package に直すと,
(use-package emacs-lisp-mode
:hook
(emacs-lisp-mode . action-lock-mode)
(emacs-lisp-mode . auto-complete-mode))
となる.'':hook'' を利用する場合,emacs-lisp-mode-hook のように -hook がついていたが,'':hook'' を利用する場合は,-hook は除外して記述してくれ,とのこと.
'':hook'' という記述方法は,どうも ''cl-lib'' で提供される common-lisp の記述方法のようだが,これも良く分かっていない.そのうち調べたい.
use-package には,'':hook'' のように事前に設定する機能がたくさんある.
==== - atomic-chrome 設定の例 ====
[2023-11-05]
ここでは,色々設定している僕の atomic-chrome を例に載せておく.
(use-package atomic-chrome
:ensure t
:after action-lock ;; howm ;; howm を起動するまで atomic-chrome が起
;; 動しないことになってしまう?action-lock は事前
;; に起動されている.
:if (window-system)
:init
(setq atomic-chrome-default-major-mode 'org-mode) ;; org-mode での編
;; 集をデフォルト
;; にする
(setq atomic-chrome-buffer-open-style 'full) ;; split is default.
(setq debug-on-error t)
(setq winactivate nil)
;; URL 毎の編集 mode 設定
(setq atomic-chrome-url-major-mode-alist
'(("redmine\\.cho-textbook\\.jp" . markdown-mode)
("app\\.slack\\.com" . slack-text-mode)))
:bind (:map atomic-chrome-edit-mode-map
("C-c d" . erase-buffer))
:hook
((after-init . atomic-chrome-start-server)
(atomic-chrome-edit-mode . turn-off-auto-fill))
:config
;; 編集開始時の hook
(add-hook
'atomic-chrome-edit-mode-hook
(lambda ()
;; (atomic-chrome-edit-mode . turn-off-auto-fill)
(setq winactivate (shell-command-to-string "focusWslEmacs3.exe"))
))
;; 編集終了時の hook
(add-hook
'atomic-chrome-edit-done-hook
(lambda ()
(my-atomic-chrome-send-buffer-text)
(setq windeactivate
(shell-command-to-string (format "back_to_win.exe %s" winactivate)))
))
;;(atomic-chrome-start-server)
)
'':ensure'' は,そのパッケージがインストールされているかを確認する.t だと package から自動でインストールしてくれる.
'':after'' は指定されたパッケージが require されたあとにロードされるようにする.
'':if'' は,そこで指定された式や関数が non-nil を返したら読み込みをする,というもの.ここでは,(window-system) が何らか指定されていれば,ということになる.WSL の場合は,x11 で起動しているので x と返ってくる.Windows や Mac ネイティブな emacs だとどうなるのかは調べてない.
'':init'' は,ロード前に指定しておく命令を記述する.ここでは,atomic-chrome の初期設定で必要ないくつかの変数に値を指定している.
'':bind'' は,キーマップを指定する.特に,'':map'' で指定する時は,このモード専用のキーマップに指定するので,このモードだけのキーマップが設定できる.
'':hook'' は前述の通り,hook を指定する.atomic-chrome に関係する hook でなくともここに記載しておけば良い.
'':config'' は,ロード後に指定する命令を記述する.'':init'' と分けて考えるように.
日本語では,以下の Qiita の記事がある程度まとめてくれているので,読みやすい.
https://qiita.com/kai2nenobu/items/5dfae3767514584f5220
===== - scratch-log [2023-10-20] =====
*scratch* バッファに色々書く人は多いと思う.そして大事なことを書いたまま,emacs を閉じてしまい,メモが消えたことがある人も多いと思う.
そういう人のために,*scratch* バッファに書いた情報を自動保存しておいてくれる scratch-log.el というものがある.設定しておけば,数十秒毎など,指定した時間毎にバッファの内容を保存してくれる.
インストールは,M-x package-list-packages から.
設定は,例えば以下のような形.
;;; scratchのログ、直前の内容
(setq sl-scratch-log-file "~/.emacs.d/.scratch-log")
(setq sl-prev-scratch-string-file "~/.emacs.d/.scratch-log-prev")
(setq sl-restore-scratch-p t) ;復元
(setq sl-prohibit-kill-scratch-buffer-p t) ;削除不能
;; *scratch*とscratch-logのメジャーモードをorg-modeにする
;; initial-major-mode は,after-init-hook の後に設定される.
(setq initial-major-mode 'org-mode)
(add-to-list 'auto-mode-alist '("scratch-log" . org-mode))
;;; 30秒ごとに自動保存
(setq sl-use-timer t)
(setq sl-timer-interval 3)
;;; requireした時点で各種フック・タイマーが設定される
(require 'scratch-log)
;;(add-hook 'after-init-hook 'my-scratch-func)
(add-hook 'emacs-startup-hook 'my-scratch-func)
(defun my-scratch-func ()
(with-current-buffer "*scratch*"
(message "my-scratch-func")
(highlight-lines-matching-regexp "^>" "hi-blue")))
参考サイトから更に,*scratch* バッファのデフォルトモードを設定し,メールのように行頭に ''>'' がある場合に色を付ける設定を付け加えた.
どのタイミングで org-mode の指定や,ハイライト指定をすべきかは,[[https://www.sakaki.works/doku/doku.php?id=emacs#%E8%B5%B7%E5%8B%95%E6%99%82%E3%81%AE%E5%87%A6%E7%90%86%E3%82%B7%E3%83%BC%E3%82%B1%E3%83%B3%E3%82%B9_2023-10-20|起動時シーケンス]] についてを確認のこと.
参考:
* [[http://emacs.rubikitch.com/scratch-log/|るびきち「新生日刊Emacs」]]
ちなみに,emacs 29 で,scratch-buffer という新たな命令が出来て,間違って消しても *scratch* バッファを作れるなんてのは見かけたが,書いた内容が復活しないのかな?と思いつつ,まだちゃんと確認はしていない.
===== - time-stamp [2023-10-19] =====
ファイルを保存した際に,ファイル内の特定の場所に保存時間を書いておきたくなった.howm-mode 利用時に,1 行目に書いておけば,一覧の中で更新日時が見られるので便利.
[[https://okumuralab.org/~okumura/misc/220319.html|奥村先生のページ]]にほぼ解答が載っていた.
(add-hook 'before-save-hook 'time-stamp)
(setq time-stamp-pattern "2/LM:[ \t]+\\\[%:y-%02m-%02d %02H:%02M:%02S\\\]")
奥村先生の方は,''Last modified: '' という記載方法だったが,これだと長過ぎるし,''