Browse Source

Search view: Search for substrings rather than boolen workd lists

The default in search view is not that the search expression is
searched for as a substring, i.e. the different words must occur in
direct sequence.  The old way is only used it the first word in
the search string is preceded by a plus or a minus.

This was, more-or-less, requested by John Wiegley.
Carsten Dominik 15 years ago
parent
commit
4fe057f4aa
4 changed files with 71 additions and 39 deletions
  1. 1 0
      doc/ChangeLog
  2. 21 22
      doc/org.texi
  3. 3 0
      lisp/ChangeLog
  4. 46 17
      lisp/org-agenda.el

+ 1 - 0
doc/ChangeLog

@@ -2,6 +2,7 @@
 
 	* org.texi (Agenda commands): Document that SPC is a filter for
 	any tag.
+	(Search view): Renamed from "Keyword search".
 
 2009-10-04  Carsten Dominik  <carsten.dominik@gmail.com>
 

+ 21 - 22
doc/org.texi

@@ -281,7 +281,7 @@ The built-in agenda views
 * Global TODO list::            All unfinished action items
 * Matching tags and properties::  Structured information with fine-tuned search
 * Timeline::                    Time-sorted view for single file
-* Keyword search::              Finding entries by keyword
+* Search view::                 Find entries by searching for text
 * Stuck projects::              Find projects you need to review
 
 Presentation and sorting
@@ -6143,14 +6143,14 @@ TODO state associated with them,
 a @emph{timeline view} that shows all events in a single Org file,
 in time-sorted view,
 @item
