Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.6

====== Searching ======

There are two kinds of searching in zim: searching within a page, this is called **Find**, and searching through multiple pages, this is called **Search**.

===== Find =====
The "//Search//->//Find...//" menu item  triggers a search box at the bottom of the page. By typing a word here you can find occurrences of this word in the current page. You can use either the ''<Alt>N'' and ''<Alt>P'' or the ''<Ctrl>G'' and ''<Shift><Ctrl>G'' keybindings to go to the next/previous occurrence. If the word you type can not be found the box turns red and the buttons become insensitive.

* The **Match case** check-box toggles case sensitivity. The search is by default not case sensitive. But it can be useful to match case when looking for names or acronyms.
* The **Whole word** check-box toggles whether partial word matches are included. This is especially useful when looking for rather short words.
* The **Regular expressions** check-box toggles advanced search and replace where "regular expressions" can be used to matched text patterns. When this option is enabled also escapes in the replacement string will be expanded and groups in the pattern can be referenced in the replacement string. See the [[http://docs.python.org/library/re.html|python documentation]] documentation for details on the syntax for regular expressions.
* The **Highlight** check-box toggles highlighting for all results in the buffer.

The find function supports globs, with the same logic as the page search documented below.


===== Find and Replace =====
The "//Search//->//Replace...//" menu item triggers a dialog for 'find and replace' in the current page. The "Next" and "Previous" buttons can be used to go to the next or previous occurrence without replacing. The "Replace" button can be used to replace one occurrence only. The "Replace all" button can be used to replace all occurrences in the current page at once.

Syntax and options are the same as for the //Find// bar


===== Search =====
The "//Search//->//Search//..." menu item triggers the search dialog to pop up. This dialog allows you to e.g. search for pages that contain a certain word. You can have multiple search dialogs open at the same time.

You can not only search for multiple words, but zim also allows using more refined search queries. See below for the query syntax supported by this dialog for advanced usage.

A normal search runs through all the pages of the notebook. Special searches, such as searching for links or page names, search only part of the index and are correspondingly faster, which may be important for large notebooks with hundreds to thousands of pages.

===== Back links =====
This is the last item in the Search menu. As a special case, you can search for a page name. Instead of a 'full text search', a cache lookup is performed and a list is displayed, containing pages that have link to the searched page. Page names are defined as words containing a ":" character in this context.

When you open the "//Search//->//Search Back links//..." menu item you get the same Search dialog as with //Search// but the name of the current page is filled in already.

As an alternative you can click on the "Back links" area in the status bar, this will pop up a menu with all back links to the current page.


===== Commandline usage =====
You can also execute a search using commandline arguments, e.g.:

'''
zim --search Notes "tag:home and tag:foo"
'''

which will print a list of all pages that contain both the [[tags]] "''@home''" and "''@foo''"


===== Search Query Syntax =====
This section describes the query syntax that can be used in the search dialog.

==== Summary ====
Queries can exist of just a word or a quoted string. Multiple words are interpreted as an "AND" query where results must match all terms. Operators can be used to create "OR" queries and negate terms. There is a keyword-value syntax to match specific properties of a page. Keyword matches can use the page index and typically are faster than content searches.

**Operators:**
''AND'', ''and, +''	all the search terms  must be on the page
''OR'', ''or''		any one of the search must be on the page
''-'', ''NOT''		the page must not contain this term
''( .. )''		group terms into a sub-query

**Keywords:**
''Content:''	match page content
''Text''		alias for ''content''
''Name:''		match the page name, matches anywhere in the full page name, including ":" separators
''Section:''	match the given page and any sub-pages, value should be a fully specified page name
''Namespace:''	alias for "''Section''"
''Tag:''		match a given tag on the page
''Tags:''		match multiple tags
''LinksFrom:''	match pages linked from the given page(s), value is interpreted as ''Name'' query
''LinksTo:''	match pages linking to the given page(s), value is interpreted as ''Name'' query
''Links:''		alias for "''LinksFrom''"
''Any:''		default keyword, matches text content, page name, links and tags - applied to all queries with a keyword


==== Operators ====
The Boolean operators AND NOT OR give you great flexibility in searching. If you have large, long-term notebooks, it is worth the learning curve.

AND is the default: it serves to narrow your search by stipulating that 2 or more terms appear on the same page

As in most search programs (e.g. Google and Yahoo) logical AND is **implied** by default: If you enter a couple of words in the search dialog zim looks for pages that contain all of these words in either in the page name or in the page contents. For multiple words an implicit AND operator is assumed. >>If you search pages containing both words foo and bar, the following queries are all equivalent:

'''
foo bar
foo AND bar
foo and bar
+foo +bar
'''

To exclude pages that contain a certain word from your query prefix the word with a "-" or the NOT operator. It is the opposite of AND. So to look for pages that contain "foo" but not "bar" try one of these:

'''
foo -bar
+foo -bar
foo NOT bar
foo AND NOT bar
'''

For pages that contain neither "foo" nor "bar":

'''
-foo - bar
NOT foo NOT bar
NOT foo AND NOT bar
'''

OR is helpful is you are not sure, which exact word occurs in your text. You can enter words with similar meaning that might have occurred on the page you are looking for.
In our example the OR operator serves for finding pages containing either "foo" or "bar" or both , so to find any pages matching "foo" or "bar" the following operators yield the same results:

'''
foo OR bar
foo or bar
'''

When combining the operators AND has precedence over OR. So a query like:

	''foo OR bar AND dus''

is equivalent with:

	''(foo OR bar) AND dus''

Brackets can be used to group terms into sub-queries. This allows to defnine the alternative for the above example:

	''foo OR (bar AND dus)''

Groups can also be negated, as in this example:

	''foo AND NOT (bar or dus)''

To match phrases, i.e. strings containing whitespace (blanks), or to match things that look like operators, you need to put the string between double quotes. So when looking for a literal string "foo bar" and a literal "+1" use:

	''"foo bar" and "+1"''

To match partial words you can use a "''*''" as wildcard. The rules how these are applied vary slightly per keyword, as specified below.


==== Keyword searches ====
So far we just searched for words. In all of the above examples a keyword-value pair can be used as a search term as well.

Keywords are case-insensitive and end in a ":". The keyword can be followed by an optional whitespace. For example to only search the page names you can use:

'''
Name: foo
'''

This query only returns pages that contain "foo" in the page name without looking at their content and therefore is quite a bit faster.

The same query can be written as:

'''
Name: foo
name: foo
name:foo
name:"foo"
Name:'foo'
name: "foo"
'''

All of these result in the same query

The "Content:" keyword only matches page contents and excludes e.g. page names. (Although if the pagename is given as a heading in the page, it still matches.)

''Content: foo AND NOT Name: foo'' will find pages that have "foo" written somewhere in their page content but that do not contain "foo" in the page name.

Most keywords support "*" to match partial words. The "*" matches any non-whitespace characters. Globs are expanded even in quoted strings.

Words that end in a ":" but are not a recognized keyword are understood as plain text and result in a content search.

Keywords support also the following operators: "'':=''" for equal, "''<=''", "''>=''", "''<''", and "''>''" for less-equal, greater-equal, less, and greater respectively. Keywords that do not implement comparison ignore these operators. Some keywords use the "equals" operator ("'':=''") to indicate case-sensitivity.

As a special case, a keyword can also contain a group.

''name:(foo bar)'' is equivalent with ''(name:foo name:bar)''

Such keyword groups cannot contain sub-groups or nested keyword terms and do not support ''AND'' and ''OR'' operators. However you can use ''name:(foo -bar)'' to include ''"foo"'' and exclude ''"bar"''.


==== Implicit keywords ====
A search for a single word that starts with an "''@''" will automatically be converted in a search for tags. For example "''@home''" will automatically be converted to "''Tags: home''" which matches all tags starting with "home". For an exact tag match you can use "''@home@''". See the "''Tags:''" keyword for details.


==== Supported Keywords ====

=== Content, Text ===
The "''Content:''" keyword matches text content anywhere in the page. A "''*''" can appear anywhere in the string (start, middle, end) and is expanded to match non-whitespace characters.

This keyword does not match e.g. object attributes or the link target for links that have different value for the text and for the link target.

The following rules are applied:

* a "*" optionally matches any character except whitespace
* a space " " matches any combination of whitespace or characters that are not letters or numbers
* by default, matches anywhere in the text, so implying "*" at the start and end of the word
* however, if a "*" is used, begin and end will automatically match word boundaries, unless the search term starts or ends with "*"
* a space " " at the start or the end forces a word bounderay, " word " only matches the whole word
* if the option "Whole Word" is set, word boundaries are always added automatically, and a "*" is required to match elsewhere
* by default matches case insensitive, unless the "equal" operator is used or the "Match case" option is set

For example the query "day" matches "day", "Day", "days", and "monday" and is equivalent with "*day*". The query " day " only matches "day" and "Day".
The query "*day" matches "day" and "monday" but not "mondays". And "day*" matches "day" and "daylight" but not "monday".

To make this keyword search case-sensitive, you can use the equals operator, like this: "''Content:=''". For example "''Content: Monday''" matches "monday", "Monday", "MONDAY" etc. while "''Content:= Monday''" only matches "Monday" with exact case as spelled in the query

The "''Text:''" keyword is an alias for "''Content:''".

=== Name ===
The "''Name:''" keyword matches anywhere in the full page name. This is the full page name, including "'':''" separators.

Since links can be CamelCase or consist of multiple words without whitespace, the word start heuristic as applied for text content is dropped here.

In addition to the rules for a Content search, the following rules apply:

* a "*" glob does not cross name segments, it does stop at the ":" separator
* a ":" matches the start or end of a name segment
* a "::" at the start matches start at the top-level of the notebook
* a "::" at the end excludes sub-pages
* a ":+" at the end gives sub-pages put excludes the parent page

For example "''Name: Project''" will match any page with the word "Project" in the name and is equivalent to "''Name: *Project*''". To match an exact page name you can search "''Name: :Project:''" but this can still match many pages that have a page called "Project" as a parent. The query "''Name: ::Project:''" results only in pages which have the page ":Project" as their parent.

To make this keyword search case-sensitive, you can use "''Name:=''".

=== Section, Namespace ===
The "''Section:''" matches the given page and any sub-pages. This allows searching a sub-set of the full notebook. The value should be a fully specified name. The start is always the top level of the notebook.

Suppose under Home you have the page "photo" as top-level page with multiple pages below it and you want to search only the photo part of your large notebook. You want to find all entries about the depth of field or its abbreviation DoF, so you type the following search:

	''Section: Home:photo "depth of field" or dof''

The ''Section:'' keyword is identical to a ''Name:'' keyword if the value starts with "::" and ends in ":".

The "''Namespace:''" keyword is an alias for "''Section:''".

=== Tag ===
The keyword "''Tag:''" can be used to search for specifics tags like:
'''

Tag: home
Tag: @home
'''

Will return any page that has the tag "home".

This keyword does a strict match for one given tag, to match multiple tags, see ''Tags''.


=== Tags ===
The keyword "''Tags:''" can be used to match multiple tags

Since tags can be CamelCase or consist of multiple words without whitespace, the word start heuristic as applied for text content is dropped here.

In addition to the rules for a Content search, the following rules apply:

* if the term starts with a "@" it will only match from the start of the name
* if the term ends with a "@" it will only match from the end of the name
* tags are always case in-sensitive, so the "Match case" option does nothing

For example "''Tags: @project'' matches any tag starting with project, like @projectA, @projectB etc. And "''Tags: project''" will also match @computer_project. The query "''Tags: @project@''" will only match @project, this is the same as "''Tag: project''".

Search terms that start with a "''@''" and match a tag query are automatically interpreted as a "''Tags:''" keyword.

=== Links, LinksFrom, LinksTo ===
The "Links" and "LinksFrom" keywords return all pages linked by a certain page while "LinksTo" returns all pages that link to a certain page, this is used to find back links.

To exclude all pages linking to ":Done" try:

'''
NOT LinksTo: "::Done:"
'''

A complex example would be to find any pages in the section ":Date" that link to ":Planning".

'''
section: Date and linksto: ::Planning:
'''

The glob expansion rules are the same as for the ''Name:'' keyword. So if you search ''Links: Project'' you will find links from any page that has the word "project" in the page name. If you only want the specific name you would search for ''Links: ::Project::''.


=== Any ===
The keyword "''Any:''" is applied implicitly to any query term that does not have a keyword. It just runs the term through the ''Content'', ''Page'', ''Tags'', and ''Links'' keywords

It can be specified explicitly if a non-keyword term would ambigous
