Is there a way to provide a region to isearch?
I want to overload isearch so that:
C-s ->
1. isearch as usual if no region is selected, OR
2. isearch with region as to-be-used-for-search string
example: i 'select' the words "no exit", then C-s should search the buffer for "no exit".
In a way this can be done with C-s C-w C-w when the cursor is at the beginning of "no".
I wonder if there is a way to reverse this, so first select (some how) and then use the selection for searching
You may find the commands narrow-to-region and widen useful, do C-hfnarrow-to-regionRET and C-hfwidenRET to know more
UPDATE
Here is some quick and dirty code to do what you want, I have not handled some cases for simplicity but this should give an idea
(add-hook 'isearch-mode-end-hook (lambda ()
(when (buffer-narrowed-p)
(widen))))
(defun my-isearch(&optional start end)
(interactive "r")
(when (region-active-p)
(narrow-to-region start end))
(call-interactively 'isearch-forward-regexp))
UPDATE 2
Try the following function, this should do what you want
(defun my-isearch(&optional start end)
(interactive "r")
(if (region-active-p)
(progn
(let ((string (buffer-substring-no-properties start end)))
(deactivate-mark)
(isearch-resume string nil nil t string nil)))
(call-interactively 'isearch-forward-regexp)))
This is exactly what is available with Isearch+ (isearch+.el). Whether searching is restricted to the active region is controlled by Boolean option isearchp-restrict-to-region-flag.
You can use C-x n (command
isearchp-toggle-region-restriction) during search to toggle this behavior.
A second Boolean option, isearchp-deactivate-region-flag, controls whether the region is to be deactivated during search (e.g., so you can better see the search region).
Both options are true by default (search is restricted to the active region, and the region is deactivated during search).
(For Isearch to be limited to the active region in Info, you must also use library Info+ (info+.el).
UPDATE
Well, it was exactly what you described initially. Your later reply to comments shows that you do not in fact want to search the text in the region; you want to search for the text in the region, elsewhere in the buffer. This does the former, not the latter.
Related
I use org-mode to handle my tasks and projects in multiple files.
In the weekly agenda, it is possible to jump to the location of each TODO entry using <TAB> or <RET>. If the target file was not previously open, it is loaded an the cursor is set to the correct headline and the entire document is unfolded, including drawers.
I would very much prefer to see only a sparse tree with everything but the correct headline folded (subtree visibility does not matter).
It is possible to collapse the entire tree by cycling global visibility using C-u <TAB, but then I have to find the heading again.
I know I can hide the rest by narrowing the buffer as described here:
Emacs, How can I display only current task and hide others in org-mode?
but then I loose context (parent heading, easy access to siblings) and the drawers are still open.
Ideally, I would like to have a command that shows the following:
The top level headings
The current headline, and all it's parents up to the top level
The current headline's children
Edit:
A slighty modified version of the functions user3173715 posted seems to do the trick:
(defun org-show-current-heading-tidily ()
"Show next entry, keeping other entries closed."
(if (save-excursion (end-of-line) (outline-invisible-p))
(progn (org-show-entry) (show-children))
(outline-back-to-heading)
(unless (and (bolp) (org-on-heading-p))
(org-up-heading-safe)
(hide-subtree)
(error "Boundary reached"))
(org-overview)
(org-reveal t)
(org-show-entry)
(show-children)))
This is based on the answer in the edit in the actual question.
If of help to anyone:
When I tried to bind the above to a hotkey, I kept getting an error, commandp wrong argument something something ... It turned out one had to add the (interactive) flag to make it work.
Below is an example of the function tied to M-=
(defun org-show-current-heading-tidily ()
(interactive) ;Inteactive
"Show next entry, keeping other entries closed."
(if (save-excursion (end-of-line) (outline-invisible-p))
(progn (org-show-entry) (show-children))
(outline-back-to-heading)
(unless (and (bolp) (org-on-heading-p))
(org-up-heading-safe)
(hide-subtree)
(error "Boundary reached"))
(org-overview)
(org-reveal t)
(org-show-entry)
(show-children)))
(global-set-key "\M-=" 'org-show-current-heading-tidily)
#Patrick.B thanks for edit!
Check your org startup options (customize-group > org-startup) like org-startup-folded or org-agenda-inhibit-startup (others have mentioned these already) and set the options to show only the folded view. Org mode variables like #+STARTUP are discussed here.
You may notice that everything is folded when you now jump to the agenda, even the parents of the active item may not be visible. You can then make the context (parents, children, next sibling) visible with org-reveal (C-c C-r as per the manual)
I am not very sure if this is your demand (I just think it is suitable for your question title), but I use these two functions with plenty of pleasures by binding them in the speed command of org-mode. You can find these two functions in org-mode hacks. I slightly modified them to meet my purposes.
The two functions support:
Unfold every other headings except current heading
Move current heading to top of screen for wider reading area.
In order to accomplish (2), you need to (setq recenter-positions '(top bottom)), there may be some better solutions, but I did not dig into it.
(defun ded/org-show-next-heading-tidily ()
"Show next entry, keeping other entries closed."
(if (save-excursion (end-of-line) (outline-invisible-p))
(progn (org-show-entry) (show-children))
(outline-next-heading)
(unless (and (bolp) (org-on-heading-p))
(org-up-heading-safe)
(hide-subtree)
(error "Boundary reached"))
(org-overview)
(org-reveal t)
(org-show-entry)
(recenter-top-bottom)
(show-children)
(recenter-top-bottom)))
(defun ded/org-show-previous-heading-tidily ()
"Show previous entry, keeping other entries closed."
(let ((pos (point)))
(outline-previous-heading)
(unless (and (< (point) pos) (bolp) (org-on-heading-p))
(goto-char pos)
(hide-subtree)
(error "Boundary reached"))
(org-overview)
(org-reveal t)
(org-show-entry)
(recenter-top-bottom)
(show-children)
(recenter-top-bottom)))
And you can bind them with org-mode speed key with j and l, then you can use j and l to control the folding of headings when your cursor is in the beginning of headings.
(setq org-speed-commands-user
'(("j" . ded/org-show-next-heading-tidily)
("l" . ded/org-show-previous-heading-tidily))))
It is perfect for reading org-mode files, cheers!
Current (2022) emacs no longer requires elaborate setup to achieve the goals stated in the Question:
The top level headings
The current headline, and all it's parents up to the top level
The current headline's children
In the current Emacs and org-mode versions (Emacs 27.1, as of August 2022), you can press Shift-Tab Tab to close all headings, then open the current heading. Crucially, the cursor remains on the current collapsed heading so Tab reopens it.
The only significant change that I have from a default install is Evil, which may or may not affect the fact that the cursor remains on the collapsed heading.
Is there an analogue to inserting the word after point into the isearch query by hitting C-w after C-s but for the replace string (and replace regexp) queries?
I also enjoy Sacha Chua's modification of C-x inserting whole word around point into isearch:
http://sachachua.com/blog/2008/07/emacs-keyboard-shortcuts-for-navigating-code/
This too would be really useful in some cases if it could be used in replace string.
I'd be very thankful for any tips!
Thank you!
This will do it, although it isn't as fancy as C-w in isearch because you can't keep hitting that key to extend the selection:
(defun my-minibuffer-insert-word-at-point ()
"Get word at point in original buffer and insert it to minibuffer."
(interactive)
(let (word beg)
(with-current-buffer (window-buffer (minibuffer-selected-window))
(save-excursion
(skip-syntax-backward "w_")
(setq beg (point))
(skip-syntax-forward "w_")
(setq word (buffer-substring-no-properties beg (point)))))
(when word
(insert word))))
(defun my-minibuffer-setup-hook ()
(local-set-key (kbd "C-w") 'my-minibuffer-insert-word-at-point))
(add-hook 'minibuffer-setup-hook 'my-minibuffer-setup-hook)
EDIT:
Note that this is in the standard minibuffer, so you can use it use it anywhere you have a minibuffer prompt, for example in grep, occur, etc.
Two answers:
Replace+ automatically picks up text at point as the default value when you invoke replace commands.
More generally, Icicles does something similar to what scottfrazer's code (above) does, but it is more general. At any time, in any minibuffer, you can hit M-. (by default) to pick up text ("things") at point and insert it in the minibuffer. You can repeat this, to either (a) pick up successive things (e.g. words) of the same kind, accumulating them like C-w does for Isearch, or (b) pick up alternative, different things at point. More explanation here.
I think this exists in Emacs already - you just start replace with M-S-% and then press M-n (while the minibuffer is empty), this fills in the word under cursor, there are more useful things you can do with this, check http://endlessparentheses.com/predicting-the-future-with-the-m-n-key.html?source=rss#disqus_thread.
In Emacs, C-u C-SPC will "jump to the mark, and set the mark from
position popped off the local mark ring". Is there a way to go the opposite way around the mark ring? Say you have typed C-u C-SPC several times and want to go back to a mark you have seen without going all the way around the ring.
Unlike previous answers, this one does only exactly what was asked: the reverse of C-u C-SPC. I find it the most useful.
(defun unpop-to-mark-command ()
"Unpop off mark ring. Does nothing if mark ring is empty."
(interactive)
(when mark-ring
(setq mark-ring (cons (copy-marker (mark-marker)) mark-ring))
(set-marker (mark-marker) (car (last mark-ring)) (current-buffer))
(when (null (mark t)) (ding))
(setq mark-ring (nbutlast mark-ring))
(goto-char (marker-position (car (last mark-ring))))))
Comparing to the answer by scottfrazer, this command has a subtle difference of how it moves the cursor and mark, which more accurately mirrors C-u C-spc, and it does not require that the previous command was a unpop/pop-to-mark-command.
Here's a solution I just finished spending way too much time on. The difference between this and the other solutions is it works across buffers, ie it works on the 'global-mark-ring'. My goal was to emulate history browsing similar to Eclipse or IntelliJ. I bind it to M-left and M-right, obviously you can choose different keys for this.
(defun marker-is-point-p (marker)
"test if marker is current point"
(and (eq (marker-buffer marker) (current-buffer))
(= (marker-position marker) (point))))
(defun push-mark-maybe ()
"push mark onto `global-mark-ring' if mark head or tail is not current location"
(if (not global-mark-ring) (error "global-mark-ring empty")
(unless (or (marker-is-point-p (car global-mark-ring))
(marker-is-point-p (car (reverse global-mark-ring))))
(push-mark))))
(defun backward-global-mark ()
"use `pop-global-mark', pushing current point if not on ring."
(interactive)
(push-mark-maybe)
(when (marker-is-point-p (car global-mark-ring))
(call-interactively 'pop-global-mark))
(call-interactively 'pop-global-mark))
(defun forward-global-mark ()
"hack `pop-global-mark' to go in reverse, pushing current point if not on ring."
(interactive)
(push-mark-maybe)
(setq global-mark-ring (nreverse global-mark-ring))
(when (marker-is-point-p (car global-mark-ring))
(call-interactively 'pop-global-mark))
(call-interactively 'pop-global-mark)
(setq global-mark-ring (nreverse global-mark-ring)))
(global-set-key [M-left] (quote backward-global-mark))
(global-set-key [M-right] (quote forward-global-mark))
Following up my comment to scottfrazer's very handy solution, here's some advice which works in conjunction with that to make it easy to reverse directions around the mark ring at will, without the need to use a different key-binding for each direction.
I use cua-selection-mode, so for me C-SPC is bound to cua-set-mark, but I've written this as a macro so as to advise whichever function is bound to C-SPC, and verified that it works with the default set-mark-command.
To unpop, simply supply a negative prefix argument. e.g. C-- C-SPC
One of the nice things about cua-set-mark is that after an initial C-u C-SPC, you can continue to pop successive marks with just C-SPC, and I've included that behaviour here: After an initial C-- C-SPC you can continue un-popping with just C-SPC. To reverse the direction again and call pop-to-mark, simply supply a positive argument once more with C-u C-SPC.
(defmacro my-unpop-to-mark-advice ()
"Enable reversing direction with un/pop-to-mark."
`(defadvice ,(key-binding (kbd "C-SPC")) (around my-unpop-to-mark activate)
"Unpop-to-mark with negative arg"
(let* ((arg (ad-get-arg 0))
(num (prefix-numeric-value arg)))
(cond
;; Enabled repeated un-pops with C-SPC
((eq last-command 'unpop-to-mark-command)
(if (and arg (> num 0) (<= num 4))
ad-do-it ;; C-u C-SPC reverses back to normal direction
;; Otherwise continue to un-pop
(setq this-command 'unpop-to-mark-command)
(unpop-to-mark-command)))
;; Negative argument un-pops: C-- C-SPC
((< num 0)
(setq this-command 'unpop-to-mark-command)
(unpop-to-mark-command))
(t
ad-do-it)))))
(my-unpop-to-mark-advice)
Here's a function to do it:
(defun unpop-to-mark-command ()
"Unpop off mark ring into the buffer's actual mark.
Does not set point. Does nothing if mark ring is empty."
(interactive)
(let ((num-times (if (equal last-command 'pop-to-mark-command) 2
(if (equal last-command 'unpop-to-mark-command) 1
(error "Previous command was not a (un)pop-to-mark-command")))))
(dotimes (x num-times)
(when mark-ring
(setq mark-ring (cons (copy-marker (mark-marker)) mark-ring))
(set-marker (mark-marker) (+ 0 (car (last mark-ring))) (current-buffer))
(when (null (mark t)) (ding))
(setq mark-ring (nbutlast mark-ring))
(goto-char (mark t)))
(deactivate-mark))))
There are two rings of markers: one local to the current buffer and one global among all buffers.
By default, in Icicles (in Icicle global minor mode):
C-- C-SPC lets you trip among the local markers
C-- C-x C-SPC lets you trip among the global markers
IOW, with a negative prefix arg, C-SPC and C-x C-SPC navigate. Without it they just do what they normally do (set-mark-command and pop-global-mark, respectively).
Navigating works as follows:
Locations are available as completion candidates: the text is that of the marker's line.
Completion: you can use substring, regexp, prefix, fuzzy (various kinds).
You can cycle among any of the completion candidates, or go to any of them directly.
Keys available during completion include:
up, down -- cycle among candidates in *Completions*, without navigating to their locations
C-up, C-down -- cycle, navigating to each location in turn
C-RET, C-mouse-2 -- go directly to the current/clicked candidate (e.g. in *Completions*)
RET, mouse-2 -- same as previous (go to candidate), but end the command (done)
S-TAB -- apropos-complete (substring/regexp)
TAB -- prefix or fuzzy complete
It doesn't do exactly what you're asking for, but it might be worth looking for a package called marker-visit.el which lets you navigate the marks in the current buffer in 'buffer position order'. From that file:
;;; Commentary:
;; This file provides a simple way to navigate among marks in a
;; buffer. C-u C-SPC is similar, but takes you haphazardly around the
;; buffer. Setting bookmarks is a lot of extra work if you just want
;; to jump around your buffer quickly; plus, you have to come up with
;; a name for every bookmark.
;; All the marks you've left while editing a buffer serve as bread
;; crumb trails of areas in the buffer you've edited. It is
;; convenient to navigate back and forth among these marks in order.
;; This file provides two methods to do just that, marker-visit-prev
;; and marker-visit-next. These two functions will take you, from
;; point, to the nearest mark in either direction. The function
;; marker-visit-truncate-mark-ring will truncate the mark ring.
;; The marks you can visit in a buffer consist of: "the mark" plus the
;; contents of the mark-ring.
I bind [S-up] and [S-down] to marker-visit-prev and marker-visit-next respectively.
If you really want/need to navigate in the order your mark-ring has currently, then you might get somewhere by looking at the functions pop-to-mark-command and pop-mark and implementing your own versions to rotate the mark ring in the opposite direction.
The manual says this:
The variable mark-ring-max
specifies the maximum number of
entries to keep in the mark ring. If
that many entries exist and another
one is pushed, the earliest one in the
list is discarded. Repeating `C-u
C-' cycles through the positions
currently in the ring.
I suggest you use that to contain the size of the mark ring (to 3 or 4, mine is currently 16). Then you can move around it much faster using prefixes.
Also:
If you want to move back to the
same place over and over, the mark
ring may not be convenient enough. If
so, you can record the position in a
register for later retrieval (*note
Saving Positions in Registers:
RegPos.).
Not directly answer for this question for emacs keybindings.
For evil users
I found better-jumper for evil users. If you are interested with evil-mode honestly offering to use.
By using How it's offer in it's main repository
(with-eval-after-load 'evil-maps
(define-key evil-motion-state-map (kbd "C-o") 'better-jumper-jump-backward)
(define-key evil-motion-state-map (kbd "<C-i>") 'better-jumper-jump-forward))
It's really easy to go back and forward to old positions of the cursor.
Additional you can create new scenarios by using it's hook function like if I change the buffer mark the old point etc.
For emacs key binding fans
Only advice which I can give for default-keybinding style is helm-all-mark-rings. It gives best visibility about mark-rings.
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
I need to get selection as a string in my Emacs Lisp function.
Selected text is called region in Emacs universe. See How do I access the contents of the current region in Emacs Lisp?
The accepted answer pointed me to the right answer. I want to leave this piece of code for more ELisp beginners like me. regionp contains the "selection" (known as region in ELisp) as a variable in the ELisp function. The if condition checks if the region is active.
(defun get-selected-text (start end)
(interactive "r")
(if (use-region-p)
(let ((regionp (buffer-substring start end)))
(message regionp))))