reddit / emacs
macro to open file with keyboard shortcut
Constant_Try_2065 · 2022-10-18 00:43
I am a doom-emacs user. Right now, I have assigned some files with keys like the following:
`:desc "..." "<key>" #'(lambda() interactive() (find-file "<file path>"))`
I want to write a macro to skip `lambda`, and `interactive` each time like following:
`:desc "..." "<key>" #'(<new macro> "<file path>")`
can anyone please help me?
inglourious_basterd · 2022-10-18 00:57
What have you tried so far?
Constant_Try_2065 · 2022-10-18 01:09
I tried following, but does not work, I am newbie to elisp:
```
(defmacro shrt-cut-files (filename)
(lambda() (interactive) (find-file ,filename)))
```
inglourious_basterd · 2022-10-18 01:15
Did you add the \` before the `(lambda ...`?
Honestly though I don't see why use a macro, you can just use a function. Unless this is for learning purposes, in which case go nuts of course.
Constant_Try_2065 · 2022-10-18 01:23
yes, sorry I missed it here.
I have many files with key bindings (and I am afraid the number will increase in the future), I think macro will be helpful for a slightly cleaner config file.
Do you mean instead of a macro I use a function?
inglourious_basterd · 2022-10-18 01:40
Yep, I don't think a macro is the right tool for this job, instead use a function that returns a lambda. Your config file will still be cleaner.
Constant_Try_2065 · 2022-10-18 01:52
I tried this but did not work, that's why trying macro
```
(defun shrt-cut-files (filename)
(interactive) (find-file filename)
)
```
inglourious_basterd · 2022-10-18 01:58
That doesn't return a lambda my friend. Try the original thing you sent me, but replace `defmacro` with `defun`. There will be one other thing to change as this is no longer a macro, but I don't want to give you the _full_ answer ;)
Constant_Try_2065 · 2022-10-18 02:11
Could not make it working, It will be great help if you could please send the full answer.
igorepst · 2022-10-18 05:54
Not sure there is a clean solution, as a mapping function expects a bound function as an only argument. Hence anyway you need lambda to pass the file name
dcharness · 2022-10-18 06:59
I don't know. A macro seems like exactly the tool for this job to me.
I think OP's attempt just needed the backquote inglourious\_basterd already asked about and the `#'` removed from the use of the macro.
Evaluating a macro gives you back code, so the macro in OP's first reply, but with the missing backquote in place, like `\`(lambda …)`, looks right to me for *generating* the interactive call to `find-file` with a specific filename.
Certainly, a function could also do the same as a macro, whether by just returning exactly that same form or by actually evaluating the `(lambda …)`…which creates the same lambda.
To me, looks like the missing piece was the "evaluating" in my "evaluating a macro", above. That gets back to removing the `#'`.
The `#'` read syntax is shorthand for `(function …)`, about which the [Elisp manual/info file](https://www.gnu.org/software/emacs/manual/html_node/elisp/Anonymous-Functions.html) says, "This special form returns FUNCTION-OBJECT without evaluating it." (Like `'` aka `quote` as far as just returning the quoted lisp, but also tells the evaluator or byte-compiler the function object is meant to be executed.)
OP didn't say in what way their original attempt with a macro failed, but I suspect something like `Wrong type argument: commandp, (<new macro> "<file path>")` (as I get from binding such a `#'`\-quoted list to a key).
Structure-wise, the `#'(<new macro> "<file path>")` returns exactly that `(<new macro> "<file path>")`, which the keybinding tries to invoke as a command (as with `command-execute` or its equivalent). That two-item list isn't itself a command, but would return something callable as a command if the macro could do its work.
Without that `#'` to prevent evaluation, the definition for the key should be the macro's output, just the `(lambda …)` form, which that same Elisp manual page points out is equivalent to having `#'` quoted the lambda. And the quoted lambda is the OP's current pre-macro definition.
Danrobi1 · 2022-10-18 07:20
You could use something like this:
- (global-set-key (kbd "C-x <f5>") (lambda() (interactive)(find-file "~/.emacs.d/init.el")))
https://www.masteringemacs.org/article/mastering-key-bindings-emacs
https://www.emacswiki.org/emacs/InteractiveKeybinding
Gallipo · 2022-10-18 13:10
Is this only about opening some files which are used regularly? If so, I would recommend using bookmarks for that. They don't clutter up your config at all.
Constant_Try_2065 · 2022-10-18 13:33
thank you dcharness, it worked.
Constant_Try_2065 · 2022-10-18 13:38
thank you Gallipo, I use bookmarks for projects with the "bookmark-in-project" package, so it's already cluttered up, and keybindings for frequently used org files for notes.
igorepst · 2022-10-18 13:43
Please post the complete solution. It will be helpful:)
Constant_Try_2065 · 2022-10-18 22:53
macro:
```
(defmacro shrt-cut-files (filename)
`(lambda() (interactive) (find-file ,filename))
)
```
keybinding for doom-emacs:
```
:desc "..." "<key>" (shrt-cut-files "<file path>")
```
for me <file path> is string and defvar variables.