2015-06-01 2 views
5

Ищете способ оценить код elisp, хранящийся во внешнем файле, и передать его результат как аргумент функции. Пример демонстрирует, что я хотел бы достичь следующим образом:Значение результата кода elisp, хранящегося в файле?

;; 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)))) 

Вероятно ищет Eval-как функции, которая помимо побочных эффектов также возвращает результат последнего выражения.

Любая идея?

+0

(а) вы должны прочитать документацию 'Eval-buffer', без вывода дополнительных аргументов отбрасывается (б) второй аргумент' определить-авто-insert' должен быть функцией, вы можете использовать лямбда-форму для анонимной функции. –

+0

Вы правы с eval-буфером, я искал альтернативную версию, которая возвращает результат последнего выражения. Btw. как это могло бы помочь лямбда в качестве второго аргумента в этом случае, т. е. удаление внешнего файла elisp? –

+0

Я просто имел в виду, что вам может понадобиться обернуть вызывающий код в '(lambda() ...)', так что это анонимная функция. –

ответ

3

Использование переменной для обмена данными проще и чаще, например:

;; 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) 

Update функция eval-file должна делать то, что вы хотите:

;; 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) 

Update два: не оценивать последнее выражение дважды

(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

Спасибо. У меня уже есть идея решить эту проблему с помощью переменной, просто любопытной, если ее можно решить более элегантным функциональным способом. –

+0

@DavidUnric Это мой первый раз, когда я услышал результат ** файла **, и результат последнего выражения не очень полезен или правдоподобен, поэтому я думаю, что нет никакой существующей функции, чтобы делать то, что вы хотите, хотя Я знаю неловкий способ. – xuchunyang

+0

Я не работал в (e) lisp, но в ruby ​​/ python иногда становится удобным для файла eval, где возвращаемое значение является результатом последнего выражения/явного возврата. Я думаю, что он не намного менее надежный, чем загрузка этого файла. –

1

Не читает из строки. Чтение из буфера.

(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))))) 
Смежные вопросы