Merge branch 'search'

Conflicts:

	ChangeLog
This commit is contained in:
Carsten Dominik 2008-02-29 14:54:18 +01:00
commit c7c61deaf8
6 changed files with 478 additions and 6646 deletions

View File

@ -1,3 +1,14 @@
2008-02-29 Carsten Dominik <dominik@science.uva.nl>
* org.el (org-agenda-text-search-extra-files): Renamed from
`org-agenda-multi-occur-extra-files'.
(org-agenda-manipulate-query-add)
(org-agenda-manipulate-query-subtract)
(org-agenda-manipulate-query-add-regexp)
(org-agenda-manipulate-query-subtract-regexp)
(org-agenda-manipulate-query): New functions.
(org-agenda-query-register): New option.
2008-02-28 Bastien Guerry <bzg@altern.org> 2008-02-28 Bastien Guerry <bzg@altern.org>
* org.el (org-open-at-point): Deleted mismatching `catch' form. * org.el (org-open-at-point): Deleted mismatching `catch' form.
@ -22,8 +33,15 @@
* org.el (org-auto-repeat-maybe): Make sure that the repeat stuff * org.el (org-auto-repeat-maybe): Make sure that the repeat stuff
does not add another state note. does not add another state note.
(orgtbl-setup): Fix menu bug. (orgtbl-setup): Fix menu bug.
(org-agenda-search-history): New variable.
(org-search-view): New command.
(org-agenda-prefix-format, org-agenda-sorting-strategy): New
setting for search.
(org-agenda-custom-commands, org-agenda)
(org-agenda-get-restriction-and-command, org-run-agenda-series):
Cater for new agenda view.
2008-02-28 Bernt Hansen <bernt@norang.ca> (tiny change) 2008-02-28 Bernt Hansen <bernt@norang.ca>
* org.el (org-put-clock-overlay): increase the limit of allowed * org.el (org-put-clock-overlay): increase the limit of allowed
levels to 8 when building the clock summary. levels to 8 when building the clock summary.

File diff suppressed because it is too large Load Diff

View File

