1 ポイント 投稿者 GN⁺ 4 시간 전 | 1件のコメント | WhatsAppで共有
  • Emacsの基本機能には、別パッケージなしで使えるものの目立ちにくいツールが多く、現代の Emacs 28.1+ でも 5 分以内に覚えられる実用機能が今なお見つかる
  • ファイルを開く・URL を集める・比較する・変更を追跡するといった日常作業は、find-filediredffap-menucompare-windowshighlight-changes-mode だけでもかなりの部分をこなせる
  • バックアップファイルとバージョン管理ファイルは、vc-diff 系のコマンドを拡張すれば 以前のバージョンと比較する という 1 つの作業モデルにまとめられる
  • 編集・探索・表示の作業は、apropos 系、find-function-on-keykmacro-edit-lossagesubword-mode、画像操作キーマップのような、すでに含まれている機能だけでも素早く改善できる
  • 重要な takeaway は、Emacs の lisp ディレクトリがそれほど大きくなくても、標準内蔵機能だけで作業フローを広げる余地がまだまだ残っているという点である

概要と範囲

  • Emacs の機能には発見しにくさという問題があり、この記事は、あまり知られていないが便利な内蔵機能を 1 つずつ紹介する形でその問題を和らげようとする試みである
  • 今回の記事は、Emacs に標準で含まれている便利だがあまり知られていない機能を扱う 3 本目の記事である
  • 「あまり知られていない」は主観的な判断であり、過去 20 年にわたってオンラインの Emacs 談義を見てきた中で、その機能が 5 回未満しか言及されていない、あるいは一度も見たことがない場合をおおむね指す
  • 新しい Emacs ユーザーはここから始めないほうがよく、基本概念や広く推奨されるパッケージに慣れてからのほうが、この一覧はより役に立つ
  • 基準としては、パッケージなしの 素の Emacs のみを使い、急な学習曲線がなく、遊び的な機能やよく話題になる機能を除き、現代の Emacs 28.1+ を前提とする

マウスオーバー辞書: M-x dictionary-tooltip-mode

  • dictionary-tooltip-mode を有効にすると、単語の上にマウスを置いたときにツールチップで意味を見られる
  • tooltip-mode も有効である必要があるが、これはデフォルトで有効になっている
  • ローカル辞書が設定されていればまずそれを使い、Emacs の辞書は通常 Wiktionary 経由で現代的な用語やスラングも見つけられる

