how to bind helm-do-grep-1 to a key in emacs? - 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.

Related

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

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).

Two key shortcut in emacs without repressing the first key?

Suppose I define the following shortcut
(global-set-key (kbd "C-d C-j") "Hello!")
Is it possible to configure emacs so that if I type "C-d C-j C-j C-j" I will get "Hello! Hello! Hello!" rather than having to type "C-d C-j C-d C-j C-d C-j"?
I don’t think you can configure Emacs so that it does that for all commands. However, you can implement this functionality in the commands themselves. This is what is done for C-x e. Here is a macro I just wrote (guided by the standard definition of kmacro-call-macro in GNU Emacs 23.1.1) that makes it easy to add this functionality to your own commands:
(defmacro with-easy-repeat (&rest body)
"Execute BODY and repeat while the user presses the last key."
(declare (indent 0))
`(let* ((repeat-key (and (> (length (this-single-command-keys)) 1)
last-input-event))
(repeat-key-str (format-kbd-macro (vector repeat-key) nil)))
,#body
(while repeat-key
(message "(Type %s to repeat)" repeat-key-str)
(let ((event (read-event)))
(clear-this-command-keys t)
(if (equal event repeat-key)
(progn ,#body
(setq last-input-event nil))
(setq repeat-key nil)
(push last-input-event unread-command-events))))))
Here’s how you use it:
(defun hello-world ()
(interactive)
(with-easy-repeat
(insert "Hello, World!\n")))
(global-set-key (kbd "C-c x y z") 'hello-world)
Now you can type C-c x y z z z to insert Hello, World! three times.
If you are looking for something generic that works on all commands I cant see how that would work - how would emacs know if you are starting a new command or want to repeat the previous. A better example would be "C-c h", if you type "h" after that, should emacs repeat the command or insert a h?
That said, emacs already has a mechanism for this - the universal argument.
Try this key sequence:
C-u 3 C-d C-j
It is even fewer keypresses than C-d C-j C-j C-j C-j
Try something like this:
(global-set-key (kbd "C-c C-j") (lambda()
(interactive)
(insert "Hello!")
(message "Type j to print Hello!")
(while (equal (read-event) ?j)
(insert "Hello!"))
(push last-input-event unread-command-events)))
Idea taken from kmacro-call-macro
No. The sequence "ctrl-d ctrl-j" is what is bound to the string "Hello!" Emacs binds the sequence as a whole to the given string. Here's some good info on the topic:
Link
On the other hand, if you wanted just three instances of "Hello!", you could define that sequence C-d C-j C-d C-j C-d C-j as "Hello! Hello! Hello!", but it would be shorter to just define a simpler sequence for the string you want.
I use this all the time. You'll need library repeat.el (part of GNU Emacs) to use it.
(defun make-repeatable (command)
"Repeat COMMAND."
(let ((repeat-message-function 'ignore))
(setq last-repeatable-command command)
(repeat nil)))
(defun my-hello ()
"Single `hello'."
(interactive)
(insert "HELLO!"))
(defun my-hello-repeat ()
(interactive)
(require 'repeat)
(make-repeatable 'my-hello))
Now bind my-hello-repeat:
(global-set-key (kbd "") 'my-hello-repeat)
Now just hold down the home key to repeat HELLO!.
I use this same technique in multiple libraries, including Bookmark+, thing-cmds, and wide-n.
smartrep is all you want
(require 'smartrep)
(defvar ctl-d-map (make-keymap)) ;; create C-d map
(define-key global-map "\C-d" ctl-d-map)
(smartrep-define-key
global-map "C-d"
'(("C-j" . (insert "hello"))))

emacs lisp call function with prefix argument programmatically

I want to call a function from some elisp code as if I had called it interactively with a prefix argument. Specifically, I want to call grep with a prefix.
The closest I've gotten to making it work is using execute-extended-command, but that still requires that I type in the command I want to call with a prefix...
;; calls command with a prefix, but I have to type the command to be called...
(global-set-key (kbd "C-c m g")
(lambda () (interactive)
(execute-extended-command t)))
The documentation says that execute-extended-command uses command-execute to execute the command read from the minibuffer, but I haven't been able to make it work:
;; doesn't call with prefix...
(global-set-key (kbd "C-c m g")
(lambda () (interactive)
(command-execute 'grep t [t] t)))
Is there any way to call a function with a prefix yet non-interactively?
If I'm understanding you right, you're trying to make a keybinding that will act like you typed C-u M-x grep <ENTER>. Try this:
(global-set-key (kbd "C-c m g")
(lambda () (interactive)
(setq current-prefix-arg '(4)) ; C-u
(call-interactively 'grep)))
Although I would probably make a named function for this:
(defun grep-with-prefix-arg ()
(interactive)
(setq current-prefix-arg '(4)) ; C-u
(call-interactively 'grep))
(global-set-key (kbd "C-c m g") 'grep-with-prefix-arg)
Or you could just use a keyboard macro
(global-set-key (kbd "s-l") (kbd "C-u C-SPC"))
In this example, the key combination "s-l" (s ("super") is the "windows logo" key on a PC keyboard) will go up the mark ring, just like you if typed "C-u C-SPC".

How can I bind compile using comint to a key combination

I currently bind compile to C-x c. I know I can run compile in comint mode by using C-u C-x c but I'd prefer to just bind it to C-x c directly. I can't fathom how to do this without copying the whole of the compile function from compile.el, tweaking it and binding that. Is there a better way?
Edit: To clarify my sloppy language, I don't wish to bind C-x c whilst in comint mode. I wish to cause C-x c to run 'compile using comint mode. I currently have C-x bound to 'compile. I can do what I want by typing C-u C-x c but I'd prefer to just be able to type C-x c to do that.
I think this works...
(defun c-w-c ()
(interactive)
(call-interactively 'compile t (vector 21 (this-command-keys-vector))))
(global-set-key (kbd "C-x c") 'c-w-c)
the '21' prepended into the vector is the ctrl-u prefix key, and it seems to fool the compile function into thinking it was called with C-u C-x c.
Edit:
It didn't work, but this does:
(defun c-w-c ()
(interactive)
(setq current-prefix-arg '(4))
(call-interactively 'compile))
You can do something like this :
(global-set-key [(C-f5)] 'compile)
(global-set-key [(f5)] 'recompile)
It binds compile to C-f5 and each time you want to recompile with the same command as you've given in compile, just type f5. It works whatever the major mode you're currently in.
For your case, do like this :
(global-set-key [?\C-x ?c] 'compile)
Are you asking for this?
(define-key comint-mode-map (kbd "C-x c") 'compile)
This works too:
(define-key comint-mode-map (kbd "C-x c")
(lambda (command)
(interactive
(list
(let ((command (eval compile-command)))
(if (or compilation-read-command current-prefix-arg)
(compilation-read-command command)
command))))
(compile command t)))
It's ugly because it duplicates the "interactive" spec from the compile command.

.emacs global-set-key and calling interactive function with argument

In my .emacs i have the following function that transposes a line
(defun move-line (n)
"Move the current line up or down by N lines."
(interactive "p")
(let ((col (current-column))
start
end)
(beginning-of-line)
(setq start (point))
(end-of-line)
(forward-char)
(setq end (point))
(let ((line-text (delete-and-extract-region start end)))
(forward-line n)
(insert line-text)
;; restore point to original column in moved line
(forward-line -1)
(forward-char col))))
And I bind a key to it like this
(global-set-key (kbd "M-<down>") 'move-line)
;; this is the same as M-x global-set-key <return>
However, I want to bind M-up to move-line (-1) But I cant seem to be able to do it correctly:
;; M-- M-1 M-x global-set-key <return>
How do I define the above using global-set-key to call move-line -1?
Not minutes after asking the question I figured it out by copy+pasting code. However I have no clue how it works.
(global-set-key (kbd "M-<up>") (lambda () (interactive) (move-line -1)))
global-set-key only takes 2 arguments: the key sequence and the command you want to bind to it. So
(global-set-key (kbd "M-<down>") 'move-line)
works fine. But if you want to use move-line with an argument you need to wrap it in an anonymous (aka lamba) function so that it presents itself to global-set-key as one value.
You can simply ask for the number of lines you want and convert the input string into an integer:
(global-set-key (kbd "M-<up>")
(lambda ()
(interactive)
(move-line (string-to-int (read-string "Lines: ")))))
I found this when I had the same problem, but I ended up solving it in another way.
(global-set-key (kbd "M-<down>") 'move-line)
(global-set-key (kbd "M-<up>") (kbd "C-u -1 M-<down>"))
Definitely not a perfect solution, since M-<down> could be reassigned and C-u -1 might not make sense on it, but since it's just my local init file, it should be no problem.
Also this obvious only works well for keyboard commands that you want to have reversed.
You might want to check out the "transpose-lines" built-in function.