I am trying to grep current word under cursor in emacs. I have written code below, which throws the error: Wrong number of arguments... When I remove (grep) from xx() and bind it to f4 key (commented last line), after f3 and f4 grep searches word under cursor. Does any one know why (grep) can not be called from xx()?
Thanks, Alex.
(require 'grep)
(defun xx ()
"setting up grep-command using current word under cursor as a search string"
(interactive)
(setq curWord (thing-at-point 'word))
(setq VALUE (concat "grep -nH -r --exclude='TAGS' --include='*.h' --include='*.cpp' --include='*.pl' --include='*.c' -e " curWord " /home/alex/code/") )
(grep-apply-setting 'grep-command VALUE)
(grep))
(global-set-key (kbd "<f3>") 'xx)
;(global-set-key (kbd "<f4>") 'grep )
The grep function takes one argument, so change your function to pass it:
(defun xx ()
"setting up grep-command using current word under cursor as a search string"
(interactive)
(let* ((cur-word (thing-at-point 'word))
(cmd (concat "grep -nH -r --exclude='TAGS' --include='*.h' --include='*.cpp' --include='*.pl' --include='*.c' -e " cur-word " /home/alex/code")))
(grep-apply-setting 'grep-command cmd)
(grep cmd)))
You don't need to change the grep command or define your own replacement. You just need to grab the default value that it provides, which is already the word at point.
You should be able to use M-n to retrieve the word at point, after you use M-x grep. (But be careful to put back the switches. Apparently vanilla Emacs removes them when you hit M-n.)
M-n inserts the default value of a command into the minibuffer at the prompt. If there are multiple default values then repeating M-n cycles among them. This is true in general, not just for command grep.
If you use library Grep+ then the default value is automatically inserted into the minibuffer (without changing the command switches). And you have more control over just what you want the default value and other default behaviors to be.
If using counsel-projectile https://github.com/ericdanan/counsel-projectile, set counsel-projectile-grep-initial-input, counsel-projectile-ag-initial-input, or counsel-projectile-rg-initial-input to option "Symbol or selection at point"
Related
I have the following code that attempts to create a new line and then jump to it. The idea is that move-end-of-line will jump to the end of the current line, and ["C-m"] would act as return/enter. Yet executing this command gives the error: "wrong number of arguments". How do I fix this?
(global-set-key (kbd "C-.") 'new-line)
(defun new-line ()
(interactive)
(move-end-of-line)
["C-m"]
)
I think you need to read the Emacs & elisp manuals: these questions are pretty easy to answer. Here's one way to do it.
(defun insert-line-after-line (&optional n)
(interactive "p")
(end-of-line 1) ;end of current line
(open-line n) ;open n new lines
(forward-line 1)) ;go to start of first of them
But seriously: Emacs has very extensive self-documentation, it is easy to find out how to do these things.
An option is to record a macro and use that.
M-x kmacro-start-macro
C-e
C-m
M-x kmacro-end-macro
If you don't care about the macro persisting, just run it:
C-x e
But if you want it to persist you would save it:
M-x name-last-kbd-macro new-line
M-x insert-kbd-macro new-line
and paste the output into your initialisation file (with your shortcut definition):
(global-set-key (kbd "C-.") 'new-line)
(fset 'new-line
[end return])
["C-m"] is like the way you specify a key for doing a key binding, but this is not the same as how you programmatically tell Emacs to insert a character into a document. You could use (insert-char ?\^M) (see ref here), but that would result in a literal ^M character (try it; another way to do the same thing interactively is Ctrl-Q followed by Ctrl-M). (insert "\n") seems to be what you're looking for.
Also, the reason you're getting the message "wrong number of arguments" is because (move-end-of-line) requires an argument when called out of interactive context. (move-end-of-line 1) works.
That said, possibly an easier way to achieve the result you're looking for is with the following setting:
(setq next-line-add-newlines t)
This will allow you to just do C-n at the end of the file and not worry about the distinction between moving and inserting.
I'm currently using the terminal Terminator,
and i got a bash function
set_title() { printf '\e]2;%s\a' "$*"; }
wich permit me to set the terminator window title
So I would want to know if it's possible to execute this specific shell command (like this):
set_title ##filename
on each opening (or re-opening) of the said file in emacs?
(btw english is not my native language, please be indulgent!)
If you mean that you're running the non-GUI Emacs inside bash inside Terminator and you want Terminator's title to reflect the current file in Emacs, then the fact that bash sits in between is of no use to you: Emacs is in control here.
But you can define an Elisp function that will do the same job as your set_title:
(defun my-set-title (title)
(send-string-to-terminal (format "\e]2;%s\a" title)))
And then you could use it via find-file-hook:
(add-hook 'find-file-hook (lambda () (my-set-title buffer-file-name)))
Note that this will set the terminal's title to the last file Emacs visits, so if you switch back to a previous file-buffer via C-x C-b, the title won't be updated to reflect the current buffer's file name. If you want to do that, you'd need something more like:
(defvar my-last-file nil)
(defun my-keep-file-title ()
(when (and buffer-file-name
(not (equal buffer-file-name my-last-file)))
(setq my-last-file buffer-file-name)
(my-set-title buffer-file-name)))
(add-hook 'post-command-hook #'my-keep-file-title)
As suggested by #Dan, you can do
(add-hook find-file-hook
(lambda ()
(when (string= buffer-file-name "my-file")
(shell-command "printf ...."))))
to call printf when you open "my-file".
However, if what you want is to set the frame title (emacs calls "frame" what window managers call "window"),
you should be setting frame-title-format, e.g.:
(setq frame-title-format
'(buffer-file-name "%b - %f" ; File buffer
(dired-directory dired-directory ; Dired buffer
(revert-buffer-function "%b" ; Buffer Menu
("%b - Dir: " default-directory)))) ; Plain buffer
icon-title-format "%b")
I am looking for a command M-x find in Emacs, which behave exactly like M-x grep (allows to modify the command, prints the output nicely including links to the found files, ...) and which executes find . -iname '*|*' (with the cursor placed at the vertical bar -- for inserting a search pattern -- if not too complicated to implement). Has anyone implemented this before? [I am aware of M-x find-grep]
Let's start with M-xfind-dired that does almost what you want: it reads directory from minibuffer, defaulting to current directory, and then reads other find arguments. The result is opened in dired mode, and I think it's as nicely as it can get (if you think that dired is too verbose, check out dired-details and maybe dired-details+ packages at MELPA).
Now let's make it start with -iname ** with a cursor between the stars when it's asking for options. Looking at find-dired source, we can see that it uses the value of find-args as an initial input argument to read-string. This argument is obsolete and deprecated but awfully useful. One of its features (as we read in read-from-minibuffer description) is providing a default point position when a cons of a string and an integer is given.
(defun marius/find-dired ()
(interactive)
(let ((find-args '("-iname '**'" . 10)))
(call-interactively 'find-dired)))
We added single quotes around stars in '**' because the arguments are subject to shell expansion.
Instead of reading our own arguments from the minibuffer, we just
rebind find-args and delegate all the rest to find-dired. Normally
find-dired remembers last arguments you enter in find-args so they
become the new default. Rebinding it with let ensures that this
modification from our call to find-dired will be thrown away, so
regular find-dired will use the arguments given to the latest
regular find-dired. It probably doesn't matter if you don't use regular find-dired. If you want find arguments given to our wrapper to be used by regular find-dired, use the following definition instead:
(defun marius/find-dired ()
(interactive)
(setq find-args '("-iname '**'" . 10))
(call-interactively 'find-dired))
I think that find-dired fulfills your requirements (except it doesn't initialize the command with "-iname" and lets you enter it).
For example:
M-xfind-diredRET (execute find-dired)
C-j (accept default directory : .)
-iname "*.foo" RET (enter command-line arguments)
Results are presented in a dired buffer.
You can start with:
(defun eab/find-grep ()
(interactive)
(let ((grep-host-defaults-alist nil)
(grep-find-command
`(,"find . -iname '**' -type f -print0 | xargs -0 -e grep -nH -m 1 -e \"^\"" . 17)))
(call-interactively 'find-grep)))
Also I use:
(defun eab/grep ()
(interactive)
(let ((grep-host-defaults-alist nil)
(grep-command
`(,(concat "grep -i -nH -e *."
(ignore-errors
(file-name-extension buffer-file-name))) . 16)))
(call-interactively 'grep)))
EDIT: Now grep-find-command is for searching only first line of each file by default.
Is there a way to search all the open buffers for a particular pattern?
C-s interactively searches current buffer.
Similarly, is there something that searches all the open buffers?
I know I can use "occur", but "Occur" brings a new buffer and changes/messes with the buffer organization.
The built-in multi-occur-in-matching-buffers hasn't been mentioned. I use a modified version of this (because I invariably want to search all buffers, and specifying a buffer name pattern each time is annoying).
(defun my-multi-occur-in-matching-buffers (regexp &optional allbufs)
"Show lines matching REGEXP in all file-visiting buffers.
Given a prefix argument, search in ALL buffers."
(interactive (occur-read-primary-args))
(multi-occur-in-matching-buffers "." regexp allbufs))
(global-set-key (kbd "M-s /") 'my-multi-occur-in-matching-buffers)
To invert the behaviour of the prefix argument so that the default behaviour is to search all buffers, change the call to:
(multi-occur-in-matching-buffers "." regexp (not allbufs))
(and, of course, update the docstring accordingly.)
I've fixed the TODO:
;; I know that string is in my Emacs somewhere!
(require 'cl)
(defcustom search-all-buffers-ignored-files (list (rx-to-string '(and bos (or ".bash_history" "TAGS") eos)))
"Files to ignore when searching buffers via \\[search-all-buffers]."
:type 'editable-list)
(require 'grep)
(defun search-all-buffers (regexp prefix)
"Searches file-visiting buffers for occurence of REGEXP. With
prefix > 1 (i.e., if you type C-u \\[search-all-buffers]),
searches all buffers."
(interactive (list (grep-read-regexp)
current-prefix-arg))
(message "Regexp is %s; prefix is %s" regexp prefix)
(multi-occur
(if (member prefix '(4 (4)))
(buffer-list)
(remove-if
(lambda (b) (some (lambda (rx) (string-match rx (file-name-nondirectory (buffer-file-name b)))) search-all-buffers-ignored-files))
(remove-if-not 'buffer-file-name (buffer-list))))
regexp))
(global-set-key [f7] 'search-all-buffers)
ibuffer might help you. Have a look at this article. I imagine that this might be most interesting for you:
'O' - ibuffer-do-occur
- Do an occur on the selected buffers.
This does a regex search on all the selected buffers and displays the result in an occur window. It is unbelievably useful when browsing through code. It becomes truly awesome when you combine it with the ‘filter’ powers of ibuffer (coming up ahead). Eg: Do C-x C-b, mark all files using (say) Perl major-mode, do occur to find out all places where a certain function is mentioned in these files. Navigate to the point at will through the Occur window.
'M-s a C-s' - ibuffer-do-isearch
- Do an incremental search in the marked buffers.
This is so awesome that you have to try it right this instant. Select two or more buffers, hit the hotkey, search for something that occurs in all these buffers. These two features alone are enough to make me a lifelong fan of IBuffer. Go do it now!
Taking a clue from Leo's comment to Bozhidar:
(defun my-isearch-buffers ()
"isearch multiple buffers."
(interactive)
(multi-isearch-buffers
(delq nil (mapcar (lambda (buf)
(set-buffer buf)
(and (not (equal major-mode 'dired-mode))
(not (string-match "^[ *]" (buffer-name buf)))
buf))
(buffer-list)))))
You might have to tweak the conditions inside the and to filter whatever other kinds of buffers you want to ignore.
Although this is not exactly what you're asking for, I search multiple files using grep (M-X grep) and grep-find (M-X grep-find).
This sort of does what you want, in that when you've come to the end of matches for the string/regexp you're searching for, the next search command will start in a new buffer.
(setq isearch-wrap-function 'isearch-bury-buffer-instead-of-wrap)
(defun isearch-bury-buffer-instead-of-wrap ()
"bury current buffer, try to search in next buffer"
(bury-buffer))
It doesn't switch to a different buffer when the search fails, and when you "back up" the search results by pressing <backspace>, you won't pop back into the previous buffers searched.
In Icicles, C-c ' is command icicle-occur, which can search multiple buffers.
C-u C-c ' searches a set of buffers that you choose. You can choose by dynamically filtering the buffer names with your minibuffer input, then hit C-! to search all of those buffers whose names match. Similarly, C-99 C-c ' searches only the buffers that are visiting files.
Like occur and grep, icicle-occur searches line by line. More generally, instead of using lines as the search contexts you can use any buffer portions at all. C-c ` (backquote instead of quote) is command icicle-search. With a non-negative prefix arg it searches a set of buffers that you choose.
The first thing you do is give it a regexp that defines the search contexts. E.g., if you give it .* then it acts like icicle-occur: each search context is a line. If you give it a regexp that matches only function definitions then those are the search contexts, and so on.
http://www.emacswiki.org/emacs/Icicles_-_Search_Commands%2c_Overview
Is there a substitute in emacs for the vi "gf" command?
meaning try to open the file which is under the cursor right now
if a real file name is in fact there.
Thanks
You want the find-file-at-point function (which is also aliased to ffap). It's not bound to a key by default, but you can use
M-x ffap
Or, you can put in your .emacs file:
(ffap-bindings)
This will replace many of the normal find-file key bindings (like C-x C-f) with ffap-based versions. See the commentary in ffap.el for details.
Thanks, it works quite well but somehow the vi (gf) version is
still somewhat smarter. I think it looks at some path variable for search paths.
I made something which is needlessly complicated but works for me (only in linux).
It uses the "locate" command to search for the path under the cursor.
I guess it could be made smarter by searching the relative path to the current file first.
sorry for my bad elisp skills...It can probably be achieved in a much nicer way.
put in your .emacs, then use with M-x goto-file
(defun shell-command-to-string (command)
"Execute shell command COMMAND and return its output as a string."
(with-output-to-string
(with-current-buffer standard-output
(call-process shell-file-name nil t nil shell-command-switch command))))
(defun goto-file ()
"open file under cursor"
(interactive)
(find-file (shell-command-to-string (concat "locate " (current-word) "|head -c -1" )) ))