search

package
v0.2.15 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 2, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package search implements project-wide literal content search over a pre-built file list (the fuzzy finder's git-aware index). It is pure and synchronous — the app layer runs it in a goroutine and posts the results back onto the event queue. Matching is smart-case: an all-lowercase query matches case-insensitively, any uppercase letter makes it exact. Binary files and oversized files are skipped.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CompileQuery added in v0.1.2

func CompileQuery(query string, opts Options) (needle string, caseSensitive bool, re *regexp.Regexp, ok bool)

CompileQuery resolves the query into the matcher pieces ReplaceLine needs, honouring the same smart-case / regex rules as Search. ok is false for an invalid regex.

func ReplaceLine added in v0.1.2

func ReplaceLine(line, query, repl string, opts Options) (string, int)

ReplaceLine rewrites every qualifying occurrence of query on line with repl and returns the new line plus the occurrence count. In regex mode repl is an expansion template with Go's ReplaceAllString semantics — $1 / ${name} insert capture groups, $$ is a literal dollar. Literal mode writes repl verbatim. Scanning walks left to right over the ORIGINAL text, so a replacement can never re-match its own output.

func ReplaceLineAt added in v0.2.11

func ReplaceLineAt(line string, col int, query, repl string, opts Options) (string, int)

ReplaceLineAt rewrites only the occurrence that starts at rune column col on line, returning the new line and 1, or the line unchanged and 0 when no qualifying occurrence starts exactly there. The panel's row-apply uses it so one row rewrites one occurrence — its sibling rows on the same line stay valid.

func VerifyLine added in v0.1.2

func VerifyLine(actual, recorded string) bool

VerifyLine reports whether a live line still matches what the sweep recorded — the guard that keeps replace from rewriting a line the user (or anything else) edited after the search. Compared through the same cap the sweep stored.

Types

type Match

type Match struct {
	Path string
	Line int
	Col  int
	Text string
}

Match is one hit: a project-relative path, a 1-based line number, the rune column of the first hit on that line, and the line's text (capped — see maxLineRunes).

func Search(rootDir string, files []string, query string, opts Options) ([]Match, bool)

Search scans files (project-relative, resolved against rootDir) for query and returns matches in file order plus a truncated flag that is true when any cap cut the sweep short. An empty or whitespace-only query returns nothing.

type Options

type Options struct {
	MaxTotal    int // stop after this many matches overall
	MaxPerFile  int // stop after this many matches in one file
	MaxFileSize int // skip files larger than this many bytes
	// Cancelled, when set, is polled between files: a true return
	// abandons the sweep immediately. The app wires it to "a newer
	// query generation exists", so keystrokes stop paying for their
	// predecessors' disk walks.
	Cancelled func() bool

	// MatchCase forces exact-case matching (default is smart-case:
	// exact only when the query carries an uppercase letter).
	// WholeWord requires non-word characters (or line edges) around
	// the hit. Regex treats the query as a Go regexp instead of a
	// literal; a bad pattern simply matches nothing.
	MatchCase bool
	WholeWord bool
	Regex     bool
}

Options caps the sweep so a short query over a big repo can't stall the app or flood the UI.

func DefaultOptions

func DefaultOptions() Options

DefaultOptions returns the caps the app uses: 500 total, 50 per file, 1 MiB per file.

type ReplaceReport added in v0.1.2

type ReplaceReport struct {
	Replaced int // occurrences rewritten
	Files    int // files touched
	Skipped  int // matches skipped (file or line changed since the sweep)
}

ReplaceReport summarises an ApplyReplace run.

func ApplyReplace added in v0.1.2

func ApplyReplace(rootDir string, matches []Match, query, repl string, opts Options) ReplaceReport

ApplyReplace rewrites matches on disk: per file, verify each matched line still reads as recorded, rewrite the survivors, and write the file back via atomicfile.Replace — symlink-resolving and mode-preserving, so a save through a link updates the target and a 0755 script stays executable. Matches whose file or line drifted are counted as skipped, never guessed at. The caller is expected to have routed open-buffer files elsewhere — this function only ever sees paths whose truth lives on disk.

func ApplyReplaceAt added in v0.2.11

func ApplyReplaceAt(rootDir string, m Match, query, repl string, opts Options) ReplaceReport

ApplyReplaceAt is ApplyReplace narrowed to exactly one occurrence: it verifies the recorded line once, rewrites only the occurrence at m.Col via ReplaceLineAt, and writes the file back atomically. The panel's single-row apply on a closed file goes through this instead of ApplyReplace, so applying one row can never sweep up a sibling occurrence recorded on the same line.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL