2015-06-01 23 views
5

Cercare un modo per valutare il codice elisp memorizzato in un file esterno e passare il risultato come argomento di funzione. Esempio dimostrando quello che mi piacerebbe raggiungere segue:Valore di risultato del codice elisp memorizzato in un file?

;; content of my_template.el 
'(this is a list) 

;; content of .emacs where result of my_template.el has to be used 
(define-auto-insert "\.ext$" 
    ;; bellow is my attempt to retrieve resulting list object 
    ;; but getting nil instead 
    (with-temp-buffer 
     (insert-file-contents ("my_template.el")) 
     (eval-buffer)))) 

probabilmente alla ricerca di una funzione eval-like, che oltre ad effetto collaterale restituisce anche risultato dell'ultima espressione.

Qualche idea?

+0

(a) si dovrebbe leggere la documentazione di 'eval-buffer', senza uscita argomenti extra viene scartato (b) il secondo argomento a' definire-auto-insert' deve essere una funzione, è possibile utilizzare una forma lambda per una funzione anonima. –

+0

Hai ragione con il buffer di eval, stavo cercando una versione alternativa che restituisca il risultato dell'ultima espressione. Btw. come potrebbe aiutare lambda come seconda argomentazione in questo caso - vale a dire. valutare un file elisp esterno? –

+0

Intendevo solo che potrebbe essere necessario avvolgere il codice chiamante in un '(lambda() ...)' in modo che sia una funzione anonima. –

risposta

3

Utilizzando variabile per condividere dati è più facile e più comune, per esempio:

;; content of ~/my_template.el 
(defvar my-template '(this is a list)) 

;; content of .emacs where result of my_template.el has to be used 
(load-file "~/my_template.el") 
(define-auto-insert "\.ext$" 
    my-template) 

Aggiornamento la funzione eval-file dovrebbe fare ciò che si vuole:

;; content of ~/my_template.el 
'(this is a list) 

(defun eval-file (file) 
    "Execute FILE and return the result of the last expression." 
    (load-file file) 
    (with-temp-buffer 
    (insert-file-contents file) 
    (emacs-lisp-mode) 
    (goto-char (point-max)) 
    (backward-sexp) 
    (eval (sexp-at-point)))) 

(eval-file "~/my_template.el") 
=> (this is a list) 

Aggiornamento due: senza valutare l'ultima espressione due volte

(defun eval-file (file) 
    "Execute FILE and return the result of the last expression." 
    (eval 
    (ignore-errors 
    (read-from-whole-string 
     (with-temp-buffer 
     (insert-file-contents file) 
     (buffer-string)))))) 

(eval-file "~/my_template.el") 
=> (this is a list) 
+0

Grazie. Ho già avuto un'idea per risolvere questo problema attraverso una variabile, solo curioso di sapere se può essere risolto in un modo più elegante e funzionale. –

+0

@DavidUnric Questa è la prima volta che ho sentito del risultato di ** un file ** e il risultato dell'ultima espressione non è molto utile o realizzabile, quindi suppongo che non ci sia una funzione esistente per fare ciò che vuoi, anche se Conosco un modo imbarazzante. – xuchunyang

+0

Non ho lavorato in (e) lisp ma in ruby ​​/ python a volte diventa utile nel file eval, dove il valore di ritorno è il risultato dell'ultima espressione/ritorno esplicito. Penso che non sia molto meno affidabile quindi caricare quel file. –

1

Non leggere da una stringa. Leggi da un buffer.

(defun load&return (file &optional msgp) 
    "Load FILE. Return the value of the last sexp read." 
    (interactive "fFile: \np") 
    (let* ((sexp (with-current-buffer (find-file-noselect file) 
        (goto-char (point-min)) 
        (read (current-buffer)))) 
     (val (ignore-errors (eval sexp)))) 
    (prog1 val (when msgp (message "Value: %S" val)))))