Searching for marked (selected) text in Emacs - search

I use emacs for viewing and editing code and other text files. I wanted to know if there is a way to search forward or backward for text which is marked in the current buffer. Similar to what I can do in notepad or wordpad. As in can I mark some text in the buffer and do a C-s or C-r and be able to search with the marked text without actually typing in the whole search text?
Thank you,
Rohit

#Alex nails it.
Another option I use quite often is C-s C-w to search for the word after the current mark. Hitting C-w repeatedly increases the search with additional words (e.g., C-s C-w C-w C-w searches for the 3 words after the current mark).
Similarly, C-s M-s C-e searches for the rest of the line after the current mark and C-s C-M-y searches for the character after the mark. These are both repeatable in the same way (the former by somewhat-awkwardly repeating M-s C-e after C-s).

Yes. M-W (to get a copy of the selected text) C-s <RET> C-y <RET>. Then repeat C-s as needed. Similarly for C-r.

I am using the following which does not have the problem of having to type more then one successive C-s to find later occurences:
(defun search-selection (beg end)
"search for selected text"
(interactive "r")
(kill-ring-save beg end)
(isearch-mode t nil nil nil)
(isearch-yank-pop)
)
(define-key global-map (kbd "<C-f3>") 'search-selection)
The disadvantage of the previous code is that the selected text is copied to the stretch. The following code does not have this problem:
(defun search-selection (beg end)
"search for selected text"
(interactive "r")
(let (
(selection (buffer-substring-no-properties beg end))
)
(deactivate-mark)
(isearch-mode t nil nil nil)
(isearch-yank-string selection)
)
)
(define-key global-map (kbd "<C-f3>") 'search-selection)

Other answers describe how to search for copied text, or how to search for the word at point. But none of them actually describe how to "search with the marked text."
Adding the following hook will make it so that the currently-selected text is the text used for an isearch:
(defun jrh-isearch-with-region ()
"Use region as the isearch text."
(when mark-active
(let ((region (funcall region-extract-function nil)))
(deactivate-mark)
(isearch-push-state)
(isearch-yank-string region))))
(add-hook 'isearch-mode-hook #'jrh-isearch-with-region)
Tip: This pairs nicely with expand-region.

The shortest key sequence to do this is M-w C-s M-y.

There is a great function for this: isearch-forward-symbol-at-point. It highlights all occurrences of the word where your point is located - no need to place the point at the beginning of the word. Then you can move to next or previous with C-s or C-r.
Note that it is an exact match: if you use it on hi it won't match chill for instance.
I mapped if to command-f (mac OSX): (global-set-key (kbd "s-f") 'isearch-forward-symbol-at-point) in the init file.

The answers above (including the accepted one) are too cumbersome IMHO. I found the following info and like it well better:
“Ctrl+s Ctrl+w”. This will search the current word, but you must move
your cursor to the beginning of the word first.
http://xah-forum.blogspot.com/2009/08/search-word-under-cursor-in-emacs.html

You can find C-s help by doing C-h k C-s, and it says:
Type DEL to cancel last input item from end of search string. Type RET
to exit, leaving point at location found. Type LFD (C-j) to match end
of line. Type C-s to search again forward, C-r to search again
backward. Type C-w to yank next word or character in buffer onto the
end of the search string, and search for it. Type C-M-w to delete
character from end of search string. Type C-M-y to yank char from
buffer onto end of search string and search for it. Type M-s C-e to
yank rest of line onto end of search string and search for it. Type
C-y to yank the last string of killed text. Type M-y to replace string
just yanked into search prompt with string killed before it. Type C-q
to quote control character to search for it. Type C-x 8 RET to add a
character to search by Unicode name, with completion. C-g while
searching or when search has failed cancels input back to what has
been found successfully. C-g when search is successful aborts and
moves point to starting point.
If you try to exit with the search string still empty, it invokes
nonincremental search.
Type M-c to toggle search case-sensitivity. Type M-s i to toggle
search in invisible text. Type M-r to toggle regular-expression mode.
Type M-s w to toggle word mode. Type M-s _ to toggle symbol mode. Type
M-s ' to toggle character folding.
Type M-s SPC to toggle whitespace matching. In incremental searches, a
space or spaces normally matches any whitespace defined by the
variable ‘search-whitespace-regexp’; see also the variables
‘isearch-lax-whitespace’ and ‘isearch-regexp-lax-whitespace’.
Type M-s e to edit the search string in the minibuffer.
Also supported is a search ring of the previous 16 search strings.
Type M-n to search for the next item in the search ring. Type M-p to
search for the previous item in the search ring. Type C-M-i to
complete the search string using the search ring.
Type M-% to run ‘query-replace’ with string to replace from last
search string. Type C-M-% to run ‘query-replace-regexp’ with the last
search string. Type M-s o to run ‘occur’ that shows the last search
string. Type M-s h r to run ‘highlight-regexp’ that highlights the
last search string.
Type C-h b to display all Isearch key bindings. Type C-h k to display
documentation of Isearch key. Type C-h m to display documentation of
Isearch mode.

Adopted Jackson's Answer for Swiper:
(defun swiper-isearch-selected ()
"Use region as the isearch text."
(interactive)
(if mark-active
(swiper-isearch (funcall region-extract-function nil))
(swiper-isearch)))
Additionally, if there is no selected region, it just falls back to the regular swiper-isearch.

Related

Difference Between Substitute and Change in Vim

In Vim, what is the difference between s and c? If I substitute n letters or words, is there any difference to changing them? And are there any instances where substituting and changing are different?
When in doubt, check the :help:
:help s
*s*
["x]s Delete [count] characters [into register x] and start
insert (s stands for Substitute). Synonym for "cl"
(not |linewise|).
:help c
*c*
["x]c{motion} Delete {motion} text [into register x] and start
insert. When 'cpoptions' includes the 'E' flag and
there is no text to delete (e.g., with "cTx" when the
cursor is just after an 'x'), an error occurs and
insert mode does not start (this is Vi compatible).
When 'cpoptions' does not include the 'E' flag, the
"c" command always starts insert mode, even if there
is no text to delete.
TL;DR: c takes normal movements (like cw to change the word you're on) to determine how much text to delete before entering insert. s takes a number (like 10s) to determine how much text to delete before entering insert. That being said, you could do <num>s with c, by using c<num>l (and the help mentions that s is, in fact, a synonym for cl).

How does "daw" to delete a word in Vim work if "dw" only deletes part of the word?

I'm a Vim user and I want to delete a keyword. I always use "dw" to delete a specific keyword, but it sometimes doesn't work well. For example, I want to delete "valule123" in sample program.
ex) public void function(int valule123)
When I put my cursor is on "2", and then I input "dw", only part of keyword is deleted and the result is "valule1". Why?
I tried another command, "daw". In this case, the result is just as expected! But what does "a" mean? I think "a" means "add".
The command/action/verb d in Vim acts on an object. For dw the object is "all text the cursor moves over with a w command". For daw you're actually using a Vim concept called a "text object". There are many of these, including aw (a word), as (a sentence), i} (inner {...} block, e.g. code within a block in C code), it (inner tag, useful for XML-like languages), and more.
See :help text-objects for the full list.
These can not only be used by the d command, but any command/action/verb that takes an object. For example, =aB will reindent an entire code block, cas will delete a sentence and drop you into insert mode to type a new one, and yit will yank/copy everything inside the current XML tag.
dw: deletes word from the cursor to the end of the word.
daw: deletes the word under the cursor.
There is also the option of writing caw, this one does the same as daw, but also puts you into insert mode.
If you type :help daw inside Vim console, you will see it means "delete a word". So, 'a' means a here. More from the doc:
For example, compare "dw" and "daw": "dw" deletes from the cursor
position to the start of the next word, "daw" deletes the word under
the cursor and the space after or before it.
If you don't want to delete the space after/before it, you can use diw (delete inner word).
For these cases, you can always use: diw that way it won't matter where your cursor is over the word it will always remove the entire word.
d: delete
i: internal/inner
w: word
Another useful use is ciw (change internal word) to delete the word and go into insert mode.
Cheers!
In case that I know the word to delete, my flow of deleting would be:
Find :/deleting-word and cursor at the end of the deleting word.
on -- INSERT --, combo [ctrl + w] to delete that word, or keep going for multiple words.
lbce may work well if you want to change a word in a english sentence despite where the cursor position in the word you want to delete.
When navigating around dw will delete a word. Of course w will navigate from the first character of a word to the next word, whilst b the previous word etc.
Given that you use the navigation keys j,k,h,l (down, up, left, right ), if you're in a word on a particular charachter, you can type d for delete then l and the character to the right will be deleted, or h and the character to the left will. It's more intuitve when your fingers are actually on the keys 😄

Emacs: Is it possible to list all matching lines for a certain query string for marked files in dired?

I found out M-x occur the other day.
(How to achieve code folding effects in Emacs?)
I wonder if I could list all matching lines in multiple files(or buffers) preferably marked in dired mode.
Files
This can be done using package noccur which can be installed from MELPA.
It provides two functions:
noccur-dired that will perform multi-occur on dired marked files
noccur-project that will perform multi-occur on all files in current project. This is recursive.
From documentation a typical usage is: M-x noccur-project RET foo RET
The occur buffer's content can then be edited with occur-edit-mode (bound to e). To save changes in all modified buffer and go back to occur-mode press C-c C-c.
Buffers
This can be done using the built-in ibuffer. Mark buffers with m key, then key O to launch ibuffer-do-occur on marked buffers. I personally activate ibuffer using (defalias 'list-buffers 'ibuffer) in my .emacs.
You can also use the built-in multi-occur-in-matching-buffers that will perform multi-occur on buffers matching a regexp. Typical usage is M-x multi-occur-in-matching-buffers RET ext$ RET regexp RET where ext$ is regexp for buffers already opened in Emacs, and regexp is what to match.
M-x multi-occur
M-x multi-occur-in-matching-buffers
and also:
M-x multi-occur-in-this-mode
(defun get-buffers-matching-mode (mode)
"Returns a list of buffers where their major-mode is equal to MODE"
(let ((buffer-mode-matches '()))
(dolist (buf (buffer-list))
(with-current-buffer buf
(if (eq mode major-mode)
(add-to-list 'buffer-mode-matches buf))))
buffer-mode-matches))
(defun multi-occur-in-this-mode ()
"Show all lines matching REGEXP in buffers with this major mode."
(interactive)
(multi-occur
(get-buffers-matching-mode major-mode)
(car (occur-read-primary-args))))
You may try
(defun dired-do-multi-occur (regexp)
"Run `multi-occur' with REGEXP on all marked files."
(interactive (list (read-regexp "Regexp: ")))
(multi-occur (mapcar 'find-file-noselect (dired-get-marked-files)) regexp))
Run it in a dired buffer with M-x dired-do-multi-occur or bind it to a key of your liking.
Warning: all marked files will be opened by emacs.
In Icicles, use M-s M-s m (command icicle-search-dired-marked-recursive) to search the marked files in the current Dired buffer and in all marked subdirs, recursively.
Similarly, in your bookmark-list display the same key, M-s M-s m, searches the targets of all marked bookmarks. And similarly for Ibuffer and Buffer Menu: M-s M-s m searches the marked buffers.
This is Icicles search, which is a different kind of incremental search (and on-demand replace). You can confine searching within particular contexts (defined by a regexp). The search hits are updated incrementally as you change your search pattern. You can combine multiple search patterns, to refine your search progressively. You can cycle through any set of search hits or access them directly. You can change cycle orders --- you are not limited to buffer-occurrence order.
http://www.emacswiki.org/emacs/Icicles_-_Search_Commands%2c_Overview
Let me improve on the answer of mk1 since I think it is the best one so far. This keeps the same history of previous searches of occur and allows for the optional argument for displaying more lines after or before the match (using C-u followed by a number before calling the function), just as in standard occur.
(defun dired-do-multi-occur (regexp &optional nlines)
"Run `multi-occur' with REGEXP on all dired marked files."
(interactive (occur-read-primary-args))
(multi-occur (mapcar 'find-file-noselect (dired-get-marked-files)) regexp nlines))
Wrt Dired:
Not sure whether you are asking (a) to regexp-search the files marked in Dired or (b) to mark files (in Dired) whose contents match a regexp. - or (c) something else.
You can do the former (search marked files) using A (or M-S a C-M-s for incremental regexp search). And this answer lets you search all files marked here and in marked subdirs (recursively).
You can do the latter (mark the files whose contents match) using %q (dired-mark-files-containing-regexp).

How do I get fine-grained undo in Vim

I find Vim's undo to be a bit too coarse. E.g. if I type something like this:
a // to go into edit mode
to be or not to ve
<esc> // to exit insert mode
Oops! I made a typo. I want to start undoing so I press u, but then it clears the whole line. Is there a way to undo word-by-word or character-by-character?
You can break undos via :help i_ctrl-g_u. You can map this if you want for every character, but that might a little bit complicated. Mapping this to space button is a way.
:inoremap <Space> <Space><C-g>u
After that every word can be undo via u
So as you see from the others what you are asking for doesn't exist in Vi (AFAIK).
Undo undoes what your last action was. If your last action was to enter insert mode and then add a line and then exit insert mode. That will be undone, however if from the default mode you hit the "x" key then you will delete 1 character or if in visual mode with text selected the text will be deleted. If you hit undo then you will restore that one character or the text that was selected.
...You should think of this as an action, and actions can be atomically undone or restored
As mentioned previously if you wish to delete the previous word then you should be able to hit Ctrl + w and delete the previous word while remaining in insert mode.
If you exit insert mode you can navigate (motion) back a word with "b" forward a word with "w" to the end of a word with "e", and can cut (which leaves you in insert mode) with "c" or delete with "d". Both actions cut and delete can accept a motion following them so you can delete the current word / up to the next word with "dw" or cut the previous word with "cb"
This concept becomes more useful when you remember to use the "." command (in normal mode). This command is to repeat the last action. I have used this many times to find and replace a small group of words in a file (It is especially useful if you are paranoid about changing too much). The scenario would be the following:
File:
This is my post
really it is a test
this is the middle
This is the end
if I wanted to replace "is" with "was" I could write:
%s/\<is\>/was/g
however if I wanted to change the first line and the third line "is" to "was" (and I didn't know their line numbers, and I wanted to see if there were any other places I wanted to change is to was I could type
"/is"
hit "n" until I reach the place I want substituted, and then hit "cw" and type "was"
I can now hit "n" until I reach another place I want substituted and hit ".", and that will replace "is" with "was" (Note: my search string didn't limit to the word "is", just the two characters "is" so "This" & "this" will match in this case)
No, it is not possible and is actually not necessary either. Vim has a million ways of dealing with that. Try cb for example. Or bC. Or brb. Or Tspace to jump back instead of b. Or ciw.
You can, of course use most of these solutions in insert mode (by pressing CTRLo first), or bind one to your favorite key combination (:help map and :help imap).
On Linux, using control-w while in input mode deletes the last 'word'.

Unable to search effectively in Emacs

I want to have a similar tool in Emacs as the following in Vim
:g/search/
to get a list of matches.
How can you get a list of matches in Emacs?
M-x occur?
From the manual:
M-x occur
Prompt for a regexp, and display a list showing each line in the buffer that contains a match for it. The text that matched is highlighted using the match face. To limit the search to part of the buffer, narrow to that part (see Narrowing). A numeric argument n specifies that n lines of context are to be displayed before and after each matching line. The default number of context lines is specified by the variable list-matching-lines-default-context-lines.
In the *Occur* buffer, you can click on each entry, or move point there and type RET, to visit the corresponding position in the buffer that was searched. o and C-o display the match in another window; C-o does not select it. Alternatively, you can use the C-x ` (next-error) command to visit the occurrences one by one (see Compilation Mode).
Typing e in the *Occur* buffer switches to Occur Edit mode, in which edits made to the entries are also applied to the text in the originating buffer. Type C-c C-c to return to Occur mode.
The command M-x list-matching-lines is a synonym for M-x occur.
In addition to M-x occurr check also M-x grep. This works in several files at once.
My usual workflow is not to get a list and choose (don't know how to do that), but to use the incremental search:
C-s <search target>
gets the fist match after the point. If you don't like it another C-s gets the next one. Continue until you're happy (you'll need an extra C-s to wrap around from the and of the buffer). New enough emacsen can also highlight all the matches that are visible.
As noted in the comments by Török Gábor, this is the typical keybinding of isearch-forward. In the event that your bindings are different, you need to modify the prescribed procedure.

Resources