How can I bind compile using comint to a key combination - emacs

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.

Related

Emacs: How to redefine Ctrl-Enter when CUA-mode is enabled?

If cua-mode is enabled, redefining Ctrl-Enter does not works as expected and always runs cua-set-rectangle-mark function. In the code below you can see that I also defined Alt-Enter to my function, just for testing, and it runs fine. But I wish to left Alt-Enter to cua-set-rectangle-mark because I prefer to use Ctrl-Enter to call my function that creates a line below the current line. What is wrong?
(cua-mode t)
(defun vscode-insert-line-below()
(interactive)
(move-end-of-line 1)
(newline-and-indent))
(global-set-key (kbd "C-<return>") 'vscode-insert-line-below)
(global-set-key (kbd "M-<return>") 'vscode-insert-line-below)
This is probably what you want:
(cua-mode t)
(defun vscode-insert-line-below()
(interactive)
(move-end-of-line 1)
(newline-and-indent))
(define-key cua-global-keymap (kbd "<C-return>") 'vscode-insert-line-below)
(You can use either (kbd "<C-return>") or (kbd "C-<return>"), but I like to use the form that C-h k shows me.)
When you are in cua-mode the local keymap is cua-global-keymap, and its bindings override the same global bindings.
I found that map by doing C-h k C-RET in cua-mode. It told me:
<C-return> runs the command cua-set-rectangle-mark (found in
cua-global-keymap), which is an interactive autoloaded Lisp function
in cua-rect.el.
It is bound to <C-return>.
[Arg list not available until function definition is loaded.]
Start rectangle at mouse click position.

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.

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

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