find-filedired のワイルドカード

  • find-filedired は対話的に使う場合でも ワイルドカード を使える
  • find-file*foo*.txt のようなパターンを使えば、複数ファイルを一度に開ける
  • Dired でディレクトリを開くときにファイル名ワイルドカードを指定すると、特定のファイルだけを集めたカスタム一覧を作れる
  • 例の流れでは、*/*_region_* パターンでサブディレクトリの AucTeX 一時ファイルを探し、Dired で選択して削除し、その後またワイルドカードでサブディレクトリ内の複数の TeX ファイルを開く
  • この機能は関数シグネチャ上はプログラミング呼び出しで分かるものの、対話的な利用でも可能だという点は docstring 全体を読まないと気づきにくい
  • Dired のワイルドカード機能は、consult-findembark-export で作る現代的な Dired フローに押されがちだが、素の状態でそのまま動く

バッファ内の URI 一覧: M-x ffap-menu

  • ffap は、カーソル位置が有効なファイルパスまたは URL かどうかを判定して開けるようにする find-file-at-point 機能である
  • ffap-menu はバッファ全体を走査し、ファイルパスや URL のように見える項目を見つけて一覧として提示する
  • completing-read インターフェースを使うため、絞り込んだ候補一覧をバッファへエクスポートしたり、一部または全部をコピー・開く・Embark で処理したりできる
  • 属性付きリンクの一覧化

    • EWW のような Emacs アプリケーションは、URL を通常のテキストリンクではなくテキスト属性として埋め込むことがあり、ffap-menu はそれを見逃す
    • これを補うには、ffap-menu に着想を得たユーザー定義コマンドで shr-url テキスト属性まで収集できる
    • 例のコマンド my/search-occur-browse-url は、通常の URL 正規表現と shr-url 属性の両方を見つけて補完候補を作り、選んだ URL を browse-url または browse-url-generic で開くように構成されている

ウィンドウ比較: M-x compare-windows

  • Emacs には、diffdiff-buffersdiff-backupdired-diffvc-diff、さまざまな ediff-* コマンドのように比較コマンドが多い
  • compare-windows は 2 つのウィンドウのカーソル位置からテキストを比較し、次の不一致箇所で停止してそれを報告する
  • 比較対象はアクティブなウィンドウと、other-window が選ぶウィンドウであり、Ediff や diff より機能は少ないが、実行はより簡単で速い
  • バッファの種類、変更状態、ファイル、バージョン管理状態に関係なく、2 つのウィンドウに表示されている実際のテキストだけを比較する
  • 同じバッファの別の部分を 2 つのウィンドウに表示すれば、同じバッファ内の 2 つのテキスト片も比較できる
  • ディレクトリ一覧も比較でき、例ではファイルの更新時刻が最初の不一致として検出される
  • 前置引数を与えると空白の違いを無視できる

Dired でディレクトリ比較: M-x dired-compare-directories

  • dired-compare-directories は Dired で比較するディレクトリを尋ね、2 つの Dired 一覧で名前が異なるファイルを表示する
  • この方法は、最も一般的なディレクトリ比較のユースケースを処理できる
  • ファイルレベルの比較なので、更新時刻やサイズなどのファイル属性を含むカスタムの一致条件を与えられる
  • (> mtime2 mtime1) 条件なら、より新しく更新されたファイルを表示できる
  • (/= size1 size2) 条件なら、名前は同じだがサイズが異なるファイルを表示できる
  • より対話的な比較が必要なら ediff-directories も使える

バッファ変更の強調表示: M-x highlight-changes-mode

  • highlight-changes-mode はファイルの変更箇所を強調表示する機能で、diff-buffer-with-file のような diff コマンドの「ライブ」代替として使える
  • 基本動作では、モードを有効にした時点から無効にするまでの変更を強調表示し、未保存の変更だけを自動で強調する仕組みではない
  • before-save-hookafter-save-hook を使えば、保存前に強調表示を切り、保存後に再び有効にする形で、保存前の変更だけを強調するフローを作れる
  • 例のコードでは、text-mode-hook でファイルバッファに highlight-changes-mode を有効にし、保存前後のフックで強調状態を調整する
  • 独立した highlight-unsaved-mode の形にすれば、保存するまでのすべての変更を強調表示するマイナーモードになる
  • highlight-changes-next-changehighlight-changes-previous-change で次・前の変更箇所へ移動できる
  • highlight-changes-remove-highlight で視覚的な強調表示を取り除き、変更追跡にもとづく移動だけを使うこともできる

バックアップファイルを実際に役立てる: vc-diff

  • Emacs バックアップの問題

    • Emacs はデフォルトで、編集して保存するファイルのバックアップを定期的に作成する
    • このバックアップシステムは、通常 make-backup-files で無効にすべき面倒な機能として言及される
    • 機密ファイルがディスク上の別の場所にコピーされることへのセキュリティ上の懸念がありうる
    • それ以外では、問題は主に作業ディレクトリにバックアップが散らばることと、バックアップファイルを調べたり扱ったりしやすい UI が不足している点にある
    • backup-directory-alist, kept-old-versions, kept-new-versions などのユーザーオプションで、バックアップの場所と保持数を調整できる
    • 外部パッケージ backup-walker は、バックアップをタイムトラベルのようにたどるインターフェースを提供する
  • VC インターフェース拡張

    • Emacs 組み込みの VC パッケージは、バージョン管理されたファイルの過去バージョンを見るためのインターフェースを提供する
    • vc-diff はファイルを直前のバージョンまたは指定したバージョンと diff する
    • vc-ediff はファイルの直前のバージョンまたは指定したバージョンに対して Ediff を実行する
    • vc-revision-other-window は、直前または指定した過去バージョンを現在のファイルの横に表示する
    • このインターフェースは Git 限定ではないが、バージョン管理されていないファイルでは動作しない
    • 3 つの VC コマンドをオーバーロードすれば、未保存バッファ、バージョン管理ファイル、バージョン管理されていないファイルのバックアップをすべて「以前のバージョンと比較する」というモデルにまとめられる
    • 未保存ファイルでは vc-diffvc-ediff がバッファとファイルを比較する
    • バージョン管理ファイルでは、元の vc-diff, vc-ediff, vc-revision-other-window がそのまま実行される
    • バージョン管理されていないファイルでは、最新番号のバックアップ、または接頭引数で選んだ番号のバックアップと比較または表示する

apropos

  • describe-key である C-h k は、キー入力が呼び出す関数を直接確認できるため、非常に便利なヘルプキーである
  • 2 番目に学ぶヘルプ機能としては apropos が強力で、何を探せばよいかわからないときに Emacs の機能配置を把握する入口になる
  • apropos は単一のコマンドではなく、apropos-library, apropos-function, apropos-command, apropos-variable, apropos-user-option, apropos-documentation, info-apropos など、複数の専門検索コマンドのファミリーである
  • 例の設定では、これらのコマンドを C-h a 配下のキーマップに束ねて apropos を置き換えている
  • which-key のようなプロンプターがなくても、接頭キー C-h a の後に C-h を押せば使用可能なコマンド一覧を見られる
  • customize-apropos は、検索語に一致するオプション、フェイス、グループを集めて、専用の customize バッファを作ってくれる

find-func ツール: M-x find-function-on-key, M-x find-function

  • キーバインディングが気に入らない、または動作を知りたいとき、そのキーが呼び出すコマンドの定義へ移動すれば、その動作を読んだり修正したりできる
  • 一般的な流れは、describe-key または C-h k でキーが呼び出すコマンドを確認したあと、s を押してソースへ移動するというものだ
  • find-function-on-key はこの 2 番目のステップを省き、キーバインディングから関数ソースへ直接移動する
  • 例の設定では、help-mapC-h M-kfind-function-on-key にバインドしている

copy-from-above-commandduplicate-dwim

  • Emacs には最近、複数のユーザーがずっと以前から使っていたテキスト複製コマンドが追加された
  • copy-from-above-command は、現在の行の上にある最初の空でない行からテキストをコピーし、Vim の C-y に近い
  • duplicate-dwim は、現在の行またはアクティブリージョンを現在の行の下にコピーし、Vim の yy<N>p に近い
  • copy-from-above-command は接頭引数の分だけ上の行から文字をコピーするが、例の advice では C-u 接頭引数を「上の行全体をコピーしてコメントアウトする」動作に変えている
  • 数値接頭引数 C-<N> を使えば、従来どおり上から指定した数の文字をコピーできる
  • duplicate-dwim は複製後にカーソルを元の位置に置くか複製先に置くかを選ぶ必要があり、ユーザーオプションでこれを決められる
  • 例の設定では、duplicate-region-final-positionduplicate-line-final-position-1 にして、カーソルとリージョンが複製されたテキストへ移動するようにしている

キー入力履歴をマクロにする: M-x kmacro-edit-lossage

  • Emacs のキーボードマクロは、テキスト変換だけでなく、マウスクリックを含む Emacs のあらゆる操作シーケンスをキャプチャして再生できる
  • キーボードマクロは強力だが、記録開始前に反復可能性を見込む必要があり、エラーのない一般化された操作を行わなければならないため、認知負荷が高い
  • Vim の . コマンドや Emacs の dot-mode パッケージは、編集の繰り返しという問題を和らげるが、完全なキーボードマクロとは守備範囲が異なる
  • view-lossage(C-h l) は最近およそ 300 個のキー入力履歴を表示する
  • kmacro-edit-lossage は、このキー入力履歴からいつでもマクロを作れるようにする
  • lossage は実際に編集可能なので、マクロ作成時に新しいコマンドを記録の中へ入れられる
  • すでに定義したマクロは edit-kbd-macro(C-x C-k e) でより頻繁に編集できるが、kmacro-edit-lossage は、まれな状況で今しがた行った複雑な作業を繰り返し可能にするのに役立つ
  • 一般化可能なマクロを作るには、kbd-macro-query 呼び出しを lossage に入れる必要があることが多い

subword-mode, superword-mode, 単語文法

  • Emacs の単語ベースの移動・編集コマンドは、major mode ごとの syntax table を使っており、何を単語と見なすかはユーザーが調整できる
  • subword-mode では CamelCase 記号の各構成要素が単語として扱われる
  • 例として GtkWindowGtkWindowEmacsFrameClassEmacs, Frame, ClassNSGraphicsContextNS, Graphics, Context に分かれる
  • superword-mode では this_is_a_symbol のような snake_case 記号が 1 つの単語として扱われる
  • 実際の利用では *-sexp コマンドによるシンボル操作がすでによくサポートされているため、superword-modesubword-mode より有用性が低い
  • major mode の syntax table を数分いじるだけでも、構造的移動で感じる不便を減らせる
  • Lisp 系の文脈では、: を単語構成文字にすると、:foo のようなキーワードを backward-kill-word で扱いやすくなる
  • Org mode では =~ の区切り文字を単語構成文字として扱うように変更できる
  • 文字文法の指定方法は describe-syntax(C-h s) と modify-syntax-entry で確認できる

画像表示の操作

  • Emacs が画像を表示するほぼすべての場所で、画像の上にカーソルを置いて i を押すと表示を操作できる
  • Org mode の画像リンクプレビューや Elfeed の項目バッファ内の画像でも同じ操作を使える
  • i +i - は拡大・縮小に便利で、i r は画像を 90 度回転する
  • i c で画像を切り抜くこともでき、詳しいキーは M-x describe-keymap RET image-map で見られる
  • ブラウザーや他のアプリケーションで慣れた C-<wheel> ショートカットも使える
  • repeat-mode を使えば、最初の呼び出しの後は i 接頭なしで +, -, r だけを繰り返せる
  • この機能は画像上に置かれたキーマップとして提供され、別途有効化は不要である
  • 操作されるのはディスク上の画像ファイルそのものではなく、表示状態 だけである
  • ウェブページとレンダリング済み HTML バッファでは、z(shr-zoom-image) が画像を複数行の横方向スライスに分け、サイズを順に切り替えることで、大きな画像表示の限界を和らげる

すべてのテキストを表示: M-x visible-mode

  • Emacs はバッファ内のテキストを選択的に非表示にでき、この機能が Magit section、Outline mode、Org mode のような折りたたみ動作の基盤になっている
  • 折りたたみ機能を提供するモードは通常、折りたたみ状態を切り替えるキーバインドを用意しており、TAB がたいてい機能する
  • モードごとのキーバインドを覚えるのが難しい、あるいは使う頻度が十分高くない場合は、visible-mode ですべての隠されたテキストを表示できる
  • visible-mode はバッファ全体のテキスト不可視化を無効にし、再度実行すると以前の不可視状態を復元する
  • 動的な折りたたみ UI があるバッファでは、visible-mode が有効な間は画面表示が崩れて見えることがある
  • この機能は一時的な対処やデバッグツールに近いが、1つのコマンドでバッファ内のすべてのテキストを一様に表示できる

見えないテキストを無視: isearch-toggle-invisible

  • Isearch のような一部の Emacs コマンドは、デフォルトでテキスト不可視性を無視するため、実際の文書全体を簡単に検索できる
  • 表示されているバッファ状態がナビゲーションの手がかりとして機能している場合、折りたたまれたテキストを自動で露出する検索は期待どおりに動かないことがある
  • Isearch を検索よりもナビゲーションツールとして使うとき、折りたたまれた領域の一致箇所へ移動してしまうと問題になる
  • Isearch 中に M-s i にバインドされた isearch-toggle-invisible で、見えないテキストを検索するかどうかを切り替えられる
  • 例では Org 文書の最後の見出しへ移動しようとして zero を検索したが、折りたたまれた領域の一致へ飛んでしまい、再検索しながら M-s i を押して表示されているテキスト内の一致だけをたどる
  • Isearch の動作切り替えキーは、C-s の基本バインディングに対応する M-s キーマップの下にある

ルーラー: M-x ruler-mode

  • Emacs には過去の WYSIWYG ワードプロセッシング機能の名残として、center-* コマンドのような機能が残っている
  • center-* コマンドは行、段落、リージョンを fill-column 基準で中央揃えし、コードの装飾コメントのような用途に使える
  • 表示 margin と fringe の幅は多くの機能を詰め込める画面領域だが、表示 margin の幅を直接変える作業は簡単ではない
  • set-left-marginset-right-margin は表示 margin の幅を変えるコマンドではなく、実際のバッファテキストを字下げするという点で center 系コマンドのように動作する
  • 表示 margin の設定には直接的なコマンドがなく、ウィンドウが再表示されるまで効果が反映されないという問題もある
  • ruler-mode を有効にすると、header-line 上のツールチップで使い方を確認できる
  • S-<mouse-1>S-<mouse-3> でバッファの左・右 margin を設定できる
  • <mouse-2> のドラッグで fill-column も設定できる
  • プリセット幅を切り替えるのではなく、その場で margin を変えたいなら、visual-fill-columnolivetti のようなパッケージより ruler-mode のほうが使いやすいかもしれない

テキストを再充填: M-x refill-mode

  • Emacs はテキストを整形するためのさまざまな fill-* コマンドと、入力中の改行を処理する auto-fill-mode を提供している
  • auto-fill-mode は Emacs チュートリアルの早い段階で扱われるほど、テキスト整形を重要な編集機能として位置づけている
  • auto-fill-mode は実際には完全自動ではなく、現在の行だけを折り返し、貼り付けなどで生じた前の段落の乱れは手動で直す必要がある
  • refill-mode は文書が fill-column に合うよう維持する、Emacs の実質的な自動テキスト整形機能である
  • M-x refill-mode を実行するとその動作を使える

すべてのウィンドウを一緒にスクロール: M-x scroll-all-mode

  • scroll-other-window は選択されていない別ウィンドウを切り替えずにスクロールでき、現在のウィンドウで作業しながら次のウィンドウの参考資料を見るときに便利である
  • follow-mode は 1 つのバッファを複数のウィンドウにまたがって連続表示する機能である
  • scroll-all-mode はあまり知られていないが、フレーム内のすべてのウィンドウを同時にスクロールする
  • 同期させて見比べたいバッファを確認するときに便利で、例では Ediff セッションに入らずにファイルの 2 つの版を目視で比較するのに使われている
  • 例の流れは、現在のファイルの特定の過去バックアップを vc-revision-other-window で開き、scroll-all-mode を有効にしたあと、普段どおりスクロールするとすべてのウィンドウが同時に動くというものだ
  • 他ウィンドウのスクロールと master-mode

    • 画面にウィンドウが 2 つより多くあり、スクロールしたいウィンドウが Emacs の選ぶ next-window でない場合、問題が起きることがある
    • 組み込みの master-mode は、別バッファからスクロールできるバッファをあらかじめ指定したり、その場で指定したりできるようにする
    • より即効性のある方法は、スクロール対象ウィンドウを見つける戦略を設定することだ
    • (setq other-window-scroll-default #'get-lru-window) は常に最も長く使われていないウィンドウをスクロールする
    • 参考資料が入っていて、ほとんど選択しないウィンドウをスクロールしたいときにこの方法は有効である
    • 頻繁に編集する 2 つのウィンドウが複数ウィンドウの中にあるなら、最も最近使ったウィンドウを他ウィンドウスクロールの対象にするラムダ関数を設定できる
    • こうした設定の組み合わせは、scroll-other-window が意図したウィンドウをスクロールする助けになる

終了拒否: M-x emacs-lock-mode

  • 未保存のファイルがあると、Emacs は各ファイルをどう処理するかに答えるまで終了を拒否する
  • emacs-lock-mode はこの考え方を拡張し、ユーザーが任意のバッファをロックできるようにする
  • ロックが解除されるまで、そのバッファは kill を拒否し、Buffer "*scratch*" is locked and cannot be killed のようなメッセージを出す
  • ロックされたバッファがあると Emacs も終了を拒否し、Emacs cannot exit because buffer "*scratch*" is locked のようなメッセージを出す
  • ファイルを訪問していないバッファに入っている情報を誤って失わないようにしたり、そのバッファに作業が残っていることを思い出させたりするのに役立つ
  • Org-capture 以後、前者の問題はまれになったが、shell・compilation バッファ、Web サイト、その他の特殊アプリケーションの出力や状態を失わないための用途としては依然有用である

フレームを復元: M-x undelete-frame-mode, M-x undelete-frame

  • 丹念に構成した Emacs フレームを誤って閉じたとき、undelete-frame で復元できる
  • この機能を使うには undelete-frame-mode を有効にしておく必要がある
  • 組み込みの winnertab-bar-history がウィンドウに対して提供する機能を、フレームを対象に行う
  • undelete-frame-mode を Emacs と一緒に有効にしておけば、フレームを閉じることをそれほど心配しなくて済む
  • 削除されたフレームは最大 16 個まで復元できる

残った機能と除外された機能

  • 過去 6 年間で出会った機能のうち、2026 年の Emacs 利用の現実の中で生き残った機能は 20 個である
  • 偶然見つけた多くの Emacs ライブラリは、一般ユーザーの要求に対する安定した解決策というより、考古学的な興味のほうが大きかった
  • allout-mode は Org mode に似た平行世界の outline 管理機能で、Org の speed-key やサブツリー単位の暗号化のような機能を備えている
  • shadowfile は Emacs 内で unison を実装するが、その有用性には疑問がある
  • double-modequail に先行する、キー変換ベースの非キーボード文字入力方式である
  • bs ライブラリは、より賢い list-buffers コマンドを作ろうとした試みだったが、ibuffer のほうが優れているため使う理由がなくなった
  • electric-pair-mode によるリージョンを区切り文字で囲む機能のように、表面的には有用でも扱いの難しさに見合う価値が低い機能は除外された
  • この種の用途には wrap-regionsmartparensembrace のような外部パッケージのほうが優れている
  • appt のような Org および Org 周辺の組み込みライブラリは興味深いが、別記事で扱うに値するほど範囲が広い
  • thunk のように主に Elisp 開発者に役立つライブラリも、別途整理が必要である
  • Emacs に同梱される lisp ディレクトリはそれほど大きくないが、有用な標準機能は今後も発見の余地がある

1件のコメント

 
GN⁺ 4 시간 전
Lobste.rsの意見
  • find-fileC-x C-f)で *foo*.txt のように ワイルドカードで複数ファイル を開くのはたいていミスなので、ワイルドカードを使ったら find-file がすぐ dired を開くように find-file-noselectadvice-add を仕込んでいる
    file-expand-wildcards の結果が2件以上のときは dired-noselect に渡し、そうでなければ元の find-file-noselect を呼ぶ方式

  • ruler-mode は本当に面白い。Emacs にこんな WYSIWYG機能 があるとはまったく知らなかったし、Emacs は本当に変わっていて楽しいソフトウェアだ

  • 普通の Emacs だけを使いながら、ほとんど見尽くしたと思っていたのに、まだ発見できるものがずっと多かった。ruler-mode は文章を書く用途としてかなり良い

    • こうした機能が Emacs 自体に入っているのは驚きだ。Emacs はこういうものを作れる elisp API だけを提供していると思いがちだが、標準ツールをかなり見落としていた
      以前は Magit をずっと多用していたが、今は組み込みの vc-modediff ツールに移行しており、どちらもとてもよく動くので満足している
  • こういう記事は好きだ。Emacs や Neovim のような複雑でカスタマイズ可能なエディタを使うとき、標準のエディタが何をできるのか理解する前に、肥大化したディストリビューション を先に入れてしまい、あまりにも早く走り出してしまうことが多い
    時間があるなら、マニュアルを読んで最初から自分で設定を積み上げていく過程はかなりやりがいがある。あまり知られていない Emacs の関数に finder-list-keywords があり、実行すると見つけにくい Emacs の機能を探せるメニューが出てくる。たとえば、組み込みゲームが 24個 もあるのを知っていただろうか?