JED a S-Lang

Michal Halva



JED

JED je programatorsky textovy editor, ktery vytvoril John E. Davis (nemusime tedy dlouho patrat po puvodu jeho jmena ;). Mezi jeho vyhody patri pomerne mala velikost (necele 2MB vcetne vsech knihoven), rychlost, schopnost pracovat na konzoli (pod Linuxem i barevne),v X-Windows a dokonce i pod MS-DOSem :), syntax highligting a inteligentni automaticka indentace pro mnoho jazyku (C, C++, Java, HTML, Fortran, Pascal ...) a v neposledni rade programovatelnost v jazyce S-Lang, jehoz syntax je velice podobna jazyku C (coz jiste uvitaji vsichni, kterym po psani v Emascovem Lispu spatne funguji zavorky na klavesnici ;)). Je to tedy IMHO takova rozumna "stredni cesta" mezi strohosti editoru jako JOE nebo VI a preplacanosti, pomalosti a spotrebou mista (X)Emacs. Posledni verzi (v soucasne dobe 0.98.4) muzete ziskat bud primo z ftp://space.mit.edu/pub/davis/jed/ nebo napriklad z mirroru na SunSite MFF.

XJed
XJed v plne parade


S-Lang

Co je to

  1. Knihovna terminaloveho I/O

  2. tj. S-Lang umoznuje obsluhu klavesnice a obrazovky (vstup a vystup znaku, podpora barev a atributu pisem, kresleni ramecku ...), v soucasne dobe jiz zacina byt skoro stejne popularni jako n/curses (uz vzhledem k tomu, ze S-Lang umoznuje castecne ncurses emulovat). S-Lang pouziva napriklad Midnight Commander (od verze 4.1 jiz nepotrebuje svou mutaci knihovny a spokoji se se standardni libslang), SlRn (program pro cteni Usenet News), DosEmu a dalsi.
    Posledni verzi knihovny (0.99.38) najdete na ftp://space.mit.edu/pub/davis/slang/ nebo na SunSite MFF.
  3. Jazyk

  4. Ackoliv by se ze syntaxe mohlo zdat, ze je S-Lang jen nejaka "divna" a "orezana" mutace jazyka C, vse je trochu (uplne ;) jinak. S-Lang je totiz jazyk interpretovany a zasobnikove orientovany.

Zaklady jazyka

  1. definice promennych

  2. Slang je beztypovy jazyk, ale promenne je treba pred pouzitim deklarovat klicovym slovem variable
    variable x, y = 3, sinus = sin(x);
  3. funkce

  4. funkce se definuji klicovym slovem define
    define funkce1(param1)
    {
    ...
    }
    funkce muze vracet jednu nebo vice hodnot
    return x;
    return (a,b,c); nebo return a,b,c;
  5. vyrazy a prikazy

  6. velmi podobne jako v jazyce C s nekolika dulezitymi odlisnostmi:
  7. pole
  8. p = create_array(typ,n1,n2,...,ndim,dim);
    vytvori dim-rozmerne (dim <= 3) pole o rozmerech n1 x n2 x ... x ndim, kde typ je: 's' - pole retezcu, 'f' - pole floatu, 'i' - pole integeru, 'c' - pole znaku. Pozor, indexy zacinaji od 1 (ne od 0 jako v C).
  9. operace se zasobnikem
  10. pop()
    odebere vrchol zasobniku
    dup()
    zdvoji hodnotu na vrcholu zasobniku
    exch()
    prohodi 2 hodnoty na vrcholu zasobniku
  11. RPN zapis
    Pokud chcete zrychlit vykonavani programu, mate moznost pouzit misto normalniho infixoveho zapisu programu zapis v "obracene polske notaci". Kazdy radek v RPN musi zacinat teckou, tedy napriklad:
    setkey("eol","^E") muzeme prepsat jako
    . "^E" "eol" setkey
    if ( n > 1 ) {flush("Working ...")} prepiseme na
    . n 1 > {"Working ..." flush} if

Pouziti v editoru JED

