od Alexey Samoshkin
Nalezena chybějící ukázka
V tomto tutoriálu vám pomohu posunout vaše návyky v příkazovém řádku na další úroveň pomocí fzf
. Začněte prohledávat soubory jako profesionál. Naučte se méně známé funkce, jako je změna adresáře, prohledávání historie příkazů, vyhledávání názvu hostitele, ke kterému se chcete připojit přes SSH, zabití procesu, okamžitý náhled souboru se zvýrazněním syntaxe a další…
Dnes vám povím o nástroji, který může změnit váš technický život na části „před“ a „po“. Věřte mi – není to hyperbola. Seznamte se s fzf, což je zkratka pro fuzzy finder. Jak tvrdí definice, jedná se o univerzální fuzzy finder pro příkazový řádek. To nezní příliš popisně a lákavě pro ty, kteří o něm slyší poprvé. Jedná se však o velmi populární projekt, který je na Githubu hodnocen přibližně 21 000 hvězdičkami. Je tedy na čase rozptýlit mlhu a získat hlubší vhled.
Tento příspěvek doprovází můj nedávný screencast na toto téma. Pokud tedy patříte k lidem, kteří se učí sledováním, podívejte se na něj. V opačném případě se na něj podívejte také ?, protože nástroje jako fzf
se nejlépe představují pomocí živé ukázky, a ne tuny textu.
Jelikož na stránce projektu fzf
zatím žádné ukázkové video není, nazval jsem tento příspěvek „nalezeno chybějící demo“. Nyní však již bylo toto video staženo do repozitáře fzf
a stalo se součástí readme projektu.
Vyhledávání souborů
Lidé, kteří jsou zvyklí na prostředí příkazového řádku, pravděpodobně znají koncept unixových filtrů. Jedná se o situaci, kdy je několik nezávislých nástrojů složeno dohromady do pipeline, která krok za krokem vytvoří požadovaný výstup. Například tato pipeline vytváří seznam řetězců:
$ yes | head -10 | awk '{ print NR, NR % 2 == 0 ? "even" : "odd" }'
1 odd2 even3 odd4 even5 odd6 even7 odd8 even9 odd10 even
Každý program funguje jako filtr. Zjednodušeně řečeno, fzf
je jen další filtr systému Unix. Čte řádky z stdin
, spouští interaktivní dialog vyhledávače a nakonec vybrané položky zapisuje do stdout
. Klíčovým bodem a rozdílem od nástrojů, jako je GNU find
, je jeho interaktivní dialog vyhledávače, který filtruje položky okamžitě během psaní.
Možná to zatím nezní příliš prakticky, ale hlavním případem použití fzf
je vyhledávání souborů na příkazovém řádku. Díky fuzzy porovnávání a okamžité zpětné vazbě vás od nalezení správného souboru dělí jen několik znaků bez ohledu na to, jak hluboko je ztracen v hierarchii adresářů. Není třeba skákat zpět do správce souborů, procházet hierarchii adresářů, kopírovat cestu k souboru a vkládat ji zpět do shellu. Porovnejte níže pracovní postupy „správce souborů“ vs. „fzf“
fzf
podporuje fuzzy matching, takže stačí zadat několik znaků za sebou a dojde k porovnání řádků s těmito znaky roztroušenými v řetězci. Případně můžete vyhledávací výraz předřadit jedné uvozovce, například 'string
, a zvolit pouze přesnou shodu, nebo jej spustit jako fzf --exact
.
Nepodporuje regulární výrazy ani globální vzory, takže vzor *.sh
by nefungoval. Zachovejte však jednoduchost – vaším dnešním cílem je produktivita a rychlost. Nemáte volný čas na sestavování a psaní správných regulárních výrazů. Místo toho stačí zadat několik slov, nebo dokonce jejich částí, ohraničených mezerou, a to by pokrylo >90 % případů použití. Pro zbývajících 10 % použijte us
e ^ an
d $ pro přiřazení začátku, respektive konce řetězce, a us
e ! pro negaci přiřazení.
Vypisování vybraných souborů do příkazového řádku není super užitečné, takže se obvykle vyhledávání kombinuje s nějakou další akcí. Například je můžete otevřít pomocí Vimu nebo vybrané položky přeposlat do dalšího programu.
# Open file in a Vimvim -o `fzf`
# Print info for each selected filefzf | xargs ls -l
Fuzzy doplňování pro bash a zsh
Pro větší pohodlí lze fuzzy doplňování spustit, pokud slovo před kurzorem končí spouštěcí sekvencí, která je standardně **
. Například napište vim ~/path/**
a stiskněte TAB
. Voilà, nastoupí fzf!!!
**
spustí vyhledávač fzf
a podobá se *
, která je určena pro nativní rozšíření shellu. V určitém okamžiku můžete na přítomnost fzf
dokonce zapomenout a získat dojem, že jde o nativní funkci shellu.
Formát je následující, přičemž FUZZY_PATTERN
je nepovinný.
COMMAND **<TAB>
Pokud se vám sekvence **
nelíbí, můžete použít klávesové zkratky. CTRL+T
spustí fzf
a vloží vybraný soubor do příkazového řádku, zatímco ALT+C
změní do vybraného adresáře.
Změna adresáře
Ok, dost o vyhledávání souborů. Pojďme si povědět o dalších užitečných aplikacích. Změna pracovního adresáře je takovou běžnou operací. Ale přesto se vždycky trochu zaseknu, když se snažím vzpomenout a zadat správnou cestu k adresáři a cestou udělám několik chyb. Zpomaluje to mé tempo. Ani doplňování zsh to nevykompenzuje. Ale s fzf
je změna adresáře hračka, bez ohledu na to, jak hluboko a daleko je. Stačí napsat cd **
a jste téměř u cíle.
Všimněte si, že zatímco fzf indexuje strom adresářů, můžete hned začít hledat. Změna adresářů je můj oblíbený případ použití a fuzzy matching zde opravdu exceluje. Vyžaduje od vás stejné úsilí, abyste změnili adresář, ať už je v hloubce jedné nebo deseti úrovní.
ALT+C
Klávesová zkratka je alternativní způsob, jak spustit fzf
v režimu změny adresáře.
Historie příkazů
Možná používáte klávesovou zkratku Ctrl+R
pro prohledávání historie příkazů. Skvělé, ale co ji nadstavit fuzzy vyhledávačem? Podívejte se a porovnejte.
Vloží vybranou položku na příkazový řádek, takže ji můžete dále upravovat.
Vyhledání názvu hostitele, ke kterému se chcete připojit SSH
Pokud jste vývojáři backendu a pracujete s řadou vzdálených serverů, možná oceníte kombinaci ssh+fzf
. Použijte stejnou sekvenci spouštěčů s dvojitou hvězdičkou a zadejte ssh **
. Vytáhne nedávno použité IP adresy a názvy hostitelů z vašeho ~/.ssh/config
a vyvolá interaktivní vyhledávač.
Poslání signálu procesu
Někdy chceme poslat signál procesu, ale nejprve musíme získat jeho PID podle jména. Obvykle se pro vyřešení PID používá pgrep <process_na
me> a následně by a kill <pro
cess_pid> odkazující na totot P
ID. Pomocí fzf můžete při výpisu všech procesů kombinovat oba kroky steps. Typ
e kill <TAB> a fzf. Už nemusíte přepínat na specializovaný monitor procesů, jako je například „Activity Monitor“ na Macu.
Náhled souborů při hledání
Předpokládejme, že hledáte soubory, ale někdy vám samotný název souboru neřekne dost. Proto možná budete chtít na chvíli nahlédnout do obsahu souboru, abyste se mohli rozhodnout. fzf
I tady se vás to týká.
Ve výchozím nastavení mám okno náhledu vypnuté, ale zapínám ho, když chci do souborů nahlédnout. Navíc jsem ho rozšířil o barevný výstup a zvýraznění syntaxe pomocí příkazu bat jako náhled.
Přizpůsobení
Existují dva hlavní způsoby, jak si přizpůsobit základní verzi fzf
:
- Změnit chování dialogu vyhledávače (okno náhledu, klávesové zkratky, rozměry, vlastní akce atd.). Viz proměnná prostředí
FZF_DEFAULT_OPTS
. - Změna základního backendu vyhledávání. Ve výchozím nastavení používá nástroj GNU
find
, ale můžete přepnout na pokročilejší nástroje jako fd nebo ripgrep. Především je rychlejší než základní nástrojfind
. Za druhé tyto nástroje respektují pravidla.gitignore
, takže se vám ve výsledcích hledání neobjeví souborynode_modules
nebo.git
. Můžete také použítgit ls-tree
pro výpis souborů, když jste v repozitáři Git. Viz proměnná prostředíFZF_DEFAULT_COMMAND
.
Konfigurace se provádí prostřednictvím proměnných prostředí. Zde je úryvek z mého nastavení. Nejsem si jistý, jestli by to fungovalo tak, jak to je, když se to zkopíruje a vloží, nejspíš tam chybí nějaké další závislosti. Ale je to jen pro představu, jak konfigurace vypadá.
Fzf a Vim
Dosud jsme viděli pouze použití příkazového řádku. Ale fzf
je dodáván také jako zásuvný modul pro Vim. A věřte mi, že pokud jste uživatelem Vimmeru, stojí za to si ho do vimrc
přidat. Použití ve Vimu je mimo rozsah tohoto příspěvku, jinak by ho nikdo nečetl ?. Ale důkladně o něm mluvím v druhé části svého videa, na které je také odkaz na začátku příspěvku.
Jestliže jste netrpěliví, zde je malý úryvek, který vás upozorní. Použijte příkaz :grep
pro vyhledávání textu v celém projektu, otevřete shody v okně fzf
v celoobrazovkovém režimu, dále filtrujte shody v rámci fzf
a přejděte na vybranou shodu. A nezapomeňte na okamžitý náhled souboru na přesné pozici řádku. To je úžasné, že?“
Závěr
Doufám, že jste ohromeni tím, jak je fzf super úžasný. Je pravděpodobné, že už si ho chcete nainstalovat a vyzkoušet.
Mějte na paměti, že fzf
neslouží jen k vyhledávání souborů, i když je to jeho primární funkce. Jak vidíte, „hledání + akce“ je obecný princip, ale je dostatečně abstraktní a výkonný, aby mohl pracovat s jakýmkoli druhem seznamu: soubory, adresáři, procesy, názvy hostitelů atd. Vzpomeňte si na začátek tohoto příspěvku – fzf je pouze unixový filtr. Popusťte uzdu své fantazii, nakrmte jej libovolným seznamem a přizpůsobte jej vlastním potřebám. Můžete se inspirovat nepřeberným množstvím příkladů.
BTW, oceňte, jak je unixová filozofie nadřazená. fzf
Je to skvělý příklad programu, který tyto zásady dodržuje.
- Nechte program dělat jednu věc a dělat ji dobře (zásada jediné odpovědnosti)
- Udělejte jej dostatečně abstraktní, aby byl agnostický vůči nepodstatným detailům nebo datovým typům
- Skládejte samostatné jednotlivé programy pomocí standardních dobře definovaných rozhraní.
Držte se těchto zásad ve své kariéře vývojáře softwaru. Znalost základních principů, které stojí za rychlým zrodem a zánikem mnoha nástrojů, jazyků a frameworků na trhu, je to, co odlišuje profesionální vývojáře od amatérů.
Zdroje
junegunn/fzf: fzf – fuzzy finder pro příkazový řádek – YouTube – https://www.youtube.com/watch?v=qgG5Jhi_Els
Můj kanál na Youtube. Je tam jen pár videí, protože dělám první krůčky v tvorbě screencastů. Buďte trpěliví, slibuji, že natočím další videa. Alexey Samoshkin – YouTube – https://www.youtube.com/channel/UCfju8u-YOpNMO4CbyzIsc9Q.
sharkdp/fd: Jednoduchá, rychlá a uživatelsky přívětivá alternativa k ‚find‘ – https://github.com/sharkdp/fd
BurntSushi/ripgrep: ripgrep rekurzivně prohledává adresáře podle vzoru regex – https://github.com/BurntSushi/ripgrep
junegunn/fzf.vim: fzf vim – https://github.com/junegunn/fzf.vim