<type>documentation</type>
<domain>scripting</domain>
<id>search</id>
<title>API Reference - Search</title>
<product>per+</product>


Class CAPISearch
================

API for searching files and directories. One instance of this class should be
instantiated for each search.  The arguments to the constructor are:

  ``txt`` -- The text to search for (required)
  
  ``match_case`` -- True for case-sensitive search (default=True)
  
  ``whole_words`` -- True to match only whole words (default=False)
  
  ``omit_binary`` -- True to omit files that appear to be binary files (default=True)
                          
  ``search_styles`` -- One of 'text' for plain text search, 'wildcard' for wild card
  matches (unix glob style matching), and 'regex' for regular expression matching
  (default='text')
                          
  ``include_linenos`` -- True to include line numbers in the results (when False, line
  numbers are not computed, which makes for faster searching) (default=False)
                          
  ``use_buffer_content`` -- True to use the content of edited buffers instead of the
  disk file when unsaved edits exist (default=True)
                          
  ``regex_flags`` -- For regex searches: the regex flags from the re module (default=0)

After an instance of is created, use *one* of the following to start searching:

.. python::
  
  SearchDirectory()
  SearchFile()
  SearchFiles()

**Signals**

Search results and status are reported through the following signals called
asynchronously until the search completes.  The can be connected to a callback
with ``Connect(signal, cb)``:

  ``start`` -- A new search was started. Calls ``cb()``.
  
  ``end`` -- The search completed or aborted. Calls ``cb()``.
  
  ``match`` -- One or more matches have been found. Calls ``cb(filename, matches)``
  where ``filename`` is the full path of the file, and ``matches`` is list of ``(lineno,
  linestart, line_text, positions)`` where ``lineno`` is the line number in the file
  (0=first), ``linestart`` is the position in the file where the line begins,
  ``line_text`` is the text for the line, and ``positions`` is a list of ``(start,
  end)`` tuples. The match signal may occur more than once per file or line, to report
  additional matches found. Line numbers are zero unless ``include_lineos`` was
  ``True``. All positions are from the start of the file.
                   
  ``dir`` -- Scanning a new directory. Calls ``cb(dirname:str)``.
  
  ``scanning`` -- Scanning a new file. Calls ``cb(filename)``.
  
  ``file-done`` -- Done scanning a file. Calls ``cb(filename)``.
  
File and directory names passed to signal handlers are full paths or for remote
files and directories, in the form ``ssh://hostname/path/to/item`` where ``hostname``
is the ``Identifier`` of a `Remote Host <ref:proj/remote-hosts>`__.

Use ``Disconnect(signal_id)`` to preemptively disconnect a signal handler, where
``signal_id`` is the signal ID previously returned from ``Connect``.

**Example**

.. python::

  s = CAPISearch("test", match_case=False)
  def match(filename, matches):
    print(filename, matches)
  def end():
    print("done")
  s.Connect('match', match)
  s.Connect('end', end)
  s.SearchFile('/path/to/myfile.txt')

**CAPISearch.SearchDirectory(dirname, file_set, recursive)**

Start searching the given directory for all files that match the file set,
optionally recursively.

The ``dirname`` is the full path of the directory name or for remote directories
in the form ``ssh://hostname/path/to/dir`` where ``hostname`` is the ``Identifier``
of a `Remote Host <ref:proj/remote-hosts>`__.

The ``file_set`` can either be a name of a configured file filter stored in the
'main.file-sets' preference or ``(includes, excludes)`` where ``includes`` and
``excludes`` are lists of tuples ``(spec_type, text)`` in which ``spec_type`` is one
of 'wildcard-filename', 'mime-type', or 'wildcard-directory' and text is the pattern
to apply to the file name, mime type, or directory name in order to filter which
files are searched.

For example, to search only Python files use ``'Python Files'`` as the
filespec. Or to search ``*.py`` files other than those within a directory
named ``'test'``, use the following:

.. python::

  [(('wildcard-filename', '*.py'),), (('wildcard-directory', 'test'),)]

If the file filter in file_set is a string, an exception will be raised if it is not a
valid file filter name.

**CAPISearch.SearchFiles(files)**

Start searching all the given ``files``, which is a list of full path filenames or
URLs in the form ``ssh://hostname/path/to/file.py`` where ``hostname`` is the
``Identifier`` of a `Remote Host <ref:proj/remote-hosts>`__.

This accepts only filenames and not directories.  Use ``SearchDirectory`` to search
a directory.

**CAPISearch.SearchFile(filename, start_pos=0)**

Search a single file for search matches, optionally starting at a given point. The
``filename`` should be a full path or URL in the form ``ssh://hostname/path/to/file.py``
where ``hostname`` is the ``Identifier`` of a `Remote Host <ref:proj/remote-hosts>`__.

This can also be used to re-search a file previously searched through
``SearchDirectory`` if the file changes.

**CAPISearch.Stop()**

Terminate searching, if a search is active.

**CAPISearch.Pause()**

Pause the search process.

**CAPISearch.Continue()**

Continue the search process after it was previously paused with ``Pause``.

