Emacs keystroke representation confusion

夙愿已清 提交于 2019-12-30 10:55:44

问题


I usually define new keybindings in emacs using

"C-x (" --> (command kmacro-start-macro)
"C-x )" --> (kmacro-end-macro)
(name-last-kbd-macro)
(insert-kbd-macro)
But the code it generates looks different than the code I read and modify in various major / minor modes and other emacs utilities.
I recently came across this blog post that clears up some of my confusion.

Is there an emacs tool that simplifies keystroke representation ? Ideally one that translates from ahk keystroke notation to any sane emacs keystroke notation.

Edit: some other reading to clear my confusion: keybinding guide by Jari Aalto.


回答1:


The sequence you specify does simplify the keystroke representation. What you're left with is essentially the set of keystrokes you typed.

It's already been asked if you can convert an emacs macro into elisp.

Perhaps you're asking if it could be made more human readable? If so, then you're in luck.

You can use the kbd macro to convert the printed representation of keystrokes into the equivalent vector of keystrokes.

For example, the sequence which results in a query-replace of 3 with tj looks like: M-% 3 RET tj RET !

Well, you can manually set that up with:

(fset 'my-hand-crafted-kbd-macro (kbd "M-% 3 RET tj RET !"))

And this piece of elisp code should generate the above for you if you have named your macro 'my-hand-crafted-kbd-macro:

(defun insert-pretty-kbd-macro (macro-name)
  (interactive (list (intern (completing-read
                              "Insert kbd macro (name): "
                              obarray
                              (lambda (elt)
                                (and (fboundp elt)
                                     (or (stringp (symbol-function elt))
                                         (vectorp (symbol-function elt))
                                         (get elt 'kmacro))))
                              t))))
  (interactive)
  (insert "(fset '")
  (prin1 macro-name (current-buffer))
  (insert "\n   (kbd \"")
  (insert (key-description (symbol-function macro-name)))
  (insert "\"))\n"))

To get this to happen automatically when you finish a keyboard macro C-x ), you can use this advice:

(defadvice kmacro-end-macro (after kmacro-end-macro-name-it-and-insert activate)
  "user wants to insert elisp to reproduce the last kbd macro"
  (let ((name (read-string "Name for this kbd macro: ")))
    (insert "(fset '")
    (insert name)
    (insert "\n   (kbd \"")
    (insert (key-description last-kbd-macro))
    (insert "\"))\n")))



回答2:


Thanks Trey.
I combined name-last-kbd-macro with your insert-pretty-kbd-macro into name-and-insert-last-kbd-macro

(defun name-and-insert-last-kbd-macro (macro-name)
  (interactive (list (intern (completing-read
                              "Insert kbd macro (name): "
                              obarray
                              t))))
  (interactive)
  (insert "(fset '")
  (prin1 macro-name (current-buffer))
  (insert "\n   (kbd \"")
  (fset symbol last-kbd-macro)
  (insert (key-description (symbol-function symbol)))
  (insert "\"))\n"))
now, I can start defining a macro with f8,
end and test / run it with f9
, and name and insert it with f10:
(global-set-key [f8] 'kmacro-start-macro)
(global-set-key [f9] 'kmacro-end-and-call-macro)
(global-set-key [f10] 'name-and-insert-last-kbd-macro)
(global-set-key [f12] 'menu-bar-open)  ; originally bound to F10



回答3:


I made a package that allows pretty much exactly this at https://github.com/Silex/elmacro

It has some quirks but it works pretty well... for example, the following macro:

F3 C-e M-b M-u C-a C-n F4

Generates the following elisp:

(defun upcase-last-word ()
  "Change me!"
  (interactive)
  (move-end-of-line 1)
  (backward-word 1)
  (upcase-word 1)
  (move-beginning-of-line 1)
  (next-line 1 1))


来源:https://stackoverflow.com/questions/3121274/emacs-keystroke-representation-confusion

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!