helm(anything)の挙動に関するメモ

helm-gtags-selectを実装してみた - Life is very short


で述べた。helm(anything)の気になる挙動についてのメモ

概要

helm(anything)の actionから、もう一回 helm(anything)を実行するとき
アクションが複数あるときの挙動がおかしい

ソース

サンプルとして以下のようなものを用意しました。

(setq test-source-fruit
      '((name . "fruit")
        (candidates . ("apple" "melon" "orange"))
        (action . (lambda (c)
                    (message (format "%s" c))))))

(setq test-source-vegetable
      '((name . "vegetable")
        (candidates . ("tomato" "potato" "onion"))
        (action . (lambda (c)
                    (message (format "%s" c))))))

(defun test1 ()
  (helm :sources '(test-source-fruit) :buffer "*test*"))

(defun test2 ()
  (helm-run-after-quit
   (lambda ()
     (helm :sources '(test-source-vegetable) :buffer "*test*"))))

(setq test-source
      '((name . "select")
        (candidates . ("candidate1" "candidate2"))
        (action . (("TEST1" . (lambda (c) (test1)))
                   ("TEST2" . (lambda (c) (test2)))))))

(setq test-source2
      '((name . "select")
        (candidates . ("candidate1" "candidate2"))
        (action . (lambda (c) (test1)))))


参考に anything版も載せます。

(add-to-list 'load-path "~/.emacs.d/auto-install")
(require 'anything)

(setq test-source-fruit
      '((name . "fruit")
        (candidates . ("apple" "melon" "orange"))
        (action . (lambda (c)
                    (message (format "%s" c))))))

(setq test-source-vegetable
      '((name . "vegetable")
        (candidates . ("tomato" "potato" "onion"))
        (action . (lambda (c)
                    (message (format "%s" c))))))

(defun test1 ()
  (anything :sources '(test-source-fruit) :buffer "*test*"))

(defun test2 ()
  (run-at-time 0 nil
   (lambda ()
     (anything :sources '(test-source-vegetable) :buffer "*test*"))))

(setq test-source
      '((name . "select")
        (candidates . ("candidate1" "candidate2"))
        (action . (("TEST1" . (lambda (c) (test1)))
                   ("TEST2" . (lambda (c) (test2)))))))

(setq test-source2
      '((name . "select")
        (candidates . ("candidate1" "candidate2"))
        (action . (lambda (c) (test1)))))

テスト

以下を実行します。

(helm :sources '(test-source) :buffer (get-buffer-create "*test*"))


このとき、候補選択バッファで "TAB"を押し、アクション "TEST1"を実行すると
test1関数が終了しません(何度も呼ばれている??)。ただしデフォルトアクションと
して実行した場合("TAB"を押さず、RETURN等でいきなり選択)は問題が起きません。


またアクションが以下のようなアクションが一つしかない場合(test-source2)の
場合も同様に問題がおきません。

(helm :sources '(test-source2) :buffer (get-buffer-create "*test*"))


アクション "TEST2"は結果として timerを使って関数を実行するためか
問題ありません。なので helm-gtags-selectはアクション "TEST2"のような
実装になっています。

おわりに

anything版でも再現するのでもともとあった問題なのかなと
思います。actionを選択して実行するあたりが疑わしいので
そのあたりからあたっていこうかと思います。