Attempting to code a command that runs out of .emacs [duplicate] - emacs

This question already has answers here:
"Wrong type argument: commandp" error when binding a lambda to a key
(3 answers)
Closed 2 years ago.
I'm attempting to set up a command that automatically reloads my .emacs file bound to a control key.
I have used ielm mode and the defun portion evaluates fine, but the keyboard macro is where it's failing
Defun starts here
(defun reinit ()
"reloads .emacs file "
(load "/home/phoenix/.emacs"))
keyboard shortcut starts here
(global-set-key (kbd "C-c r") 'reinit)
in ielm both evalute as reinit, however, if I attempt to reload and run I get wrong type argument: commandp, reinit
Any ideas on how to get this working? I'm using Emacs 26.3.
Thanks!

Thanks for the assistance #steve-vinoski.
I went back and read it again, and I was able to figure it out.
In case anyone else has this issue with 26.3 or 27.1, don't write a separate defun then call it later - it won't work.
On one line only do the enter this ("C-c r" maps to Control-C then r, change that to what ever you want!)
(global-set-key (kbd "C-c r") (lambda () (interactive) (load "/your/home/directory/.emacs")))
It works like a champ! Thanks again!
(change the your/home/directory/.emacs to whatever you call your init file and point it to wherever it lives in your directory.

Related

What's the right name for CTL-]?

From my .emacs:
(defun flip-window () "Flip this window" (interactive)
(switch-to-buffer (other-buffer)))
;; later
(global-set-key [(control ?])] 'flip-window)
It works great, but I have two questions:
is there a built-in function to flip to most recently visited buffer?
While the above works at emacs startup, it causes problems when I'm trying to update settings, there's a parse error caused by the ?]. So is there a better way to express the control-] keystroke?
Answer to the question 2.
You may try the kbd function while setting the key binding.
Like so:
(global-set-key (kbd "C-]") 'flip-window)
And to the question 1: I guess there is no built in function for that. Emacs redux teaches us to implement it like:
(defun er-switch-to-previous-buffer ()
"Switch to previously open buffer. Repeated invocations toggle between the two most recently open buffers."
(interactive)
(switch-to-buffer (other-buffer (current-buffer) 1)))
This is part of Emacs Prelude distro. See https://emacsredux.com/blog/2013/04/28/switch-to-previous-buffer/
As a side note, you can get a description of any key combination in emacs using using the C-h k key combination, which runs the describe-key function. You'll have to read the textual form of your input from the description buffer. If you want to programmatically retrieve a string containing your key combination, you could also run the following Elisp code:
(destructuring-bind ((str . code)) (help--read-key-sequence)
(help-key-description str code))
It will prompt you for input in the minibuffer and return a string, such as e.g. "C-]".

Strange Emacs behavior (produces garbage on the screen)

I'm trying to learn Emacs and eLisp by writing some simple macros. Here is one of them:
(global-set-key (kbd "C-c d") 'local-delete-line)
(defun local-delete-line ()
"deletes 1 line"
(interactive)
(beginning-of-line)
(set-mark-command)
(next-line)
(delete-region))
Unfortunately, after triggering C-c d (or any other hotkey that I set up by global-set-key), Emacs responds with this:
Any ideas what can cause this?
To troubleshoot, I've removed my whole .emacs file, created an empty one, and I've put only the definition of local-delete-line function, together with global-set-key command. Emacs still produces garbage when invoking the function.
Start by reading the doc of set-mark-command (C-h f set-mark-command). See what it says about not setting the mark in code you write. See how many arguments it requires.
Read the doc of delete-region: it requires two arguments.
Do M-: (setq debug-on-error t), and then try your recipe. The backtrace buffer will tell you what you have done wrong.
State what it is that you are trying to do. So far, it seems like you just want to delete or kill a line. If so, what's wrong with C-k?

emacs map several keystrokes and command to one key

I'm trying to map c-u m-x indent-pp-sexp to a single key, like F5, so that working with Emacs doesnt erode my fingerprints.
I use (global-set-key (kbd "C-u M-x indent-pp-sexp") "<f5>") but i'm getting the following error:
global-set-key: Key sequence C-u M-x i n d e n t - p p - s e x p starts with non-prefix key C-u
EDIT
With this lambda function (global-set-key (kbd "<f5>") (lambda (interactive) (universal-argument) (indent-pp-sexp t)))
Getting error:
recursive-edit: Wrong type argument: commandp, (lambda (interactive) (universal-argument) (indent-pp-sexp t))
Weird, because univeral-argument takes no parameters, and indent-pp-sexp takes boolean
You have the arguments the wrong way around, and you bind keys to functions, not to other key sequences. Perhaps you are really looking for a named macro; or you can write some actual Lisp and bind that to F5:
(global-set-key (kbd "<f5>")
(function (lambda () (interactive) (indent-pp-sexp t) )) )
The presence of an argument in the call form appears to be sufficient to select the prefix argument functionality.
You're missing the argument list to the lambda. Additionally I think passing t to indent-pp-sexp negates the need to call universal-argument.
(global-set-key (kbd "<f5>") #'(lambda ()
(interactive)
(indent-pp-sexp t)))
I'm a noob like you, but I already happened to figure basic things like making macros. I don't really know what's wrong with your code, but here's walkthrough of how I do things at home. What you need to do first, is press F3. Then type your keystrokes, and when finished, press F4. Congratulations, you have defined an anonymous macro. You can replay it as many times you wish by pressing F4 again. When you have played enough, enter M-x name-last-keybord-macro, and name it eg. foobar. Go to your ~/.emacs.d/macros/ directory (make it if you don't have one) and visit a file that you will name foobar.el. In its buffer, M-x insert-kbd-macro. When asked about name, say foobar. You will see that emacs has entered the contents of your just recorded macro into the file. Save it. Open your .emacs file, and add lines:
(load (expand-file-name "~/.emacs.d/macros/foobar.el"))
(global-set-key (kbd "M-<f5>") 'foobar)
And things start working for me after restart, with M-F5 as the binding for foobar.el macro.

How to use ctrl-i for an emacs shortcut without breaking tabs [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
How do I bind a command to C-i without changing TAB?
I want to redefine the emacs keyboard shortcut control-i to be "MOVE CURSOR UP"
To do this, I added the following line to my .emacs file:
(global-set-key (kbd "C-i") 'previous-line)
What I then discovered is that the tab key, by default, does whatever is bound to control-i, which is obviously not what I want. So, to restore normal tab behavior, I added this to my .emacs file
(global-set-key (kbd "<tab>") 'indent-for-tab-command)
This mostly works. BUT, tab no longer works for auto-completing commands in the mini buffer. How can I fix that? Or is there a better way of going about this?
Thanks.
Control-i and TAB are usually considered the same (in a terminal for instance). However Emacs makes a distinction and allows a separate binding.
See Emacs TAB and C-i.
You can also set a local binding with (local-set-key key binding).
You could create an (interactive) command in your .emacs that would set the local binding, and call that command only in the buffers of interest.
Edit
Example: put this in your .emacs, or in a new buffer and then do M-xeval-current-buffer
(defun mybinding ()
(interactive)
(local-set-key [tab]
'(lambda () (interactive)
(message "hello"))))
Then go to a buffer of interest and M-xmybinding and then press TAB to see the result ("hello" should be displayed as a message in the minibuffer).
Try C-f to open a new file and press TAB which has the same completion behavior as usual.
Using a post in this thread:
How do I bind a command to C-i without changing TAB?
I was able to find a solution:
;; Translate the problematic keys to the function key Hyper,
;; then bind this to the desired ctrl-i behavior
(keyboard-translate ?\C-i ?\H-i)
(global-set-key [?\H-i] 'previous-line)

How can I easily reload Emacs lisp code as I am editing it?

As an Emacs beginner, I am working on writing a minor mode. My current (naive) method of programming elisp consists of making a change, closing out Emacs, restarting Emacs, and observing the change. How can I streamline this process? Is there a command to refresh everything?
You might try using M-C-x (eval-defun), which will re-evaluate the top-level form around point. Unlike M-x eval-buffer or C-x C-e (exal-last-sexp), this will reset variables declared with defvar and defcustom to their initial values, which might be what's tripping you up.
Also try out C-u C-M-x which evaluates the definition at point and sets a breakpoint there, so you get dropped into the debugger when you hit that function.
M-x ielm is also very useful as a more feature-rich Lisp REPL when developing Emacs code.
M-x eval-buffer should do it.
What Sean said. In addition, I have (eval-defun) bound to a key, along with a test. The development loop then becomes: 1) edit function, 2) press eval-and-test key, 3) observe results, 4) repeat. This is extremely fast.
During development I write a test, bind it to jmc-test, then use the above key to run it on my just-edited function. I edit more, then press key again, testing it again. When the function works, I zap jmc-test, edit another function, and write another jmc-test function. They're nearly always one line of code, so easy to just bang out.
(defun jmc-eval-and-test ()
(interactive)
(eval-defun nil)
(jmc-test))
(define-key emacs-lisp-mode-map (kbd "<kp-enter>") 'jmc-eval-and-test)
(when t
(defun myfunc (beer yum)
(+ beer yum))
(defun jmc-test () (message "out: %s" (myfunc 1 2))))
When editing "myfunc", if I hit keypad enter, it prints "out: 3".
It all depends on what you're writing and how you've written it. Toggling the mode should get you the new behavior. If you're using [define-minor-mode][1], you can add code in the body of the macro that keys off the mode variable:
(define-minor-mode my-minor-mode
"doc string"
nil
""
nil
(if my-minor-mode
(progn
;; do something when minor mode is on
)
;; do something when minor mode is off
)
But, another way to check it quickly would be to spawn a new Emacs from your existing one:
M-x shell-command emacs&
I just define a function called ldf (short for load-file) in my .emacs file,
like this:
(defun ldf (arg) (interactive "P") (load-file (buffer-file-name)))
As you can see, this little function looks up the filename of the current buffer and then loads the file. Whenever I need to reload the current buffer elisp file, just type "M-x ldf"