avy-migemoを使わずにivy/swiperをmigemo化した際に遭遇したエラーの解決と新たなminor-modeの提案

はじめに

avy-migemoを使わずにswiperやswiper-isearchをmigemo化することに成功した偉大な先人がいる:

これらの記事では、ivyに食わせるmigemo的な正規表現を生成する関数を独自に定義している。
そして、これらの設定を適用したのち、swiper-isearchを実行したところ、以下のエラーに遭遇した。

Error in post-command-hook (ivy--queue-exhibit): (invalid-regexp "Unmatched ) or \\)")

この原因は以下の設定をしていたことにあった:

 (setq search-default-mode #'char-fold-to-regexp)

そこで以下のように修正することで、エラーは解消され、件のmigemo化が実現できた。

 (setq search-default-mode nil)

毎回、search-default-modeを評価しなおすのも手間なので、オリジナルのminor-modeを作ることにした。
このminor-modeの紹介が本記事の主旨である。

作成したminor-modeおよび使い方

以下のivy-with-migemo-modeである。

コードを表示する

本minor-modeを有効化することで、swiperやswiper-isearchでmigemoが使えるようになる。すなわち、有効化されている間はsearch-default-modenilに設定される。

(require 'ivy-with-migemo)
(setq ivy-with-migemo-enable-command
      '(swiper swiper-isearch))
(global-ivy-with-migemo-mode 1)

上記、ivy-with-migemo-enable-commandという変数が、migemoを使う対象となるコマンドを格納するリストである。counsel-recentfを対象に追加する場合は、以下の設定にする。

(setq ivy-with-migemo-enable-command
      '(swiper
        swiper-isearch
        counsel-recentf))

無効化する場合は、C-u -1 M-x global-ivy-with-migemo-modeとすればよい。もしくは

(global-ivy-with-migemo-mode -1)

を評価する。バッファローカルで有効・無効を切り替える場合は、global-ivy-with-migemo-modeによる有効化を使わず、各バッファごとにM-x ivy-with-migemo-modeとする。

もしcounsel-agやcounsel-rgも併せて使う場合は以下の設定を試してみるとよい。ただしripgrepは最新版のソースコードをダウンロードしてコンパイル/インストールしておくこと。複数ファイルの串刺し検索がmigemoで実現できるので、とても快適である。

(require 'ivy-with-migemo)
(setq ivy-with-migemo-enable-command
      '(swiper swiper-isearch counsel-rg counsel-ag))
(setq migemo-options '("--quiet" "--nonewline" "--emacs"))
(migemo-kill)
(migemo-init)
(global-ivy-with-migemo-mode 1)

補足

ivyインターフェイスを持つコマンドに対してmigemoを有効化するためのパッケージとしては、すでにivy-migemoが存在する。

このパッケージも同様の機能を提供するが、search-default-modeの設定には踏み込んでいない。さらにmigemo化のON/OFFには専用のtoggleコマンドを用意しており、minor-modeは用意されていない点も異なる。もっとも、toggleコマンド自体は良いインターフェイスであると思う。またivy-migemoではfuzzyマッチングも利用でき、ユーザによっては嬉しい点である。以上がivy-migemoivy-with-migemo-modeとの違いである。

LaTeXソースを保存と同時にコンパイルしPDFを作成するための設定(smart-compile.elとlatexmk利用)

以下の記事にて、表題に関する設定が公開されていた。「自動コンパイル」のところである。

銭谷誠司氏のサイトにて公開されているsmart-compile.elを用いている。上記の記事ではリンク切れであったが、現在はgithubにて継続的に開発が続いている。

smart-compile.el自体のコンセプトは明解で, さまざまなソースファイルと対応するコンパイルコマンドをひもづけるためのインターフェイスを提供する。これをLaTeXソースのコンパイルに応用したのが上記の設定である。

現在はオリジナルから多少変更を加えて以下の設定を利用している(AUCTeX利用)。latexmkをバックグラウンドで走らせている。

;; 保存と同時にlatexmkを走らせる
(eval-when-compile (require 'smart-compile))
(declare-function smart-compile-string "smart-compile")
(defun run-latexmk ()
  (when (string-match ".tex$" (buffer-file-name))
    (let ((buf (get-buffer "*Background TeX proccess*")))
      (if (bufferp buf) (kill-buffer buf)) ) ;; flush previous log
    (require 'smart-compile) ;; for smart-compile-string
    (start-process-shell-command
     "Background TeX" "*Background TeX proccess*"
     (smart-compile-string "latexmk %f"))))
(define-minor-mode AutoTeX-mode
  "Mode for compiling latex sources and creating PDFs after saving."
  :global nil
  :lighter " Auto"
  (if AutoTeX-mode
      (add-hook 'after-save-hook 'run-latexmk t t)
    (remove-hook 'after-save-hook 'run-latexmk t)))

(add-hook 'TeX-mode-hook #'(lambda () (AutoTeX-mode 1)))

after-save-hookに引っ掛けることで、保存と同時にlatexmkを走らせてLaTeXソースをコンパイルしPDFを生成する。smart-compile-stringにより実行される、latexmkへのオプション引数にはカスタマイズの余地はある。

ちなみにlatexmkの設定ファイル(.latexmkrc)の設定例は以下の通りである。

#!/usr/bin/env perl

$pdf_mode = 3;

$latex  = "uplatex -synctex=1 -halt-on-error -interaction=nonstopmode %O %S";
$dvipdf = 'dvipdfmx %O -o %D %S';
$bibtex = 'upbibtex %O %S';
$makeindex = 'mendex %O -o %D %S';
$max_repeat = 5;

個人的にpdf-toolsを用いているため、外部アプリによるプレビュー関連の設定はしていない。もしプレビューワの設定をするならば、$pdf_previewerという変数に、プレビューワ起動に必要なコマンドラインを設定する。例えば

$pdf_previewer = 'open -a /Applications/Preview.app';

$pdf_previewer = 'evince %O %S';

などである。そのうえで上記のrun-latexmk関数において以下の修正を施し、latexmkに-pvオプションをつけることで、プレビューワを起動する。

(smart-compile-string "latexmk -pv %f")

マウスホイールによる連続スクロールのスピードを調節 on Emacs

マウスホイールにより連続スクロールすると画面がどんどん飛んでしまうので、それを抑制する設定。

(global-set-key [mouse-5] '(lambda () "" (interactive) (scroll-up 1)))
(global-set-key [mouse-4] '(lambda () "" (interactive) (scroll-down 1)))
(global-set-key [double-mouse-5] '(lambda () "" (interactive) (scroll-up 1)))
(global-set-key [double-mouse-4] '(lambda () "" (interactive) (scroll-down 1)))
(global-set-key [triple-mouse-5] '(lambda () "" (interactive) (scroll-up 2)))
(global-set-key [triple-mouse-4] '(lambda () "" (interactive) (scroll-down 2)))
(global-set-key [wheel-down] '(lambda () "" (interactive) (scroll-up 1)))
(global-set-key [wheel-up] '(lambda () "" (interactive) (scroll-down 1)))
(global-set-key [double-wheel-down] '(lambda () "" (interactive) (scroll-up 1)))
(global-set-key [double-wheel-up] '(lambda () "" (interactive) (scroll-down 1)))
(global-set-key [triple-wheel-down] '(lambda () "" (interactive) (scroll-up 2)))
(global-set-key [triple-wheel-up] '(lambda () "" (interactive) (scroll-down 2)))

summarye.elの設定 改訂版

かつてsummarye.elの設定に関する記事を書いたことがあるが、今回いくつか見直した。

display-line-numbers-modeによる行番号の表示を止めた。これをしないと行番号がsummarye由来ものと合わせて2重に行番号が表示されるからである。またサマリがポップアップする位置とサイズをshackleにより制御した。つねにframeの半分以上を占拠してポップアップするsummaryeデフォルトの挙動が不満だったからである。

(eval-when-compile (require 'summarye)
                   (require 'view)
                   (require 'shackle))
(declare-function View-quit "view")

;; fで当該バッファのサマリ位置にジャンプ
;; SPCでカーソル位置のサマリをプレビュー
;; nでプレビューしながら次のサマリを表示
;; bでプレビューしながら前のサマリを表示
;; dでサマリ一覧から削除
;; gでリロード、削除したサマリも復活
;; mでマーク

(autoload 'se/make-summary-buffer "summarye" nil t)
(autoload 'socuur "summarye" nil t)

(define-key help-map "M" 'se/make-summary-buffer)

(defun se/quit-summary-item ()
  "Quit summary."
  (interactive)
  (view-mode 1)
  (View-quit))

(defvar summary-edit-summary-mode-hook nil)
(add-hook 'summary-edit-summary-mode-hook
          #'(lambda ()
              ;; 行番号の表示を止める
              (display-line-numbers-mode -1)

              (define-key summary-edit-mode-map (kbd "q") 'se/quit-summary-item)))

(with-eval-after-load "shackle"
  (add-to-list 'shackle-rules
               '("^function-in-.*" :regexp t :align right :ratio 0.3))
  (add-to-list 'shackle-rules
               '("^Items-in-.*" :regexp t :align right :ratio 0.3)))

バイトコンパイル時の警告を抑制した修正版summarye.elのコードはこちらから。

EmacsにおけるLaTeX執筆環境構築(2)LaTeXのlanguage serverであるtexlabをeglotから使う

はじめに

LaTeXにもlanguage serverがあると聞いて、早速インストールを試してみたときの記録。そのlanguage serverとはtexlabである。これをEglotによりEmacs上から使うのが目的である。

実行環境

手順

texlabの公式を見ると、Rustをインストールせよ、とのことなのでインストール。

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

続いてtexlabのマスターブランチをcloneする(cloneの場所はお好みで)。

 git clone https://github.com/latex-lsp/texlab.git

texlab/srcにcdする。

 cd texlab/src

ビルドする。

cargo build --release

texlab/target/release/texlabが目当てのバイナリである。これをPATHの通った場所に置く(例えば/usr/local/bin)。

コピーが終わったら余分なものは消しておくとディスクスペースの節約になる。ただしtargetフォルダもすべて消えるので注意。

cargo clean

最初からcloneしない方法もある。このあたりはお好みで。

cargo install --git https://github.com/latex-lsp/texlab.git --locked

Emacsの設定

Emacsでlanguage serverを扱うためにEglotを使うことにする。EglotはEmacsのパッケージシステムからインストールできる。

M-x package-install RET eglot RET

Eglotの設定は以下。Eglotはデフォルトでdigestifという別のtex用language serverの設定が入っているので、最初にそれを取り除きtexlabの設定で置き換える。

(require 'eglot)

;; AUCTeXで使う設定
(add-hook 'TeX-mode-hook 'eglot-ensure)
;; digestifの設定を取り除く
(delete (assoc '(tex-mode context-mode texinfo-mode bibtex-mode)
               eglot-server-programs) eglot-server-programs)
;; texlabの設定を追加する
(add-to-list 'eglot-server-programs
             '((latex-mode tex-mode context-mode
                           texinfo-mode bibtex-mode) . ("texlab")))

またLaTeXの編集モードにはAUCTeXを使っている。YaTeXユーザならばyatex-mode-hookにeglot-ensureを引っ掛ければよいだろう。

EmacsにおけるLaTeX執筆環境構築(1)AUCTeXの設定と使い方について

Emacs上でLaTeXを編集するときに便利なパッケージの一つとしてAUCTeXが知られている。本記事は設定と使い方を備忘録として残すのが主旨である。

TeXのインストール

TeX Wikiを参考にするとよい。Emacs上で執筆するならばscheme-small (BasicTeX)とcollection-langjapaneseをインストールするのが良いだろう。

AUCTeXのインストール

M-x package-install RET auctex RET

とするか、もしくは

M-x list-packages RET

からauctexを選択する。

設定

Emacsの設定

日本語文章の執筆を前提とする。

コードを表示する
gist.github.com

latexmkの設定

もしlatexmkを利用する場合は、.latexmkrcを設定して~/.latexmkrcなどに保存したうえで実行するのが良い。以下の.latexmkrcはdviを経由するタイプである。

uplatexを用いる場合は以下の設定を参考に。

コードを表示する

#!/usr/bin/env perl

$latex  = "uplatex -halt-on-error -interaction=nonstopmode -file-line-error %O %S";
$bibtex = 'upbibtex %O %S';
$biber = 'biber --bblencoding=utf8 -u -U --output_safechars %O %S';
$makeindex = 'mendex %O -o %D %S';
$dvipdf = 'dvipdfmx %O -o %D %S';

$pdf_mode = 3;
$max_repeat = 5;

platexを用いる場合は以下の設定を参考に。

コードを表示する

#!/usr/bin/env perl

$latex  = "platex -kanji=utf8 -halt-on-error -interaction=nonstopmode -file-line-error %O %S";
$bibtex = 'pbibtex -kanji=utf8 %O %S';
$biber = 'biber --bblencoding=utf8 -u -U --output_safechars %O %S';
$makeindex = 'mendex %O -o %D %S';
$dvipdf = 'dvipdfmx %O -o %D %S';

$pdf_mode = 3;
$max_repeat = 5;

もしtexから直接pdfを生成する場合の設定例は以下。$pdf_modeを1にすることが重要である。

コードを表示する

#!/usr/bin/env perl

# texからpdfを直接生成 (pdflatex)
$pdf_mode = 1;

$bibtex = 'upbibtex %O %S';
$makeindex = 'umendex %O -o %D %S';
$pdf_previewer = "evince %S";
$max_repeat = 5;


ただし日本語文章でpdflatexを通す場合はBXjscls パッケージなどを併用するとよい。

\documentclass[pdflatex, ja=standard]{bxjsarticle}  %ほかはa4paperなどがオプションに入る

設定の参考にしたサイト

解説と補足

AUCTeXの公式情報

ホームページは以下のサイトである。
www.gnu.org

また最新のソースコードは以下のサイトから確認できる。

AUCTeXの設定の情報源

AUCTeX Wikiに多くの情報が集約されており、まずはここに書いてある設定を参考にしながら自身の設定ファイルに追記していくのがよい。

使い方

コンパイルからPDF表示まで

AUCTeX Wikiを参考に、よく使うものをテーブルにリストする。

  • コマンド起動
入力 機能
C-c C-c コマンドの選択メニューを表示(処理対象範囲:文書全体)
C-c C-r コマンドの選択メニューを表示(処理対象範囲:リージョン)
C-c C-b コマンドの選択メニューを表示(処理対象範囲:カレントバッファ)

C-c C-cの「文書全体」とは、例えばファイル分割している場合にそれらをすべて取り込む形を指す。C-c C-bはカレントバッファ(=現在編集中のバッファ)のみが処理対象となる。

  • コマンド例(C-c C-cの場合)
メニュー 入力例 機能
LaTeX C-c C-c latex 指定された TeX エンジン (TeX-engine)でタイプセット
BibTeX C-c C-c bibtex bibtex の実行(文献データベースの更新)
Dvipdfmx C-c C-c dvipdfmx dvipdfmx の実行
View C-c C-c view プレビュー
Clean C-c C-c clean 中間ファイル (.log .aux etc...) の削除
Clean All C-c C-c clean all 中間ファイル及び dvi ps pdf の削除

上記はC-c C-c経由でコマンドを発動した場合の例である。個々のコマンドの機能はC-c C-rC-c C-bでも同じである。

  • その他
入力 機能
C-c C-v プレビューの起動(Viewのショートカット起動)
C-c C-a タイプセット、(文献DB更新、)dvipdfmx、プレビューを順に実行
C-c C-l タイプセット処理を表示

基本となるのは

1. "LaTeX"によりタイプセットコンパイル)→texソースからdviファイルを生成
2. "Dvipdfmx"によりdviからpdfを生成
3. "View"によりpdfを開く

という一連の流れである。文章中で参考文献を引用している場合は1と2の間にBibTeXが入る。

1. "LaTeX"によりタイプセット
2. "BiBTeX"により文献データベースを更新 →bibファイルからbblファイルを生成
3. "LaTeX"によりもう一度タイプセットtexソースからdviファイルを生成
4. "Dvipdfmx"によりdviからpdfを生成
5. "View"によりpdfを開く

これらはC-c C-aの一発で済むので便利である。

編集中に便利なキーバインドスニペット

以下は多用するキーバインドである。

入力 機能
C-c C-e LaTeX環境(\begin{...} \end{....})を選択的に挿入
C-c C-s セクション関係(\section{}や\subsection)を選択的に挿入
C-c ] LaTeX環境を閉じる(\end{...} をのみ挿入)
C-c ; リージョンをコメントアウト
C-c % カーソル最寄りの段落をコメントアウト
C-c * カーソルに最寄りのセクション関係をマーク
C-c . カーソルに最寄りのLaTeX環境をマーク


yasnippetユーザならば、多くのスニペットLaTeX用に提供されるので、使ってみるとよい。上記のキーバインドがあれば十分かもしれないが、どちらも便利なので併用している。

latexmkについて

latexmkを用いて PDF をコマンド一つで生成するという主旨の記事がある。同記事では"auctex-latexmk"というパッケージが件の機能を提供するものとして紹介されている。本記事で紹介している設定ではauctex-latexmk関連をコメントアウトしてある。利用はお好みで。

日本語対応のエンジンの例としてLuaTeX-jaが知られている。LuaTeX-jaを用いるとpdflatexでなくともtexからpdfを直接生成できるので便利に使える。ほか、LuaTeXを用いるメリットとして、フォント周りの設定がしやすいことが挙げられる。詳細は別の記事で紹介する予定である。

latexmkを保存と同時に走らせる場合は以下の記事で紹介した設定を追記する。

インラインプレビューについて

AUCTeXでは数式や画像のインラインプレビューが可能である。対象となる数式はpng画像に変換されてEmacs上でプレビューされる。以下は主なキーバインドである。C-c C-p(pはpreviewの意味)から始まるので比較的覚えやすい。

入力 機能
C-c C-p C-d マスタ文書のプレビュー開始
C-c C-p C-c C-d 文書全体のプレビュー終了
C-c C-p C-b カレントバッファのプレビュー開始
C-c C-p C-c C-b カレントバッファのプレビュー終了
C-c C-p C-p ポイント位置のプレビュー開始
C-c C-p C-c C-p ポイント位置のプレビュー終了
C-c C-p C-e LaTeX環境で囲まれた部分のプレビュー開始
C-c C-p C-c C-e LaTeX環境で囲まれた部分のプレビュー終了
C-c C-p C-s セクションのプレビュー開始
C-c C-p C-c C-s セクションのプレビュー終了

Emacs27で"Package cl is deprecated"を抑制する方法

起動直後

early-init.elの先頭に以下を記述する。

(setq byte-compile-warnings '(cl-functions))

設定ファイルなどをバイトコンパイルするとき

以下の設定を追記する。

(eval-when-compile (setq byte-compile-warnings '(cl-functions)))