Emacs lisp, How `interactive' reads buffer? - emacs

For example there is a function:
(defun testb (buf)
(interactive "bTest: ")
buf)
The question is how emacs internally reads a buffer for such interactive form?
Looks like it doesn't use read-buffer(or it calls the read-buffer as a C function(and doesn't look at symbol-function)?).
(flet ((read-buffer (&rest args) (current-buffer)))
(call-interactively #'testb))

It uses Lisp function read-buffer. The interactive spec you show is equivalent to this one:
(interactive (list (read-buffer "Test: " nil t)))
See the Elisp manual, node Using Interactive.
I guess you're referring to the fact that you got this error, or similar, which you get when you try to use flet on a built-in function. And yes, read-buffer is a subr, i.e., implemented in C. (symbol-function 'read-buffer) returns the built-in function #<subr read-buffer>.
Use ‘labels’, not ‘flet’, to rebind macro names

Related

How to pass arg in Emacs abstract function

I try to write a function to abstract which helm-imenu variant to use:
(defun my/helm-menu ()
"For Org mode buffers, show Org headlines.
For programming mode buffers, show functions, variables, etc."
(interactive)
(cond ((derived-mode-p 'org-mode)
(helm-org-in-buffer-headings))
(t
(helm-semantic-or-imenu))))
Though, when using it in a non-Org mode buffer, it fails, saying it needs one argument.
Indeed, helm-semantic-or-imenu requires arg.
How should I pass that?
Why is that working with a M-x helm-semantic-or-imenu: where is the argument?
Following Drew's piece of advice, this should do it:
(defun my/helm-menu (arg)
"For Org mode buffers, show Org headlines.
For programming mode buffers, show functions, variables, etc."
(interactive "P")
(cond ((derived-mode-p 'org-mode)
(helm-org-in-buffer-headings))
(t
(helm-semantic-or-imenu arg))))
At least, it works!

How to convert kbd-macro to real command in Emacs? [duplicate]

This question already has answers here:
Convert Emacs macro into Elisp
(2 answers)
Closed 8 years ago.
It seems kbd-macro only records keys I pushed. But I want to record real commands(that is tied with key I pushed) and save these as function.
So my question is something like following.
How to record commands I used as executable format?
How to convert key sequence to command sequence?
How to convert my-kbd-macro to command sequence function?
Example:
F3(M-x kmacro-start-macro)
C-f
F4(M-x kmacro-end-or-call-macro)
M-x name-last-kbd-macro my-kbd-macro
M-x insert-kbd-macro my-kbd-macro
Output:
(fset 'my-kbd-macro
"\C-f")
My desired output is like following:
(defun my-kbd-macro ()
(interactive)
(forward-char)
)
Thanks.
Here's a simplistic implementation of what you want.
It will work only for simple commands that don't want input, like forward-char.
To do any more in a fully automated way seems hard / not feasible. That's why this functionality
isn't in place already, I guess.
I've added these functions to
my macro package that allows multiple anonymous macros
You can get it from github or from MELPA as centimacro.
To use it, just do your F3 ... F4 thing, and
M-x last-macro-to-defun from e.g. *scratch*.
(defun macro->defun (str)
"Convert macro representation STR to an Elisp string."
(let ((i 0)
(j 1)
(n (length str))
forms s f)
(while (< i n)
(setq s (substring str i j))
(setq f (key-binding s))
(if (keymapp f)
(incf j)
(push (list f) forms)
(setq i j)
(setq j (1+ i))))
(with-temp-buffer
(emacs-lisp-mode)
(insert
"(defun foo ()\n (interactive)")
(mapc (lambda (f)
(newline-and-indent)
(insert (prin1-to-string f)))
(nreverse forms))
(insert ")")
(buffer-string))))
(defun last-macro-to-defun ()
"Insert last macro as defun at point."
(interactive)
(insert (macro->defun last-kbd-macro)))
Do bear in mind that when writing a function there are frequently better ways to do things than to exactly mimic the interactive bindings, so while not necessary, some refactoring is likely going to be beneficial if you start out with just the commands used when the macro runs.
Anyhow, I can think of a couple of useful tools to assist with working this out manually:
Firstly, if you edit a keyboard macro, the macro editor comments each key with the function it is bound to (n.b. for the buffer in which you invoke the editor! -- if you are switching buffers while your macro executes, I would suggest checking the editor for each buffer).
Obviously you can obtain the same information in other ways, but the macro editor gives you the whole list, which could be convenient.
The other helper is repeat-complex-command bound to C-xM-:, which gives you the resulting elisp form from certain types of interactive function call ("a complex command is one which used the minibuffer"). My favourite example of this is align-regexp, as it's a case where the user's interactive arguments are further manipulated, which isn't necessarily obvious. e.g.:
M-x align-regexp RET = RET C-xM-: might tell you:
(align-regexp 1 191 "\\(\\s-*\\)=" 1 1 nil)

Programatically insert text into command that normally blocks event loop

I'd like to implement a command that types the first few characters into an existing command and lets me type the rest.
For example, a variant of icicle-execute-extended-command that starts with "icicle-" already entered.
I have tried:
keyboard macros
fail (even on simple things like M-x i c i c l e s) for no apparent reason.
functions
calling icicle-execute-extended-command block the command sequence
How would I go about doing this in a generalized manner?
Nice question.
Here's something generic you can try:
(defun no-mondays ()
(interactive)
(minibuffer-with-setup-hook
(lambda()
(insert "monday"))
(call-interactively 'query-replace)))
And here's a refactoring:
(defun with-initial-minibuffer (str fun)
`(lambda ()
(interactive)
(minibuffer-with-setup-hook
(lambda ()
(insert ,str))
(call-interactively ',fun))))
(defalias 'no-weekends
(with-initial-minibuffer
"\\(?:satur\\|sun\\)day"
'query-replace-regexp))
If you are calling completing-read yourself in your command definition, then just pass the text to insert as the INITIAL-INPUT argument. That's what it's for.
If you use icicle-define-command or icicle-define-file-command (so that your command will be a multi-command), then same thing: pass the INITIAL-INPUT arg.
If you use such a macro, be sure to put something like this in the file that defines the command, so the macro definition is available a byte-compilation time:
(eval-when-compile
(or (condition-case nil
(load-library "icicles-mac") ; Use load-library to ensure latest .elc.
(error nil))
(require 'icicles-mac)))

Get list of interactive functions in Elisp/Emacs

I have a bunch of my interactive functions with a prefix, say *zb/" (e.g. "zb/create-temp-buffer"). I am a bit tired every time to type in M-x interaction this prefix of a command I like to run.
To automate this I'd like to retrieve a list of all my interactive functions and show them through ido-completing-read (btw, possibly there are other alternative and modern ways to create input with predefined items and autocompletion?). But I did not manage to find how to retrieve a such list. Could you please give me a cue how to achieve this?
List of all available interactive functions will be enough; to filter is not an issue.
Thanks.
You can use this function for selection
(defun eab/select-zb/ ()
(interactive)
(call-interactively
(intern
(ido-completing-read "M-x zb/"
(mapcar 'symbol-name (apropos-internal "^zb/"))))))
Maybe give Smex a try?
Smex is a M-x enhancement for Emacs. Built on top of Ido, it provides a convenient interface to your recently and most frequently used commands. And to all the other commands, too.
You say "possibly there are other alternative and modern ways to create input with predefined items and autocompletion?".
Use Icicles and just bind icicle-must-match-regexp:
(defun zb/ ()
(interactive)
(let ((icicle-must-match-regexp "^zb/"))
(call-interactively (intern (completing-read "zb/ command: " obarray 'commandp t)))))
You can also do it with vanilla Emacs and without Ido:
(defun zb/ ()
(interactive)
(call-interactively
(intern (completing-read
"zb/ command: "
obarray
(lambda (cmd)
(and (commandp cmd) (string-match-p "^zb/" (symbol-name cmd))))
t))))
Or do as #artscan suggested: use apropos-internal to match the regexp. IOW, either let completing-read do the matching or match first using apropos-internal. You can pass the commandp predicate to apropos-internal as well.

Define an emacs command that calls another emacs command (preserving interactive stuff)

How can I define an emacs command X that does something and then calls another emacs command Y and also copying the interactive interface of the command Y too?
I want to define an altenative version of query-replace with temporarilly toggled value of case-fold-search:
(defun alt-query-replace (a b c d e)
(interactive)
(let ((case-fold-search (not case-fold-search))
(query-replace a b c d e)))
This doesn't work. When I call alt-query-replace, it says "wrong number of arguments". I want the interactive interface of alt-query-replace to be the same as query-replace. Do I need to inspect the source code of query-replace or is there a general approach?
You may advise the original function, if you want to modify its behavior instead of calling a separate function.
From chapter 17.3 Around-Advice of the GNU Emacs Lisp Reference Manual:
Around-advice lets you “wrap” a Lisp
expression “around” the original
function definition.
(defadvice foo (around foo-around)
"Ignore case in `foo'."
(let ((case-fold-search t))
ad-do-it))
In your case, you can write:
(defadvice query-replace (around alt-query-replace (from-string to-string &optional delimited start end))
(let ((case-fold-search (not case-fold-search)))
ad-do-it))
(ad-activate 'query-replace)
Use call-interactively:
(defun alt-query-replace ()
(interactive)
(let ((case-fold-search (not case-fold-search)))
(call-interactively 'query-replace)))