Function: org-search-view
org-search-view is an autoloaded, interactive and byte-compiled
function defined in org-agenda.el.gz.
Signature
(org-search-view &optional TODO-ONLY STRING EDIT-AT)
Documentation
Show all entries that contain a phrase or words or regular expressions.
With optional prefix argument TODO-ONLY, only consider entries that are TODO entries. The argument STRING can be used to pass a default search string into this function. If EDIT-AT is non-nil, it means that the user should get a chance to edit this string, with cursor at position EDIT-AT.
The search string can be viewed either as a phrase that should be found as
is, or it can be broken into a number of snippets, each of which must match
in a Boolean way to select an entry. The default depends on the variable
org-agenda-search-view-always-boolean.
Even if this is turned off (the default) you can always switch to
Boolean search dynamically by preceding the first word with "+" or "-".
The default is a direct search of the whole phrase, where each space in the search string can expand to an arbitrary amount of whitespace, including newlines.
If using a Boolean search, the search string is split on whitespace and
each snippet is searched separately, with logical AND to select an entry.
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. Words are enclosed by word delimiters (i.e. they must
match whole words, not parts of a word) if
org-agenda-search-view-force-full-words is set (default is nil).
Boolean search snippets enclosed by curly braces are interpreted as regular expressions that must or (when preceded with "-") must not match in the entry. Snippets enclosed into double quotes will be taken as a whole, to include whitespace.
- If the search string starts with an asterisk, search only in headlines.
- If (possibly after the leading star) the search string starts with an
exclamation mark, this also means to look at TODO entries only, an effect
that can also be achieved with a prefix argument.
- If (possibly after star and exclamation mark) the search string starts
with a colon, this will mean that the (non-regexp) snippets of the
Boolean search must match as full words.
This command searches the agenda files, and in addition the files
listed in org-agenda-text-search-extra-files unless a restriction lock
is active.
Key Bindings
Source Code
;; Defined in /usr/src/emacs/lisp/org/org-agenda.el.gz
;;;###autoload
(defun org-search-view (&optional todo-only string edit-at)
"Show all entries that contain a phrase or words or regular expressions.
With optional prefix argument TODO-ONLY, only consider entries that are
TODO entries. The argument STRING can be used to pass a default search
string into this function. If EDIT-AT is non-nil, it means that the
user should get a chance to edit this string, with cursor at position
EDIT-AT.
The search string can be viewed either as a phrase that should be found as
is, or it can be broken into a number of snippets, each of which must match
in a Boolean way to select an entry. The default depends on the variable
`org-agenda-search-view-always-boolean'.
Even if this is turned off (the default) you can always switch to
Boolean search dynamically by preceding the first word with \"+\" or \"-\".
The default is a direct search of the whole phrase, where each space in
the search string can expand to an arbitrary amount of whitespace,
including newlines.
If using a Boolean search, the search string is split on whitespace and
each snippet is searched separately, with logical AND to select an entry.
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. Words are enclosed by word delimiters (i.e. they must
match whole words, not parts of a word) if
`org-agenda-search-view-force-full-words' is set (default is nil).
Boolean search snippets enclosed by curly braces are interpreted as
regular expressions that must or (when preceded with \"-\") must not
match in the entry. Snippets enclosed into double quotes will be taken
as a whole, to include whitespace.
- If the search string starts with an asterisk, search only in headlines.
- If (possibly after the leading star) the search string starts with an
exclamation mark, this also means to look at TODO entries only, an effect
that can also be achieved with a prefix argument.
- If (possibly after star and exclamation mark) the search string starts
with a colon, this will mean that the (non-regexp) snippets of the
Boolean search must match as full words.
This command searches the agenda files, and in addition the files
listed in `org-agenda-text-search-extra-files' unless a restriction lock
is active."
(interactive "P")
(when org-agenda-overriding-arguments
(setq todo-only (car org-agenda-overriding-arguments)
string (nth 1 org-agenda-overriding-arguments)
edit-at (nth 2 org-agenda-overriding-arguments)))
(let* ((props (list 'face nil
'done-face 'org-agenda-done
'org-not-done-regexp org-not-done-regexp
'org-todo-regexp org-todo-regexp
'org-complex-heading-regexp org-complex-heading-regexp
'mouse-face 'highlight
'help-echo "mouse-2 or RET jump to location"))
(full-words org-agenda-search-view-force-full-words)
(org-agenda-text-search-extra-files org-agenda-text-search-extra-files)
regexp rtn rtnall files file pos inherited-tags
marker category level tags c neg re boolean
ee txt beg end last-search-end words regexps+ regexps- hdl-only buffer beg1 str)
(unless (and (not edit-at)
(stringp string)
(string-match "\\S-" string))
(setq string (read-string
(if org-agenda-search-view-always-boolean
"[+-]Word/{Regexp} ...: "
"Phrase or [+-]Word/{Regexp} ...: ")
(cond
((integerp edit-at) (cons string edit-at))
(edit-at string))
'org-agenda-search-history)))
(catch 'exit
(setq org-agenda-buffer-name
(org-agenda--get-buffer-name
(and org-agenda-sticky
(if (stringp string)
(format "*Org Agenda(%s:%s)*"
(or org-keys (or (and todo-only "S") "s"))
string)
(format "*Org Agenda(%s)*"
(or (and todo-only "S") "s"))))))
(org-agenda-prepare "SEARCH")
(org-compile-prefix-format 'search)
(org-set-sorting-strategy 'search)
(setq org-agenda-redo-command
(list 'org-search-view (if todo-only t nil)
(list 'if 'current-prefix-arg nil string)))
(setq org-agenda-query-string string)
(if (equal (string-to-char string) ?*)
(setq hdl-only t
words (substring string 1))
(setq words string))
(when (equal (string-to-char words) ?!)
(setq todo-only t
words (substring words 1)))
(when (equal (string-to-char words) ?:)
(setq full-words t
words (substring words 1)))
(when (or org-agenda-search-view-always-boolean
(member (string-to-char words) '(?- ?+ ?\{)))
(setq boolean t))
(setq words (split-string words))
(let (www w)
(while (setq w (pop words))
(while (and (string-match "\\\\\\'" w) words)
(setq w (concat (substring w 0 -1) " " (pop words))))
(push w www))
(setq words (nreverse www) www nil)
(while (setq w (pop words))
(when (and (string-match "\\`[-+]?{" w)
(not (string-match "}\\'" w)))
(while (and words (not (string-match "}\\'" (car words))))
(setq w (concat w " " (pop words))))
(setq w (concat w " " (pop words))))
(push w www))
(setq words (nreverse www)))
(setq org-agenda-last-search-view-search-was-boolean boolean)
(when boolean
(let (wds w)
(while (setq w (pop words))
(when (or (equal (substring w 0 1) "\"")
(and (> (length w) 1)
(member (substring w 0 1) '("+" "-"))
(equal (substring w 1 2) "\"")))
(while (and words (not (equal (substring w -1) "\"")))
(setq w (concat w " " (pop words)))))
(and (string-match "\\`\\([-+]?\\)\"" w)
(setq w (replace-match "\\1" nil nil w)))
(and (equal (substring w -1) "\"") (setq w (substring w 0 -1)))
(push w wds))
(setq words (nreverse wds))))
(if boolean
(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))
(if full-words
(setq re (concat "\\<" (regexp-quote (downcase w)) "\\>"))
(setq re (regexp-quote (downcase w)))))
(if neg (push re regexps-) (push re regexps+)))
words)
(push (mapconcat #'regexp-quote words "\\s-+")
regexps+))
(setq regexps+ (sort regexps+ (lambda (a b) (> (length a) (length b)))))
(if (not regexps+)
(setq regexp org-outline-regexp-bol)
(setq regexp (pop regexps+))
(when hdl-only (setq regexp (concat org-outline-regexp-bol ".*?"
regexp))))
(setq files (org-agenda-files nil 'ifmode))
;; Add `org-agenda-text-search-extra-files' unless there is some
;; restriction.
(when (eq (car org-agenda-text-search-extra-files) 'agenda-archives)
(pop org-agenda-text-search-extra-files)
(unless (get 'org-agenda-files 'org-restrict)
(setq files (org-add-archive-files files))))
;; Uniquify files. However, let `org-check-agenda-file' handle
;; non-existent ones.
(setq files (cl-remove-duplicates
(append files org-agenda-text-search-extra-files)
:test (lambda (a b)
(and (file-exists-p a)
(file-exists-p b)
(file-equal-p a b))))
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)))
(unless 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
(with-syntax-table (org-search-syntax-table)
(unless (derived-mode-p 'org-mode)
(error "Agenda file %s is not in Org mode" file))
(let ((case-fold-search t))
(save-excursion
(save-restriction
(if (eq buffer org-agenda-restrict)
(narrow-to-region org-agenda-restrict-begin
org-agenda-restrict-end)
(widen))
(goto-char (point-min))
(unless (or (org-at-heading-p)
(outline-next-heading))
(throw 'nextfile t))
(goto-char (max (point-min) (1- (point))))
(while (re-search-forward regexp nil t)
(setq last-search-end (point))
(org-back-to-heading t)
(while (and (not (zerop org-agenda-search-view-max-outline-level))
(> (org-reduced-level (org-outline-level))
org-agenda-search-view-max-outline-level)
(forward-line -1)
(org-back-to-heading t)))
(skip-chars-forward "* ")
(setq beg (line-beginning-position)
beg1 (point)
end (progn
(outline-next-heading)
(while (and (not (zerop org-agenda-search-view-max-outline-level))
(> (org-reduced-level (org-outline-level))
org-agenda-search-view-max-outline-level)
(forward-line 1)
(outline-next-heading)))
(point)))
(catch :skip
(goto-char beg)
(org-agenda-skip)
(setq str (buffer-substring-no-properties
(line-beginning-position)
(if hdl-only (line-end-position) 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)))
(if todo-only
(cons (concat "^\\*+[ \t]+"
org-not-done-regexp)
regexps+)
regexps+))
(goto-char beg)
(setq marker (org-agenda-new-marker (point))
category (org-get-category)
level (make-string (org-reduced-level (org-outline-level)) ? )
inherited-tags
(or (eq org-agenda-show-inherited-tags 'always)
(and (listp org-agenda-show-inherited-tags)
(memq 'todo org-agenda-show-inherited-tags))
(and (eq org-agenda-show-inherited-tags t)
(or (eq org-agenda-use-tag-inheritance t)
(memq 'todo org-agenda-use-tag-inheritance))))
tags (org-get-tags nil (not inherited-tags))
txt (org-agenda-format-item
""
(buffer-substring-no-properties
beg1 (line-end-position))
level category tags t))
(org-add-props txt props
'org-marker marker 'org-hd-marker marker
'org-todo-regexp org-todo-regexp
'level level
'org-complex-heading-regexp org-complex-heading-regexp
'priority 1000
'type "search")
(push txt ee)
(goto-char (max (1- end) last-search-end))))))))))
(setq rtn (nreverse ee))
(setq rtnall (append rtnall rtn)))
(org-agenda--insert-overriding-header
(with-temp-buffer
(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-agenda-structure-filter))
(setq pos (point))
(unless org-agenda-multi
(insert (substitute-command-keys "\\<org-agenda-mode-map>\
Press `\\[org-agenda-manipulate-query-add]', \
`\\[org-agenda-manipulate-query-subtract]' to add/sub word, \
`\\[org-agenda-manipulate-query-add-re]', \
`\\[org-agenda-manipulate-query-subtract-re]' to add/sub regexp, \
`\\[universal-argument] \\[org-agenda-redo]' for a fresh search\n"))
(add-text-properties pos (1- (point))
(list 'face 'org-agenda-structure-secondary)))
(buffer-string)))
(org-agenda-mark-header-line (point-min))
(when rtnall
(insert (org-agenda-finalize-entries rtnall 'search) "\n"))
(goto-char (point-min))
(or org-agenda-multi (org-agenda-fit-window-to-buffer))
(add-text-properties (point-min) (point-max)
`(org-agenda-type search
org-last-args (,todo-only ,string ,edit-at)
org-redo-cmd ,org-agenda-redo-command
org-series-cmd ,org-cmd))
(org-agenda-finalize)
(setq buffer-read-only t))))