31025


趣味で現在、エンターキーを叩くと音が鳴るように、自分のEmacsを拡張しています。そのときに、以下のようなEmacs Lispを書いています:

[code]

     (defun java-button ()
        (interactive)
        (progn
          (start-process
           "java-button-process"
           nil
           "aplay"
           (concat (getenv "HOME") "/Archive/" "java.wav"))
          ;; (newline) ???
          ))
    
      (global-set-key [return] 'java-button)
    
[/code]

このとき、`global-set-key`の段階で、`java-
button`という関数に上書きされてしまうため、元々ある`return`(エンターキー)の「バッファでのメニュー決定」などの機能が無くなってしまいます。

`newline`を使えばいいのかなとも思ったのですが、`Readonly-
buffer`のエラーとなってしまい、そのバッファのテキスト内容を編集しようとしてしまいます。

この場合、`java-
button`という関数(?)から何を呼び出すのが適切なのでしょうか。それとも本来はこのように書くべきではなく、他の上書きしないような回避方法があるのでしょうか?


CC BY-SA 3.0
2016-12-08T13:41:29.603
31021
2020-05-16T22:58:15.713
2020-05-16T22:58:15.713
19110
939
question
emacs elisp
returnを拡張した上で、その機能を呼び出す方法


Enterを押したときに限らず、newlineの実行時でよいなら次のような感じでどうでしょうか。

[code]

    (defun advice-java-button (proc string)
      (start-process
       "java-button-process"
       nil
       "aplay"
       (concat (getenv "HOME") "/Archive/" "java.wav")))
    (advice-add 'newline :before #'advice-java-button)
    
[/code]


CC BY-SA 3.0
2016-12-08T14:57:21.863
31024
2016-12-08T14:57:21.863
19855
31021
answer


キー入力を監視するフック変数 `post-self-insert-hook` (または `post-command-hook`) を利用して、その中で
`return` キーが押された場合に音を鳴らすのがよいかと思います。  
この方法であれば元のキー定義を上書きする必要はありません。

[code]

    (require 'cl-lib)
    
    (defun user/play-sound-maybe ()
      (cl-case last-input-event
        ((?\C-m return)
         (java-button))))
    
    (add-hook 'post-self-insert-hook 'user/play-sound-maybe)
    
[/code]

関数名は適当に置き換えてください。


CC BY-SA 3.0
2016-12-08T16:41:21.330
31025
2016-12-08T16:41:21.330
2391
31021
answer