avyでmigemoりたいのに……

Qiitaのavyならなんでもできるを読んで、「そういえばavyって真剣に試してみたことないなあ」と思い、 書いてある通りにやってみたらわりとよい感じだった。

だが、日本語が多い局面だとavyで飛べない事が多い。こういう時はmigemoが使いたくなる。で、調べてみると avy-migemoがあるのだが、どうもissueなど見ていると最近はメンテされてない様子。

別にそんな凝ったことをしたいわけじゃないんだよ、ということで再度調べると avy で migemo る (avy-migemo を使わずに)が見つかる。これこそ欲しかったものだ。そのままいただこう。

……しかしavy-goto-migemo-timerを実行して何か1文字入力するとout of range(だったと思う)が出てうまく動かなかった。

原因

migemo-get-patternが、入力長さがmigemo-isearch-min-length未満の時に""を返すのが原因である。私の設定だとmigemo-isearch-min-lengthが2なので、1文字入れると""を食らってavy–read-candidatesがエラーを返すのである。

じゃあこの時だけ1にしてあげようと、avy-goto-migemo-timerの中のletでmigemo-isearch-min-lengthを1にしてみると、だいたい問題ないのだが、ふとcを入力すると"too long ほげほげ"1とか言われしまって幸せになれなかった。2

そもそも、本来のmigemoの動作だってmigemo-isearch-min-lengthが未満の時は、引数をそのまま返したほうが幸せになるんじゃないの?とふとと思ったので、下記のようなadviceを入れて対策とした。

  (defun my/migemo-get-pattern-advice (func word)
    (let ((ret (funcall func word)))
      (if (string-equal ret "")
	  word ret)))
  (advice-add 'migemo-get-pattern :around #'my/migemo-get-pattern-advice)

migemo-isearchとavy-goto-migemo-char以外の用途で何か副作用があるかもしれないが、まあ、そう悪い挙動にはならない気もする。


1

何が出たのかメモってなかった。

2

そもそも1文字の時にmigemoが動いてもいらんものがひっかかってあまり嬉しくなかったからmigemo-isearch-min-lengthを1にしているわけで、まあ当然といえば当然である。