@ -11,6 +11,49 @@
** Details ** Details
*** New keyword search agenda view
`C-c a s' now invokes a special agenda view that can be used
to search notes by keyword and regular expressions. The
search knows the boundaries of an entry, can use simple
Boolean logic and is reasonably fast. For example, the
search string
: +computer +wifi -ethernet -{8\.11[bg]}
will search for note entries that contain the keywords
@code{computer} and @code{wifi}, but not the keyword
@code{ethernet}, and which are also not matched by the
regular expression @code{8\.11[bg]}, meaning to exclude both
8.11b and 8.11g. If the first character of the search string
is an asteriks, the search will only look at headlines -
otherwise it will look at the headine and the text below it,
up to the next (possibly sub-) heading.
The command searches all agenda files, and in addition the
files listed in `org-agenda-text-search-extra-files'.
I find it very useful to define a custom command to do such
a search only in a limited number of files (my notes files),
like this:
: ("N" "Search notes" search ""
: ((org-agenda-files '("~/org/notes.org" "~/org/computer.org"))
: (org-agenda-text-search-extra-files nil)))
*** Many new extensions available in the CONTRIB directory
The new development model already starts to pay off, a number
of interesting extensions are now part of the distribution.
Check the file CONTRIB/README for a list.
Interesting for developers may be that there is a file
org-id.el which implements global ID's for org-mode entries.
These can be used in dependency implementations, for
example.
*** Misc
- M-RET can again be used to split a line so tha the rest of - M-RET can again be used to split a line so tha the rest of
the line becomes the new heading. However, if you do this the line becomes the new heading. However, if you do this
in a heading containing tags, the tags will stay in the old in a heading containing tags, the tags will stay in the old

View File

@ -6,12 +6,112 @@ lang="en" xml:lang="en">
<title>Org-mode list of User-visible changes</title> <title>Org-mode list of User-visible changes</title>
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"/> <meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"/>
<meta name="generator" content="Org-mode"/> <meta name="generator" content="Org-mode"/>
<meta name="generated" content="2008/02/19 09:12:40"/> <meta name="generated" content="2008/02/28 17:49:40"/>
<meta name="author" content="Carsten Dominik"/> <meta name="author" content="Carsten Dominik"/>
<link rel=stylesheet href="freeshell2.css" type="text/css"> <style type="text/css">
html {
font-family: Times, serif;
font-size: 12pt;
}
.title { text-align: center; }
.todo { color: red; }
.done { color: green; }
.timestamp { color: grey }
.timestamp-kwd { color: CadetBlue }
.tag { background-color:lightblue; font-weight:normal }
.target { background-color: lavender; }
pre {
border: 1pt solid #AEBDCC;
background-color: #F3F5F7;
padding: 5pt;
font-family: courier, monospace;
}
table { border-collapse: collapse; }
td, th {
vertical-align: top;
<!--border: 1pt solid #ADB9CC;-->
}
</style>
</head><body> </head><body>
<h1 class="title">Org-mode list of User-visible changes</h1> <h1 class="title">Org-mode list of User-visible changes</h1>
<div class="outline-2">
<h2>Version 5.23</h2>
<div class="outline-3">
<h3>Incompatible changes</h3>
</div>
<div class="outline-3">
<h3>Details</h3>
<div class="outline-4">
<h4>New keyword search agenda view</h4>
<p>
This is a special search that lets you select entries by keywords or
regular expression, using a boolean logic. For example, the search
string
</p>
<p>
<pre>
+computer +wifi -ethernet -{8\.11[bg]}
</pre>
</p>
<p>
will search for note entries that contain the keywords @code{computer}
and @code{wifi}, but not the keyword @code{ethernet}, and which are also
not matched by the regular expression @code{8\.11[bg]}, meaning to
exclude both 8.11b and 8.11g. If the first character of the
search string is an asteriks, the search will lonly look at
headlines - otherwise it will look at the headine and the
text below it, up to the next (possibly sub-) heading.
</p>
<p>
The default key binding for this view is `C-c a s'.
</p>
<p>
You can define a custom command to do such a search only in a
limited number of files, like this:
</p>
<p>
<pre>
("S" "Search notes" search ""
((org-agenda-files '("~/org/notes.org" "~/org/computer.org"))))
</pre>
</p>
</div>
<div class="outline-4">
<h4>Misc</h4>
<ul>
<li>
M-RET can again be used to split a line so tha the rest of
the line becomes the new heading. However, if you do this
in a heading containing tags, the tags will stay in the old
line.
<p>
Customize the variable `org-M-RET-may-split-line' if you
don't want this command to split a line in the middle. The
same variable also influences line splitting in items and in
tables.
</p>
</li>
</ul></div>
</div>
</div>
<div class="outline-2"> <div class="outline-2">
<h2>Version 5.22</h2> <h2>Version 5.22</h2>
@ -6602,6 +6702,6 @@ HTML exporter upgrade, in particular table of contents
<div id="postamble"><p class="author"> Author: Carsten Dominik <div id="postamble"><p class="author"> Author: Carsten Dominik
<a href="mailto:carsten at orgmode dot org">&lt;carsten at orgmode dot org&gt;</a> <a href="mailto:carsten at orgmode dot org">&lt;carsten at orgmode dot org&gt;</a>
</p> </p>
<p class="date"> Date: 2008/02/19 09:12:40</p> <p class="date"> Date: 2008/02/28 17:49:40</p>
</div></body> </div></body>
</html> </html>

262
org.el
View File

@ -2260,12 +2260,21 @@ Nil means to remove them, after a query, from the list."
:group 'org-agenda :group 'org-agenda
:type 'boolean) :type 'boolean)
(defcustom org-agenda-multi-occur-extra-files nil (defcustom org-agenda-text-search-extra-files nil
"List of extra files to be searched by `org-occur-in-agenda-files'. "List of extra files to be searched by text search commands.
The files in `org-agenda-files' are always searched." These files will be search in addition to the agenda files bu the
commands `org-search-view' (`C-c a s') and `org-occur-in-agenda-files'.
Note that these files will only be searched for text search commands,
not for the other agenda views like todo lists, tag earches or the weekly
agenda. This variable is intended to list notes and possibly archive files
that should also be searched by these two commands."
:group 'org-agenda :group 'org-agenda
:type '(repeat file)) :type '(repeat file))
(if (fboundp 'defvaralias)
(defvaralias 'org-agenda-multi-occur-extra-files
'org-agenda-text-search-extra-files))
(defcustom org-agenda-confirm-kill 1 (defcustom org-agenda-confirm-kill 1
"When set, remote killing from the agenda buffer needs confirmation. "When set, remote killing from the agenda buffer needs confirmation.
When t, a confirmation is always needed. When a number N, confirmation is When t, a confirmation is always needed. When a number N, confirmation is
@ -2365,9 +2374,11 @@ key The key (one or more characters as a string) to be associated
desc A description of the commend, when omitted or nil, a default desc A description of the commend, when omitted or nil, a default
description is built using MATCH. description is built using MATCH.
type The command type, any of the following symbols: type The command type, any of the following symbols:
agenda The daily/weekly agenda.
todo Entries with a specific TODO keyword, in all agenda files. todo Entries with a specific TODO keyword, in all agenda files.
tags Tags match in all agenda files. search Entries containing search words entry or headline.
tags-todo Tags match in all agenda files, TODO entries only. tags Tags/Property/TODO match in all agenda files.
tags-todo Tags/P/T match in all agenda files, TODO entries only.
todo-tree Sparse tree of specific TODO keyword in *current* file. todo-tree Sparse tree of specific TODO keyword in *current* file.
tags-tree Sparse tree with all tags matches in *current* file. tags-tree Sparse tree with all tags matches in *current* file.
occur-tree Occur sparse tree for *current* file. occur-tree Occur sparse tree for *current* file.
@ -2399,6 +2410,7 @@ cmd An agenda command, similar to the above. However, tree commands
(alltodo) (alltodo)
(stuck) (stuck)
(todo \"match\" options files) (todo \"match\" options files)
(search \"match\" options files)
(tags \"match\" options files) (tags \"match\" options files)
(tags-todo \"match\" options files) (tags-todo \"match\" options files)
@ -2424,6 +2436,7 @@ should provide a description for the prefix, like
(choice (choice
(const :tag "Agenda" agenda) (const :tag "Agenda" agenda)
(const :tag "TODO list" alltodo) (const :tag "TODO list" alltodo)
(const :tag "Search words" search)
(const :tag "Stuck projects" stuck) (const :tag "Stuck projects" stuck)
(const :tag "Tags search (all agenda files)" tags) (const :tag "Tags search (all agenda files)" tags)
(const :tag "Tags search of TODO entries (all agenda files)" tags-todo) (const :tag "Tags search of TODO entries (all agenda files)" tags-todo)
@ -2443,6 +2456,12 @@ should provide a description for the prefix, like
(choice (choice
(const :tag "Agenda" (agenda)) (const :tag "Agenda" (agenda))
(const :tag "TODO list" (alltodo)) (const :tag "TODO list" (alltodo))
(list :tag "Search words"
(const :format "" search)
(string :tag "Match")
(repeat :tag "Local options"
(list (variable :tag "Option")
(sexp :tag "Value"))))
(const :tag "Stuck projects" (stuck)) (const :tag "Stuck projects" (stuck))
(list :tag "Tags search" (list :tag "Tags search"
(const :format "" tags) (const :format "" tags)
@ -2480,6 +2499,13 @@ should provide a description for the prefix, like
(string :tag "Access Key(s)") (string :tag "Access Key(s)")
(string :tag "Description "))))) (string :tag "Description ")))))
(defcustom org-agenda-query-register ?o
"The register holding the current query string.
The prupose of this is that if you construct a query string interactively,
you can then use it to define a custom command."
:group 'org-agenda-custom-commands
:type 'character)
(defcustom org-stuck-projects (defcustom org-stuck-projects
'("+LEVEL=2/-DONE" ("TODO" "NEXT" "NEXTACTION") nil "") '("+LEVEL=2/-DONE" ("TODO" "NEXT" "NEXTACTION") nil "")
"How to identify stuck projects. "How to identify stuck projects.
@ -2808,7 +2834,8 @@ a grid line."
(defcustom org-agenda-sorting-strategy (defcustom org-agenda-sorting-strategy
'((agenda time-up category-keep priority-down) '((agenda time-up category-keep priority-down)
(todo category-keep priority-down) (todo category-keep priority-down)
(tags category-keep priority-down)) (tags category-keep priority-down)
(search category-keep))
"Sorting structure for the agenda items of a single day. "Sorting structure for the agenda items of a single day.
This is a list of symbols which will be used in sequence to determine This is a list of symbols which will be used in sequence to determine
if an entry should be listed before another entry. The following if an entry should be listed before another entry. The following
@ -2871,7 +2898,8 @@ agenda entries."
'((agenda . " %-12:c%?-12t% s") '((agenda . " %-12:c%?-12t% s")
(timeline . " % s") (timeline . " % s")
(todo . " %-12:c") (todo . " %-12:c")
(tags . " %-12:c")) (tags . " %-12:c")
(search . " %-12:c"))
"Format specifications for the prefix of items in the agenda views. "Format specifications for the prefix of items in the agenda views.
An alist with four entries, for the different agenda types. The keys to the An alist with four entries, for the different agenda types. The keys to the
sublists are `agenda', `timeline', `todo', and `tags'. The values sublists are `agenda', `timeline', `todo', and `tags'. The values
@ -2926,7 +2954,8 @@ See also the variables `org-agenda-remove-times-when-in-prefix' and
(cons (const agenda) (string :tag "Format")) (cons (const agenda) (string :tag "Format"))
(cons (const timeline) (string :tag "Format")) (cons (const timeline) (string :tag "Format"))
(cons (const todo) (string :tag "Format")) (cons (const todo) (string :tag "Format"))
(cons (const tags) (string :tag "Format")))) (cons (const tags) (string :tag "Format"))
(cons (const search) (string :tag "Format"))))
:group 'org-agenda-line-format) :group 'org-agenda-line-format)
(defvar org-prefix-format-compiled nil (defvar org-prefix-format-compiled nil
@ -19312,6 +19341,7 @@ FIXME: describe the elements."
(defvar org-agenda-follow-mode nil) (defvar org-agenda-follow-mode nil)
(defvar org-agenda-show-log nil) (defvar org-agenda-show-log nil)
(defvar org-agenda-redo-command nil) (defvar org-agenda-redo-command nil)
(defvar org-agenda-query-string nil)
(defvar org-agenda-mode-hook nil) (defvar org-agenda-mode-hook nil)
(defvar org-agenda-type nil) (defvar org-agenda-type nil)
(defvar org-agenda-force-single-file nil) (defvar org-agenda-force-single-file nil)
@ -19448,6 +19478,11 @@ The following commands are available:
(org-defkey org-agenda-mode-map [(left)] 'org-agenda-earlier) (org-defkey org-agenda-mode-map [(left)] 'org-agenda-earlier)
(org-defkey org-agenda-mode-map "\C-c\C-x\C-c" 'org-agenda-columns) (org-defkey org-agenda-mode-map "\C-c\C-x\C-c" 'org-agenda-columns)
(org-defkey org-agenda-mode-map "[" 'org-agenda-manipulate-query-add)
(org-defkey org-agenda-mode-map "]" 'org-agenda-manipulate-query-subtract)
(org-defkey org-agenda-mode-map "{" 'org-agenda-manipulate-query-add-re)
(org-defkey org-agenda-mode-map "}" 'org-agenda-manipulate-query-subtract-re)
(defvar org-agenda-keymap (copy-keymap org-agenda-mode-map) (defvar org-agenda-keymap (copy-keymap org-agenda-mode-map)
"Local keymap for agenda entries from Org-mode.") "Local keymap for agenda entries from Org-mode.")
@ -19712,6 +19747,8 @@ Pressing `<' twice means to restrict to the current subtree or region
(org-let lprops '(org-agenda-list current-prefix-arg))) (org-let lprops '(org-agenda-list current-prefix-arg)))
((eq type 'alltodo) ((eq type 'alltodo)
(org-let lprops '(org-todo-list current-prefix-arg))) (org-let lprops '(org-todo-list current-prefix-arg)))
((eq type 'search)
(org-let lprops '(org-search-view current-prefix-arg match)))
((eq type 'stuck) ((eq type 'stuck)
(org-let lprops '(org-agenda-list-stuck-projects (org-let lprops '(org-agenda-list-stuck-projects
current-prefix-arg))) current-prefix-arg)))
@ -19742,6 +19779,7 @@ Pressing `<' twice means to restrict to the current subtree or region
(setq org-agenda-custom-commands org-agenda-custom-commands-orig) (setq org-agenda-custom-commands org-agenda-custom-commands-orig)
(customize-variable 'org-agenda-custom-commands)) (customize-variable 'org-agenda-custom-commands))
((equal keys "a") (call-interactively 'org-agenda-list)) ((equal keys "a") (call-interactively 'org-agenda-list))
((equal keys "s") (call-interactively 'org-search-view))
((equal keys "t") (call-interactively 'org-todo-list)) ((equal keys "t") (call-interactively 'org-todo-list))
((equal keys "T") (org-call-with-arg 'org-todo-list (or arg '(4)))) ((equal keys "T") (org-call-with-arg 'org-todo-list (or arg '(4))))
((equal keys "m") (call-interactively 'org-tags-view)) ((equal keys "m") (call-interactively 'org-tags-view))
@ -19791,7 +19829,8 @@ a Agenda for current week or day e Export agenda views
t List of all TODO entries T Entries with special TODO kwd t List of all TODO entries T Entries with special TODO kwd
m Match a TAGS query M Like m, but only TODO entries m Match a TAGS query M Like m, but only TODO entries
L Timeline for current buffer # List stuck projects (!=configure) L Timeline for current buffer # List stuck projects (!=configure)
/ Multi-occur C Configure custom agenda commands s Search for keywords C Configure custom agenda commands
/ Multi-occur
") ")
(start 0)) (start 0))
(while (string-match (while (string-match
@ -19828,6 +19867,7 @@ L Timeline for current buffer # List stuck projects (!=configure)
((string-match "\\S-" desc) desc) ((string-match "\\S-" desc) desc)
((eq type 'agenda) "Agenda for current week or day") ((eq type 'agenda) "Agenda for current week or day")
((eq type 'alltodo) "List of all TODO entries") ((eq type 'alltodo) "List of all TODO entries")
((eq type 'search) "Word search")
((eq type 'stuck) "List of stuck projects") ((eq type 'stuck) "List of stuck projects")
((eq type 'todo) "TODO keyword") ((eq type 'todo) "TODO keyword")
((eq type 'tags) "Tags query") ((eq type 'tags) "Tags query")
@ -19908,7 +19948,7 @@ L Timeline for current buffer # List stuck projects (!=configure)
((eq c ?>) ((eq c ?>)
(org-agenda-remove-restriction-lock 'noupdate) (org-agenda-remove-restriction-lock 'noupdate)
(setq restriction nil)) (setq restriction nil))
((and (equal selstring "") (memq c '(?a ?t ?m ?L ?C ?e ?T ?M ?# ?! ?/))) ((and (equal selstring "") (memq c '(?s ?a ?t ?m ?L ?C ?e ?T ?M ?# ?! ?/)))
(throw 'exit (cons (setq selstring (char-to-string c)) restriction))) (throw 'exit (cons (setq selstring (char-to-string c)) restriction)))
((and (> (length selstring) 0) (eq c ?\d)) ((and (> (length selstring) 0) (eq c ?\d))
(delete-window) (delete-window)
@ -19934,6 +19974,9 @@ L Timeline for current buffer # List stuck projects (!=configure)
((eq type 'alltodo) ((eq type 'alltodo)
(org-let2 gprops lprops (org-let2 gprops lprops
'(call-interactively 'org-todo-list))) '(call-interactively 'org-todo-list)))
((eq type 'search)
(org-let2 gprops lprops
'(org-search-view current-prefix-arg match)))
((eq type 'stuck) ((eq type 'stuck)
(org-let2 gprops lprops (org-let2 gprops lprops
'(call-interactively 'org-agenda-list-stuck-projects))) '(call-interactively 'org-agenda-list-stuck-projects)))
@ -20836,6 +20879,163 @@ given in `org-agenda-start-on-weekday'."
(defun org-agenda-ndays-to-span (n) (defun org-agenda-ndays-to-span (n)
(cond ((< n 7) 'day) ((= n 7) 'week) ((< n 32) 'month) (t 'year))) (cond ((< n 7) 'day) ((= n 7) 'week) ((< n 32) 'month) (t 'year)))
;;; Agenda word search
(defvar org-agenda-search-history nil)
;;;###autoload
(defun org-search-view (&optional arg string)
"Show all entries that contain words or regular expressions.
If the first character of the search string is an asterisks,
search only the headlines.
The search string is broken into \"words\" by splitting at whitespace.
The individual words are then interpreted as a boolean expression with
logical AND. Words prefixed with a minus must not occur in the entry.
Words without a prefix or prefixed with a plus must occur in the entry.
Matching is case-insensitive and the words are enclosed by word delimiters.
Words enclosed by curly braces are interpreted as regular expressions
that must or must not match in the entry.
This command searches the agenda files, and in addition the files listed
in `org-agenda-text-search-extra-files'."
(interactive "P")
(org-compile-prefix-format 'search)
(org-set-sorting-strategy 'search)
(org-prepare-agenda "SEARCH")
(let* ((props (list 'face nil
'done-face 'org-done
'org-not-done-regexp org-not-done-regexp
'org-todo-regexp org-todo-regexp
'mouse-face 'highlight
'keymap org-agenda-keymap
'help-echo (format "mouse-2 or RET jump to location")))
regexp rtn rtnall files file pos
marker priority category tags c neg re
ee txt beg end words regexps+ regexps- hdl-only buffer beg1 str)
(unless (and (not arg)
(stringp string)
(string-match "\\S-" string))
(setq string (read-string "[+-]Word/{Regexp} ...: "
(cond
((integerp arg) (cons string arg))
(arg string))
'org-agenda-search-history)))
(setq org-agenda-redo-command
(list 'org-search-view 'current-prefix-arg string))
(setq org-agenda-query-string string)
(if (equal (string-to-char string) ?*)
(setq hdl-only t
words (substring string 1))
(setq words string))
(setq words (org-split-string words))
(mapc (lambda (w)
(setq c (string-to-char w))
(if (equal c ?-)
(setq neg t w (substring w 1))
(if (equal c ?+)
(setq neg nil w (substring w 1))
(setq neg nil)))
(if (string-match "\\`{.*}\\'" w)
(setq re (substring w 1 -1))
(setq re (concat "\\<" (regexp-quote (downcase w)) "\\>")))
(if neg (push re regexps-) (push re regexps+)))
words)
(setq regexps+ (sort regexps+ (lambda (a b) (> (length a) (length b)))))
(if (not regexps+)
(setq regexp (concat "^" org-outline-regexp))
(setq regexp (pop regexps+))
(if hdl-only (setq regexp (concat "^" org-outline-regexp ".*?"
regexp))))
(setq files (append (org-agenda-files) org-agenda-text-search-extra-files)
rtnall nil)
(while (setq file (pop files))
(setq ee nil)
(catch 'nextfile
(org-check-agenda-file file)
(setq buffer (if (file-exists-p file)
(org-get-agenda-file-buffer file)
(error "No such file %s" file)))
(if (not buffer)
;; If file does not exist, make sure an error message is sent
(setq rtn (list (format "ORG-AGENDA-ERROR: No such org-file %s"
file))))
(with-current-buffer buffer
(unless (org-mode-p)
(error "Agenda file %s is not in `org-mode'" file))
(let ((case-fold-search t))
(save-excursion
(save-restriction
(if org-agenda-restrict
(narrow-to-region org-agenda-restrict-begin
org-agenda-restrict-end)
(widen))
(goto-char (point-min))
(unless (or (org-on-heading-p)
(outline-next-heading))
(throw 'nextfile t))
(goto-char (max (point-min) (1- (point))))
(while (re-search-forward regexp nil t)
(org-back-to-heading t)
(skip-chars-forward "* ")
(setq beg (point-at-bol)
beg1 (point)
end (progn (outline-next-heading) (point)))
(catch :skip
(goto-char beg)
(org-agenda-skip)
(setq str (buffer-substring-no-properties
(point-at-bol)
(if hdl-only (point-at-eol) end)))
(mapc (lambda (wr) (when (string-match wr str)
(goto-char (1- end))
(throw :skip t)))
regexps-)
(mapc (lambda (wr) (unless (string-match wr str)
(goto-char (1- end))
(throw :skip t)))
regexps+)
(goto-char beg)
(setq marker (org-agenda-new-marker (point))
category (org-get-category)
tags (org-get-tags-at (point))
txt (org-format-agenda-item
""
(buffer-substring-no-properties
beg1 (point-at-eol))
category tags))
(org-add-props txt props
'org-marker marker 'org-hd-marker marker
'priority 1000 'org-category category
'type "search")
(push txt ee)
(goto-char (1- end)))))))))
(setq rtn (nreverse ee))
(setq rtnall (append rtnall rtn)))
(if org-agenda-overriding-header
(insert (org-add-props (copy-sequence org-agenda-overriding-header)
nil 'face 'org-agenda-structure) "\n")
(insert "Search words: ")
(add-text-properties (point-min) (1- (point))
(list 'face 'org-agenda-structure))
(setq pos (point))
(insert string "\n")
(add-text-properties pos (1- (point)) (list 'face 'org-warning))
(setq pos (point))
(unless org-agenda-multi
(insert "Press `[', `]' to add/sub word, `{', `}' to add/sub regexp, `C-u r' to edit\n")
(add-text-properties pos (1- (point))
(list 'face 'org-agenda-structure))))
(when rtnall
(insert (org-finalize-agenda-entries rtnall) "\n"))
(goto-char (point-min))
(org-fit-agenda-window)
(add-text-properties (point-min) (point-max) '(org-agenda-type search))
(org-finalize-agenda)
(setq buffer-read-only t)))
;;; Agenda TODO list ;;; Agenda TODO list
(defvar org-select-this-todo-keyword nil) (defvar org-select-this-todo-keyword nil)
@ -22279,6 +22479,46 @@ When this is the global TODO list, a prefix argument will be interpreted."
(goto-line line) (goto-line line)
(recenter window-line))) (recenter window-line)))
(defun org-agenda-manipulate-query-add ()
"Manipulate the query by adding a search term with positive selection.
Positive selection means, the term must be matched for selection of an entry."
(interactive)
(org-agenda-manipulate-query ?\[))
(defun org-agenda-manipulate-query-subtract ()
"Manipulate the query by adding a search term with negative selection.
Negative selection means, term must not be matched for selection of an entry."
(interactive)
(org-agenda-manipulate-query ?\]))
(defun org-agenda-manipulate-query-add-re ()
"Manipulate the query by adding a search regexp with positive selection.
Positive selection means, the regexp must match for selection of an entry."
(interactive)
(org-agenda-manipulate-query ?\{))
(defun org-agenda-manipulate-query-subtract-re ()
"Manipulate the query by adding a search regexp with negative selection.
Negative selection means, regexp must not match for selection of an entry."
(interactive)
(org-agenda-manipulate-query ?\}))
(defun org-agenda-manipulate-query (char)
(cond
((eq org-agenda-type 'search)
(org-add-to-string
'org-agenda-query-string
(cdr (assoc char '((?\[ . " +") (?\] . " -")
(?\{ . " +{}") (?\} . " -{}")))))
(setq org-agenda-redo-command
(list 'org-search-view
(+ (length org-agenda-query-string)
(if (member char '(?\{ ?\})) 0 1))
org-agenda-query-string))
(set-register org-agenda-query-register org-agenda-query-string)
(org-agenda-redo))
(t (error "Canot manipulate query for %s-type agenda buffers"
org-agenda-type))))
(defun org-add-to-string (var string)
(set var (concat (symbol-value var) string)))
(defun org-agenda-goto-date (date) (defun org-agenda-goto-date (date)
"Jump to DATE in agenda." "Jump to DATE in agenda."
(interactive (list (org-read-date))) (interactive (list (org-read-date)))
@ -27615,7 +27855,7 @@ really on, so that the block visually is on the match."
(interactive "sOrg-files matching: \np") (interactive "sOrg-files matching: \np")
(let* ((files (org-agenda-files)) (let* ((files (org-agenda-files))
(tnames (mapcar 'file-truename files)) (tnames (mapcar 'file-truename files))
(extra org-agenda-multi-occur-extra-files) (extra org-agenda-text-search-extra-files)
f) f)
(while (setq f (pop extra)) (while (setq f (pop extra))
(unless (member (file-truename f) tnames) (unless (member (file-truename f) tnames)

View File

@ -245,6 +245,7 @@ The built-in agenda views
* Global TODO list:: All unfinished action items * Global TODO list:: All unfinished action items
* Matching tags and properties:: Structured information with fine-tuned search * Matching tags and properties:: Structured information with fine-tuned search
* Timeline:: Time-sorted view for single file * Timeline:: Time-sorted view for single file
* Keyword search:: Finding entries by keyword
* Stuck projects:: Find projects you need to review * Stuck projects:: Find projects you need to review
Presentation and sorting Presentation and sorting
@ -4729,7 +4730,7 @@ important for a particular date, this information must be collected,
sorted and displayed in an organized way. sorted and displayed in an organized way.
Org-mode can select items based on various criteria, and display them Org-mode can select items based on various criteria, and display them
in a separate buffer. Six different view types are provided: in a separate buffer. Seven different view types are provided:
@itemize @bullet @itemize @bullet
@item @item
@ -4745,6 +4746,9 @@ the tags associated with them,
a @emph{timeline view} that shows all events in a single Org-mode file, a @emph{timeline view} that shows all events in a single Org-mode file,
in time-sorted view, in time-sorted view,
@item @item
a @emph{keyword search view} that shows all entries from multiple files
that contain specified keywords.
@item
a @emph{stuck projects view} showing projects that currently don't move a @emph{stuck projects view} showing projects that currently don't move
along, and along, and
@item @item
@ -4869,14 +4873,17 @@ Create a list of headlines matching a TAGS expression (@pxref{Matching
tags and properties}). tags and properties}).
@item L @item L
Create the timeline view for the current buffer (@pxref{Timeline}). Create the timeline view for the current buffer (@pxref{Timeline}).
@item # @r{/} ! @item s
Create a list of stuck projects (@pxref{Stuck projects}). Create a list of entries selected by a boolean expression of keywords
and/or regular expressions that must or must not occur in the entry.
@item / @item /
Search for a regular expression in all agenda files and additionally in Search for a regular expression in all agenda files and additionally in
the files listed in @code{org-agenda-multi-occur-extra-files}. This the files listed in @code{org-agenda-multi-occur-extra-files}. This
uses the Emacs command @code{multi-occur}. A prefix argument can be uses the Emacs command @code{multi-occur}. A prefix argument can be
used to specify the number of context lines for each match, default is used to specify the number of context lines for each match, default is
1. 1.
@item # @r{/} !
Create a list of stuck projects (@pxref{Stuck projects}).
@item < @item <
Restrict an agenda command to the current buffer@footnote{For backward Restrict an agenda command to the current buffer@footnote{For backward
compatibility, you can also press @kbd{1} to restrict to the current compatibility, you can also press @kbd{1} to restrict to the current
@ -4906,6 +4913,7 @@ In this section we describe the built-in views.
* Global TODO list:: All unfinished action items * Global TODO list:: All unfinished action items
* Matching tags and properties:: Structured information with fine-tuned search * Matching tags and properties:: Structured information with fine-tuned search
* Timeline:: Time-sorted view for single file * Timeline:: Time-sorted view for single file
* Keyword search:: Finding entries by keyword
* Stuck projects:: Find projects you need to review * Stuck projects:: Find projects you need to review
@end menu @end menu
@ -5100,6 +5108,34 @@ When called with a @kbd{C-u} prefix, all unfinished TODO entries
The commands available in the timeline buffer are listed in The commands available in the timeline buffer are listed in
@ref{Agenda commands}. @ref{Agenda commands}.
@node Keyword search, Stuck projects, Timeline, Built-in agenda views
@subsection Keyword search
@cindex keyword search
@cindex searching, for keywords
This agenda view is a general text search facility for Org-mode entries.
It is particularly useful to find notes.
@table @kbd
@kindex C-c a s
@item C-c a s
This is a special search that lets you select entries by keywords or
regular expression, using a boolean logic. For example, the search
string
@example
+computer +wifi -ethernet -@{8\.11[bg]@}
@end example
@noindent
will search for note entries that contain the keywords @code{computer}
and @code{wifi}, but not the keyword @code{ethernet}, and which are also
not matched by the regular expression @code{8\.11[bg]}, meaning to
exclude both 8.11b and 8.11g.
Note that in addition to the agenda files, this command will also search
the files listed in @code{org-agenda-text-search-extra-files}.
@end table
@node Stuck projects, , Timeline, Built-in agenda views @node Stuck projects, , Timeline, Built-in agenda views
@subsection Stuck projects @subsection Stuck projects
@ -5393,6 +5429,23 @@ Display the previous dates.
@item . @item .
Goto today. Goto today.
@tsubheading{Query editing}
@cindex query editing, in agenda
@kindex [
@kindex ]
@kindex @{
@kindex @}
@item [ ] @{ @}
In the @i{search view} (@pxref{Keyword search}), these keys add new
search words (@kbd{[} and @kbd{]}) or new regular expressions (@kbd{@{}
and @kbd{@}}) to the query string. The opening bracket/brace will add a
positive search term prefixed by @samp{+}, indicating that this search
term @i{must} occur/match in the entry. Closing bracket/brace add a
negative search term which @i{must not} occur/match in the entry for it
to be selected.
@tsubheading{Remote editing} @tsubheading{Remote editing}
@cindex remote editing, from agenda @cindex remote editing, from agenda
@ -5711,7 +5764,10 @@ right spot in @code{org-agenda-custom-commands}. For example:
(org-agenda-prefix-format " Mixed: "))) (org-agenda-prefix-format " Mixed: ")))
("U" tags-tree "+boss-urgent" ("U" tags-tree "+boss-urgent"
((org-show-following-heading nil) ((org-show-following-heading nil)
(org-show-hierarchy-above nil))))) (org-show-hierarchy-above nil)))
("N" search ""
((org-agenda-files '("~org/notes.org"))
(org-agenda-text-search-extra-files nil)))))
@end group @end group
@end lisp @end lisp
@ -5721,7 +5777,8 @@ priority, and the prefix format is modified to just say @samp{ Mixed: }
instead of giving the category of the entry. The sparse tags tree of instead of giving the category of the entry. The sparse tags tree of
@kbd{C-c a U} will now turn out ultra-compact, because neither the @kbd{C-c a U} will now turn out ultra-compact, because neither the
headline hierarchy above the match, nor the headline following the match headline hierarchy above the match, nor the headline following the match
will be shown. will be shown. The command @kbd{C-c a N} will do a text search limited
to only a single file.
For command sets creating a block agenda, For command sets creating a block agenda,
@code{org-agenda-custom-commands} has two separate spots for setting @code{org-agenda-custom-commands} has two separate spots for setting