std/search
Searching a project's files, as an editor's search does.
import "std/search"
SearchOptions o = SearchOptions("todo")
o.ignore_case = true
o.include = ["*.cz"]
search_files("src", o, func(SearchMatch m) bool do
print(f"{m.path}:{m.line}:{m.column}: {m.text}")
return true
end)?The files are those under the folder but the ones that .gitignore,
.ignore, and .git/info/exclude leave out, as Git reads them, .git
itself, hidden ones (whose names start with .), binary ones (with a zero
byte in their first 8,000), and those over max_file_size.
SearchOptions |
|
|---|---|
query |
the text, or a regular expression of std/regex when regex is true |
ignore_case, whole_word |
|
multiline |
a regular expression may match across lines; text with \n always may |
context |
how many lines before and after each match come with it |
include, exclude |
patterns, as in .gitignore, of the files to search and of files and folders to leave out |
use_ignore_files, hidden, max_file_size |
which files are searched |
max_matches |
the search stops after this many |
| Function | Result |
|---|---|
search_files(root, options, found) |
gives found each SearchMatch as it is found, until it returns false, and gives a SearchSummary: how many files were read, how many matches found, and whether it stopped |
search(root, options) |
every match |
project_files(root, options) |
the files a search reads, as paths from root with / |
replace_preview(root, options, replacement) |
the FileReplacements that replacing every match would make: each file's path, its text before and after, and how many matches it had (count); a regular expression's replacement takes $1, ${1}, ${name}, and $$ |
apply_replacements(root, replacements) |
writes them, or none when a file changed since the preview, which is an ERROR of kind "changed" |
file_index(root) |
a FileIndex of the files' names: index.find(query) gives the fuzzy matches, the best first; index.refresh() reads the folder again |
ignore_rules() |
an IgnoreRules: rules.add(folder, text) adds an ignore file's patterns, and rules.ignored(path, is_folder) says whether a path is left out |
glob_matches(pattern, path) |
whether a path fits a glob of .gitignore: *, ?, [a-z], [!a-z], and ** for any folders |
is_binary(data) |
whether bytes look binary, as Git judges |
A SearchMatch has the file's path, the match's line and column (in
bytes), both from 1, its length in bytes, the text of its lines, and the
lines before and after it.