Pri startu JED provede prikazy obsazene v konfiguracnim souboru ~/.jedrc (pripadne v $JED_HOME/lib/jed.rc). Zde je mozno provadet nektere zakladni zmeny v jeho konfiguraci. Typicky:
  1. zmeny mapovani klaves - setkey(akce,klavesa), kde akce je jakykoliv prikaz S-Langu.
    setkey("eol","^E")
    Klavesam Ctrl+E priradi akci eol() tj. presun na konec radku
    setkey("bol();skip_white();","^A")
    Ctrl+A zpusobi skok na prvni "newhitespacovy" (nevite nekdo jak se to rekne cesky ??? :) znak na radku
    setkey(" ahoj()","/et")
    Po stisknuti klaves ESC+T vlozi do textu retezec ahoj(), vsimnete si, ze akce zacina mezerou. Pokud ji vynechate, provede se ahoj() jako prikaz S-Langu (coz pravdepodobne nedopadne dobre ;).
    setkey("self_insert_cmd","^I")
    klavesa Tab (a Ctrl+I) bude vkladat znak Tab misto toho aby volala defaultni funkci indent_line_cmd()
    unsetkey(klavesa)
    zrusi prirazeni klavey prislusne akci
  2. nastaveni systemovych promennych
    HIGHLIGHT = 1;
    popis ostatnich promennych naleznete v $JED_HOME/lib/jed.rc
  3. nacteni konfiguracnich souboru - evalfile(jmeno_souboru)
    () = evalfile("wordstar")
    Nacte soubor s mapou klavesnice podobnou editoru WordStar (emulace WordStaru neni prilis dobra, vzhledem k tomu, ze JED bohuzel nepodporuje perzistentni bloky :(( )
  4. prirazeni funkci "hakum"
    Pokud nechcete (nebo nemuzete) modifikovat primo knihovni soubory, JED Vam umoznuje napsat si vlastni funkce, ktere budou vyvolany, kdyz dojde k prislusne udalosti.

    Jednoduchy priklad z dokumentace:
    define exit_hook()                                                              
    {                                                                        
              variable ch;                                                          
              if (BATCH) exit_jed();   % pokud je JED v neinteraktivnim modu
    
              flush("Really Exit? ");  % vypise dotaz                                             
              ch = getkey();                                                        
              if ((ch == 'Y') || (ch == 'y')) exit_jed ();  % ukonci JED                        
              error ("Aborted!");                                               
    }
    
    Funkce exit_hook() je volana pred kazdym pokusem o opusjteni JEDu.
    Popis dalsich "haku" najdete v doc/hooks.txt.
  5. zmeny barev - set_color(oblast,popredi,pozadi)
    oblast - napr. "normal","menu","number","comment" ....
    popredi,pozadi - barva popredi/pozadi "black","yellow","white" ...
Nejdulezitejsi knihovni soubor JEDu je site.sl ktery musi byt pritomen v $JED_LIBRARY (normalne /usr/local/jed/lib) a je provaden vzdy pri startu jako prvni (tj. dokonce pred parsovanim prikazoveho radku a konfiguracnim souborem ~/.jedrc); zde jsou definovany vsechny hlavni funkce, ktere JED pouziva.

Priklady funkci
% smazani radky
define delete_line()
{
   bol();       % presuneme kurzor na zacatek radky
   push_mark(); % zacneme oznacovat od pozice kurzoru
   eol();       % presuneme kurzor na konec radky
   % -> mame tedy oznaceny cely radek
   del_region() % smazeme ho
}

Funkce untab_convert_to_tabs - zmeni mezery na tabelatory
define untab_convert_to_tabs ()
{
   variable c;                    % deklarace promenne
   while (fsearch_char (' '))     % dokud v souboru existuji mezery
     {                            % presuneme se dopredu na prvni od pozice kurzoru
        c = what_column ();       % c <- sloupec (po expanzi tabelatoru)
        push_mark ();             % zacneme oznacovat (*)
        skip_white ();            % presuneme kurzor pres whitespace znaky
        c = what_column () - c;   % c <- pocet preskocenych znaku
        if (c > 1)                % vice nez jeden ?
          {
             del_region ();       % smazeme je
             whitespace (c);      % a nahradime tabelatory a minimalnim poctem ' '
          }
        else pop_mark_0 ();       
		% odstranime znacku (*) ze zasobniku, ale nepohnmeme kurzorem
     }
}

Funkce trim_buffer - odstrani zbytecne mezery na koncich radku a nekolikanasobne prazdne radky.
define trim_buffer()
{
   push_spot();        % ulozime pozici kurzoru na zasobnik
   bob();              % presuneme kurzor na zacatek souboru (bufferu)

   forever             % nekonecny cyklus
     {
        eol_trim();    % odstranime mezery na konci aktualniho radku
        bol();         % presuneme se na jeho zacatek
        if (eolp())    % jsme na konci radku ? ano -> prazdny radek
          {
             go_down_1 ();  % presuneme se na nasledujici radek
             while (eol_trim(), bol(),
                    eolp() and not(eobp())) del();
             % smazeme vsechny nasledujici prazdne radky
          }
        !if (down_1 ()) break(); % jsme na konci souboru ? ano -> konec cyklu
     }
   
   bob(); eol_trim(); bol(); if (eolp()) del();
   % odstranime pripadnou prazdnou radku na zacatku souboru
   pop_spot();
   % ze zasobniku odebereme ulozenou pozici a  vratime kurzor na puvodni misto
   !if (BATCH) message ("done.");
   % pokud nejsme v neinteraktivnim rezimu oznamime konec uzivateli
}