Back to site
Since 2004, our University project has become the Internet's most widespread web hosting directory. Here we like to talk a lot about web development, networking and server security. It is, after all, our expertise. To make things better we've launched this science section with the free access to educational resources and important scientific material translated to different languages.

Pymacs versiunea 0.24-beta2

Emacs Extinderea cu Python

Autor: François Pinard
E-mail: pinard@iro.umontreal.ca
Drepturi de autor: © Progiciels Bourbeau-Pinard inc, Montreal 2003., 2008, 2010

Conţinut

1 Introducere

1.1 Ce este Pymacs?

Pymacs este un instrument puternic care, odată pornit de la Emacs, permite comunicarea bidirectionala între Emacs Lisp şi Python. Pymacs îşi propune să angajeze Python ca o limbă extensie pentru Emacs, mai degrabă decât invers, şi această asimetrie este reflectat în unele alegeri de design. În termen de Emacs Lisp cod, se poate încărca şi de a folosi module Python. Funcţii de piton se pot utiliza serviciile de Emacs, Emacs-ul şi să gestioneze obiecte Lisp ţinute în Emacs Lisp spaţiu.

Obiectivele sunt de a scrie in mod natural în ambele limbi, depana cu uşurinţă, cădea înapoi cu graţie privind erorile, şi permite de eco-recursivitate.

Este foarte usor de instalat Pymacs, după cum nici Emacs-ul, nici Python trebuie să fie compilate şi nici nu Relinked. Emacs-ul pur şi simplu începe Python ca un subproces, şi Pymacs pune în aplicare un protocol de comunicare între cele două procese.

Raport probleme, defecte documentaţie, sau sugestiile la François Pinard:

1.2 Documentaţie şi exemple

Principalele site-ul Pymacs transmite documentaţia Pymacs (pe care o citiţi manualul de Pymacs chiar acum) şi distribuţii:

Mă aştept ca utilizatorii medie Pymacs să aibă o cunoaştere mai profundă a Python decât Emacs Lisp. Oamenii au diferite abordări pe scară largă, în scris, emacs. fişiere, în măsura în care este Pymacs în cauză:

  • Unele pot merge şi de a scrie aproape nici Emacs Lisp, încă un pic este încă necesară pentru stabilirea unui carlige câteva încărcare. Pentru multe nevoi simplu, se poate face o mulţime fără a fi nevoie să înveţe mai mult.
  • Pe de altă parte, pentru utilizări mai sofisticate, oamenii nu pot scăpa cu adevărat cunoaşterea Emacs Lisp API-o oarecare măsură, deoarece acestea trebuie să fie familiar, programare-înţelept, cu ceea ce este un tampon, un punct, o marcă, etc şi care sunt operaţiunile cu privire la aceste permise.

În timp ce exemple Pymacs nu sunt un substitut pentru o lectură atentă a manualului Pymacs, contemplarea şi studiul operelor altora "frumos poate enligthen bine şi să aprofundeze înţelegerea dumneavoastră. Câteva exemple sunt incluse în cadrul de distribuţie Pymacs, fiecare ca un subdirector al contrib / director, şi fiecare având propriile sale README fişier. Acestea sunt enumerate mai jos, cea mai simplă primele exemple:

  • Paul Winkler exemplu
    • http://pymacs.progiciels-bpi.ca/Winkler.html
  • Fernando Pérez "exemple
    • http://pymacs.progiciels-bpi.ca/Perez.html
    • http://pymacs.progiciels-bpi.ca/contrib/Perez/
  • Giovanni Giorgi de fişiere
    • http://pymacs.progiciels-bpi.ca/Giorgi.html
    • http://pymacs.progiciels-bpi.ca/contrib/Giorgi/
  • O reformatter pentru comentarii în cutie
    • http://pymacs.progiciels-bpi.ca/rebox.html
    • http://pymacs.progiciels-bpi.ca/contrib/rebox/

Câteva exemple mai substanţiale de utilizare a Pymacs au fost aduse în atenţia mea, şi sunt disponibile pe plan extern (enumerate aici, în nici o ordine anume):

  • pymdev - Un Python Emacs-ul de dezvoltare Modulul:
    • http://www.toolness.com/pymdev/
  • Ropemacs - Caracteristici precum şi codul de refactorizare-ajută:
    • http://rope.sf.net/ropemacs.html
    • http://rope.sf.net/hg/ropemacs
  • Reparatii biciclete, Man - Un instrument Refactorizare pentru Python:
    • http://bicyclerepair.sourceforge.net/
  • Emacs Freex - Un wiki personală pe steroizi:
    • http://www.princeton.edu/% 7Egdetre/software/freex/docs/index.html
  • PyJde - Java dev codul sursă navigare caracteristici în Emacs folosind Python:
    • http://code.google.com/p/pyjde/

Proiectul QaTeX a fost influenţată de Pymacs, potrivit autorului său:

  • http://qatex.sourceforge.net/
  • http://www.pytex.org/doc/eurotex2005.pdf

1.3 Alte resurse

Sunteti bineveniti scris sau aderarea la lista de discuţii următoare, în cazul în care există câţiva oameni în jurul valorii de probabil să vă dea feedback-ul:

  • mailto: pymacs-devel@googlegroups.com
  • https://groups.google.com/group/pymacs-devel/

Dacă nu aveţi frică de larg mulţimile :-), încă mai există:

  • mailto: python-list@python.org

Există alte site-uri web în mod specific despre Pymacs. Giovanni Giorgi are una dintre ele:

  • http://blog.objectsroot.com/projects/pymacs/

Există o intrare pentru Pymacs pe Freshmeat:

  • http://freshmeat.net/projects/pymacs/

2 Instalare

Verificaţi 2.1 căi de căutare

Trebuie să vă asiguraţi că atât Emacs si Python sunt utilizabile, indiferent de director se întâmplă să fie cea actuală. Acest lucru este deosebit de important în momentul lansează Emacs Python sub scena, ca Python ar trebui să fie găsit, apoi a început. Pe majoritatea sistemelor, aceasta înseamnă stabilirea calea de căutare corect.

Următoarele note, pentru MS Windows, au fost furnizate de către Greg Detre.

  • După Start/Run/Cmd, de tip python. Dacă acest lucru funcţionează oriunde vă aflaţi, apoi directorul de instalare Python este deja în sistemul dumneavoastră PATH variabilă de mediu. În cazul în care nu este cazul, urmaţi instrucţiunile de aici pentru ao adăuga:

    http://www.computerhope.com/issues/ch000549.htm

  • Este posibil să fi să adăugaţi directorul ce conţine script Python pe care doriţi să rulaţi prin Pymacs la dvs. PYTHONPATH variabilă, în acelaşi mod ca mai sus. Puteţi testa acest lucru prin rularea Python, şi apoi:

    python

    sau pur si simplu:

    import my_python_scripts
    

    de undeva de pe lângă directorul dvs. script-uri.

2.2 Editaţi fişierul de configurare

În cele mai multe cazuri, este posibil să săriţi acest pas, deoarece este necesară numai în circumstanţe neobişnuite, problematic. Doar verifica faptul că nici una dintre următoarele vi se aplică.

  • În conformitate cu Aquamacs (care este un port de MacOS X nativ de Emacs), sa raportat că unul devine cuiburi Lisp depăşeşte max-Lisp-eval-aprofundată mesaje în timp ce solicită interactiv documentaţia pentru funcţiile Lisp (nu ştim de ce). Dacă aveţi această problemă, editaţi fişierul ppppconfig.py, localizaţi linia de definire DEFADVICE_OK, asiguraţi-vă că acesta devine şirul de caractere "zero", ca valoare, în loc de string "T", apoi salvaţi fişierul editat anterior înainte de a trece mai departe. Acest lucru ar trebui să funcţioneze în jurul valorii de problema. Preţul de a plăti este că nu veţi primi docstring Python pentru modulele importate prin Pymacs.

2.3 Verificaţi dacă ar funcţiona Pymacs

Pentru a şti, înainte de instalarea Pymacs, în cazul în care ar funcţiona pe sistemul dvs., încercaţi să suita de validare prin rularea face check. Suita este destul de elementar, dar cu toate acestea, este capabil de a detecta unele comune arată dopuri. Pentru a verifica un anumit Amestec Emacs şi Python, utilizează make check EMACS=some_Emacs PYTHON=some_Python.

Dacă PYTHON este lăsată nesetat sau gol, apoi comanda de începere a Pymacs ajutor este python. În caz contrar, aceasta poate fi setat pentru a da calea completă a executabil Python în cazul în care există la o locaţie în afara programului de calea de căutare. Acesta poate fi, de asemenea, având în vedere atunci când numele interpretului este diferit, de exemplu, atunci când versiunea Python este o parte din numele programului.

Dacă Emacs este lăsată nesetat sau gol, apoi comanda de începere a editorul Emacs este emacs. Pentru utilizare normală Pymacs, Emacs-ul este lansat de către ghidul de mult timp înainte de Pymacs este ea însăşi a început, şi, în consecinţă, nu există absolut nici o nevoie să-i spuneţi Pymacs care este nevoie de Emacs. Pentru suita de validare Cu toate acestea, ea poate fi setat pentru a da calea completă a executabil cazul în care programul Emacs există la o locaţie în afara programului de calea de căutare. Acesta poate fi, de asemenea, având în vedere atunci când numele de editor este diferit, de exemplu, atunci când versiunea Emacs este o parte a numelui programului, sau atunci când acest lucru este un editor de diferit. De exemplu,  make check EMACS=xemacs ruleaza suita validării prin utilizarea xemacs pentru un editor.

Restul de această secţiune pot fi sărite fi în condiţii de siguranţă pentru instalare simpla Pymacs.

Nu am de bază suita de validare pe JUnit (cadru Python unitate de testare este o re-punerea în aplicare a acesteia), dar pe Codespeak lui pylib py.test, care este mult mai simplu, şi încă foarte puternic. Pylib Proiectul este condus de Holge Kregel, dar a atras unele creiere Python, cum ar fi Armin Rigo (cunoscut pentru Repere, printre altele - cred că sa lsprof asemenea, a fost adăugat pentru a Python 2.5 sub numele cProfile ). Această bandă se adresează metode de chinuit / grele în Python, şi nu le mai bine. Chiar py.test este un pic mai complex care mi-aş dori, şi are (sau cel puţin au avut) defecte pe partea de Unicode, asa ca am rescris propria mea, ca un singur fişier simplu. Am doar tradus din franceză în engleză, pentru ao face mai distribuit în cadrul Pymacs.

Am încercat iniţial utilizând Emacs stdin si stdout pentru comunicarea expresii pentru a evalua şi de a obţine rezultate înapoi, din cadrul suitei de validare. Acest lucru nu sa dovedit atât de util, astfel încât după câteva lupte, mi-am pus deoparte fără tragere de inimă această cale. În prezent, suita de probleme scrie in fisiere, pentru Emacs pentru a citi, scrie şi Emacs-ul răspunsurile în fişiere, pentru suita pentru a verifica. Ocupat în aşteptare (cu somn mic adăugată în bucle) este utilizată pe ambele părţi. Acest lucru este prea grea, si incetineste suita. Să sperăm că, suita nu se execută de multe ori, acest lucru nu este o problemă reală.

2.4 Instalarea propriu Pymacs