-a @emph{keyword search view} that shows all entries from multiple files
+a @emph{text 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
 along, and
 @item
-@emph{custom views} that are special tag/keyword searches and
-combinations of different views.
+@emph{custom views} that are special searches and combinations of different
+views.
 @end itemize
 
 @noindent
@@ -6320,7 +6320,7 @@ In this section we describe the built-in views.
 * Global TODO list::            All unfinished action items
 * Matching tags and properties::  Structured information with fine-tuned search
 * Timeline::                    Time-sorted view for single file
-* Keyword search::              Finding entries by keyword
+* Search view::                 Find entries by searching for text
 * Stuck projects::              Find projects you need to review
 @end menu
 
@@ -6670,7 +6670,7 @@ Select @samp{:work:}-tagged TODO lines that are either @samp{WAITING} or
 @samp{NEXT}.
 @end table
 
-@node Timeline, Keyword search, Matching tags and properties, Built-in agenda views
+@node Timeline, Search view, Matching tags and properties, Built-in agenda views
 @subsection Timeline for a single file
 @cindex timeline, single file
 @cindex time-sorted view
@@ -6691,10 +6691,11 @@ When called with a @kbd{C-u} prefix, all unfinished TODO entries
 The commands available in the timeline buffer are listed in
 @ref{Agenda commands}.
 
-@node Keyword search, Stuck projects, Timeline, Built-in agenda views
-@subsection Keyword search
-@cindex keyword search
-@cindex searching, for keywords
+@node Search view, Stuck projects, Timeline, Built-in agenda views
+@subsection Search view
+@cindex search view
+@cindex text search
+@cindex searching, for text
 
 This agenda view is a general text search facility for Org mode entries.
 It is particularly useful to find notes.
@@ -6702,15 +6703,14 @@ 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
+This is a special search that lets you select entries by matching a substring
+or specific words using a boolean logic.
+@end table
+For example, the search string @samp{computer equipment} will find entries
+that contain @samp{computer equipment} as a substring.  If the two words are
+separated by more space or a line break, the search will still match.
+Search view can also search for specific keywords in the entry, using Boolean
+logic.  The search string @samp{+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
@@ -6719,9 +6719,8 @@ exclude both 8.11b and 8.11g.
 @vindex org-agenda-text-search-extra-files
 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,  , Keyword search, Built-in agenda views
+@node Stuck projects,  , Search view, Built-in agenda views
 @subsection Stuck projects
 
 If you are following a system like David Allen's GTD to organize your
@@ -11693,7 +11692,7 @@ format that can be displayed by @i{MobileOrg}, and for integrating notes
 captured and changes made by @i{MobileOrg} into the main system.
 
 For changing tags and TODO states in MobileOrg, you should have set up the
-customization variables @code{org-todo-keywords} and {org-tags-alist} to
+customization variables @code{org-todo-keywords} and @code{org-tags-alist} to
 cover all important tags and todo keywords, even if individual files use only
 part of these.  MobileOrg will also offer you states and tags set up with
 in-buffer settings, but it will understand the logistics of todo state

+ 3 - 0
lisp/ChangeLog

@@ -2,6 +2,9 @@
 
 	* org-agenda.el (org-agenda-filter-make-matcher): Allow to filter
 	entries that have no tags.
+	(org-agenda-search-view): New customize group.
+	(org-agenda-search-view-search-words-only): New option.
+	(org-search-view): Implement substring search.
 
 2009-10-13  Carsten Dominik  <carsten.dominik@gmail.com>
 

+ 46 - 17
lisp/org-agenda.el

@@ -482,6 +482,10 @@ this one will be used."
   "Options concerning the general tags/property/todo match agenda view."
   :tag "Org Agenda Match View"
   :group 'org-agenda)
+(defgroup org-agenda-search-view nil
+  "Options concerning the general tags/property/todo match agenda view."
+  :tag "Org Agenda Match View"
+  :group 'org-agenda)
 
 (defvar org-agenda-archives-mode nil
   "Non-nil means, the agenda will include archived items.
@@ -871,6 +875,16 @@ current display in the agenda."
   :group 'org-agenda-daily/weekly
   :type 'plist)
 
+(defcustom org-agenda-search-view-search-words-only nil
+  "Non-nil means, the search string is interpreted as individual words
+The search then looks for each word separately in each entry and
+selects entries that have matches for all words.
+When nil, matching as loose words will only take place if the first
+word is preceded by + or -.  If that is not the case, the search
+string will just be matched as a substring in the entry, but with
+each space character allowing for any whitespace, including newlines."
+  :group 'org-agenda-search-view
+  :type 'boolean)
 
 (defgroup org-agenda-time-grid nil
   "Options concerning the time grid in the Org-mode Agenda."
@@ -3142,10 +3156,19 @@ user should get a chance to edit this string, with cursor at position
 EDIT-AT.
 
 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.
+Depending on the variable `org-agenda-search-view-search-words-only'
+and on wether the first character in the search string is \"+\" or \"-\",
+The string is then interpreted either as a substrig with variable amounts
+of whitespace, or as a list or individual words that should be matched.
+
+The default is a substring match, where each space in the search string
+can expand to an arbitrary amount of whitespace, including newlines.
+
+If matching individual words, these 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.
@@ -3170,7 +3193,7 @@ in `org-agenda-text-search-extra-files'."
 		      'keymap org-agenda-keymap
 		      'help-echo (format "mouse-2 or RET jump to location")))
 	 regexp rtn rtnall files file pos
-	 marker category tags c neg re
+	 marker category tags c neg re as-words
 	 ee txt beg end words regexps+ regexps- hdl-only buffer beg1 str)
     (unless (and (not edit-at)
 		 (stringp string)
@@ -3193,19 +3216,25 @@ in `org-agenda-text-search-extra-files'."
     (when (equal (string-to-char words) ?!)
       (setq todo-only t
 	    words (substring words 1)))
+    (if (or org-agenda-search-view-search-words-only
+	    (member (string-to-char string) '(?- ?+)))
+	(setq as-words t))
     (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)
+    (if as-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)
+      (push (mapconcat (lambda (w) (regexp-quote w)) words "\\s-+")
+	    regexps+))
     (setq regexps+ (sort regexps+ (lambda (a b) (> (length a) (length b)))))
     (if (not regexps+)
 	(setq regexp (concat "^" org-outline-regexp))