Emacs rgrep customization - emacs

I have the following custom function in ~/.emacs:
(defun xi-rgrep (term)
(grep-compute-defaults)
(interactive "sSearch Term: ")
(rgrep term "*.[ch]*" "../"))
This function just runs rgrep for the term entered in the files/directories I'm interested in. However, I want to match the original rgrep functionality of having the default search term be the word at the point (I think that's the term?). How do I achieve this? I've tried several things, including running (grep-read-regexp) but haven't been successful.

You can use the 'thingatpt package like so:
(require 'thingatpt)
(defun xi-rgrep (term)
(interactive (list (completing-read "Search Term: " nil nil nil (thing-at-point 'word))))
(grep-compute-defaults)
(rgrep term "*.[ch]*" "../"))

Here is another way which does not require the 'thingatpt package and uses (grep-read-regexp):
(defun xi-rgrep ()
(interactive)
(grep-compute-defaults)
(rgrep (grep-read-regexp) "*.[ch]*" "../"))
I prefer this as 'thingatpt requires setting boundaries if you want to rgrep words with symbols, such as underscores, which is often the case for variables.

Related

Get list of interactive functions in Elisp/Emacs

I have a bunch of my interactive functions with a prefix, say *zb/" (e.g. "zb/create-temp-buffer"). I am a bit tired every time to type in M-x interaction this prefix of a command I like to run.
To automate this I'd like to retrieve a list of all my interactive functions and show them through ido-completing-read (btw, possibly there are other alternative and modern ways to create input with predefined items and autocompletion?). But I did not manage to find how to retrieve a such list. Could you please give me a cue how to achieve this?
List of all available interactive functions will be enough; to filter is not an issue.
Thanks.
You can use this function for selection
(defun eab/select-zb/ ()
(interactive)
(call-interactively
(intern
(ido-completing-read "M-x zb/"
(mapcar 'symbol-name (apropos-internal "^zb/"))))))
Maybe give Smex a try?
Smex is a M-x enhancement for Emacs. Built on top of Ido, it provides a convenient interface to your recently and most frequently used commands. And to all the other commands, too.
You say "possibly there are other alternative and modern ways to create input with predefined items and autocompletion?".
Use Icicles and just bind icicle-must-match-regexp:
(defun zb/ ()
(interactive)
(let ((icicle-must-match-regexp "^zb/"))
(call-interactively (intern (completing-read "zb/ command: " obarray 'commandp t)))))
You can also do it with vanilla Emacs and without Ido:
(defun zb/ ()
(interactive)
(call-interactively
(intern (completing-read
"zb/ command: "
obarray
(lambda (cmd)
(and (commandp cmd) (string-match-p "^zb/" (symbol-name cmd))))
t))))
Or do as #artscan suggested: use apropos-internal to match the regexp. IOW, either let completing-read do the matching or match first using apropos-internal. You can pass the commandp predicate to apropos-internal as well.

Use the default-input-method when doing an incremental search in EVIL?

Before loading EVIL for vim emulation in emacs, I have the following in my .emacs file:
(activate-input-method "english-dvorak")
(setq default-input-method "english-dvorak")
However, when I type / to start an incremental search with EVIL, the default input method is not used. Why is this? How can I make it so EVIL uses default-input-method whenever I am typing letters on screen?
I was able to hack in proper support for the f and t commands by mapping the qwerty characters to dvorak before the rest of the those function's code executed, but I still haven't been able to get my searches with / to use dvorak.
I've tested the following configuration on my PC and it seem to make Dvorak to be on everywhere in Emacs:
;; Main setup for all the buffers
(defadvice switch-to-buffer (after activate-input-method activate)
(activate-input-method "english-dvorak"))
;; Sets up Dvorak for the minibuffer
(add-hook 'minibuffer-setup-hook (lambda () (set-input-method "english-dvorak")))
;; Sets up Dvorak for *scratch* buffer (used Qwerty on my PC otherwise)
(save-excursion
(set-buffer (get-buffer "*scratch*"))
(set-input-method "english-dvorak"))
The problem is that Evil's incremental searches are performed in normal-state, which, to my knowledge, cannot be used with an input method. This is a quick hack that switches to insert-state just before performing a search to allow the use of input methods. Since it switches to back normal-state immediately after the search is finished, the only quirk is a different cursor in the buffer while you are performing the search.
(evil-define-motion evil-search-forward ()
(format "Search forward for user-entered text.
Searches for regular expression if `evil-regexp-search' is t.%s"
(if (and (fboundp 'isearch-forward)
(documentation 'isearch-forward))
(format "\n\nBelow is the documentation string \
for `isearch-forward',\nwhich lists available keys:\n\n%s"
(documentation 'isearch-forward)) ""))
:jump t
:type exclusive
:repeat evil-repeat-search
(progn ;MADE CHANGES HERE
(evil-insert-state)
(evil-search-incrementally t evil-regexp-search)
(evil-normal-state)
))
(evil-define-motion evil-search-backward ()
(format "Search forward for user-entered text.
Searches for regular expression if `evil-regexp-search' is t.%s"
(if (and (fboundp 'isearch-forward)
(documentation 'isearch-forward))
(format "\n\nBelow is the documentation string \
for `isearch-forward',\nwhich lists available keys:\n\n%s"
(documentation 'isearch-forward)) ""))
:jump t
:type exclusive
:repeat evil-repeat-search
(progn ;MADE CHANGES HERE
(evil-insert-state)
(evil-search-incrementally nil evil-regexp-search)
(evil-normal-state)
))

How to replace a word instead of a string in emacs like this?

For example, I have the codes below:
(defun toggle-light ()
"Toggle setting tab widths between 4 and 8"
(setq a
(if (boundp 'a) a nil))
(interactive)
(if a
(progn
(load-theme 'solarized-dark t)
(setq a nil))
(progn
(load-theme 'solarized-light t)
(setq a t) )))
And now I want to refactor this blocks by replacing the variable name a with is-lighted, but without changing other character a in other words (for example, in interactive or tab).
Is there a built-in function in emacs that can finsih that job?
C-uM-% a RET is-lighted RET
The prefix argument ("delimited") to the standard query-replace functions wraps the pattern with word-boundary markers.
While phils's answer is correct and idiomatic, you should also learn about \b word boundary regular expression. Thus, equivalent regexp replace would be M-%\ba\b. See Backslash in Regular Expressions # Emacs Manual and Regular Expression # EmacsWiki.

Passing Emacs variables to minibuffer shell commands

I can run a shell command quickly by hitting M-!. One thing I'd like to do is perform shell quick operations on the current file. An example would be checking the file out through perforce:
M-! p4 edit buffer-file-name RET
(Yes there are perforce integrations, but I'm more interested in the minishell/variable problem rather than a specific workflow)
Of course, the buffer-file-name variable is not evaluated before the command is sent to the shell.
Is there an easy on-the-fly way to do this? Or will I have to roll a custom elisp function?
It seems current Emacs has something built-in to achieve the desired result, after M-! (shell-command) press <down>, you will get the file name you are currently visiting on the prompt. Now you can edit it to add the command you want to run on it.
In dired-mode it will give you the file your cursor is currently on.
Indeed using C-u M-: is almost right. I'm not so sure about using shell-quote-argument in eval-to-shell-argument since it only works on strings making it impossible to use eval-to-shell-argument to insert a number or a symbol. You could try something like:
(defun sm-minibuffer-insert-val (exp)
(interactive
(list (let ((enable-recursive-minibuffers t))
(read-from-minibuffer "Insert: "
nil read-expression-map t
'read-expression-history))))
(let ((val (with-selected-window (minibuffer-selected-window)
(eval exp)))
(standard-output (current-buffer)))
(prin1 val)))
and then bind this function in your minibuffer with (define-key minibuffer-local-map [?\M-:] 'sm-minibuffer-insert-val).
Of course, if the only thing you ever want to insert is the buffer-file-name, then your execute-shell-command-on-buffer is simpler.
I did roll my own elisp function, and it looks like this:
(defun execute-shell-command-on-buffer (shell-command-text)
(interactive "MShell command:")
(shell-command (format shell-command-text (shell-quote-argument buffer-file-name)))
)
https://gist.github.com/2367513
I bound it to M-", so now my example can be completed with:
M-"p4 edit %sRET
I won't accept this as the answer, because I did ask for solutions that don't require a function.
You can use C-u M-: (eval-expression with a universal prefix argument) to evaluate any Lisp expression and insert its value at point in the current buffer (including minibuffers, as long as you have enable-recursive-minibuffers set to a non-nil value).
In your example: C-u M-: buffer-file-name RET.
Note that the result of the expression is printed in Lisp form: that is, quoted in such a way that a subsequent call to read would construct an equal Lisp value. For strings, this means enclosing in double quotes, which will probably be interpreted as you expect by the inferior shell. However, you may run into problems with strings that contain special characters, which need different escaping by Elisp and the shell.
The more correct way uses shell-quote-argument, as in phils' solution. Here's a quick defun that reads a Lisp expression and inserts its value at point as a properly quoted shell word:
(defun eval-to-shell-argument (form)
(interactive "XEval: ")
(insert (shell-quote-argument form)))
The read-and-evaluate step happens automatically by using an "X" as the argument to interactive.
Edited to add: As #tenpn notes, the above solution doesn't work for inserting buffer-local variables like buffer-file-name in a minibuffer like the one M-! pops up (more precisely, it inserts the buffer-local value of the minibuffer, which is unlikely to be useful). Here is a revised version which seems to work. If the minibuffer is active, it makes the buffer of the previously-selected window temporarily active while reading and evaluating an expression.
Final edit: From #Stefan's answer I see that I should have used (minibuffer-selected-window) to find the previously-selected window. I've also added a (format "%s" ..) to allow inserting non-string values, while still quoting special characters in strings. Here's the final version:
(defun eval-to-shell-argument ()
(interactive)
(let* ((buffer
(if (minibufferp)
(window-buffer (minibuffer-selected-window))
(current-buffer)))
(result
(with-current-buffer buffer
(eval-minibuffer "Eval: "))))
(insert (shell-quote-argument (format "%s" result)))))
You can't do that with M-!, but you can evaluate arbitrary elisp from the minibuffer, so writing a function isn't strictly necessary:
M-: (shell-command (format "p4 edit %s" (shell-quote-argument buffer-file-name))) RET
In this case however, I think eshell is what you want to use:
M-x eshell-command RET p4 edit (eval buffer-file-name) RET
Edit: Except unfortunately that doesn't work, as the *eshell cmd* buffer is selected when that is evaluated. One solution would be:
M-x eshell-command RET p4 edit (eval buffer-file-name (other-buffer nil t)) RET
(Not quite as elegant, sorry.)
Everyone seems to be rolling their own version, so here's mine -- it will substitue the current filename or marked dired-files or current dired file wherever a % is in the shell command. It follows the same conventions as M-! so I bind it to that.
(defun my-shell-command (command &optional output-buffer error-buffer)
"Run a shell command with the current file (or marked dired files).
In the shell command, the file(s) will be substituted wherever a '%' is."
(interactive (list (read-from-minibuffer "Shell command: "
nil nil nil 'shell-command-history)
current-prefix-arg
shell-command-default-error-buffer))
(cond ((buffer-file-name)
(setq command (replace-regexp-in-string "%" (buffer-file-name) command nil t)))
((and (equal major-mode 'dired-mode) (save-excursion (dired-move-to-filename)))
(setq command (replace-regexp-in-string "%" (mapconcat 'identity (dired-get-marked-files) " ") command nil t))))
(shell-command command output-buffer error-buffer))

Emacs Elisp dynamic interactive prompt

I am trying to have a dynamic prompt from my elisp function. I want something like replace-regexp where it will show you the last regexp entered. I tried
(interactive
(concat "sab" "bab")))
that doesnt work!
I also tried message like format
(interactive "s %s" last-used-regexp)
and that doesn't work!
Anyone know how to do this?
Thank you!
M-x find-function is your friend. It will tell you how anything in emacs works by showing you the source code. Using it, I find that query-regexp-replace calls query-replace-read-args which calls query-replace-read-from which calls read-from-minibuffer using a prompt created from the last used regexp, which is saved in the dotted pair query-replace-defaults.
So:
(defun my-func ()
"Do stuff..."
(interactive)
(read-from-minibuffer "Regexp? " (first query-replace-defaults)))
is a command that throws up a prompt with the last entered regexp as the default.
Use a variable for input history, and interactive with a list:
(defvar my-func-history nil)
(defun my-func (str)
(interactive (list (read-from-minibuffer "Input string: " (car my-func-history) nil nil 'my-func-history)))
(insert str))
If you don't want the last value entered in there initially, change the (car my-func-history) to nil. You can of course up/down arrow to go through the history at the prompt.