Legkedvesebb szakócám dicsérete I. rész
2004. év 9. szám
Váncsa István
Huszadik életévét tölti be az idén a GNU Emacs, a szabadszoftver-mozgalom zászlóshajója, ami egyébként Váncsa István legkedvesebb szakócája is.
Maga a GNU Emacs, amit most használunk, amihez az nXML készült, és amin ezt a jegyzetet is írom, 1984-ben született. Stallmannak ez a műve a GNU-mozgalom zászlóshajója lett, ily módon szimbolikus értékekkel bír és kultikus tiszteletnek örvend. Hogy emellett igazából micsoda, azt nem is annyira könnyű megmondani. Lisp alapú, továbbfejleszthető, integrált környezet, talán még ez a legpontosabb megfogalmazás, ami persze bővebb kifejtésre szorul. A saját honlapján James Clark (egyebek között a groff, az expat és más közkézen forgó nyílt forráskódú alkalmazások létrehozója, az XML 1.0 specifikáció egyik szellemi atyja) elérhetővé tett egy új Emacs major mode-ot, amely a szerkesztett XML-dokumentum érvényességét Relax NG séma alapján ellenőrzi. Mindez alig pár hónapja történt, és igen nagy szenzációnak minősült azokban a körökben, amelyekben a Relax NG kifejezés önmagában véve is izgalmi állapotot idéz elő. Az xmlhack.com szerint az nXML megjelenése mérföldkő, és ezzel a véleményével az xmlhack.com nem áll egyedül. Az igazán finom ember tehát arról ismerszik meg, a múlt év vége óta legalábbis, hogy XML-dokumentumokat szerkeszt, ezen dokumentumok nyelvtanának leírására a Relax NG típusnyelvet használja, s mindezt Emacs nXML major mode-ban teszi. Ez utóbbi fogalomra, tehát a major mode mibenlétére később majd visszatérünk, momentán annyi a lényeg, hogy az nXML révén az Emacs az egyik legdinamikusabban fejlődő szoftvertechnológia (XML) legeslegfrissebb hajtásával (Relax NG) kapcsolódik össze. Noha az Emacs húszéves az idén (sőt ha jobban meggondoljuk, harminc), mégpedig egy olyan iparágban, amelyben a hároméves fejlesztések általában elavultnak számítanak. Némelyek azt mondják, hogy harminc évvel ezelőtt még nem is volt informatika, szélsőségesebb megfogalmazások szerint harminc évvel ezelőtt az informatikusok még le se jöttek a fáról. Mindamellett egy Richard Stallman nevű példány egészen biztosan lejött, sőt 1974-ben halomnyi makrót írt a TECO nevű antik editorhoz, ezt a halomnyi makrót az Emacs ősformájának szokás tekinteni. Maga az Emacs név is ezt fejezi ki: Editor MACroS, de az a név csak 75-ben vagy 76-ban bukkant fel, a pontos időpontot illetően a vélemények megoszlanak. (Ami pedig a TECO-t illeti, ő köszöni szépen, megvan, VMS alatt folytatott túlélési gyakorlata sikerrel járt, Windows konzolalkalmazásként ma is letölthető, emellett DOS és OS/2 alatti változatban is létezik. Nagyon archaikus képződmény, 1962-ben keletkezett, negyvenkét évvel ezelőtt, semmilyen létező szoftverre nem emlékeztet, érdemes megnézni közelebbről.) Maga a GNU Emacs, amit most használunk, amihez az nXML készült, és amin ezt a jegyzetet is írom, 1984-ben született, vagyis idén tölti be a húszat. Stallmannak ez a műve a GNU mozgalom zászlóshajója lett, ily módon szimbolikus értékekkel bír és kultikus tiszteletnek örvend. Hogy emellett igazából micsoda, azt nem is annyira könynyű megmondani. Lisp alapú, továbbfejleszthető, integrált környezet, talán még ez a legpontosabb megfogalmazás, ami persze bővebb kifejtésre szorul. Ez következik alább.
Mért pont Emacs?
Most tehát a GNU Emacsról írok, erre több okom van. A tárgy aktuális az nXML miatt és aktuális a huszadik születésnap miatt is. Számomra aktuális továbbá azért, mert közben mellesleg az Adobe Framemakert piszkálgatom, ami ismeretes módon egy XML/SGML-közeli kiadványszerkesztő eszköz. Az Emacs pedig XML/SGML-közeli szövegszerkesztő. A Framemaker az egyik pólus, az Emacs a másik, vagyis - szerintem - az volna a legnormálisabb, ha az ember Emacsben írná a könyvét, és (akár ő, akár valaki más) Framemakerben tördelné. Ez azt jelenti, hogy az Emacs nem speciálisan programozói editor, noha úgy tartják nyilván, hanem univerzális szövegszerkesztő. Irodai célokra nem való, nyers szöveg előállítására viszont ez a legjobb, teljesen függetlenül attól, hogy az illető szöveg tanulmány, újságcikk, szakkönyv, dráma vagy családregény. Azért is írok róla, mert legalább két éve folyamatosan használom, mégpedig egyre kizárólagosabban, úgy értve, hogy mind kevésbé igénylek rajta kívül további eszközöket. Korábban a gVim volt a legkedvesebb szakócám, 2002 dereka óta pedig az Emacs. Mindamellett ez nem vallás, esetemben legalábbis nem az (némelyeknél deklaráltan igen), hanem gyakorlati megfontolások eredménye, de elsősorban a (megalapozott) bizalmatlanságé. Az Emacsban szerkesztett állományt szerkesztés közben is el tudom menteni a helyi hálózat valamely más gépére vagy egy ftp-kiszolgálóra, ugyanis az Emacs az állományt nem tartja megnyitva. Bemásolja a tárba, aztán ezt a másolatot szerkesztjük és mentegetjük (másoljuk) vissza a lemezre, közben a lemezen lévő változat teljesen szabad, megnyitható valamely más editorban, másolható, mozgatható stb. Most például elmentem (lemezre másolom) az állományt, majd ezt a lemezen lévő változatot egy, az Emacsen belül kiadott hárombetűs parancscsal felküldöm egy ftp-kiszolgálóra, s ezt a műveletet igen nagy gyakorisággal megismétlem. Így aztán a gépem bármikor öszszeomolhat, széteshet, felrobbanhat, ellophatják, az állományom akkor se semmisül meg, ott van az ftp-kiszolgálón, netán még a helyi hálózat egy másik gépén is, vagy esetleg mindegyiken, azaz előszedhető, továbbírható. Szomorú tapasztalatok vannak e mögött. Elsősorban tehát azért használom az Emacset, mert így némileg nagyobb a valószínűsége annak, hogy például ez a jegyzet a leadás előtti utolsó pillanatokban nem válik köddé. Másodsorban azért, mert nekem épp arra van szükségem, amit az Emacs előállít, vagyis formázatlan, tiszta szövegre. (Igaz, hogy ezt egy sed scripttel később RTF-fé konvertálom, és úgy küldöm tovább, de ez más lapra tartozik.) Az írásaimat szövegállományokban őrizgetem, miáltal is a grep révén fél pillanat alatt megtalálok bennük bármit. (A grep amúgy egy UNIX-segédprogram, a Cygwin - általában a GNU környezet - része, de az Emacsból közvetlenül elérhető.) Harmadsorban pedig azért használok Emacset, mert igen tág határok között konfigurálható, saját igényeimhez tudom formálni, utána olyan szövegszerkesztőm lesz, ami csakis az én szokásaimhoz és munkastílusomhoz illik, de ahhoz nagyon. És, mint föntebb írtam, igazából Lisp alapú, továbbfejleszthető, integrált környezet, vagyis nemcsak szövegszerkesztő, bár eredetileg annak indult, hanem alkalmazáscsomag. Tartozik hozzá egy erőteljes állománykezelő, egy még erősebb hírolvasó, több levelezőprogram, egy parancsértelmező (shell), amely a legjobb UNIX-shellekkel egyenrangú, némely tekintetben a zsh-t is veri. Böngészője korábban w3 néven futott és gyakorlatilag semmire se volt jó, a mostanit w3m-nek hívják, aránylag tűrhető, persze karakteres. (Szöveges HTML-állományok megnyitására használható, és mellesleg lapozónak is; egyébként a Lynx jobb, a Links meg pláne.) Van még az Emacsben határidőnapló, naptár, kalkulátor, ftp- és LDAP-kliens, telnet/rsh, még egy pár játékprogram is, továbbá mindaz, amit a felhasználó utólag letölt az internetről, és hozzácsatol, vagy amit esetleg ő maga ír. És így máris a Lispnél vagyunk.
Nyakig a forrásban
Az Emacs magja C-ben íródott, de az egész Emacs-környezet legnagyobbrészt Lisp-kódból áll. A Lisp története egészen az ötvenes évek végéig nyúlik viszsza, eredetileg mesterséges intelligenciával összefüggő célokra fejlesztették ki. Némelyek szerint a programozásnak mindössze két hibátlan, konzisztens modellje létezik, az egyik a C modell, a másik a Lisp modell. Én ehhez nem tudok hozzászólni, mindenesetre az tény, hogy a Lisphez az Emacs felhasználója a gyakorlatban elég közel kerül, már csak azért is, mert idővel rákap a forráskód olvasgatására, minthogy bizonyos információkat csak ott találhat meg. Például az Eshell - az Emacs beépített parancsértelmezője, föntebb már említettem - igen kiváló darab, viszont dokumentáció egyelőre nemigen van hozzá. Kívül legalábbis; maga a forráskód elég rendesen dokumentált, azt kell szorgalmasan tanulmányozni, és akkor spirituálisan is tökéletesedünk. Ennél is fontosabb az a körülmény, hogy az Emacs valójában egy klasszikus UNIX-program, konfigurálása ennek megfelelően a dotemacs állomány szerkesztéséből áll, az illető állomány pedig Emacs Lisp-kódot tartalmaz, semmi egyebet. A felhasználó ezt nyomorgatja, s ezenközben valami úgyis ráragad. Természetesen az Emacs bizonyos határok között menüből is konfigurálható, de az a gyakorlatban többnyire kevésnek bizonyul. Valójában az Emacsszel való megismerkedésünk folyamata a konfigurációs állomány terjedelmének folyamatos növekedése alapján követhető nyomon, minél tartalmasabb az az állomány, minél több saját funkciót tartalmaz, annál inkább mienk az Emacs, annál inkább nekünk dolgozik. És persze annál lassabban indul, de hát nem is szokás újraindítgatni, az Emacset a felhasználó akkor állítja le, amikor a rendszert is, fagyálló OS-ek esetében szinte soha. A GNU Emacs fut a következő operációs rendszerek alatt: AIX 4.3.3 és későbbi, FreeBSD, GNU/Linux, Mac OS X, NetBSD, OpenBSD, Solaris, SunOS, Ultrix és Windows, ez utóbbi platformra pedig két változata van, az egyik a Cygwin környezet része, a másik önállóan telepíthető. A Cygwinben lévő változat Windows alatt is az X Window grafikus környezetet igényli, egyébként csak a konzolon fut és különféle idegesítő dolgokat produkál, tehát - szerintem - még próbálkozni se érdemes vele. A másik változat beceneve NTEmacs, ez egy normális Windows-alkalmazás, a telepítőállományát kicsomagoljuk, megkeressük az exéjét, elindítjuk, működik. Más kérdés, hogy amit művel, azt a Windows-környezetben szocializálódott felhasználó nem fogja működésnek tekinteni, hiszen Emacs ebben az originális, mondhatni nyers állapotában nem ismeri (illetve másra használja) a CTRL-X, CTRL-C és CTRL-V gyorsbillentyűket, továbbá láthatólag nem ismeri a sortörést sem, amennyiben a hosszú sorokat nem a szóközökben töri meg, hanem ott, ahol az ablak széléhez érnek, a szavak belsejében is akár. És evvel a különös szokásával mintha nem is kívánna fölhagyni. Viszont ez csak a látszat.
Sor- és billentyűügyek
Az Emacs legfőbb sajátossága, mint mondtam, hogy igen tág határok között konfigurálható, tehát, ha akarom, szalonképesen tördeli a sorokat, ahogy az a civilizált világban szokás. Igaz, ehhez le kell töltenem a longlines.el nevű Lisp-állományt valahonnan, mondjuk az Emacs-Wikiről (www.emacswiki.org /elisp/longlines.el), azt berakom az Emacs lisp könyvtárába, és persze elolvasom, mármint az illető állományt, legalábbis az elejét. Amúgy nekem nincs szükségem rá, mert kifejezetten sortöréses szövegeket akarok létrehozni és archiválni, lévén ezek az összes lehetséges eszközzel megjeleníthetők és jól olvashatók, továbbá mert a nagy DTP-alkalmazások (Framemaker, InDesign) ezeket az állományokat is hibátlanul veszik be, azaz kigyomlálják a kemény sorvégeket, az üres sorokban pedig felismerik a bekezdések határait. Némiképp más a helyzet a CUA billentyűzettel, tehát a Windowsban megszokott gyorsbillentyűkkel. (A CUA rövidítés azt jelenti, Common User Access, ez az IBM től származó definíció, ami a Windowsban, a Mac OS-ben és a Motif ablakkezelőben ölt testet.) Igen valószínű, hogy a felhasználó ezekről nem akar lemondani, de nem is kell. Az Emacs billentyűkombinációi ugyan mások, és annyi van belőlük mint csillag az égen - vélhetőleg nincs a földön még egy olyan szoftvertermék, amely ehhez fogható mennyiségű gyorsbillentyűt definiálna - viszont valamennyi átírható, a műveletnek akár tüstént neki is foghatunk. További örömhír, hogy mások ezt a munkát már elvégezték, az EmacsWikin megtalálható a cua.el nevű Lisp-állomány, amitől az Emacs némiképp windowsosan kezdi riszálni magát, és más tekintetben is okosodik. Vannak viszont olyan - mondjuk így: stiláris - sajátosságai, amelyeket nem érdemes felülírni, részint mert a világörökség részét képezik, részint mert kvázi szabványnak tekinthetők, részint meg azért, mert nem is baj, ha vannak. Az Emacs (ahogy a vi editor is) abban az időben keletkezett, amikor a terminálokon még nem voltak kurzorbillentyűk, és így a kurzor mozgatását is billentyűkombinációkkal kellett megoldani. Sor elejére C-a (értsd CTRL-A), sor végére C-e, egy sorral vissza C-p, egy sorral előre C-n, egy betűvel hátra C-b, előre C-f és így tovább, ez az Emacs konvenció, amit azért jó ismerni, mert máshol is használják, különféle shellek parancssorainak szerkesztésénél, például. Persze jó az, ha vannak kurzorbillentyűk meg effélék, és természetesen az Emacsban azok is működnek, bár könynyen lehetséges, hogy a C-b, C-f meg a többi kevesebb kézmozgást igényel, azaz gyorsabb és ergonomikusabb, de ezt mindenki döntse el maga.
Dzsinnek és avatárák
Ezzel a konkrét szöveg konkrét szerkesztésének problematikájáig jutottunk, hogy tehát mi módon is szerkesztünk az Emacsben szöveget, és nyilván úgy gondoljuk, hogy egy szövegszerkesztő esetében ez aránylag fontos szempont, amiről hosszabban is érdemes beszélni. Nem így van. A szó szoros értelmében vett szövegszerkesztést illetően minden komolyabb editor nagyjából ugyanazt nyújtja, noha persze nem ugyanúgy. Ráadásul minden komolyabb editor kellőképp flexibilis, kellő mélységben konfigurálható, programozható, s ennélfogva egy idő elteltével mindegyik azt és úgy műveli, amit és ahogyan a felhasználó elvár. Ha mégis van különbség, akkor ebben nem az Emacs a nyerő, hanem a Vim. Más kérdés, hogy a Vim rendkívül erőteljes szerkesztőeszközeit én garantáltan nem tudom kihasználni, ugyanis annál a sebességnél, amivel írok, rájuk egyszerűen nincs szükség. Nekem olyasmi kell, ami egy vagy több terjedelmes szöveg átrendezését támogatja, tehát például szöveg-összegyűjtő eszközöknek tudom hasznát venni, aztán irattartóknak, azaz regisztereknek, vázlat-üzemmódnak és hasonlóknak, ezekről - tehát az Emacs speciális szerkesztőeszközeiről - a szöveg utolsó traktusában még szó lesz. Előbb azonban további két szempontot kell megemlítenem. Először is az Emacs, mint minden komolyabb editor, lehetővé teszi, hogy a szerkesztett szöveg módosításához természetfölötti erőket (külső utilityket) hívjunk segítségül, azaz elvileg az öszszes szövegmanipuláló UNIX/GNU-segédprogram a rendelkezésünkre áll. Ha például azt szeretném, hogy ez a bekezdés negyven karakter hosszú sorokból álljon és kettes sortávolsággal legyen gépelve, akkor kijelölöm, alkalmazom rá a shell-command-on-region parancsot, majd beírom, hogy "par 65 | sed G", és egy új pufferben megkapom a módosított szöveget. Vagy ha például azt akarom, hogy ez a szöveg mégse sortöréses legyen, hanem olyan, mintha a Wordből mentették volna el a Text only opcióval, tehát minden bekezdés egyetlen sor, közöttük pedig semmi nincs, üres sor a legkevésbé, akkor megint kijelölés, shell-command-on-region, majd egy viszonylag hosszabb parancs: "sed -e 's/^$/^/' | tr -s \012 ' ' | tr -s ^ \012". (Vagyis először az üres sorokat a ^ karakterekre cserélem, aztán kiszedem a sorvégeket, majd sorvégekre cserélem a ^ karaktereket.) Persze az itt leírtakhoz kell a par, a sed és a tr nevű UNIX-segédprogram, illetve a teljes GNU-környezet, ám ez aligha gond, ingyen adják. A második szempont az, hogy az Emacs általános célú editor ugyan, ám a gyakorlatban mindig célszerszám, annak megfelelően, hogy éppen mit szerkesztünk vele. Ebben a pufferban, amelyikben ezt a jegyzetet írom, a leguniverzálisabb formáját mutatja, egy másikban, ahol a saját konfigurációs állományát bütykölöm, Lisp-szerkesztővé válik, a harmadikban HTML-, a negyedikben JavaScript-, az ötödikben XML-editorrá és így tovább, vagyis különféle megtestesülései, avatárái vannak, mint Visnunak. Ezeket a megjelenési formákat az Emacs a major mode kifejezéssel illeti, a major mode-okat pedig különféle Lisp-állományok valósítják meg, néha egyetlenegy, néha meg egy egész könyvtárra való. Például a bevezetésben említett nXML nevű major mode könyvtárában több mint hatvan állomány várakozik. A major mode-ok lényege, hogy speciális, csakis erre a major mode-ra jellemző parancsok - funkciók - válnak elérhetővé, bizonyos gyorsbillentyűk rendeltetése megváltozik, és többnyire a menüszerkezet is módosul, már ha egyáltalán használunk menüt. Awk, C, HTML, Lisp, Perl stb. módoknál nyilván a megfelelő szintaxisjelölés lép életbe, továbbá előkerülnek az adott major mode-hoz tartozó rövidítéseink is. Arra gondoljunk, hogy például levélírásnál valószínűleg nem egészen ugyanazokat a rövidítéseket használjuk, mint mondjuk, egy CSS-állomány szerkesztése közben, úgyhogy ezeket lokális, csak az adott módban élő rövidítésként tároljuk el, másokat (nevünk, e-mail címünk és hasonlók) globálisként, s így azok valamennyi módban hozzáférhetők.
Gyűrűk ura
Az Emacs-környezet felépítéséről és további fődarabjairól (állománykezelő, shell, hírolvasó és egyebek) a jövő hónapban lesz szó, most lássunk néhányat az editor előnyösebb vonásai közül. Az első az Emacs belső vágólapja, ami egyfelől meghatározhatatlan méretű, másodszor nem is clipboardnak, hanem kill ringnek hívják. Ide kerül mindaz, amit a szövegből kivágunk vagy kimásolunk, és ami természetesen a Windows vágólapon is megjelenik, csak most nem arról van szó. A kill ringben minden megmarad és a C-y meg az M-y (értsd Alt-Y) kombinációk céltudatos nyomkodásával minden előszedhető. Vizuálisan pedig a menüből tárható fel a múlt, Edit | Select and Paste, aztán előjön egy nadrágszíjparcella-formátumú képződmény, ott van rajta a teljes előéletünk, klikk, és be is szúrtuk a megfelelő időszeletét. (Az érdekesség kedvéért jegyzem meg, hogy "mark ring" is van, tehát visszatalálok azokhoz a szövegekhez, amelyeket előzőleg kijelöltem, minden puffer tizenhat korábbi kijelölésre emlékszik vissza.) Másodjára említendők a regiszterek. Átmeneti tárolókról van szó, nevük egy-egy karakter (betű vagy szám), más szóval minden betűhöz vagy számhoz egy-egy regiszter tartozik. A regiszter fogalmát ismerik más editorok is, mindenekelőtt persze a Vim, de használatuk az Emacsban kiterjedtebb. Itt például a program különféle ablakainak az állapotait is regiszterekbe tudom menteni, de rakhatok regiszterekbe állományneveket - nyilván gyakran megnyitandó állományokét - és kurzorpozíciókat is, mely utóbbi lehetőség egészen olyan, mint a könyvjelző, csak éppen nem az, minthogy a könyvjelzők definiálása ettől teljesen független. A legfontosabb persze a szöveg, egész fejezeteket, sőt köteteket tárolhatnék regiszterekben, ha így akarnám (nem akarom), aztán "C-x r j x", ahol az x a megfelelő regiszter neve, és máris beszúrtam a Háború és béke 612. oldalának a közepébe a teljes Hamletet. Végezetül létezik a szöveggyűjtés mint opció, ez abból áll, hogy a kijelölt szöveget egyetlen paranccsal valamelyik puffer (értsd: szerkesztett szöveg) végéhez vagy az elejéhez csapom, vagy az egész puffert felülírom vele. Az is lehetséges, hogy a kijelölt részt valamely állomány (értsd: lemezen lévő fájl) végéhez férceljem, továbbá az is, hogy egy másik puffer tartalmát egyetlen paranccsal beszúrom oda, ahol a kurzor éppen áll. Ami pedig a vázlatmódot illeti, az olyan, amilyen a vázlatmód általában lenni szokott, csak itt valahogy ez is olyan magától értetődő és természetes. Jut eszembe, hogy az Emacset roppant bonyolult, nehezen átlátható, felhasználógyötrő képződményként tartja számon az egész világ. Szerintem pedig az egész világ téved. Van ilyen.
Linkek
Az Emacs honlapja (Windows- változat) http://www.gnu.org/software/ emacs/windows/ntemacs.html
A TECO honlapja (Windows- változat) http://www.almy.us/teco.html
Az xmlhack.com az nXML-ről http://www.xmlhack.com/ read.php?item=2061
RELAX NG-specifikáció http://www.oasisopen.org/committ ees/relax-ng/spec20011203.html
RELAX NG Tutorial http://www.oasisopen.org/ committees/relax-ng/tutorial.html
Az Emacs őstörténete http://www.multicians.org/ mepap.html
w3m az Emacs böngészője http://www.w3m.org
A Lisp keletkezése http://www.paulgraham.com/ rootsoflisp.html
Bevezetés az Emacs Lispbe http://www.delorie.com/gnu/docs/ emacs-lisp-intro/emacs-lisp-intro. html#SECűTop
|