Pymacs este un pachet mic. Punerea în practică a documentaţiei şi a dosarelor administrative deoparte, există un fişier Python şi un fişier Emacs Lisp la acesta, care urmează să fie instalate, la rândul său. Întotdeauna începe cu fişierul Python.

  • Pentru partea Python

    De la cel mai înalt nivel al distribuţiei Pymacs, executaţi make install. În cazul în care interpret Python are un nume non-standard sau locaţie, nu mai degrabă make install PYTHON = Some_Python (a se vedea secţiunea anterioară pentru o discuţie). În primul rând, script-ul exemplare câteva fişiere sursă în timp ce le configurarea: ea presetărilor şirul versiunea şi numele interpretului Python, se adaptează, de asemenea, codul sursă Python, care ar putea diferi, de exemplu, între 2 şi Python Python 3. În al doilea rând, se instalează pachetul de Python prin instrument standard Python Distutils. Pentru a obţine un memento opţiune, nu python setup.py install --help . Consultaţi documentaţia Distutils dacă aveţi nevoie de mai multe informatii despre acest lucru.

    Asta e în mod normal, tot la ea. Pentru a verifica faptul că pymacs.py este instalat corect, începe o sesiune interactivă Python şi tipul de la Pymacs de import Lisp : tu nu ar trebui să primească nici o eroare.

    O dificultate specială apare atunci când Python special pe care îl utilizaţi nu are Distutils deja instalat. Într-un astfel de caz, make install imprimă un avertisment, lăsând să vă sarcina de a imaginind în cazul în care Pymacs / directorul este cel mai bun copiat, şi de a face această copie.

  • Pentru partea Emacs

    Acest lucru se face de obicei cu mâna acum. Mai întâi, selectaţi directorul unele de-a lungul liste păstrate în Emacs dvs. de încărcare-cale, pentru care aveţi acces de scriere, şi să copiaţi fişiere pymacs.el în acel director.

    Dacă vrei viteză, în mod ideal ar trebui să-byte compila acest fişier. Pentru a face acest lucru, mergeţi la acel director, lansarea Emacs, apoi daţi comanda Mx byte-compile-file RET pymacs.el RET. Dacă din anumite motive pe care intenţionaţi să comenzi astfel de des, se poate crea un mic script pentru a face acest lucru. Aici este un exemplu de un astfel de scenariu, presupunând aici, pe care le folosesc Emacs şi doriţi să instalaţi în directorul ~ / share / emacs / Lisp / :

    # / Bin! / Bash
    cp pymacs.el ~ / share / emacs / Lisp /
    emacs-lot-eval "(byte-compila-fişier" ~ / share / emacs / Lisp / pymacs.el ")"
    

    Tu ar trebui să fie făcut acum. Pentru a verifica faptul că pymacs.el este instalat corect, a reveni la directoarele dvs. de obicei, începe Emacs şi dea comanda Mx de încărcare-bibliotecă RET pymacs RET : tu nu ar trebui să primească nici o eroare.

Unele caracteristici de la versiuni precedente Pymacs au fost ignorate:

  • Variabila de mediu PYMACS_EMACS este plecat, şi de variabile de mediu PYMACS_PYTHON de obicei nu este necesară.
  • Nu folosit pentru a fi un script pentru instalarea Emacs Lisp fişier. Aşa cum a fost dificil să-l drept în toate circumstanţele; script-ul a crescut un mod interactiv şi mulţime de opţiuni. Aceasta nu este doar în valoare de complexitate, astfel încât acest script este acum dispărut.
  • Exemple au fost instalate automat toate, dar cel puţin pentru unele dintre ele, acest lucru a fost mai mult de poluare de ajutor. Puteţi răsfoi conţinutul a contrib / director pentru a afla despre exemple disponibile.

Pregătiţi-vă 2.5 emacs. fişier

Emacs. fişier nu este dat în distribuţie, va avea probabil o deja în directorul tau de casa. Ai nevoie să adăugaţi aceste linii:

(autoload 'pymacs-apply "pymacs")
(autoload 'pymacs-call "pymacs")
(autoload 'pymacs-eval "pymacs" nil t)
(autoload 'pymacs-exec "pymacs" nil t)
(autoload 'pymacs-load "pymacs" nil t)
;;(eval-after-load "pymacs"
;;  '(add-to-list 'pymacs-load-path YOUR-PYMACS-DIRECTORY"))

Dacă intenţionaţi să utilizaţi un director special de a deţine propriul cod Pymacs în Python, care ar trebui să fie căutate înainte de Python de obicei de import calea de căutare, apoi decomentaţi ultimele două rânduri (prin eliminarea doua puncte semi-) şi înlocuiţi -VĂ PYMACS- ANUAR de numele directorul dvs. speciale. Dacă fişierul ~ /. emacs nu există, creaţi-l doar cu liniile de mai sus. Acum sunteţi gata să utilizeze Pymacs.

Pentru a verifica acest lucru, începe un nou sesiune Emacs, şi de tip Mx pymacs-eval RET. Emacs-ul ar trebui să vă va cere o expresie Python. Încercaţi repr (2L ** 111) RET (utilizarea mai degrabă repr (2 ** 111) RET dacă sunteţi folosind Python 3). Tampon mini ar trebui să afişeze "2596148429267413814265248164610048L" (încă nu există nici o L sufix în Python 3).

Hai sa facem un al doilea test. Dacă în aceeaşi sesiune Emacs sau nu, Mx pymacs-încărcare RET ar trebui să vă va cere un nume de modul Python. Răspunde os RET RET (a doua RET este pentru acceptarea prefixul implicit Acest lucru ar trebui să aibă efectul de a importa Python. os modul în Emacs dactilografiere. M-: (os-getcwd) RET ar trebui să ecou directorul curent în buffer mesaj, astfel cum returnate de os.getcwd funcţia Python.

2.6 Portarea şi limitări

Pymacs a fost iniţial dezvoltat pe Linux, Python 1.5.2, şi Emacs 20, şi este în prezent dezvoltat folosind Python 2.6, Python 3.1, Emacs 23.1 şi 21.4 Xemacs. Este de aşteptat să lucreze din caseta de pe mai multe arome de Unix, MS Windows şi Mac OSX, şi, de asemenea, pe versiunea de multe Python, Emacs şi Xemacs.

Din Pymacs 0.23 şi în sus, Python 2.2 sau mai bine este probabil necesar, şi pentru Pymacs buna, ma bazez pe testere sau utilizatorilor pentru probleme de portabilitate. Cu toate acestea, suita de validare în sine necesită Python 2.6 sau mai bine, cineva ar putea alege să contribui portare înapoi. Python 3.1 de sprijin a fost adăugată pentru Pymacs 0.24.

Pymacs Emacs foloseste tabele de dispersie slab. Se poate rula fără ele, dar apoi, obiecte complexe Python transmise la Emacs-ul va lega pentru totdeauna de memorie Python. Acesta nu ar trebui să fie o problemă de ordin practic, în cele mai multe cazuri simple. Unele versiuni ulterioare ale Emacs 20 a crea tabele în tăcere ordinară atunci când a cerut tabele de dispersie slabe. Emacses mai vechi nu au tabele de dispersie.

Pymacs Pachetul Python are un singur pymacs.py fişier (şi obligatoriu __init__.py ). Programatorii s-ar putea alege, dar nu sunt obligate, pentru a instala aplicaţiile lor proprii Pymacs fie ca sub-sub-module sau pachete pe Pymacs.

3 structuri de Emacs Lisp şi obiecte Python

3.1 Conversii

Ori de câte ori Emacs Lisp solicită funcţiile Python, oferindu-le argumente, aceste argumente sunt Emacs Lisp structuri care ar trebui să fie convertite în obiecte Python într-un fel. În schimb, ori de câte ori solicită Python Emacs Lisp funcţii, argumentele sunt obiecte Python care ar trebui să fie primite ca Emacs Lisp structuri. Avem nevoie de anumite convenţii pentru a face astfel de conversii.

Conversii transmite, în general, mutabil Emacs Lisp ca structurile mutabil obiecte pe partea de Python, în aşa fel încât transformarea obiectului în Python se va transforma în mod eficient structura pe partea Emacs Lisp (siruri de caractere sunt manipulate un pic special cu toate acestea, a se vedea mai jos). Alt mod în jurul valorii de, obiecte Python transmise Emacs Lisp pierde de multe ori mutabilitatea lor, transformand astfel Emacs Lisp structura nu se reflectă pe partea Python.

Pymacs se lipeste de standard de Emacs Lisp, se evită în mod explicit diferite Emacs Lisp extensii. Un gol pentru multi utilizatori Pymacs este de a lua o oarecare distanţă de Emacs Lisp, deci nu este Pymacs împinge prea utilizatorii mai adânc în el.

3.2 obiecte simple

Emacs Lisp zero şi echivalentul Emacs Lisp () randament Python Nici unul. Piton Nici una, Python Fals şi lista Python goale [] sunt returnate ca zero în Emacs Lisp. Notă assymetry, în care trei obiecte diferite Python sunt mapate într-un singur obiect Emacs Lisp. Deci, nici fals, nici [] sunt probabil produse de conversii automate de la Emacs Lisp în Python.

Emacs Lisp t randamentele Python Adevărat. Python Adevărat este returnat ca t în Emacs Lisp.

Emacs numere de Lisp, fie întreg sau plutitoare, sunt convertite într-un număr echivalent Python. Emacs Lisp personaje sunt într-adevăr numere şi randamentul numere Python. În cealaltă direcţie, numere de Python sunt convertite în Emacs Lisp numere, cu excepţia a întregilor lungi Python şi numere complexe.

Emacs Lisp siruri de caractere sunt, de obicei, convertite în şiruri de echivalent Python. Deoarece Python siruri de caractere nu au proprietăţi de text, acestea nu sunt reflectate. Acest lucru poate fi schimbat prin setarea pymacs-mutabil-siruri de caractere opţiune: dacă această variabilă nu este zero, Emacs Lisp siruri de caractere sunt apoi transmise opaquely. Siruri de caractere Python sunt întotdeauna convertite în şiruri de Emacs Lisp. Piton de presă înainte de versiunea 3 a face o distincţie între siruri de caractere Unicode şi înguste: siruri de caractere Unicode sunt apoi produse pe partea de Python pentru Emacs Lisp multi-octet siruri de caractere, dar numai atunci când acestea nu se potrivesc în ASCII, siruri de caractere altfel Python înguste sunt produse. În schimb, Emacs Lisp multi-byte siruri de caractere sunt produse pentru orchestra de coarde Python, dar numai atunci când acestea nu se potrivesc ASCII, altfel Emacs Lisp uni-byte siruri de caractere sunt produse. În prezent, comportamentul Pymacs este nedefinit pentru utilizatorii care ratacesc pe afara limitelor de Emacs " UTF-8 sistem de codificare.

Emacs Lisp simbolurile randament Lisp [STRING] notaţiile pe partea Python, în cazul în care STRING numele simbolului. În cealaltă direcţie, Python Lisp [STRING] corespunde unui simbol Emacs Lisp imprimate cu care STRING care, desigur, ar trebui să fie apoi o adresă validă de Emacs Lisp nume de simbol. Ca o comoditate, lisp.SYMBOL pe partea Python randamentele un simbol Emacs Lisp cu subliniaza înlocuieşte cu cratime, această convenţie este binevenită, astfel cum Emacs Lisp programatori de obicei preferaţi să utilizaţi cratime, în cazul în care programatorii Python subliniază utilizare. Desigur, această lisp.SYMBOL notaţie este utilizabil numai în cazul în care SYMBOL este un identificator valid Python, în timp ce nu este un cuvânt cheie Python.

3.3 Secvenţe

Cazul de siruri de caractere a fost discutată în secţiunea anterioară.

Buna Emacs Lisp liste, cele pentru care CdR de ultima celulă este zero, sunt în mod normal transmise opaquely la Python. Dacă pymacs-uita-mutabilitatea este setat, sau dacă mai târziu Python solicită ca acestea să fie extinse, buna Emacs Lisp listele sunt convertite în liste Python, dacă am cu excepţia listă goală, care este intotdeauna convertite ca Python Nici unul. În cealaltă direcţie, listele de Python sunt întotdeauna convertite în buna Emacs Lisp liste.

Emacs Lisp vectori sunt în mod normal transmise opaquely la Python. Cu toate acestea, în cazul în care pymacs-uita-mutabilitatea este setat, sau dacă mai târziu Python solicită ca acestea să fie extinse, Emacs Lisp vectori fi convertit într-tuple Python. În cealaltă direcţie, tupluri Python sunt întotdeauna convertite în Emacs Lisp vectori.

Amintiţi-vă de regula: paranteze rotunde corespund paranteze pătrate!. Aceasta funcţionează pentru liste, vectori, tupluri, vazut din Emacs Lisp fie sau Python.

Alternative mai sus au fost discutabil. Deoarece listele de Emacs Lisp corectă şi listele de Python sunt pâinea-şi-unt de algoritmi de modificare a structurilor, cel puţin în experienţa mea, cred ca ele sunt mult mai natural mapate într-un altul, acest lucru pune multe piese de schimb în practică. În timp ce în Python, idiomul cele mai uzuale pentru listele de crestere este adăugarea la sfârşitul lor, idiomul cele mai uzuale în Emacs Lisp să crească o listă este de cons'ing elemente noi de la începutul său:

(setq accumulator (cons 'new-item accumulator))

sau mai simplu:

(push 'new-item accumulator)

Deci, în cazul în viteză este deosebit de important şi de multe modificări întâmpla într-un rând de pe aceeaşi parte, în timp ce ordinea de elemente ar trebui să fie conservate, unele (nreverse...) pe partea Emacs Lisp sau. reverse () de pe partea Python ar putea fi necesară. Desigur, listele corespunzătoare în Emacs Lisp şi liste în Python sunt structura normala pentru o lungime care este uşor de modificat.

Noi nu putem schimba atât de uşor de marimea unui vector, la fel ca acesta este un pic mai mult de o cascadorie de a modifica un tuplu. Forma dintre aceste obiecte este fixă. Vectori de cartografiere pentru a tupluri, care este, desigur, ciudat, se va face numai în cazul în care partea Python solicită o copie extins, altfel, opac Emacs Lisp obiect este văzut în Python. În cealaltă direcţie, ori de câte ori un Emacs Lisp vector este necesar, trebuie sa scrie tuplu (python_list), în timp ce transmiterea obiect. Aceste transmisii sunt cel mai probabil să fie neobişnuit, ca oamenii nu sunt de gând să transmită orbeşte structuri întregi mare înainte şi înapoi între Emacs şi Python, ar face mai degraba o dată într-un timp doar, şi nu numai modificări locale după aceea. Turnare frecvente la tuplu pentru a obţine o Emacs Lisp vector pare să sugereze că am făcut un compromis rezonabil.

În Python, atât tuple şi liste au O (1) de acces, astfel încât nu există nici o consideraţie viteza reală acolo. Emacs Lisp este diferit: vectori au O (1) Acces în timp ce listele au O (N) de acces. Rigiditatea de Emacs Lisp vectori este de aşa natură că oamenii nu recurg la vectori excepţia cazului în care există o problemă de viteză, astfel încât în ​​termeni reali Emacs Lisp practică, vectori sunt folosite mai degrabă parsimoniously. Atât de mult, de fapt, că Emacs Lisp vectori sunt supraîncărcate pentru ceea ce nu sunt destinate: de exemplu, vectori foarte mici, sunt folosite pentru a reprezenta evenimente X-cheie în hărţi, programatori doar doriţi să le testaţi vectori pentru tipul lor, sau de utilizatori la fel ca paranteze sintaxă. Viteza de acces este cu greu o problemă atunci.

3.4 obiecte opace

3.4.1 Emacs Lisp mânere

Când o funcţie Python este sunat din Emacs Lisp, argumente de functii au fost deja convertite la tipuri de Python de la Emacs Lisp şi tipuri de rezultatul funcţia va fi convertit înapoi la Emacs Lisp.

Mai multe obiecte Emacs Lisp nu posedam echivalente Python, cum ar fi Emacs pentru ferestre, tampoane, markere, suprapuneri, etc toate acestea, este util să le transmită la funcţii Python, în speranţa că aceste funcţii Python va funcţiona pe aceste obiecte Emacs Lisp. Desigur, partea Python nu se poate modifica astfel de obiecte, trebuie să solicite servicii de Emacs să facă acest lucru. Emacs Lisp Mânerele sunt o modalitate de a uşura această comunicare.

Ori de câte ori un Emacs Lisp obiect nu poate fi convertit într-un obiect Python, o Emacs Lisp mânerul este creat şi utilizat în locul. Ori de câte ori că Emacs Lisp Manerul este returnat în Emacs Lisp dintr-o funcţie Python, sau este folosit ca argument pentru o funcţie Emacs Lisp din Python, original Emacs Lisp obiect în spatele mânerul Emacs Lisp este preluate automat.

Emacs Lisp mânerele sunt fie instanţe ale interne Lisp clasa, sau de una din subclasele sale. Dacă OBJECT este un mâner Emacs Lisp, şi în cazul în care stau la baza obiectului Emacs Lisp este o secvenţă Emacs Lisp, apoi ori de câte ori OBJECT [INDEX], OBJECT [INDEX] = VALUE şi len (obiect) sunt semnificative, acestea pot fi folosite să-i aducă sau să modifice un element al secvenţei direct în Emacs Lisp spaţiu. De asemenea, în cazul în care OBJECT corespunde la o funcţie Emacs Lisp, OBJECT (argumente) pot fi folosite pentru a aplica Emacs Lisp funcţia pe argumentele date. Din moment ce argumente au fost evaluate modul în Python pe partea Python, ar fi nejustificată conceptuală evaluare a acestora din nou Emacs Lisp modul pe partea Emacs Lisp, astfel încât Pymacs reuşesc să citez argumente pentru a învinge Emacs Lisp evaluare. Aceeaşi logică se aplică invers.

Emacs Lisp mânere au o value() metodă, care returneaza doar de sine. Ei au de asemenea, o copie () metodă, care încearcă să deschidă caseta, dacă este posibil. Emacs Lisp listele corespunzătoare sunt transformate în liste Python, Emacs Lisp vectori sunt transformate în tupluri Python. Apoi, modificarea structurii a copia de pe partea Python nu are niciun efect pe partea Emacs Lisp.

Pentru Emacs Lisp mânere, str. () returnează o reprezentare Emacs Lisp a mânerului, care ar trebui să fie echivalent cu obiectul original dacă citit şi evaluată în Emacs Lisp. repr () returnează o reprezentare Python a extins obiectul Emacs Lisp. În cazul în care Emacs Lisp obiect are o reprezentare Emacs Lisp, care Emacs Lisp putea citi înapoi, atunci repr () valoarea este de aşa natură că ar putea fi citit şi evaluate în Python, de asemenea, acest lucru ar duce la un alt obiect care este egal cu originalul, dar nu neapărat echivalent.

3.4.2 Python mânere

La fel ca Emacs Lisp mânere sunt utile pentru manipularea obiectelor Emacs Lisp pe partea de Python, mânerele Python sunt utile pentru manipularea obiectelor Python pe partea Emacs Lisp.

Multe obiecte Python nu posedam directe Emacs Lisp echivalente, inclusiv întregi lung, numere complexe, module, clase, cazuri şi cu siguranţă o mulţime de altele. Atunci când sunt transmise spre partea Emacs Lisp, Pymacs folosi Python mânere. Acestea sunt recuperate automat în obiecte originale Python ori de câte ori transmise înapoi la Python, fie ca argumente pentru o funcţie Python, ca funcţia de Python în sine, sau ca valoarea returnată de o funcţie de Emacs Lisp sunat din Python.

Obiectele reprezentate de aceste mânere Python pot fi verificate sau modificate folosind biblioteca de bază de funcţii Python. De exemplu, în:

(Pymacs-exec "re de import")
(Setq Meciuri (pymacs-eval "re.compile (" PATTERN "). Meci"))
(Pymacs-apel ARGUMENT Meciuri)

setq linia de mai sus ar putea fi descompusă în:

(Setq compilat (pymacs-eval "re.compile (" PATTERN ') ")
      Meciuri (pymacs-apel "getattr" compilate "meci"))

Acest exemplu arată că se poate folosi pymacs-apel cu getattr ca funcţia, pentru a obţine un atribut dorit pentru un obiect Python.

4 Utilizarea pe partea Emacs Lisp

4.1 speciale Emacs Lisp funcţii

Pymacs este în principal lansat si utilizat prin intermediul unei funcţii de câteva construcţii, printre toate cele adăugate de către Pymacs pentru Emacs Lisp. Aceste funcţii câteva importate sunt enumerate şi detaliate în subcapitolele următoare. Ei într-adevăr sunt modalitatea preferată de a apela serviciile de Python cu Pymacs.

Chiar şi atunci, nu ne aşteptăm că pymacs-exec, pymacs-eval, pymacs-apel sau pymacs-se aplică vor fi mult mai utilizate, dacă vreodată, în majoritatea aplicaţiilor Pymacs. În practică, partea Emacs Lisp a unei cereri de Pymacs-ar putea numi pymacs-încărcare de câteva ori pentru conectarea în module Python, cu efect indirect de definire a funcţiilor trambulină pentru aceste module pe partea Emacs Lisp, care poate fi numit mai târziu ca de obicei Emacs Lisp funcţii.

4.1.1    pymacs-exec

Funcţia (pymacs-exec TEXT) devine TEXT executat ca o declaraţie Python, iar valoarea acestuia este întotdeauna zero. Deci, această funcţie poate fi utilă numai din cauza efectelor sale adverse posibile pe partea Python.

Această funcţie poate fi, de asemenea, numit interactiv:

Mx pymacs EXEC-RET TEXT RET

4.1.2    pymacs-eval

Funcţia (pymacs-EVAL TEXT) devine TEXT evaluat ca o expresie Python, şi întoarce valoarea acestei expresii convertite înapoi la Emacs Lisp.

Această funcţie poate fi, de asemenea, numit interactiv:

Mx pymacs-eval RET TEXT RET

4.1.3    pymacs-apel

Funcţia (pymacs-apel FUNCŢIE ARGUMENT...) va primi Python să aplice dat FUNCTION peste zero sau mai multe ARGUMENT. FUNCTION este fie un şir de exploataţie Python codul sursă pentru o functie (cum ar fi un nume simplu, sau chiar o expresie), sau altceva, o toartă Python primite anterior de la Python, şi sperăm că deţine un apelabile obiect Python. Fiecare ARGUMENT devine separat convertit la Python înainte de funcţie este numită. pymacs-apel returnează valoarea care rezultă din apel de funcţie, convertit înapoi la Emacs Lisp.

4.1.4    pymacs-se aplică

Funcţia (pymacs-apply FUNCTION ARGUMENTS) va primi Python să aplice dat FUNCTION peste dat ARGUMENTE. ARGUMENTE este o listă care conţine toate argumentele, sau zero în cazul în care nu există nici unul. Pe langa argumentele fiind grupate în loc de date separat, funcţia de acte destul de mult ca pymacs-apel.

4.1.5    pymacs-încărcare

Funcţia (pymacs-încărcare PREFIX MODULE) importurile Python modul în Emacs Lisp spaţiu. MODULE este numele fişierului care conţine modulul, fără nici o py. sau pyc. prelungire. În cazul în care partea de director este omisă în MODULE, modulul va fi analizat în calea de căutare actual Python. Dot notaţie pot fi utilizate atunci când modul este parte a unui pachet. Fiecare funcţie de nivel superior în modulul produce o funcţie de trambulină în Emacs Lisp cu acelaşi nume, cu excepţia faptului că subliniază, în numele Python sunt transformate în cratime în Emacs Lisp, şi că PREFIX este uniform adaugă înainte de numele Emacs Lisp (ca o modalitate de a a evita conflictul de nume). PREFIX pot fi omise, caz în care se implicit numele de bază de MODULUL cu subliniază transformat în minusuri, şi urmată de o liniuţă.

Reţineţi că pymacs de sarcină are ca efect declararea variabilelor modul şi metodele de pe partea Emacs Lisp, dar nu nu declară nimic pe partea de Python. Desigur, Python importurile modulul înainte de acest site este disponibil pentru Emacs, dar nu există nici o variabilă Pymacs gata pe partea Python considerând că modul. Dacă aveţi nevoie pentru a importa MODULUL într-o variabilă pe partea Python, incantaţie propriu-zis este (pymacs-exec "MODULUL de import"). Şi bineînţeles, această declaraţie din urmă nu declară nimic pe partea Emacs Lisp.

Ori de câte ori pymacs_load_hook este definită în modulul încărcat Python, pymacs-încărcare se solicită fără argumente, dar înainte de a crea opinia Emacs pentru modulul respectiv. Deci, pymacs_load_hook funcţie poate crea noi definiţii sau chiar adăuga interacţiune atribute pentru funcţiile.

Valoarea întoarcere a unui succes pymacs sarcină este modulul obiect. Un argument opţional treia, noerror, atunci cand este administrata si nu zero, va avea pymacs de încărcare pentru a reveni zero în loc de creştere o eroare, în cazul în care modulul Python nu a putut fi găsit.

Atunci când mai târziu de asteptare una dintre aceste funcţii trambulină, toate argumentele furnizate sunt convertite în Python şi transmise, precum şi funcţia de întoarcere valoarea este mai târziu convertit înapoi la Emacs Lisp. Este lăsat la partea Python pentru a verifica coerenţa argument. Cu toate acestea, pentru o funcţie interactivă, caietul de sarcini interacţiune unele unităţi de control pe partea Emacs Lisp. În prezent, nu există nicio dispoziţie pentru colectarea argumente cuvânt cheie în Emacs Lisp.

Această funcţie poate fi, de asemenea, numit interactiv:

M-x pymacs-load RET MODULE RET PREFIX RET

Dacă vă aflaţi folosind pymacs-apel o mulţime de funcţii de comanda interna Python, aţi putea alege mai degrabă de a importa toate funcţiile Python interna şi definiţii direct în spaţiu Emacs Lisp, şi după aceea le numim în mod direct. Aici este o reteta (utilizarea de prima linie pentru Python 2, sau a doua linie pentru Python 3):

M-x pymacs-load RET __builtin__ RET py- RET
M-x pymacs-load RET builtins RET py- RET

După o astfel de comandă, funcţia de asteptare PY-getattr, să zicem, cu un obiect opac Python şi cu un şir de nume un atribut, returnează valoarea de care atribut pentru acest obiect.

4.2 speciale Emacs Lisp variabile

Utilizatorii ar putea modifica de lucru interioare ale Pymacs prin câteva variabile, toate acestea sunt documentate aici. Cu excepţia pymacs-python-comandă şi pymacs-încărcare-cale, care ar trebui să fie stabilite înainte de a apela orice funcţie Pymacs, valoarea acestor variabile pot fi schimbate în orice moment.

4.2.1    pymacs-python-comandă

Această variabilă este iniţializată cu executabilul Python care a fost utilizată la momentul instalării. Se spune despre Emacs interpret Python pentru a lansa incepand de departe helper Pymacs. Valoarea acestei variabile ar putea fi înlocuită prin setarea PYMACS_PYTHON variabilă de mediu, încă, în practică, pentru versiunile mai noi ale Pymacs, acest lucru este rareori necesar.

În timp ce partea a Pymacs Python este pre-procesate şi randamente diferite surse pentru Python Python 2 şi 3 (printre alte posibilităţi), parte a Emacs Pymacs este cea mai mare parte configurat la momentul execuţiei pentru versiuni diferite Emacs, astfel încât aceeaşi sursă Emacs este probabil să muncă nemodificate, ar fi pentru versiuni diferite de Emacs şi pentru diferite versiuni de Python. Deci, este logic, cel puţin în anumite circumstanţe speciale, oferind capacitatea de a selecta un anumit interpret Python prin intermediul programatic în cadrul Emacs.

4.2.2    pymacs-încărcare-path

Utilizatorii ar putea să doriţi să utilizaţi directoare speciale pentru desfăşurarea modulelor lor Python, atunci când aceste module sunt destinate a fi utilizate de la Emacs. Cel mai bun este de a presetate pymacs-încărcare-cale, zero în mod implicit, la o listă a acestor nume de director. (Tilde extinderi şi apar astfel de automat.)

Iată cum funcţionează. Pymacs prima dată este nevoie de Emacs, un ajutor Pymacs este automat pornit ca un subproces Emacs, şi având în vedere ca argumente toate siruri de caractere în pymacs-încărcare-cale listă. Aceste argumente se adaugă la începutul sys.path, sau sa mutat de la început dacă acestea au fost deja pe sys.path. Deci, în practică, nimic nu este eliminat din sys.path.

4.2.3    pymacs-urme-de tranzit

* * * Pymacs tampon, în termen de Emacs, deţine o urmă de tranzacţii între Emacs şi Python. Atunci când pymacs-urme-de tranzit este zero, buffer-ul are doar ultimul bi-direcţional tranzacţie (o cerere şi un răspuns). În acest caz, ea devine mai şterse înainte de a fiecărei tranzacţii. În cazul în care variabila este t, toate tranzacţiile sunt păstrate. Acest lucru ar putea fi utilă pentru depanare, dar dezavantajul este că acest tampon ar putea creşte mare a lungul timpului, la punctul de a diminua Emacs performanţă. Ca un compromis, care variabila poate fi, de asemenea, o celulă contra întregi (Keep. LIMIT), caz în care buffer-ul este redusă la aproximativ LĂSA bytes ori de câte ori dimensiunea sa depăşeşte LIMIT bytes, prin eliminarea unui număr de linii integral de la începutul său. Setarea implicită pentru pymacs-urme-de tranzit este (5000 30000.).

4.2.4    pymacs-uita-mutabilitatea

Comportamentul implicit de Pymacs este de a transmite Emacs Lisp obiecte de Python în aşa fel că sunt pe deplin modificabili din partea Python, ar însemna declanşarea Emacs Lisp funcţiile de a acţiona asupra lor. Atunci când pymacs-uita-mutabilitatea nu este zero, comportamentul este schimbat, iar flexibilitatea este pierdut. Pymacs apoi încearcă să-şi extindă liste corespunzătoare şi vectori ca exemplare complete atunci când le transmită pe partea de Python. Această variabilă, văzut ca o setare de utilizator, este cel mai bine la stanga la zero. Aceasta poate fi înlocuită temporar în cadrul unor funcţii, atunci când consideră util.

Nu există nici o variabila corespunzătoare de la obiecte transmise Emacs din Python. Pymacs se extinde automat ceea ce se transmit. Schimbare este păstrat doar ca un efect secundar al unei persoane fizice care nu au reprezentare Emacs Lisp pentru obiect Python. Această asimetrie este pe scop, dar discutabil. Poate Pymacs ar putea avea o variabilă spune că mutabilitatea este important pentru obiecte Python? Aceasta ar oferi utilizatorilor Pymacs capacitatea de refacere a simetriei oarecum, totusi atat de departe, din experienta noastra, aceasta nu a fost niciodata nevoie.

4.2.5    pymacs-mutabile-siruri de caractere

Strict vorbind, Emacs Lisp siruri de caractere sunt mutabile. Cu toate acestea, ea nu vine natural la un programator Python pentru a modifica un şir în loc, ca siruri de caractere Python nu sunt niciodată mutabile. Atunci când pymacs-mutabil-siruri de caractere este zero, care este setarea implicită, Emacs Lisp siruri de caractere sunt transmise Python ca siruri de caractere Python, şi aşa mai departe, pierde mutabilitatea lor. Mai mult decât atât, proprietăţi text nu sunt reflectate pe partea Python. Dar, în cazul în care variabila nu este zero, Emacs Lisp siruri de caractere sunt mai degrabă trecut ca Emacs Lisp mânere. Această variabilă este ignorat ori de câte ori pymacs-uita-mutabilitatea este setat.

4.2.6 variabile Timeout

Emacs trebuie să se protejeze un pic, în cazul în care programul de întreţinere Pymacs, care se ocupă de partea de Python de cereri, nu va începe în mod corect, sau poate mai târziu muri în mod neaşteptat. Aşa că, ori de câte ori Emacs citeşte datele care provin din acel program, se stabileşte o limită de timp, şi să ia unele măsuri ori de câte ori că expirarea termenului limită. Toate orele sunt exprimate în secunde.

Pymacs-timeout-la-start implicit variabila la 30 de secunde, de această dată ar trebui să fie a crescut doar în cazul în care o maşină este dat atât de puternic încărcate că programul de întreţinere Pymacs nu are suficient de 30 de secunde pentru a porni, în care caz Pymacs refuză să lucreze, cu un mesaj adecvat, în mini-tampon.

Cele două variabile rămase timeout nu trebuie aproape de a fi modificate în practică. Când Emacs se aşteaptă la o replică de la Python, s-ar putea verifica în mod repetat starea programului de serviciu atunci când Pymacs că răspunsul primit nu este suficient de rapid, doar pentru a vă asigura că acest program nu a murit. Pymacs-timeout-la-răspuns variabile, care implicit la 5, spune cate secunde să aştepte fără a verifica, în timp ce aşteaptă ca prima linie a unui răspuns. Pymacs-timeout-la-linie de variabile, care implicit la 2, spune cate secunde să aştepte fără a verifica, în timp ce aşteaptă la o linie de răspuns după prima.

4.2.7    pymacs-auto-restart

Procesul de ajutor Pymacs este început de îndată ce acest lucru este necesar, şi devine asociat cu * * Pymacs tampon. În cazul în care buffer-ul este ucis, după cum apare în mod automat ori de câte ori se termină sesiunea Emacs, procesul de ajutor Pymacs este ucis, de asemenea. Orice alte dispariţia din ajutor este neaşteptată, şi ar putea fi consecinţa unor erori în partea Python a cererii de utilizator (sau un bug Pymacs, poate!).

În cazul în care ajutorul Pymacs moare, toate obiectele utile Python este posibil să conţină, de asemenea, murim cu el. Aşa că, după o moarte neasteptata, ar putea exista acum marionetă trimiteri în Emacs Lisp spaţiu faţă de obiecte Python dispărut, iar utilizarea acestor referinţe pot fi fatale la cerere. În cazul în care ajutorul Pymacs moare, cel mai sigur lucru de facut este oprirea tuturor funcţionalitate Pymacs şi ieşirea chiar Emacs. Pe de altă parte, nu este întotdeauna practic pentru a reporni având în tot ceea ce în astfel de cazuri: ghidul ştie cel mai bine, si este cel care decide în cele din urmă.

Moartea ajutor Pymacs este detectat la timp, o nouă cerere Pymacs devine iniţiate din partea Emacs-ului. Pymacs nu ar putea face mult, fără un ajutor Pymacs, asa ca trebuie fie pentru a reporni un nou ajutor Pymacs, sau abandona cererea Pymacs. Variabila pymacs-auto-restart controlează modul în care se face acest lucru. Valorile posibile sunt:

  • zero - cererea Pymacs este necondiţionat avortat,
  • T - o nouă Pymacs ajutor este lansat în tăcere, şi moartea helper precedent s-ar putea merge bine neobservat,
  • "Întrebaţi - ghidul interactiv decide dacă pentru a reporni Pymacs ajutor sau nu. Aceasta este valoarea implicită.

4.2.8    pymacs-groaznice-zombi

Atunci când un ajutor Pymacs devine repornit într-o sesiune Emacs-ul dat, noul brand obiecte Python pot fi create în termen de faptul că noua helper. Nu există suficiente informaţii păstrate în partea de Emacs Lisp pentru ajutor nou Pymacs pentru a recrea obiecte utile Python care a dispărut. Cu toate acestea, există suficiente maşini pentru a recupera toate numerele lor slot (toate referinţele la obiectele opace Python de la Emacs Lisp spaţiu sunt transmise în formă de numere slot de obiect).

Noul Pymacs ajutor este dat lista cu toate numerele anterioare slot pentru încă de referinţă din partea Emacs, şi este apoi atent la alocarea niciodată un nou obiect Python folosind un număr de slot de vechi, deoarece acest lucru ar putea crea confuzii, eventual fatale. Toate sloturile anterioare sunt iniţializate cu aşa-numitele zombi pe partea Python. Dacă Emacs mai târziu, o invită dispărut obiect Python, aceasta se trezeşte doar zombie sale, ceea ce va face apoi un zgomot, intră apoi adormit din nou. Zgomotul are forma unui diagnostic în cadrul * * Şi mesajele tampon, uneori vizibil în mini-tampon prea, cel puţin atunci când mini-tampon nu este folosit simultan pentru alte scopuri.

Zombies obţine mai mult de înspăimântătoare dacă pymacs-îngrozitoare-zombi este setat la un non- zero valoare. În acest caz, a apela la un obiect dispărut Python ridică o eroare care se va întrerupe în cele din urmă de calcul actuale. Un astfel de comportament ar putea fi utile în scopuri de depanare, sau pentru a vă asigura că nici un apel la un obiect Python dispărut trece neobservat.

În ediţiile anterioare Pymacs, zombie au fost întotdeauna îngrozitoare, în ipoteza că un obiect de asteptare dispărut este o eroare real. Cu toate acestea, ar putea provoca iritaţii în anumite circumstanţe, cum ar fi atunci când este asociată frecvent cu Emacs Lisp declanşat funcţii cârlig. De aceea faptul că, în mod implicit, zombie au fost în cele din urmă transformate în fiinţe mai inofensive!

5 Utilizarea pe partea Python

5.1 Python de configurare

Pentru module Python menit să fie folosit de Emacs şi care nu primesc nimic, dar Emacs zero, numere sau siruri de caractere, sau nu returneaza nimic, dar Python Nici unul, numere sau siruri de caractere, apoi Pymacs necesită configurare puţin sau deloc. În caz contrar, utilizarea de Pymacs lisp de import de la începutul modulului dumneavoastră. Dacă aveţi nevoie de mai multe caracteristici Pymacs, cum ar fi clasa, apoi a scrie de la Pymacs de import lisp, Să.

Ajutor Pymacs execută cod Python pentru a servi pe partea Emacs, si el este blocat în aşteptare până la Emacs-ul trimite o cerere. Până la helper Pymacs returnează un răspuns, Emacs-ul este blocat la rândul său, încă pe deplin de ascultare pentru a servi o eventuală Python sub-cereri, etc Deci, fie Emacs sau ajutor Pymacs este activă la un moment dat, dar nu ambele simultan.

Cu excepţia cazului în Emacs-ul a trimis o cerere de ajutor Pymacs şi aşteaptă un răspuns, nu este doar ascultând pentru a primi cereri de Python. Deci, orice alt fir Python nu pot utiliza asincron Pymacs pentru a obţine servicii de Emacs. Designul a cererii Python ar trebui să fie astfel încât comunicarea să fie întotdeauna este canalizat din firul principal Python.

Atunci când începe Pymacs, toate semnalele proces sunt inhibate pe partea Python. Cu toate acestea, SIGINT devine re-activate în timp ce rulează ghidul de funcţii. Dacă utilizatorul alege să reactiveze un semnal alte cod Python ei, ea ar trebui să facă în aşa fel încât să nu deteriora sau severă, protocolul de comunicare.

5.2 Emacs Lisp simbole

lisp este un obiect de construcţii care a construit-utile în magie. Atributele sale nu fac nimic, ci reprezintă Emacs Lisp simboluri, creat pe acoperi după cum este necesar (simbolurile lor, de asemenea, au construit-in magie).

Ca cazuri speciale, lisp.nil sau Lisp ["zero"] sunt la fel ca unul, şi lisp.t sau Lisp ["t"] sunt aceleaşi ca şi Adevărat. În caz contrar, atât lisp.SYMBOL şi Lisp [STRING] obiecte randament de interne Simbol tip. Acestea sunt obiecte autentice Python, care ar putea fi menţionate de variabile simplu Python. Se poate scrie quote = lisp.quote, de exemplu, şi de a folosi citat după aceea să spună că Emacs Lisp simbol. Dacă o funcţie Python a primit o Emacs Lisp simbol ca un argument, se poate verifica cu == dacă acest argument este lisp.never sau lisp.ask, să zicem. O functie Python poate alege bine să se întoarcă unele simbol, cum ar fi lisp.always.

În Python, scris lisp.SYMBOL = VALOARE sau lisp [STRING] = valoarea se atribuie valoarea de la simbolul corespunzător în Emacs Lisp spaţiu. Feriţi-vă că, în astfel de cazuri, Lisp. prefixul nu poate fi cruţată. După ce rezultat = lisp.result, nu se poate spera că un mai târziu rezultat = 3 va avea niciun efect în Emacs Lisp spaţiu: acest lucru ar schimba doar variabila Python rezultat, care a fost o trimitere la un simbol instanţă, deci este acum o trimitere la numărul 3.

Symbol clasă are o valoare () şi copie () metode. Se poate folosi fie lisp.SYMBOL.value () sau lisp.SYMBOL.copy () pentru a accesa valoarea Emacs Lisp de un simbol, după conversia la un obiect Python, desigur. Cu toate acestea, în cazul în care valoarea () ar fi dat o Emacs Lisp mâner, lisp.SYMBOL.copy () are ca efect lisp.SYMBOL.value () copie ()., care este, se returnează valoarea de simbol ca a fost deschisă ca posibil.

Un simbol poate fi, de asemenea, utilizat ca în cazul în care a fost o functie Python, caz în care numele într-adevăr o funcţie de Emacs Lisp, care ar trebui să fie aplicat peste argumente următoarea funcţie. Rezultatul funcţiei Emacs Lisp devine valoarea de apel, cu toate conversiile din cauza desigur.

5.3 legături dinamice

Aşa cum Emacs Lisp foloseste legaturi dinamic, este comun faptul că Emacs Lisp utilizează programe lasa pentru stabilirea temporar noi valori pentru anumite variabile Emacs Lisp având în domeniul de aplicare la nivel mondial. Aceste variabile recupereze valoarea lor anterioară în mod automat atunci când sa terminat devine, chiar dacă apare o eroare care întrerupe fluxul normal de executie.

Pymacs are o clasă pentru a reprezenta aceste setări temporare. Să presupunem, de exemplu, că doriţi să recupereze valoarea de lisp.mark () atunci când modul de a marca tranzitoriu este activă pe partea Emacs Lisp. S-ar putea folosi cu siguranţă lisp.mark (True) pentru a forţa lectură mărcii în astfel de cazuri, dar de dragul de ilustrare, să ignore faptul că, şi a dezactiva temporar modul de marca tranzitorii în schimb. Acest lucru ar putea fi realizat în acest fel:

try:
    let = Let()
    let.push(transient_mark_mode=None)
   ... USER CODE...
finally:
    let.pop()

let.push () acceptă orice număr de argumente cuvinte cheie. Fiecare nume de cuvânt cheie este interpretat ca un simbol Emacs Lisp în scris modul Pymacs, cu subliniază. Valoarea de care Emacs Lisp simbol este stocat pe partea de Python, şi valoarea cuvântului cheie devine noua valoare temporară pentru acest Emacs Lisp simbol. Un mai târziu let.pop () restabileşte valoarea precedentă pentru toate simbolurile cu care au fost salvate impreuna la momentul corespunzător let.push (). S-ar putea fi mai mult de o let.push () apel pentru o singură exemplu, ei stivă în acest exemplu. Fiecare let.pop () va anula unul şi numai un let.push () din stivă, în ordine inversă sau împinge.

Un singur apel la let.pops () are în mod automat toate în aşteptarea let.pop (), la o dată, în ordine inversă corectă. În cazul în care exemplu dispare, fie din cauză că programatorul nu permite del sau lasa = Nici unul, sau doar pentru ca Python variabila iese din sfera de aplicare, let.pops () este executat în conformitate cu scena, astfel încât încercaţi să / în cele din urmă situaţia poate fi omisă în practică. Pentru această omisiune să funcţioneze perfect, programatorul trebuie sa fie atenti la nu ţine evidenţa trimiteri extra instanţă.

Apelul constructorului lasa = Fie (), are, de asemenea, o primă implicite. Apasă () peste toate argumentele date, având în vedere nu există nici o, astfel încât explicit let.push () pot fi omise de asemenea. În practică, acest lucru de maximum sumele şi codul de mai sus ar putea fi redusă la o simplă:

let = Let(transient_mark_mode=None)
... USER CODE...

Fiţi atenţi la atribuirea rezultat al constructorului la unele variabile Python. În caz contrar, instanţa ar putea să dispară imediat după ce au fost create, restabilirea Emacs Lisp variabila mult prea repede.

Orice variabilă să fie legat cu Lasa ar fi fost legat în prealabil pe partea Emacs Lisp. Această restricţie nu, de obicei, nici un fel de rău. Totuşi, acesta va fi probabil ridicată în unele versiune mai recentă a Pymacs.

clasă are alte metode de a insemnat pentru unele macro-uri care sunt comune în Emacs Lisp de programare, în spiritul lasa legături. Aceste nume arata ca metoda de push_ * sau * pop_, în cazul în care Emacs Lisp macrocomenzi sunt salvaţi-*. Unul trebuie să utilizeze potrivite * pop_ pentru desfacerea efectul unui anumit push_ *, mai degrabă decât un simplu pop (). : codul Python este mai clară, aceasta asigură de asemenea că lucrurile sunt anulate în ordinea corectă. Acelaşi exemplu pot utiliza mai multe push_ * metodele, efectele lor cuib.

push_excursion () şi pop_excursion () salva şi restabili actuale tampon, punctul şi marca. push_match_data () şi pop_match_data () salva şi restabili starea de ultimul meci expresie regulata. push_restriction () şi pop_restriction () salva şi restabili îngustarea curent limite. push_selected_window () şi pop_selected_window () salva şi restabili faptul că deţine-o fereastră cursorul. push_window_excursion () şi pop_window_excursion () salva şi restabili fereastra de configurare curent pe display Emacs.

Ca o comoditate, let.push () şi toate celelalte push_ * metode de a reveni instanţă. Acest lucru ajută la înlănţuirea diverse push_ * imediat după generaţie instanţă. De exemplu, se poate scrie:

let = Let(transient_mark_mode=None)
... USER CODE...

Dacă este adevărat: (utilizaţi dacă 1: cu versiuni mai vechi Python, unii oameni ar putea prefera scris, dacă permiteţi: oricum), are ca scop doar de crestarea Cod de utilizator, astfel încât domeniul de aplicare al lasa variabilei se face foarte explicit. Acest lucru este pur stilistică, şi nu la toate măsurile necesare. Ultima del permiteţi- ar putea fi omisă în câteva circumstanţe, de exemplu, în cazul în care excursia durează până la sfârşitul funcţiei de Python.

Raw 5.4 Emacs Lisp expresii

Pymacs oferă un dispozitiv de evaluare a unei prime Emacs Lisp expresie, sau o succesiune de astfel de, exprimată ca un şir de caractere. Unul foloseste doar lisp ca o funcţie, cum ar fi aceasta:

lisp('''
...
POSSIBLY-LONG-SEQUENCE-OF-LISP-EXPRESSIONS
...
''')

Valoarea Emacs Lisp a Ultima expresie sau numai în secvenţa devine valoarea Lisp apel, după conversia înapoi la Python.

5.5 Ghid de interacţiune

Funcţiile Emacs au conceptul de interacţiune cu utilizatorul pentru completarea caietului de sarcini al argumentelor lor fiind în acelaşi timp numit. Acest lucru se întâmplă doar atunci când o funcţie este interactiv numit de către utilizator, aceasta nu se întâmplă atunci când o funcţie este numit direct de către un alt. Deoarece Python nu are o instalaţie corespunzătoare, un pic de înşelăciune a fost necesar pentru că instalaţia de reabilitare pe partea de Python.

După încărcarea unui modul de Python, dar înainte de a crea o viziune Emacs-ul pentru acest modul, Pymacs decide dacă funcţii încărcate va fi interactiv, apelabile din Emacs, sau nu. Ori de câte ori o funcţie are o interacţiune atribut, acest atribut deţine caietul de sarcini interacţiune Emacs pentru această funcţie. Caietul de sarcini este fie o altă funcţie Python sau un şir. În primul caz, că alta functie este numit fără argumente şi ar trebui, poate, după consultarea ghidul, întoarce o listă de argumente reale pentru a fi utilizate pentru funcţia originală. În acest ultim caz, şirul de caietul de sarcini este utilizat textual ca argument pentru (interactive...) de funcţii pe partea de Emacs. Pentru a obţine un memento scurt despre modul în care acest şir este interpretat pe partea Emacs, încercaţi să Ch f interactive RET în Emacs. Aici este un exemplu în cazul în care un şir gol este folosit pentru a specifica faptul că o interactiv nu are argumente:

from Pymacs import lisp

def hello_world():
    "`Hello world' from Python."
    lisp.insert("Hello from Python!")
hello_world.interaction = ''

Versiunile de Python a lansat înainte de integrarea PEP 232 nu permit utilizatorilor să adauge atribute la funcţii, astfel încât nu există un mecanism de rezervă. Să presupunem că o funcţie dată nu are o interacţiune atribut cum sa explicat mai sus. Dacă modulul Python conţine un interacţiuni variabilă globală, care este un dicţionar, în cazul în care dicţionarul are o intrare pentru funcţia de dat cu o valoare, altele decât unul, această funcţie va fi interactiv pe partea Emacs. Iată cum este exemplul anterior ar trebui să fie scris pentru o versiune mai veche de Python, sau atunci când portabilitatea este la premium:

from Pymacs import lisp
interactions = {}

def hello_world():
    "`Hello world' from Python."
    lisp.insert("Hello from Python!")
interactions[hello_world] = ''

S-ar putea întreba de ce nu folosim doar lisp.interactive (...) din interior Python. Există o oarecare magie în Emacs Lisp interpret în sine, cauta pentru acel apel înainte de funcţia este de fapt înscris, aceasta explică de ce (interactive ...) trebuie să apară prima într-un Emacs Lisp defun. Pymacs ar putea încerca să scanaţi forma deja compilat de cod Python, cauta lisp.interactive, dar ca evaluarea lisp.interactive argumente ar putea primi arbitrar complexe, ar fi o adevărată provocare ne-compilarea că evaluarea în Emacs Lisp.

5.6 legături-cheie

O funcţie interactivă poate fi obligat să o secventa de taste.

Pentru a traduce legături cum ar fi Cx w, să zicem, s-ar putea trebuie să ştiţi un pic mai mult cum Emacs Lisp procesele scapă şir cum ar fi \ Cx sau \ M-\ Cx în Emacs Lisp, şi emulate acesta, în siruri de caractere Python, deoarece Python nu are scapă astfel de. \ CL, unde L este o scrisoare caz superior, produce un personaj care de ordine este rezultatul a scăzând de la 0x40 de ordinal L. \ M- are un ordinal devine prin adăugarea 0x80 la ordinal de următoarele caracter descrise. Astfel, oamenii pot folosi auto-inserarea caractere non-ASCII, \ M- este dat o altă reprezentare, care urmează să înlocuiască adăugarea de 0x80 prin prefixarea cu Escape, care este 0x1b. Deci, \ Cx în Emacs este \ x18 în Python. Acest lucru este uşor de găsit, folosind un interactiv sesiune Python, dându-l: Chr (ord ('X') - ord ('A') + 1).

Un mod mai uşor ar fi folosind kbd de funcţii pe partea Emacs Lisp, cum ar fi cu lisp.kbd ('Cx w ") sau lisp.kbd ("M-<F2>").

Pentru a lega tasta F1 pentru a ajutor funcţiona în unele module :

lisp.global_set_key ((lisp.f1,), lisp.module_helper)

(Element,) este un tuplu Python obţinându-se o Emacs Lisp vector. lisp.f1 traduce la Emacs Lisp simbolul f1. Deci, Python (lisp.f1,) este Emacs Lisp [F1]. Tastele ca [M-F2] ar putea necesita ingeniozitate unele mai mult, s-ar putea scrie, fie (Lisp ["M-F2 '],) sau (lisp.M_f2,), pe partea Python.

6 Depanare

Gasirea bug-uri într-un program este o artă, care poate fi destul de dificil atunci când deja există un singur proces, şi o singură limbă. Pymacs implică o parte (de obicei scurte), scrisă în Emacs Lisp şi o altă parte (de obicei mai substanţiale), scrisă în Python, fiecare se execută în propriul proces. Ambele procese care comunică între ele. În plus, pentru a obţine indicii de depanare, Emacs-ul este adesea necesar uşa prin care utilizatorul poate captura de programare glimpses pe ceea ce se întâmplă pe ambele părţi.

Pentru a depana eficient Pymacs cod, unul beneficiază de unele având în familiarizarea cu protocolul de comunicare, şi, de asemenea, de la a şti cum să respecte ambele părţi ale prezentului protocol la o dată. Mod obişnuit este prin * * Pymacs tampon în Emacs, ceea ce denotă o Emacs vizualiza un intreg protocol. Se poate vedea, de asemenea, prin fortarea Pymacs ajutor pentru a salva un fişier de urmărire, care arată o Python vedere un intreg protocol - dacă nu există erori de comunicare, aceasta ar trebui să spun aceeaşi poveste ca cu * * Pymacs tampon. Aceste subiecte puţini sunt dezvoltate în cele trei secţiuni de mai jos. Sectii remaning aborda aspecte mai specifice despre Emacs Lisp sau depanare Python.

6.1 protocolul de comunicare

Pymacs protocolul de comunicare este destul de simplu adânc în jos, folosind doar de evaluare privind sosirea pe ambele feţe. Tot restul este inselatorie recursivitate peste această idee simplă.

  • Este mult mai uşor de a genera decât la analiza. Mai mult, Emacs-ul are un parser Lisp şi Python are un parser Python. Aşa că, atunci când pregăteşte un mesaj la ajutor Pymacs, Emacs-ul genereaza cod Python Python pentru a analiza, şi atunci când pregătesc un mesaj pentru Emacs, Python generează Emacs Lisp expresii pentru Emacs pentru a analiza.

  • Mesajele sunt schimbate în alternativ strict de ghidare (de la Python la Emacs, de la Emacs la Python, etc), primul mesaj fiind transmis de ajutor Pymacs (de la Python la Emacs), doar după ce a început, identificarea versiunea curentă Pymacs.

  • Mesaje în ambele direcţii au un plic similar. Fiecare mesaj fizic are un prefix, conţinutul mesajului, şi o linie nouă. Începe cu prefix, fie < sau > pentru a marca directionalitatea, este urmată de expresia zecimală din lungimea conţinutului numărate în caractere, şi se termină cu o filă unic pe orizontală. Conta exclude prefixul, dar include newline.

  • În fiecare direcţie, mesajele sunt alcătuite din două elemente: un cuvânt cheie de acţiune şi un singur argument (încă argumentul poate fi uneori complexe). Ca un caz special, mesaje de reparare de memorie de la Python la Emacs folosi patru elemente: atom liber, o listă de numere slot liber, şi apoi de acţiune reală şi argument. Acest lucru se datorează faptului că de curatare este întârziată şi purceluş garantate cu peste un alt mesaj.

  • Pentru mesaje Emacs originea, de acţiune şi argumentele sunt separate de un spaţiu. Pentru mesaje Python originea, de acţiune şi argumentul sunt făcute într-o listă Lisp.

  • Cele mai multe acţiuni în tabelul de mai jos sunt disponibile in ambele directii, cu excepţia cazului în remarcat. Primele trei acţiuni a începe un nou nivel de evaluare Pymacs, cele două acţiuni rămase sfârşitul nivelul actual.

    • eval solicită evaluarea argumentului expresia sa.
    • exec solicită executarea argumentul declaraţiei sale (aceasta poate fi primite doar pe partea Python).
    • extindă cererile de deschidere a unei structuri Emacs Lisp (acest lucru poate fi primite doar pe partea Emacs).
    • întoarcere reprezintă răspunsul la o cerere normală, argumentul are valoarea care urmează să fie returnate ( zero în caz de exec ).
    • ridica reprezintă răspunsul la o cerere de eroare, argumentul detine apoi un şir de diagnostic.

    Python evaluarea se face în contextul Pymacs.pymacs modulului. Pe partea Emacs Lisp, nu există conceptul de spaţii numele modulului, deci vom folosi intern pymacs- prefixul ca o încercare să rămână curat. Utilizatorii ar trebui să se abţină de ideal, de la numirea lor Emacs Lisp obiecte cu o pymacs- prefix.

Protocol poate fi instabile la solicitările întrerupere, aşa că încearcă să recunoască fiecare acţiune mesaj înainte de evaluare se încearcă. Ideea (nu este pe deplin puse în aplicare încă) este de a face parte protocolul imun la întreruperi, dar să permită evaluări se să fie întreruptă.

6.2 * * Pymacs tampon

Emacs şi Python sunt două procese separate (bine, fiecare poate folosi mai mult de un proces). Pymacs pune în aplicare un protocol de comunicare simplă între cele două, şi face tot ce este necesar pentru ca programatorii nu trebuie să vă faceţi griji cu privire la detalii. Instrumentul principal este depanare tampon de comunicare între Emacs şi Python, care este numit * * Pymacs.

Aşa cum este uneori util pentru a intelege protocolul de comunicare, acesta este explicat pe scurt aici, folosind un exemplu complex artificial să facă acest lucru. Luaţi în considerare (acest exemplu presupune Python 2):

(Pymacs-eval "lisp ('(pymacs-eval \" repr (2L ** 111) \ ")')")
"2596148429267413814265248164610048L"

Aici, Emacs solicită Python pentru a cere Emacs pentru a cere Python pentru un calcul simplu bignum. Reţineţi că Emacs-ul nu ştie nativ, cum să se ocupe de numere întregi mari, şi nici nu are o reprezentare intern pentru ei. Acesta este de ce am folosi repr funcţia, astfel încât Python întoarce o reprezentare string a rezultat, în loc de rezultatul în sine. Aici este o urmă de acest exemplu. Imaginaţi-vă că Emacs-ul sta pe stânga şi că, Python sta pe dreapta. < Caracterul steaguri un mesaj merge de la Python la Emacs, în timp ce > caracterul steaguri un mesaj merge de la Emacs la Python. Numărul dă lungimea mesajului, inclusiv de sfarsit de linie. (Cititori acuta poate observa că primul număr este incorect, deoarece numărul de versiune se înlocuieşte în exemplul de mai în timp ce acest manual se produce.)

from Pymacs import lisp
interactions = {}

def hello_world():
    "`Hello world' from Python."
    lisp.insert("Hello from Python!")
interactions[hello_world] = ''

Parte a protocolului gestionează de memorie, iar acest lucru generează gestionarea zgomotului suplimentar-in * * Pymacs tampon. Ori de câte ori Emacs trece la o structura Python, un indicator suplimentar este generată pe partea Emacs pentru a inhiba de colectare a gunoiului de Emacs. Colector python gunoi detectează atunci când structura a primit nu mai este necesara pe partea de Python, moment în care comunicarea viitoare va spune Emacs pentru a elimina indicatorul suplimentar. Acesta funcţionează simetric, de asemenea, că este, ori de câte ori Python trece o structură de Emacs, un plus de Python de referinţă este generat de a inhiba colectare a gunoiului pe partea Python. Colector Emacs gunoi detectează atunci când structura a primit nu mai este necesară pe partea Emacs, după care Python se va spune pentru a elimina de referinţă suplimentare. Pentru eficienţă, aceste mesaje legate de alocare sunt întârziate, îmbinate şi mixte, împreună în cadrul comunicării următoare având în alt scop.

Variabila pymacs-urme-de tranzit pot fi modificate pentru a controla cum şi când Pymacs * * tampon, sau părţi ale acestora, pentru a primi şterse. În mod implicit, acest tampon devine şterse înainte de fiecare tranzacţie. Pentru a face uz de depanare de el, first set pymacs-urme-de tranzit fie t sau la unele (a se păstra. LIMIT).

6.3 Depanare helper Pymacs

Ajutor Pymacs este un program de Python care accepta opţiuni şi argumente. Opţiunile disponibile, care sunt destinate numai pentru depanare, sunt:

D- FILE Debug protocolului la FILE
S- FILE Trace a primit semnale de la FILE
  • -D opţiune salvează o copie a protocolului de comunicare în fişierul dat, aşa cum se vede de la helper Pymacs. Fişierul ar trebui să fie destul de identic cu conţinutul * * Pymacs tampon în Emacs.
  • S- opţiune de cele mai multe monitoare de semnalele primite de ajutor Pymacs şi jurnalele lor în fişierul dat. Fiecare linie jurnal conţine doar un numar de semnal, eventual urmată de o stea, dacă perioada de întrerupere a fost permis inch afară de exploatare forestieră, semnalele sunt de obicei ignorate.

Lista directoare argumente care urmează să fie adăugate la începutul modulului calea de căutare Python, şi ori de câte ori Emacs-ul lansează ajutor Pymacs, conţinutul Emacs Lisp pymacs-încărcare-path variabilă este transformată în acest lista de argumente.

Opţiunile Pymacs ajutor pot fi stabilite prin PYMACS_OPTIONS variabilă de mediu. De exemplu, s-ar putea executa ceva de genul:

PYMACS_OPTIONS export = '-d / tmp / pymacs-debug-s / tmp / pymacs semnalele "

într-o coajă (presupunând bash aici) şi începe de la faptul că Emacs-ul shell-ului. Apoi, atunci când lansează Emacs ajutor Pymacs, opţiunile de mai sus sunt transmise către aceasta.

6.4 Emacs obişnuite de depanare

Dacă încrucişate între apeluri Emacs Lisp şi cuib Python profund, o eroare se va ridica excepţii succesive, alternativ pe ambele feţe ca unstack cereri, şi de diagnosticare devine transmise înainte şi înapoi, în uşoară creştere după cum mergem. Deci, erorile vor fi în cele din urmă raportate de Emacs. Am făcut nici un fel de efort pentru a transmite Emacs Lisp înapoi urme pe partea de Python, cum nu văd un scop pentru el: toate de depanare se face în termen de Emacs ferestre oricum.

Pe Emacses recent, linia din spate Python devine afişate în mini-tampon, şi Emacs Lisp trasabilitatea este în acelaşi timp se arată în backtrace * * fereastră. Un lucru util este de a permite să mini-tampon să crească mare, deci are mai multe şanse să conţină urme pe deplin înapoi Python, ultimele rânduri din care sunt adesea deosebit de utile. Aici, eu folosesc:

(setq resize-mini-windows t
      max-mini-window-height.85)

în mea emacs. fişier, astfel încât mini-tampon poate utiliza 85% a ecranului, şi se micsoreaza rapid atunci când liniile sunt necesare mai puţine. Conţinutul mini-tampon dispar la taste următoare, dar se poate recupera linia din spate Python uitandu-se la sfârşitul * Mesaje * tampon. Caz în care ffap pachet în Emacs pot fi încă un alt prieten! Din direcţia * Mesaje * tampon, o dată pe ffap activat, pune doar cursorul pe numele de fişier al unui modul Python de la linia din spate, şi Cx Cf RET va deschide repede ca sursă pentru tine.

6.5 Python obişnuite de depanare

Un mod comun pentru a depana un script Python este să o răspândim cu imprimare comenzi. Când un astfel de script Python este executat sub control Pymacs, aceste imprima declaraţii afişa resultst dreapta în cadrul Pymacs * * tampon, şi pot fi observate acolo.

Ca de ieşire devine astfel amestecate cu protocolul Pymacs în sine niciodată, niciodată de imprimare simbolul <, urmată imediat de expresie a unui număr zecimal, urmată imediat de o filă de orizontală ( \ t ). Dacă s-au a face acest lucru, protocolul de comunicare ar obţine destul de amestecate, şi Pymacs s-ar rupe. Dar nu trebuie să vă faceţi griji prea mult despre acest lucru: este puţin probabil ca secventa interzis în practică, ar fi numai pentru că oamenii nu le utilizaţi des file orizontale mai - oh, filele au fost, fără îndoială, o dată populare, dar acest lucru a fost mulţi ani în urmă...

6.6 Auto-reîncărcarea la salvare

Am găsit util să automat pymacs-încărcare unele fişiere de Python ori de câte ori primesc salvat de la Emacs. Acest lucru poate fi decis, la un fişier sau per-per-director bază. Pentru a obţine un anumit fişier Python pentru a fi reîncărcate în mod automat la salvare, adăugaţi următoarele linii la sfârşitul:

# Local Variables:
# pymacs-auto-reload: t
# End:

Aici este un exemplu de reîncărcare automată pe o baza per-director. Codul de mai jos presupune că fişierele Python a însemnat pentru Pymacs sunt ţinute în ~ / share / emacs / python :

(defun fp-maybe-pymacs-reload ()
  (let ((pymacsdir (expand-file-name "~/share/emacs/python/")))
    (when (and (string-equal (file-name-directory buffer-file-name)
                             pymacsdir)
               (string-match "\\.py\\'" buffer-file-name))
      (pymacs-load (substring buffer-file-name 0 -3)))))
(add-hook 'after-save-hook 'fp-maybe-pymacs-reload)

7 administrative miscelaneu

7.1 Dezvoltarea istorie

O dată am flămânzit pentru un editor Python-extensibil, atat de mult incat am gândit ideea de cădere Emacs pentru alte căi, dar nu a găsit nimic mai convingător. Mai mult decât atât, analizând toate extensiile Lisp aş face pentru mine, şi luând în considerare toate acele instrumente superbe scrise de altii, toate care sunt acum parte din viaţa mea de calculator, ar fi fost o întreprindere uriaşă pentru mine de a reprograma aceste toate în Python. Aşa că, atunci când am început să văd că ceva de genul Pymacs a fost posibil, am simţit puternic motivat! :-)

Pymacs se bazează pe lucrările anterioare de Cedric Adjih care au permis de funcţionare a Python ca un proces separat de Emacs. A se vedea http://www.crepuscule.com/pyemacs/, sau a scrie Cedric la mailto: adjih-pam@crepuscule.com. Cedric a prezentat pyemacs pentru mine, ca o dovadă a conceptului. Aşa cum am simplificat această noţiune un pic, am renuntat la e în pyemacs :-). Cedric, de asemenea, a scris anterior patch-uri pentru conectarea dreptul de Python în Xemacs, dar a abandonat ideea, astfel cum a aflat că patch-uri i-au fost unmaintainable asupra evoluţiei ambelor Python şi Xemacs.

Ca Brian McErlean independent şi simultan a scris un instrument similar cu acesta, ne-am decis sa fuzioneze proiectele noastre. Într-o coincidenţă amuzantă, el a ales chiar pymacs ca un nume. Brian a acordat o atenţie bun la detalii complexe, care au scăpat curajul meu, astfel încât ajutorul lui şi colaborare au fost benefice. Puteţi ajunge la Brian mailto: brianmce@crosswinds.net.

Arunca iniţială la Pymacs a fost scris pe 2001-09-05, şi lansări din seria 0.x a urmat într-un ritm rapid de câteva luni, şi Pymacs curând a devenit stabilă. Bug-uri raportate sau sugestii au fost minore, iar setul de caracteristici a fost destul de uşor de utilizat de la început. Pentru o vreme, nu a fost suficient un material nou pentru a justifica alte versiuni.

Mai târziu, cineva ma rugat să ia în considerare Vim, Emacs-ul şi nu numai, pentru unele instrumente de scris, apoi am fost (în zona de partituri muzicale). Privind la Vim mai atent, am descoperit că este un editor de valoare, cu Python frumos integrate, suficient pentru mine pentru a comuta. Într-un articol Web (care sa bucurat de multe, cum mi-au spus), am detaliat sentimentele mele cu privire la aceste chestiuni.

Am trecut de la Emacs la Vim în mea de zi cu zi obiceiurile, si din aceasta cauza, a simţit că avea nevoie de un Pymacs maintainer mai credibile decat mine. Syver Enstad, care a fost un utilizator entuziast şi contribuitor competente, a avut amabilitatea să accepte taxa (2003-10). Syver apoi a devenit indisponibil, la punctul I nu putea să-l contactaţi în ultimii ani. Mi-ar urăsc pentru a vedea mă interferează cu un funcţionar responsabil, dar după ce am decis să se întoarcă într-o anumită utilizare moderată Emacs, şi din cauza lungă tăcere, am considerat că reluarea Pymacs de întreţinere (2007-11), şi a făcut-o (2008-01).

Giovanni Giorgi o dată (2007-03) a vrut să se extindă pe Pymacs şi o publică pe cont propriu, şi ulterior menţinerea simtit ca-l întreg (2007-12 tarziu). I-am sugerat mai degrabă o încercare de întreţinere de colaborare, iar acest experiment este încă în desfăşurare...

7.2 Ar trebui să vină cu Emacs-ul?

Gerd Möllman, care a fost menţinerea Emacs-ul la momentul naşterii Pymacs şi dezvoltare, modernizate (2001-09), ideea unei post-GC-cârlig din Xemacs, ca o modalitate de a facilita gestionarea memoriei în cadrul Pymacs.

Richard Stallman a sugerat odată (2001-10), care Pymacs trebui distribuite în cadrul Emacs, şi în timp ce discuta detaliile de acest lucru, am subliniat dificultăţile mici tehnice despre Emacs-ul instalarea pieselor, Python, şi au nevoie de o convenţie cu privire la cazul în care pentru a instala fişierele Python a însemnat pentru Pymacs. Ca Richard simtit, la acea vreme, foarte copleşit cu alte sarcini, nici o decizie nu a fost luată şi de integrare nu sa dus nicăieri.

După ce a demisionat Gerd ca maintainer Emacs, cineva din echipa de dezvoltare Emacs a scris din nou (2002-01), care solicită informaţii despre cum să se integreze Pymacs. A fost uşor pentru mine să scrie un rezumat bun şi aprofundată, după toate aceste discuţii cu Richard. Şi acesta este sfârşitul poveştii: Nu am auzit niciodată de ea din nou. :-)

7.3 Viitorul Pymacs

Unii oameni au sugerat importante schimbări interne Pymacs. În opinia mea, noi caracteristici mai mari sunt mai bine puse în aplicare într-un mod atent, mai întâi ca exemple sau contribuţii, şi sa mutat mai aproape de integrare internă, în funcţie de modul în care utilizatorii utilizează sau le aprecia. Pentru moment, ar trebui să se concentreze la Pymacs sa faci treaba bine propria umil, şi să se opună umfla.

Înainte de a se închide într-o oarecare Pymacs versiunea 1.0, unele specificaţii ar trebui să fie revizuit, sugestii ghidul de meditat, de portare aspecte documentate. Suita de teste ar trebui să crească în sus, ar trebui să colecteze mai multe exemple. Pymacs ar trebui să vizeze integrarea perfectă cu el. fişiere şi cu transparent autoload (Incearca meu mai mic nu au fost atat de mult succes). Pe partea de Python, Pymacs s-ar putea primitive cum ar fi false getindex şi putindex, şi iteratori mai bine de sprijin şi unele caracteristici noi Python.

Pymacs nu este mult mai orientată spre fire Python. Nu este clar încă dacă ar fi în mod rezonabil maleabil pentru a sprijini mai bine.

8 tehnice miscelaneu

8.1 bug-uri cunoscute sau limitări

Care este diferenţa dintre o eroare şi o limitare? Limitările sunt fie bug-uri nu merita repararea, sau altceva, bug-urile care nu ştim încă cum se repara. În timp ce documentarea unui bug este într-adevăr o modalitate de a amâna soluţionarea ei, nu neapărat se transformă într-o limitare.

Pe o listă de corespondenţă o dată am urmat indeaproape, o administratori puţini au fost obtinerea foarte, foarte supărat de fiecare dată când cuvântul bug-ul s-a întâmplat să fie utilizate în orice mesaj, în special în cazul în care bug-ul a fost documentate. Un distins membru pe această listă (William N. Venable), a inventat cuvântul minunat unfelicity, ca o modalitate de a discuta problemele evitând în acelaşi timp pagube umane.

Aceste delicatese sunt cu siguranţă nu sunt necesare pentru Pymacs. Un bug este o eroare!

8.1.1 de control necesare pe stivă relaxare

Ca Ali Gholami Rudi rezumate frumos aceasta (2008-02-12):

Programatorii Lisp ar putea folosi inhiba-renunţe la diferite niveluri de recursivitate, şi de a folosi Pymacs la aceste niveluri diferite. Ca o Emacs iesi s-ar putea propaga din stivă, dar oprindu-se la diferite niveluri de ea atunci când programatorii Lisp a luat măsuri pentru ea, cred că nu există nici o alegere această constatare un mecanism prin care Python va unstack în paralel cu Emacs, care este, nici mai mult nici mai puţin, aşa că, dacă CV-uri de prelucrare a Emacs-ul la un nivel intermediar, Python ar trebui să fie gata la un nivel corespunzător exact pe partea sa.

Făcând pymacs-eval "(time.sleep (10))", şi renunti, am văzut o dată că:

  • Emacs-ul nu se întrerupe dintr-o dată, şi în cazul în care inhibă-renunţe rămâne set în timp ce aşteaptă Emacs-ul pentru ajutor Pymacs, acest lucru nu este cu siguranţă uşor de utilizat!
  • La sfârşitul anului, aşteptaţi, am obţine o falsă eroare IO (nu stiu de unde vine).

8.1.2 Posibile scurgeri de memorie

De memorie se poate scurge, în anumite circumstanţe teoretice (spun teoretic, pentru că nimeni nu a raportat niciodată acest lucru ca fiind o problemă reală). Ca Richard Stallman a pus o dată pe ea (2002-08):

Mă întreb, însă, acest lucru se poate [de management al memoriei] tehnica se ocupe în totalitate de cicluri care se execută între LISP şi Python? Să presupunem că obiect Lisp A se referă la Python obiect B, care se referă la obiect Lisp A, şi să presupunem că nimic altceva nu se referă la unul dintre ei. Vei reuşi în vederea recunoaşterii acestor două obiecte de gunoi?

8.1.3 Moartea de la un Ctrl-C

Ali Gholami Rudi anunţuri (2008-02-20) care Pymacs moare peste:

Mx pymacs-eval RET lisp.kbd ("Cc r") RET

în care există un Ctrl-C, în valoare întors de la Emacs.

8.2 Sugestii să reflecteze

8.2.1 Python-driven Pymacs

Cred ca cea mai importanta imbunatatire am putea gândi să Pymacs ar fi unele maşini de programe prin care Python, a început în afara Emacs, ar putea accesa Pymacs, după ce aceasta a început. Asta ar putea fi utilă, cel puţin pentru testare sau depanare, şi poate pentru muncă mai grave, precum şi. Acestea sunt simple gânduri, eu nu plan de lucru la această curând, dacă nu am o nevoie reală. Dar dacă cineva provocare interesele, vă rugăm să mergeţi mai departe!

Iată cum s-ar putea merge. Pymacs are un interpret Python care rulează ca un proces de sub-Emacs. De fapt, Emacs incarcatura pymacs.el, care, la rândul său, devine Python pentru a executa pymacs.py, şi ambele comunica ulterior. pymacs.py este activă numai ori de câte ori pymacs.el îl numeşte, în caz contrar acesta este blocat. pymacs.py ar putea, în unele opţiune, începe un alt fir în sine. Firul iniţială ar bloca de aşteptare pentru Emacs, ca de obicei. Al doilea fir-ar bloca în aşteptare pentru a servi orice client care doreşte Python pentru a accesa Emacs. Atunci când se întâmplă acest lucru, ar fi al doilea fir de coadă o cerere pentru primul fir de executie, iar apoi trimite un semnal la Emacs, astfel se va genera o comunicare Pymacs. La fiecare oportunitate de comunicare, primul fir de executie de pe partea Python s-ar putea serviciu complet coada de la al doilea fir.

8.2.2 Încărcarea automată a interfeţei

O dată am încercat mai bine de interfaţă autoload, şi nu a reuşit. Acesta are mai complicate pe care m-am gândit că ar fi. I s-ar putea revedea acest lucru, dar în prioritate scăzută.

În acelaşi timp, se poate utiliza un mic el. fişier, cum ar fi aceasta, cu privire la calea de încărcare Emacs:

# File zorglub.el — just load zorglub.py.
(pymacs-load "zorglub")
(provide 'zorglub)

şi apoi utilizaţi oricare dintre:

# File zorglub.el — just load zorglub.py.
(pymacs-load "zorglub")
(provide 'zorglub)

la începutul corpului pentru orice funcţie care au nevoie de funcţii de la zorglub.py. Se poate scrie, de asemenea, unul sau mai multe:

(autoload 'FUNCTION-NAME "zorglub" nil t)

la indirect autoload zorglub.py după cum este necesar.

8.2.3 mai multe forme speciale de manipulare

Discuţia a început cu privire la lipsa de sprijin specifice Pymacs, pe partea de Python, pentru Emacs Lisp setq-default funcţie. Oamenii menţionat, de asemenea, defvar şi defcustom, dar există într-adevăr multe alte forme de construcţii în Emacs Lisp. (O formă specială este orice formă expresie în care toate argumentele nu sunt evaluate toate orbeşte înainte de a intra efectiv funcţia Funcţia primeşte apoi argumentele unevaluated,. Şi este responsabilitatea sa de a alege ce argumente ar trebui să fie evaluate, şi când.)

Faptul este că, pe lângă setq şi unele forme de defun funcţii,, forme speciale puţini sunt acceptate în Pymacs. Cineva ar putea gândi , funcţii cum ar fi salvaţi-excursie, etc Dar asta e tot, şi poate discutabil ca prea mult deja. Adevărata problemă este de a rezolva justificative forme speciale (şi macro-uri) la nivel de Pymacs. Dacă creăm cazuri speciale în Pymacs pentru fiecare formă de construcţii se întâmplă să dai peste, s-ar putea pierde Pymacs eleganţa sa, şi aşa mai departe, am să staţi un pic atent.

Toate formele speciale impun ca ghidul de înfrângerea într-un fel faptul că Pymacs evaluează toate argumentele funcţie înainte de a apela o funcţie de Lisp. Îmi dau seama ar putea fi un punct de subtil pentru persoanele familiarizat cu Lisp. aplică pe partea de Lisp se aplică o funcţie pe o listă de argumente, astfel încât truc este de a evalua ceva pe partea de Python obţinerii unui de listă, al căror conţinut trebuie să fie argumente reale. Nu sunt pe deplin sigur că aceasta este directia buna pentru a lua, chiar dacă uşor - mă refer aici, că problema reală de a rezolva este cu totul altceva.

Pe o chestiune legată, Ali Gholami Rudi a sugerat că Pymacs Emacs acceptă aşa-numitele argumente cuvinte cheie, şi să ofere chiar un patch simplu pentru a face acest lucru:

diff --git a/Pymacs/pymacs.py b/Pymacs/pymacs.py
--- a/Pymacs/pymacs.py
+++ b/Pymacs/pymacs.py
@@ -453,13 +453,16 @@
             write(') nil)')
             lisp._eval(''.join(fragments))

-    def __call__(self, *arguments):
+    def __call__(self, *arguments, **keywords):
         fragments = []
         write = fragments.append
         write('(%s' % self.text)
         for argument in arguments:
             write(' ')
             print_lisp(argument, write, True)
+        for kwd, value in keywords.items():
+            write(' :%s ' % kwd)
+            print_lisp(value, write, True)
         write(')')
         return lisp._eval(''.join(fragments))

Până în prezent, că am înţeles, nu există pur şi simplu nu argumente cuvânt cheie în Emacs. Cuvintele cheie ar putea fi nimic altceva decât un miraj creat de defcustom numai (poate prin defini-minore-mode ) şi defstruct - există nici o altă utilizare pentru cuvintele cheie? Aşa că mă întreb dacă acest lucru neobişnuit inselaciune, nici măcar o parte reală a Emacs Lisp, este destul de important pentru a justifica modificarea ceva la fel de fundamentale, astfel cum __call__ în Pymacs. Partea de reticenţa mea ar putea veni, de asemenea, de la meu (nefondate), se tem că schimbarea de mai sus ar încetini vatra Pymacs.

Pentru moment, cel puţin, utilizatorii sunt invitaţi să folosească lisp (...) pentru toate celelalte forme speciale. E simplu, e destul de sigur. Lucruri cum ar fi:

lisp ("(setq-implicit% s% s)"% (nume, valoare))

nu sunt atât de oribil... :-) Adâncul sufletului, Lisp () apelurile sunt ceea ce Pymacs face tot timpul sub masă, toate celelalte sunt biţi de zahăr. Care ar fi nevoie de o vizita la acest sprijin formular special, cu ochii larg si mintea, veni cu o soluţie unificatoare general, mai degrabă decât înmulţirea cazuri speciale.

8.2.4 Sprijin pentru dicţionare Python

În timp ce Pymacs oglinzi tuple Python şi liste în Emacs Lisp şi vectori de liste, nu are nimic în prezent, pentru a reflecta dicţionare Python.

Acesta a fost sugerat de a folosi Emacs Lisp alists să facă acest lucru, dar acest lucru nu pare suficient pentru mine. Pymacs 0.0 şi 0.1 s-au convertit dicts Python la Emacs Lisp alists. Aceasta a fost doar o jucărie pentru a obţine experienţă cu mecanica Pymacs nu, o idee serioasă. În ciuda Am vrut ceva pentru dicts Python, această alegere nu a fost foarte satisfăcătoare:

  • Viteza de acces Dicts sunt O (1); alists sunt O (N).
  • Dicts nu au nici o ordine intrinsecă; alists sunt într-adevăr o secvenţă.
  • Dicts au duplicat chei nu; alists pot avea umbre.

Ultimele două puncte, în special, au drept consecinţă faptul că nu se poate converti înainte şi înapoi, de la Lisp şi au rezultatele pe care compara cu (egal...). Acest lucru face ca echivalenţă în special urât. Liste corespunzătoare şi vectori în Lisp pot fi convertite înainte şi înapoi pentru Python şi să fie (egal...), astfel încât aceste echivalenţe sunt suportabile. Dict de conversie a fost retrasă în Pymacs 0,2; m-am gândit că ar trebui să amâne până la mai bine o idee mai bună apare, decât să permită utilizatorilor să dezvolte obiceiuri cu ceva greşit şi sortit să fie înlocuit.

Emacs Lisp tabele hash (la fel ca în Emacs 21) ar putea fi un echivalent acceptabil pentru dicts Python. Aceasta este ceea ce Brian McErlean a făcut, şi sugerează. Rezervarea mea este numai cu privire la necesitatea Python pentru non-nestatornice chei, ceva care Emacs-ul nu garantează. Aşa cum în mod implicit, de la Lisp la Python, referinţele sunt transmise în loc de conţinut, acest lucru ar fi o problemă posibilă numai atunci când o copie extins se solicită din partea Python. Acest lucru nu ar fi o problema merge de la Python la Emacs, măsura în care am înţeles lucrurile acum.

8.2.5 O mai frumos * * Pymacs tampon

Ne-ar putea îmbunătăţi modul în care * * Pymacs tampon de comunicare arată. Să schiţă acest lucru rapid, în orice caz, eu nu sunt sigur cum merită acest lucru este. Tampon ar putea fi transformat într-un mod mai deplin featured Emacs, astfel încât să poată beneficia de evidenţierea şi colourisation, şi alte bunătăţi. Primul lucru ar fi sa instalati font-blocare definiţii. Al doilea lucru ar fi să se utilizeze pentru crestarea arată cuiburi corespunzătoare a apelurilor între Emacs şi Python, în ambele direcţii. Aş prefera ca acest lucru să fie făcut ca o caracteristică ecran, nu ca parte a protocolului de comunicare. Un al treilea lucru ar fi de a interpreta în mod automat numere de obiect pe ambele feţe, înlocuindu-le cu un text mai clare ori de câte ori este posibil - aceste informaţii pot fi adesea dedus din comunicaţii anterioare. În cele din urmă, că modul ar putea permite pentru unele inspecţie la obiect Pymacs şi statutul, şi poate, de asemenea, pentru a controla serverul extern Python descrise într-o altă sugestie în această serie, în cazul în care devine vreodată pusă în aplicare.

8.3 Viteza de probleme

Trage proiecte compara viteza relativă a mai multe limbi populare, precum şi avantajele relative ale LISP şi Python s-ar putea interesul utilizatorilor Pymacs. Primele puncte URL-ul într-o versiune orientată spre sistemele Win32, al doilea este mai recentă, dar Debian orientate spre:

  • http://dada.perl.it/shootout/index.html
  • http://shootout.alioth.debian.org/

Nu am auzit de vreo Python pentru Lisp compilator. Lisp poate fi lent sau rapid, în funcţie de modul în care cineva o foloseşte, şi cât de mult se foloseşte declaraţii. Unele sisteme Lisp au compilatoare cu adevărat excelent, care oferă cod foarte repede atunci când sunt lăsat să se înţeleagă.

Python în sine poate fi lent sau rapid, încă o dată în funcţie de modul în care cineva o foloseşte. Cu îndoiţi buna, se poate dezvolta obiceiul de a scrie Python, care arată viteza de cinstit. Şi există întotdeauna Pyrex (şi Cython foarte asemănătoare), care este Python completat cu declaraţii explicite (un pic cum ar fi unele implementări Lisp), şi care pot cumpăra o mulţime de viteză.

This is quite likely that one can have fast programs while using Python, or a mix of Python and either Pyrex or Cython (or even Psyco sometimes), that is, within Python paradigms, without feeling any need of resorting to Lisp.

If Python looks like being slow while being used with Emacs, the problem probably lies in Emacs-Python communication which Pymacs implements. One has to learn how to do the proper compromises for having less communications. (In that regard, Vim and Python are really linked together, so Python in Vim is likely faster than Pymacs for someone who does not pay special attention to such matters.)

Ali Gholami Rudi also writes (2008-02):

Well, there seems to be lots of overhead when transferring large strings. Transferring them requires:

  1. escaping characters in the strings
  2. putting them in *Pymacs* buffer
  3. sending the region to Python process
  4. evaluating the Python string in Python-side (involves compiling)

In my experiments, transferring a ~5k-line file takes more than a second on a relatively new computer (data from rope-dev). Improving that probably requires a new protocol that does not use Python eval and has an optional debug buffer. Probably few applications need to transfer large strings to Python but if they do, it is quite slow.

All in all, speed may sometimes become a real issue for Pymacs. I once wrote within http://pinard.progiciels-bpi.ca/opinions/editors.html :

While Pymacs is elegant in my opinion, one cannot effectively use Pymacs (the Python part) without knowing at least the specification of many Lisp functions, and I found that it requires some doing for a Pymacs developer to decouple the Emacs interaction part from the purer algorithmic part in applications. Moreover, if you do not consider speed issues, they bite you.
Published (Last edited): 10-10-2011 , source: http://pymacs.progiciels-bpi.ca/pymacs.html