Mini Commander 2.0

Včera 20:53 (aktualizováno) Tomas Matějíček

Dnes vydávám Mini Commander verze 2.0, novou verzi malého dvoupanelového správce souborů pro Linux. Je napsaný v C, používá ncurses a obsahuje vlastní prohlížeč i editor souborů. Hlavními novinkami jsou podpora UTF‑8, pohodlnější práce s názvy souborů a několik důležitých oprav kopírování, přesouvání a ukládání. Aktuální binárka má 64 KiB, staticky slinkovaná binárka zabírá přibližně 120 KiB.

Původní Mini Commander vznikal s pomocí ChatGPT 4. Při přípravě nové verze pracoval ChatGPT Astra 6, který sám navrhl a implementoval řadu změn a oprav ve stávajícím kódu. Od předchozího vývoje s ChatGPT 4 se podle mé zkušenosti AI programování zlepšilo extrémním způsobem. Na tomto projektu se to projevilo schopností procházet související části programu, hledat chyby, upravovat implementaci a ověřovat výsledek. Součástí práce bylo dokonce sestavování a testování linuxových binárek v QEMU a měření různých optimalizací velikosti (Astru jsem spouštěl totiž na Windows, samo od sebe se to rozhodlo stáhnout QEMU a nějakou náhodnou linuxovou distribuci, aby to v ní všechno vyzkoušelo).

Nejviditelnější změnou tohoto vydání je podpora UTF‑8 v panelech, prohlížeči, editoru a vstupních polích dialogů. Implementace rozlišuje pozici v bajtech od sloupce na obrazovce. To je důležité nejen pro českou diakritiku, ale také pro znaky zabírající dva terminálové sloupce a pro kombinující diakritická znaménka. Zkrácení dlouhého názvu už nerozdělí vícebajtovou sekvenci a pohyb kurzoru či mazání v editoru respektují hranice znaků. Program nyní používá širokoznakovou variantu ncurses, tedy ncursesw. Podpora má ještě své hranice: složené emoji sekvence se nezpracovávají jako jeden celek, ale to budeme ignorovat.

Vestavěný editor, dostupný přes F4, získal také základní zvýrazňování syntaxe C a shellových skriptů. Rozpoznává soubory  .c,.h a .sh; shellové zvýraznění zapne i u souboru začínajícího shebangem #!/. Pravidla používají regulární výrazy, které se kompilují při otevření editoru, takže se tato práce neopakuje při každém překreslení. Přibylo rovněž hledání textu přes F7, další výskyt najde Shift+F7. Hledání ignoruje velikost písmen podle aktivního locale. Při práci s neobvyklým obsahem pomůže stavový řádek s pozicí v bajtech a Unicode kódem znaku pod kurzorem.

Pro běžné souborové operace přibyly zkratky Shift+F5, Shift+F6 a Shift+F7. Otevřou dialog kopírování, přesunu či přejmenování nebo vytvoření adresáře s předvyplněným názvem položky pod kurzorem, bez její cesty. Kurzor je připravený k úpravě názvu a psaní původní text rovnou nezahodí. Například pro vytvoření kopie config pod názvem config.old stačí použít Shift+F5 a dopsat příponu. Relativní cílová cesta se vyhodnocuje vůči aktivnímu adresáři.

Drobnou změnou prošlo také řazení podle názvu: položky začínající tečkou mají přednost. Platí to při vzestupném i sestupném řazení,.git se tak zobrazí před názvem začínajícím například plusem. Zbytek porovnávání nadále používá strcmp(), takže jde o bajtové řazení rozlišující velikost písmen. Česká abecední pravidla ani přirozené řazení číselných částí názvů tato změna nezavádí.

Důležitější než pořadí položek jsou opravy kopírování a přesouvání. Kopírování nyní kontroluje, zda zdroj a cíl nejsou tentýž soubor. Porovnává zařízení a inode, tedy st_dev a st_ino, což zachytí i případ dvou různých názvů představujících pevné odkazy na stejný soubor. Přesouvání nově vyžaduje potvrzení před přepsáním existujícího cíle. Kde je k dispozici potřebná podpora, používárenameat2() s příznakem RENAME_NOREPLACE , který odmítne přepsat existující cílovou položku. Na starších systémech zůstává náhradní postup s kontrolou existence a běžným  rename();

Editor dostal také spolehlivější ukládání souborů. Zapisuje do dočasného souboru ve stejném adresáři, kontroluje chyby zápisu, obnovuje vlastníka, skupinu a unixová oprávnění a před nahrazením cíle volá fsync(). Při editaci přes symbolický odkaz upravuje jeho cílový soubor a samotný odkaz zachová. Pokud ukládání selže, například kvůli nedostatku místa, editor ponechá změny v paměti a oznámí chybu. Opravena je i nenápadná chyba, kdy stisk mazací klávesy na místě, kde nebylo co smazat, mohl nesprávně zrušit příznak neuložených změn.

Další opravy se týkají názvů souborů jako vstupních dat. Názvy obsahující procenta se v dialozích předávají jako text, takže například %s uvnitř názvu není formátovací instrukce. Spuštění vybraného programu zase používá přímo fork() a execl(). Název souboru se díky tomu neposílá shellu k interpretaci a mezery nebo středníky v něm nemají význam oddělovačů příkazů. Příkazy, které uživatel vědomě napíše do příkazového řádku Mini Commanderu, si běžné shellové chování zachovávají.

Pro nasazení do menších systémů je připravený automatizovaný statický build pro 32bitové x86, konkrétně i686. Skript stáhne vlastní toolchain, musl a ncurses, ověří archivy pomocí pevných SHA‑256 součtů a vše sestaví v dočasném adresáři bez systémové instalace knihoven. Do programu jsou zabudované popisy terminálů linux, vt100, xterm,screen a tmux, včetně příslušných 256barevných variant. Výsledek tak nepotřebuje sdílené knihovny libc a ncurses ani externí databázi terminfo. Na 64bitovém x86 Linuxu potřebuje zapnutou podporu spouštění 32bitových programů v jádře.

Ve výchozím nastavení se statická binárka komprimuje pomocí UPX. Běžný build přes make automatické balení pomocí UPX neprovádí.

Při ladění velikosti se ukázalo, že samotné přidávání dalších optimalizačních přepínačů nemusí vést k menšímu souboru. Program i knihovny už používaly  -Os, odstranění nepoužitých sekcí a stripování symbolů. Největší další úsporu přineslo explicitní -fno-pie při kompilaci: linker sice už používal -no-pie, ale překladač stále standardně generoval kód pro PIE. Jde o dvě odlišné části sestavení, jak popisuje i dokumentace GCC. Na stejných zdrojích se podařilo dostat zabalený program ze 129 816 na 123 296 bajtů, přibližně o pět procent níž. LTO pro ncurses ani agresivnější režim UPX lepší finální výsledek nepřinesly.

Zdrojové kódy, statická binárka i návod k sestavení jsou v repozitáři Mini Commanderu na GitHubu. Budu rád za zkušenosti z dalších distribucí a terminálů, zvlášť pokud narazíte na problém s neobvyklým názvem souboru, kódováním nebo kombinací kláves.

Sdílet