emacs: assign single key-binding to multiple commands, using the universal argument - emacs

Here is my attempt:
(global-set-key [M-left] (key-binding (kbd "C-u C-#")))
After I evaluate the above expression, invoking alt + left gives me the message <M-left> is undefined. The following, however, works:
(global-set-key [M-left] (key-binding (kbd "C-u")))
But this is only the universal argument part of my command. How do I combine these two commands into one Emacs key-binding?

There are two ways to do this: define a Keyboard Macro interactively or write a function:
(define-key global-map [M-left]
(lambda ()
(interactive)
(set-mark-command t)))

sds has provided the solutions, but for clarification, if you evaluate (key-binding (kbd "C-u C-#")) you'll see that it returns nil -- because that is not a bound key sequence.
In fact C-u runs the command universal-argument, which takes care of reading a subsequent key sequence from the user (C-# in your case).

Related

Emacs: custom function and keybinding for commenting out line

I have been trying out stuff and looking at other answers for several hours now and I cannot figure out how to make custom functions and keybindings work... and it is absolutely infuriating.
For the purposes of testing I wrote this function
(defun my/cmmt ()
""
(interactive)
(move-beginning-of-line 1)
(comment-region 1))
(global-set-key (kbd "\C-o")
'my/cmmt)
There are 2 issues, I want it bind this to C-m but then I get an error:
symbol's value as variable is void: C-m
What does that mean?
And also, all it ever does is move the cursor to the beginning of the line, but not comment it out. Why?
Edit
(defun my/cmmt ()
""
(interactive)
(comment-region
(line-beginning-position)
(line-end-position)
)
)
(global-set-key (kbd "C-o")
'my/cmmt)
Now the error is:
symbol's function definition is void: \,
(kbd "C-o") not (kbd "\C-o")
You're confusing two methods of specifying keys -- (kbd "C-o") and "\C-o" are equivalent.
I recommend using kbd, and simply typing C-hk keys to learn what to pass to kbd to specify the key sequence keys. e.g.: when you type C-hkC-o Emacs tells you that C-o is the representation of that key sequence, so "C-o" is what you must pass to kbd.
The reason the commenting doesn't work is because (comment-region 1) isn't valid. You should be seeing an error. It takes two required arguments. See C-hf comment-region for details.

how to bind helm-do-grep-1 to a key in emacs?

I am using the following.
(global-set-key [f9] 'helm-do-grep-1)
But when I press f9, It complains wrong type argument. I just want it behavior like "C-u C-c h g" to grep recursively. But type so many keys is boring.
update:
I need to grep recursively. helm-do-grep run in non-recursive mode.
You can use
(global-set-key [f9]
(lambda ()
(interactive)
(let ((current-prefix-arg 't))
(call-interactively 'helm-do-grep))))
Upd. If you're interested: the version with kbd sequence
(global-set-key [f9]
(lambda ()
(interactive)
(let ((minibuffer-message-timeout 0))
(execute-kbd-macro (read-kbd-macro "C-u C-c h g C-x Q"))))
See the definition of C-x Q here https://stackoverflow.com/a/28435402/1937596
As the error message already points out, the function helm-do-grep-1 has one argument: https://github.com/emacs-helm/helm/blob/master/helm-grep.el#L810
Probably what you wanted is binding f9 to helm-do-grep which calls helm-do-grep-1 in return with the correct parameters (
https://github.com/emacs-helm/helm/blob/master/helm-grep.el#L1129)
(global-set-key [f9] 'helm-do-grep)
Update:
You can find several solutions to your question here: http://www.reddit.com/r/emacs/comments/2dxj69/how_do_make_helmdogrep_to_do_recursive_always/
To show another possibility you could also do the following:
(global-set-key [f5]
(lambda ()
(interactive)
(call-interactively (key-binding (kbd "C-c h g")))))
In that case, you call helm-do-grep using <f5> and the recursive approach with C-u <f5>. However, this approach will depend on your key bindings.

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.

Defining key binding with arguments

I want to map C-f C-b as moving forward and backward by a fixed amount of lines in a file.
I did this:
(global-set-key (kbd "C-f") 'next-line)
(global-set-key (kbd "C-b") 'previous-line)
but I don't know how to specify an argument before the next-line command. I guess I should use digit-argument but I am unable to write the command in a correct way.
You've changed your question to be about how to bind directly to key sequences
This binds C-c l to C-u 5 C-n
(global-set-key (kbd "C-c l") (kbd "C-u 5 C-n"))
One of the possible alternatives would be define a new function:
(defun my-next-line ()
(interactive)
(next-line 5))
(global-set-key (kbd "C-f") 'my-next-line)
Otherwise, if it is just something you can accomplish with the keyboard you might want to use
M-x name-last-kbd-macro
and save it in your .emacs file
M-x insert-kbd-macro
and have emacs implement the function for you.
It will just get the name you gave in your call to name-last-kbd-macro

having two functions executed with one keyboard combo

I'm trying to have C-<return> map to move-end-of-line then newline-and-indent
In my .emacs I have been playing around with the following:
(global-set-key (kbd "C-<return>") '(progn (move-end-of-line) (newline-and-indent)))
And
(defun c-ret()
'(move-end-of-line newline-and-indent))
(global-set-key (kbd "C-<return>") 'c-ret)
but neither work.
Pointers?
You are quoting the commands.
That implies that they won't be executed. You also need the (interactive) to signify to emacs that it's callable from the keyboard.
Then, you need to have your parameters to your functions correct.
Further, I think your nomenclature for return is wrong.
Your basic misunderstanding here is knowing how eLisp works. That's okay, it's an arcane programming language.
' a.k.a QUOTE is pretty much a Lisp-specific special instruction. It says, "Don't evaluate what comes after me", and returns the unevaluated parameter.
So '(foo bar) is desugared into (QUOTE (FOO BAR)), which returns (FOO BAR).
Try this:
(defun c-ret()
(interactive)
(move-end-of-line nil)
(newline-and-indent))
(global-set-key (kbd "C-RET") 'c-ret)
You can do this without writing any code yourself. See http://www.emacswiki.org/emacs/KeyboardMacrosTricks for instructions on capturing a sequence of commands as a keyboard macro, naming it, and saving it in your .emacs. You can then give the new command a key binding of your choice with e.g. (global-set-key (kbd "C-c i") 'new-command-name).
If you want a one-line solution, this will work too:
(global-set-key (kbd "C-<return>") (lambda () (interactive) (move-end-of-line nil) (newline-and-indent)))