I use helm for Emacs with several sources and wonder how I can extract the list of all entries that the user has marked with Ctrl+Space. As an example, execute the following in your *scratch* buffer
(require 'helm)
(defun helm-test-action (candidate)
"Test."
(interactive)
(message (concat "candidate = " (prin1-to-string candidate)
"\n, helm-marked-candidates = " (prin1-to-string (helm-marked-candidates)))))
(defun helm-test-case ()
"Test."
(interactive)
(helm :sources (list (helm-build-sync-source "First Source"
:candidates '("one" "two" "three")
:action #'helm-test-action)
(helm-build-sync-source "Second Source"
:candidates '("four" "five")
:action #'helm-test-action))))
and then M-x helm-test-case.
When you mark, say, "one" and "four" with Ctrl+Space and press Enter, how do I retrieve the two marked entries from my action? It seems candidate is always the line on which the cursor has been placed and (helm-marked-candidates) yields the list of marked entries of the current source. How do I get the list of marked entries across all sources?
Thanks for your help,
HPF
The answer is to use (helm-marked-candidates :all-sources t). This returns a list of all marked entries or, if none has been marked, the entry under the cursor when you hit enter.
It makes sense, of course, only if all your sources contain candidates of the same form and if the default action is the same for all sources. It seems this requirement isn't enforced though.
Regards,
HPF
Related
While opening a file in emacs using tab completion, emacs brings up the Completions buffer with a list of the possible completions. The list is ordered alphabetically. How would I configure emacs so that the default behavior is to sort the possible file completions based on time showing the newest or oldest file / directory at the top of the list? Could I further change the sorting criteria dynamically while looking at the completions buffer?
If you use Icicles then you can easily control sorting.
And you can easily change sort orders on the fly.
And for file-name completion the default sort orders include the order you are requesting. You can choose it to be your default sort order for file-name completion. Or you can choose it during file-name completion, by either cycling or completing its name.
And you can easily define your own sort orders.
If you use only vanilla Emacs then you can fiddle with completion metadata for file-name completion. See metadata categories display-sort-function and cycle-sort-function.
For example, you can define your own completion command that acts similar to read-file-name but that uses a different sort function.
This is what vanilla library tmm.el does, for example:
(minibuffer-with-setup-hook
#'tmm-add-prompt
(completing-read
(concat gl-str " (up/down to change, PgUp to menu): ")
(tmm--completion-table tmm-km-list) nil t nil
(cons 'tmm--history (- (* 2 history-len) index-of-default))))
(defun tmm--completion-table (items)
(lambda (string pred action)
(if (eq action 'metadata)
'(metadata (display-sort-function . identity))
(complete-with-action action items string pred))))
An additional approach can be to define advice for completion--insert-strings. For instance, I wanted to
Sort symbols with -- last.
Hide * buffers, unless explicitly filtering for them.
and came up with the following solution:
(advice-add #'completion--insert-strings :around #'my-cmplt-insstr)
(defun my-cmplt-insstr (oldfun strings &rest r)
"Hook into `completion--insert-strings' that applies some postprocessing."
;; Symbols: Sort `--' after anything else.
(when (cl-every #'intern-soft strings)
(mylog "my-cmplt-insstr: -- comes last")
(setq strings
(cl-sort strings #'<
:key (lambda (it) (s-count-matches "--" it))))
(setq strings
(cl-loop with last-had-ddash = nil
for string in strings
for has-ddash = (string-match-p "--" string)
if (and has-ddash (not last-had-ddash))
collect ""
collect string
do (setq last-had-ddash has-ddash))))
;; Buffers: * hidden by default.
(when (cl-member "*Messages*" strings :test #'string=)
(unless (cl-every (lambda (it) (string-prefix-p "*" it)) strings)
(setq strings
(cl-remove-if (lambda (it) (string-prefix-p "*" it)) strings))))
(apply oldfun strings r))
This solution uses rough heuristics to guess what is being completed, but it could be used as an alternate starting point, e.g. with specific read-* functions being advised to set flags for determining which rules are applied.
How can I let the user select multiple items from a list instead of just one? Like in the C-x b menu in helm.
Currently I can only select a single item instead of getting a complete list:
(defun test-main ()
(interactive)
(let ((choice (completing-read "Select: " '("item1 item2 item3"))))
(message choice)))
You can do that with completing-read-multiple:
(defun test-main ()
(interactive)
(let ((choice (completing-read-multiple "Select: " '("item1" "item2" "item3"))))
(message "%S" choice)))
It returns the selected items as a list, so if you type item2,item3 at the prompt, it returns ("item2" "item3").
Because that's what vanilla completing-read does. It reads and returns a single choice, providing completion to help you choose.
You can do what you are asking for with Icicles. It redefines function completing-read when Icicle mode is on.
Many Icicles commands are multi-commands, which means that you can make multiple input choices in a single command execution: a multiple-choice command. You can define your own multi-commands, using any actions.
And for any completion (not just for a multi-command), you can manipulate, save, and restore sets of completion candidates.
(You can also enter multiple inputs in the minibuffer. This is useful even for commands that read input without completion.)
I tried out Sublime Text 2 recently, and I found Goto Anything superbly useful for navigating source code (Ctrl-P file#symbol seems to work really well). Is there something similar for Emacs? Preferably something that just works, without a ton of custom elisp.
What I've tried so far:
I've seen Helm and Anything, but as far as I understand neither of them is capable of actual "instant" search (see edit below).
I've used multi-occur-in-matching-buffers, but it too seems unable to satisfy the "instant" criterion.
imenu / idomenu works well for single files, but doesn't work across files.
I currently use #2 and #3 together, as a poor substitute for Goto Anything.
If not an exact clone of Goto Anything, then I could make do with a naive instant search solution (one that searches for a given string across all open buffers and displays results dynamically). So that's acceptable too.
I use Emacs 24.2, so any v24-only elisp is also fine.
EDIT: I gave Helm another shot, at event_jr's suggestion, and I found that it does support instant searching across all open buffers. helm-multi-occur + helm-follow-mode comes surprisingly close to meeting my needs, the only minor issues being (at the risk of sounding nit-picky):
I haven't found a way to turn on helm-follow-mode automatically when I run helm-multi-occur. I have to invoke it manually with C-c C-f. Anyone care to take a shot at this with a snippet of elisp? (see edit #2 below)
it isn't "intelligent" like ST2's Goto Anything (i.e., it doesn't understand "symbols" in source code, like Goto Anything does).
EDIT #2: Now I've got most of Goto Anything, thanks to event_jr's answer below (and of course, thanks to Helm's creator, Thierry Volpiatto). I recommend it heartily to anyone looking for a similar feature. Below is the elisp I'm currently using:
;; instant recursive grep on a directory with helm
(defun instant-rgrep-using-helm ()
"Recursive grep in a directory."
(interactive)
(let ((helm-after-initialize-hook #'helm-follow-mode))
(helm-do-grep)))
;; instant search across all buffers with helm
(defun instant-search-using-helm ()
"Multi-occur in all buffers backed by files."
(interactive)
(let ((helm-after-initialize-hook #'helm-follow-mode))
(helm-multi-occur
(delq nil
(mapcar (lambda (b)
(when (buffer-file-name b) (buffer-name b)))
(buffer-list))))))
;; set keybindings
(global-set-key (kbd "C-M-s") 'instant-search-using-helm)
(global-set-key (kbd "C-M-S-s") 'helm-resume)
(global-set-key (kbd "C-M-g") 'instant-rgrep-using-helm)
Just use helm.
It is perhaps more configuration than you asked for, but once you get it
configured how you like, it should be quite comfortable. Very much like Emacs
;).
And you should file a bug with Thierry for getting some more newbie friendly
defaults. He is quite responsive with issues.
helm-multi-occur
Primarily multi-buffer interactive "occur" is provided through
helm-multi-occur. If you execute the command, you'll notice that you have
to pick some buffers first (use C-SPC to select from the list,
M-SPC to select all). Then you can enter your query at the next
prompt. It's easy to make your own version that skips the buffer selection
like so:
(eval-after-load "helm-regexp"
'(setq helm-source-moccur
(helm-make-source "Moccur"
'helm-source-multi-occur :follow 1)))
(defun my-helm-multi-all ()
"multi-occur in all buffers backed by files."
(interactive)
(helm-multi-occur
(delq nil
(mapcar (lambda (b)
(when (buffer-file-name b) (buffer-name b)))
(buffer-list)))))
helm-buffers-list
Often you don't care about the exact occurrences of the query string, but want a
list of all buffers that contain it.
helm-buffers-list has some tricks up its sleeve. The first symbol you
specify is filtering by major-mode, and you can use the "#" prefix to narrow
the list to buffers that contain a string.
To wit, "ruby #prompt" will show you a list of buffers whose major-mode
contains "ruby" and whose contents contains "prompt". Or you can just use "#prompt" to show all buffers that contain "prompt".
Powerful and comfortable once you get used to it.
EDIT modified my-helm-multi-all to enable helm-follow-mode.
EDIT 2 update helm-follow-mode code to reflect helm changes.
EDIT 3 updated again to reflect helm changes
Emacs has Projectile satisfy your need:
jump to a file in project
multi-occur in project buffers
Heml is far from the fuzzy searching of ST3.
Fiplr looks promising but doesn't work on my laptop (see first issue on the github)
Simp.el looks like Fiplr but doesn't work either on my end.
Projectile works for me! Here's your solution!
I used also ido-mode and flx-ido for the fuzzy searching,
and for the vertical way of displaying results I use this in my .emacs:
;; Display ido results vertically, rather than horizontally
(setq ido-decorations (quote ("\n-> " "" "\n " "\n ..." "[" "]" " [No match]" " [Matched]" " [Not readable]" " [Too big]" " [Confirm]")))
(defun ido-disable-line-truncation () (set (make-local-variable 'truncate-lines) nil))
(add-hook 'ido-minibuffer-setup-hook 'ido-disable-line-truncation)
(defun ido-define-keys () ;; C-n/p is more intuitive in vertical layout
(define-key ido-completion-map (kbd "C-n") 'ido-next-match)
(define-key ido-completion-map (kbd "C-p") 'ido-prev-match))
(add-hook 'ido-setup-hook 'ido-define-keys)
Icicles offers some features that are similar to what it seems you are looking for.
C-x b and C-x C-f, to choose buffers or files, allow multi-completion: you can type a pattern to match the buffer/file name and/or a pattern to match content in the buffer/file. Candidates are filtered incrementally as you type (what you call "instant" is what Emacs calls "incremental"). You can refine either or both search patterns progressively, narrowing the choices in different ways. You can visit any number of buffers/files that match, at the same time. You can also use the same method to search the marked files in Dired: C-F.
C-c `(icicle-search) incrementally searches across multiple buffers or files. Again, progressive refinement etc.
The main difference between #1 and #2 is this:
For #1, you just want to find matching buffers or files. You don't care immediately about finding particular occurrences --- any match suffices.
For #2, you provide the buffers or files to search, and you want to navigate among search hits.
You can also use #1 to locate the buffers and files you want, then search their contents: The content-matching pattern you last used is available as the search pattern for Isearch (C-s).
for emacs I customize and modify this solution (for use install helm):
(defun helm-occur-from-point (initial-value)
"Invoke `helm-occur' from point."
(interactive)
(let ((input initial-value)
(bufs (list (buffer-name (current-buffer)))))
;; (isearch-exit)
(helm-occur-init-source)
(helm-attrset 'moccur-buffers bufs helm-source-occur)
(helm-set-local-variable 'helm-multi-occur-buffer-list bufs)
(helm-set-local-variable
'helm-multi-occur-buffer-tick
(cl-loop for b in bufs
collect (buffer-chars-modified-tick (get-buffer b))))
(helm :sources 'helm-source-occur
:buffer "*helm occur*"
:history 'helm-grep-history
:input input
:truncate-lines t)))
(defun get-point-text ()
"Get 'interesting' text at point; either word, or region"
(if mark-active
(buffer-substring (mark) (point))
(thing-at-point 'symbol)))
(defun helm-occur-1 (initial-value)
"Preconfigured helm for Occur with initial input."
(helm-occur-from-point initial-value))
(defun bk-helm-occur ()
"Invoke helm-occur with initial input configured from text at point"
(interactive)
(helm-occur-1 (get-point-text)))
(global-set-key (kbd "M-s-o") 'bk-helm-occur)
primary it based on
#see https://news.ycombinator.com/item?id=6872508 but on last helm versions not work but fixed with my changes (just copy/paste from some internal helm modules)
I would like to open my five (or so) favorite files with two keystrokes in emacs. I am thinking of F9-a for file a, F9-b for file b, etc.
I have the org-mode agenda at F5 (instead of the "default" C-a), so I hit F5-a for today's agenda. I'd love to have the same for my org-file, my contacts file and so on.
Is there a way (or rather: What is the way) to make F9 open a sub-menu with a list of my favorite files to choose with another keystroke?
This setup does what you are asking for, at least in terms of keymaps. It doesn't actually pop up a menu.
(setq my-file-menu-keymap
(let ((keymap (make-sparse-keymap)))
(dolist (pair '(("a" . "~/.emacs")
("b" . "~/.phones")
("c" . "~/org/daily.org")))
(define-key keymap (car pair)
`(lambda () (interactive) (find-file ,(cdr pair)))))
keymap))
(global-set-key (kbd "<f9>") my-file-menu-keymap)
I use a single key to cycle through my favorite files (works well for a small number of files and I don't care about the random access). You can find code for that in this answer to a different SO question (see cycle-special-files).
You may get better results with a package which allows you to complete file names from recent files. This is less static than binding file names explicitly to keys and you can easily access much more recently used files with this method than only 5.
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