Funktionen

Alles, was dein Agent kennt, funktioniert weiter

Was du davon hast

Dein Agent arbeitet mit grep und ripgrep. Mit greppy behält er beides: greppy -rn MUSTER . ist grep, greppy rg … ist ripgrep, Ausgabe und Exit-Code sind dieselben. Dazu bekommt er greppys Befehle für Graph, Suche, Lesen und Ändern. Ein Werkzeug für alles, und kein gewohnter Aufruf bricht.

Vorher und nachher

Die Frage an serde: Wo stehen die Traits, die mit pub trait Deserialize beginnen?

Mit grep

$ grep -rn "pub trait Deserialize" --include=*.rs .
./serde_core/src/de/mod.rs:554:pub trait Deserialize<'de>: Sized {
./serde_core/src/de/mod.rs:632:pub trait DeserializeOwned: for<'de> Deserialize<'de> {}
./serde_core/src/de/mod.rs:803:pub trait DeserializeSeed<'de>: Sized {
./serde_core/src/de/mod.rs:945:pub trait Deserializer<'de>: Sized {
./test_suite/tests/test_serde_path.rs:38:    pub trait Deserialize<'a>: Sized {

Mit greppy

$ greppy -rn "pub trait Deserialize" --include=*.rs .
./serde_core/src/de/mod.rs:554:pub trait Deserialize<'de>: Sized {
./serde_core/src/de/mod.rs:632:pub trait DeserializeOwned: for<'de> Deserialize<'de> {}
./serde_core/src/de/mod.rs:803:pub trait DeserializeSeed<'de>: Sized {
./serde_core/src/de/mod.rs:945:pub trait Deserializer<'de>: Sized {
./test_suite/tests/test_serde_path.rs:38:    pub trait Deserialize<'a>: Sized {

Byte für Byte

cmp vergleicht beide Ausgaben, für grep und für ripgrep.

$ grep -rn "pub trait Deserialize" --include=*.rs . > grep.out; echo "exit $?"
exit 0
$ greppy -rn "pub trait Deserialize" --include=*.rs . > greppy.out; echo "exit $?"
exit 0
$ cmp grep.out greppy.out && echo identisch
identisch
$ rg -n -t rust --sort path "pub trait Deserialize" . > rg.out; echo "exit $?"
exit 0
$ greppy rg -n -t rust --sort path "pub trait Deserialize" . > greppy-rg.out; echo "exit $?"
exit 0
$ cmp rg.out greppy-rg.out && echo identisch
identisch

Dasselbe gilt für Fehlerfälle, Pipes und ripgrep-Flags. Jeder Fall lief einmal direkt und einmal über greppy, stdout und stderr getrennt verglichen:

Fall Aufruf über greppy Exit direkt / über greppy stdout und stderr
Treffer, 374 Byte greppy -rn "pub trait Deserialize" --include=*.rs . 0 / 0 identisch
kein Treffer greppy -rn "no_such_symbol_xyz" --include=*.rs . 1 / 1 identisch
Datei fehlt greppy -n "Deserialize" does/not/exist.rs 2 / 2 identisch, auch die Meldung grep: does/not/exist.rs: No such file or directory
Pipe auf stdin cat serde_core/src/de/mod.rs | greppy -c "fn deserialize" 0 / 0 identisch (38)
führendes grep-Wort greppy grep -rlw visit_content_map serde 0 / 0 identisch
ripgrep greppy rg -n -t rust --sort path "pub trait Deserialize" 0 / 0 identisch
ripgrep-Flags ohne rg-Wort greppy --smart-case -t rust --sort path "pub trait deserialize" 0 / 0 identisch

Wo greppy eingreift

greppy reicht echte grep-Aufrufe weiter. Zwei Fälle erkennt es vorher und sagt, was gemeint ist, statt grep etwas Falsches suchen zu lassen.

$ greppy -rn "visit_content_map" --code serde
`--code` is a greppy flag, not a grep flag - it belongs to greppy's navigation commands. Drop it, or name the command it goes with.
$ greppy who-call visit_content_map
status: invalid_invocation
command: `who-call`
message: unknown greppy command; nothing was passed to grep
next: did you mean `greppy who-calls ...`?

Beide enden mit Exit 64. Ein führendes -p startet den eingebauten Agenten; für das Muster -p schreibst du greppy -e -p DATEI, mit derselben Ausgabe wie grep -e -p DATEI.

So funktioniert es

greppy erkennt an der Form des Aufrufs, ob einer seiner Befehle gemeint ist. Alles andere startet das System-grep mit denselben Argumenten, und stdout, stderr und Exit-Code kommen unverändert zurück. Die Durchleitung ruft direkt das System-grep auf und braucht keinen Index: In einem Verzeichnis ohne Index legt greppy -rn TODO . weder einen Store noch eine Datei im greppy-Datenverzeichnis an.

ripgrep-Aufrufe erkennt greppy am Wort rg oder an Flags, die es nur bei ripgrep gibt, etwa --smart-case oder -t rust. Es gibt sie an dein installiertes rg weiter. ripgrep durchsucht Dateien parallel; mit --sort path ist die Reihenfolge bei jedem Lauf gleich.

greppy installiert sich ausschließlich unter dem Namen greppy, nie als grep-Alias. Dein System-grep bleibt dein grep.

Die Befehle

Befehl was er tut
greppy MUSTER [DATEI], greppy -rn MUSTER PFAD echtes grep, Ausgabe und Exit-Code byte-gleich
greppy grep … dasselbe mit führendem grep-Wort
greppy rg … ripgrep über dein installiertes rg, byte-gleich
greppy --smart-case -t rust MUSTER ripgrep-Flags werden erkannt und an rg geleitet
greppy -e -p DATEI grep nach dem Muster -p
greppy search-pattern REGEX Textsuche, die zu jedem Treffer die umgebende Definition nennt

Mehr in der Doku