I often use the capture-refile-archive structure of org-mode but I have problem with the way the refiling works. I use IDO completion so that when I refile a tree C-c C-w I get all the possible trees to refile under in the mini-buffer.
However, this results in a huge number of possible completions that really aren't very readable. It would be far better if you could choose a refile file location and then use the org-goto-interface temporary buffer to choose a particular subtree.
Does anybody know how this could be done?
Perhaps the settings you are looking for are
(setq org-refile-use-outline-path 'file)
(setq org-outline-path-complete-in-steps t)
org-refile-use-outline-path lets you give the refile targets as paths (file.org/heading/subheading) and org-outline-path-complete-in-steps will pause after competing each stage of the path. Start refiling, type the path and press [tab] to get a list of all the top level headlines. Continue to the location you want.
You can do this by setting org-refile-targets before running
org-refile. For example, I've
described doing
this for selecting and refiling to Org files that aren't in the global
org-refile-targets. That was focused on having functions other than
org-refile to handle special cases, but if you wanted org-refile to
always ask for a buffer or file to refile to, you could advise
org-refile to override org-refile-targets or you could set
org-refile-targets to a function that returns a selected buffer.
(defun km/get-open-org-file ()
(buffer-file-name
(get-buffer
(org-icompleting-read "Buffer: "
(mapcar 'buffer-name
(org-buffer-list 'files))))))
(setq org-refile-targets '((km/get-open-org-file . (:maxlevel . 2))))
How exactly you set up org-refile-targets depends a lot on your work
flow and structure for notes, but those examples hopefully give you an
idea of how you can get things working the way you want.
Related
Normally I want ido to ignore all non-user buffers, i.e. all buffers which start with a *. I have achieved this using the following setting:
(setq ido-ignore-buffers '("\\` " "^\*"))
However, this poses a problem when working with a shell or an interpreter, e.g. ielm, where the interaction buffer is named *ielm*. Obviously adding all buffers to be ignored manually is not really an option because the list can get quite long with a lot of different emacs packages loaded. I know about C-a which disabled the ignore pattern from within ido, however, I don't want to hit C-a every time I switch to an ielm buffer.
My question is:
Is there some variable which allows to specify buffers which ido should not ignore (although they match the normal ignore list)? Or is there some other approach for solving this?
The list that the ido-ignore-buffers variable points to may contain not only regular expressions but also functions (any mix of them, actually). It's easy to provide a function to filter out all non-user buffers except *ielm*:
(defun ido-ignore-non-user-except-ielm (name)
"Ignore all non-user (a.k.a. *starred*) buffers except *ielm*."
(and (string-match "^\*" name)
(not (string= name "*ielm*"))))
(setq ido-ignore-buffers '("\\` " ido-ignore-non-user-except-ielm))
Here's an example of having multiple unignored buffer names:
(setq my-unignored-buffers '("*ielm*" "*scratch*" "*foo*" "*bar*"))
(defun my-ido-ignore-func (name)
"Ignore all non-user (a.k.a. *starred*) buffers except those listed in `my-unignored-buffers'."
(and (string-match "^\*" name)
(not (member name my-unignored-buffers))))
(setq ido-ignore-buffers '("\\` " my-ido-ignore-func))
An interesting example of using ignore functions can be found among comments in the ido.el source code (I've removed ;; at the beginning of each line):
(defun ido-ignore-c-mode (name)
"Ignore all c mode buffers -- example function for ido."
(with-current-buffer name
(derived-mode-p 'c-mode)))
Basically, once you've got buffer name, you can do any checking/ignoring you want.
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)
To archive the DONE tasks i am using
C-c C-x a
command. The draw back is i have to manually move over the DONE tasks one by one and then archive it.
How to archive all the DONE tasks using a single command.
You can bulk archive (or refile/change todo etc) from within the Agenda view.
http://orgmode.org/manual/Agenda-commands.html#Agenda-commands
If you call Org-Agenda from within the buffer you want to archive you can temporarily restrict it to only that buffer and view only todo entries and filter for only DONE
C-c a < t
N r
Where N corresponds to the shortcut for your DONE state (with default states it would be 2)
Then you'd simply need to mark all the desired headlines and bulk archive
m (mark for bulk action)
B a (or B $ for arch->sibling)
Here's a corrected version of madalu's snippet. Note that this version also only operates on the current subtree (change 'tree back to 'file to operate over the entire file).
(defun org-archive-done-tasks ()
(interactive)
(org-map-entries
(lambda ()
(org-archive-subtree)
(setq org-map-continue-from (org-element-property :begin (org-element-at-point))))
"/DONE" 'tree))
You can write a function using org-map-entries:
(defun my-org-archive-done-tasks ()
(interactive)
(org-map-entries 'org-archive-subtree "/DONE" 'file))
Also from http://orgmode.org/manual/Moving-subtrees.html#Moving-subtrees
C-u C-c C-x C-s
Check if any direct children of the current headline could be moved to the archive. To do this, each subtree is checked for open TODO entries. If none are found, the command offers to move it to the archive location. If the cursor is not on a headline when this command is invoked, the level 1 trees will be checked.
There is now a command org-archive-all-done that is built into org-mode, and in org-archive.el.
If you want to do it in the source Org buffer (as opposed to in an Org agenda view), and if they are following each other, you can select all of them in a region, and apply a command (such as C-c C-t d).
Only setting needed:
;; Some commands act upon headlines in the active region.
(setq org-loop-over-headlines-in-active-region 'start-level)
I found the direct "org-map-entries" method in a couple of these answers to be a little "fragile" for some reason in situations with more varied nesting and TODOs at multiple levels.
This method - generating a list and then archiving in reverse (to avoid changes in positioning) seems to cover every use case I've thrown at it. Sharing it here for anyone else that runs into trouble.
Note the "TODO" string match on the last line needs to match how you have your TODOs defined exactly (for example in a vanilla case, the match may be: "TODO=\"DONE\"").
(defun org-archive-done-tasks ()
"Archive all tasks marked DONE in the file."
(interactive)
(mapc (lambda(entry)
(goto-char entry)
(org-archive-subtree))
(reverse (org-map-entries (lambda () (point)) "TODO=\"★ DONE\"" 'file))))
Based on Robert's Answer
(require 'org)
(require 'org-archive)
(add-hook 'org-mode-hook (lambda () (add-hook 'after-save-hook 'org-archive-all-done nil t)))
How do I prevent Emacs from showing me all the files I'm not interested in (such as ~ backup files, .pyc files, or .orig files) when I: C-x C-f TAB ?
It is working in one respect: if I know the file I want to open begins with foo and I type foo TAB then the mini-buffer correctly autocompletes all the way to foo.py. It correctly ignored foo~ and foo.pyc, because both ~ and .pyc are in completion-ignored-extensions. It also correctly lets me open either ignored file if I really want to by typing in all the letters my self.
However, if I just hit TAB to to bring up the completion list buffer then that list includes files with extensions in completion-ignored-extensions, which makes it very difficult to find what I'm looking for.
Clearly the code to ignore uninteresting files is there and working. How do I get the completion list buffer to respect completion-ignored-extensions?
(by-the-by, can I make dired behave similarly?)
This piece of advice filters out files with extensions listed in 'completion-ignored-extensions:
(defadvice completion--file-name-table (after
ignoring-backups-f-n-completion
activate)
"Filter out results when they match `completion-ignored-extensions'."
(let ((res ad-return-value))
(if (and (listp res)
(stringp (car res))
(cdr res)) ; length > 1, don't ignore sole match
(setq ad-return-value
(completion-pcm--filename-try-filter res)))))
Note: This doesn't affect dired.
For the dired issue, add this to your .emacs
(eval-after-load "dired"
'(require 'dired-x))
(add-hook 'dired-mode-hook
(lambda ()
(dired-omit-mode 1)))
Read the documentation for dired-x to get an idea of what's available there.
I would recommend using ido-mode to ignore files; it comes with Emacs by default and adds many other useful enhancements that you'll quickly learn to love. The Ignorance is Bliss section from this Mastering Emacs blog post covers how to ignore files, directories, and buffers:
ido-ignore-buffers Takes a list of buffers to ignore in C-x b
ido-ignore-directories Takes a list of directories to ignore in C-x d and C-x C-f
ido-ignore-files Takes a list of files to ignore in C-x C-f
Icicles does what you expect by default. It always respects completion-ignored-extensions for file-name completion, including for buffer *Completions*. And you can toggle this ignoring on/off at anytime, by hitting C-. in the minibuffer.
In addition, if you use library completion-ignored-build.el by Kevin Ryde, then Icicles automatically takes advantage of that library's dynamic adjustment of ignored file extensions. (Just load completion-ignored-build.el -- do not enable its minor mode or advice.)
I don't know of an answer for completion, I'm afraid. I think this is by design - when you know the name you're looking for, you probably don't want e.g. the backup file. But when you don't know, it's probably better to have a list of all of the files.
However, for dired, you can load the 'dired-x' package on startup (in your .emacs), and this provides dired-omit-mode:
(load "dired-x")
You can use 'M-x customize-variable<RET>dired-omit-files' to set the actual patterns to ignore. Then when you are in dired mode you can use M-O (the letter, not the number) to toggle 'omission' on and off.
When I call find-file to open a new file, it generally happens that the file I'm looking for is in one of the directories I've already loaded from.
Ideally, I'd like to scroll through the history using the up/down arrows.
The problem with this is that if I've already loaded 10 files from a directory, I first have to pass through those ten files, all in the same directory, before I see a new directory where my file might be.
In the end, I often just type in the directory again or cut/paste it from an xterm.
in the find-file command, can I change the behavior of the up/down arrows to iterate over directories instead of files.
Alternatively, can I change the file order to match the order of buffers most recently visited instead of when I loaded the file?
My first answer suffered from the behavior that TAB completion no longer worked as expected in 'find-file. But the technique still seems useful (and if you like it, preferable).
However, this solution has the same history behavior, but maintains the TAB completion as expected inside 'find-file.
I'd be interested to know if there were a way to avoid advising find-file, but I couldn't find any introspection that gave me the knowledge that 'find-file was called.
(defadvice find-file (around find-file-set-trigger-variable protect activate)
"bind a variable so that history command can do special behavior for find-file"
(interactive (let (inside-find-file-command) (find-file-read-args "Find file: " nil)))
ad-do-it)
(defadvice next-history-element (around next-history-element-special-behavior-for-find-file protect activate)
"when doing history for find-file, use the buffer-list as history"
(if (boundp 'inside-find-file-command)
(let ((find-file-history (delq nil (mapcar 'buffer-file-name (buffer-list))))
(minibuffer-history-variable 'find-file-history))
ad-do-it)
ad-do-it))
I suggest IDO. You can search in the buffer list or in find-file. When searching in find-file and it has no matches in the current folder it searches through history.
not what you want, but
have you tried (electric-buffer-list) Ctrl-x Ctrl-b?
or (dired)?
This will use the buffer-list's order for the history, which is what you want.
(setq read-file-name-function 'my-read-file-name)
(defun my-read-file-name (prompt dir default-filename mustmatch initial predicate)
(let ((default-directory dir)
(files (directory-files dir))
(history (delq nil (mapcar 'buffer-file-name (buffer-list)))))
(completing-read prompt files predicate mustmatch initial 'history)))
Hmmm... This changes the behavior of find-file's TAB completion because the TAB completes over the history (already opened files), and not over the files available in the directory you're specifying.
Getting both to work at the same time is a bit trickier...
With Icicles you can cycle among candidate file names, and you can sort them in many ways. You can access them in order of last use etc.
http://www.emacswiki.org/emacs/Icicles_-_History_Enhancements
http://www.emacswiki.org/emacs/Icicles_-_Sorting_Candidates
http://www.emacswiki.org/emacs/Icicles_-_File-Name_Input