0

I am trying to twist some code from slime to nrepl. The code is obvious when working with slime. It sends clojure code to evaluate, get the result string and process it as you like. I changed my code so that it can interact with nrepl. That is: creating my own value handler which process the result string and passing it to nrepl-make-response-handler. It works fine until now. But then I found some code which manipulate multiple buffers at once. Since nrepl-make-response-handler accepts only one buffer argument, I was wondering if I could ignore it and invoke my code which process multiple buffers in the value handler. I trid but faild, nothing changed. Any elisp experts there? I really need a help.

My own handler:

(defun nrepl-interactive-eval-read-replace-handler (buffer)
"Make a handler for evaluating and process global replacement."
  (nrepl-make-response-handler buffer
                           (lambda (buffer value)
                             (let ((sexp (read value)))
                               (clojure-refactorcng-process-global-replacements sexp)))
                           '()
                           (lambda (buffer err)
                             (message "%s" err))
                           '()))

The client code:

(defun nrepl-interactive-eval-read-replace (form)
"Evaluate the given FORM and process global replacement"
  (let ((buffer (current-buffer)))
    (nrepl-send-string form
                   (nrepl-interactive-eval-read-replace-handler buffer)
                   nrepl-buffer-ns)))

The code which process the result:

(defun get-from-alist (key alist)
  (car (cdr (assoc key alist))))

(defun clojure-refactoring-process-global-replace (replace)
  (if (get-from-alist :new-source replace)
    (progn
      (if (string= (file-truename (buffer-file-name))
                 (file-truename (get-from-alist :file replace)))
        nil
        (find-file (get-from-alist :file replace)))
      (goto-char (point-min))
      (erase-buffer)
      (insert (get-from-alist :new-source replace)))))

(defun clojure-refactoring-process-global-replacements (replacements)
  (save-window-excursion
    (mapcar #'clojure-refactoring-process-global-replace replacements)))
4

1 回答 1

0

看了好久我的代码,终于解决了这个问题。新的处理程序如下:

(defun nrepl-interactive-eval-read-replace-handler (buffer)
"Make a handler for evaluating and process global replacement."
(nrepl-make-response-handler buffer
                           (lambda (buffer value)
                             (with-current-buffer buffer
                                 (let ((sexp (read value)))
                                   (if sexp
                                       (clojure-refactoring-process-global-replacements sexp)))))
                           '()
                           (lambda (buffer err)
                             (message "%s" err))
                           '()))

如您所见,我添加了一个 if 条件来排除 nrepl 返回的“nil”值。另外,我添加了 with-current-buffer 来指定我要操作的缓冲区,但是,我不仅限于该缓冲区。原因是在我下面的代码中:

(defun clojure-refactoring-process-global-replace (replace)
  (if (get-from-alist :new-source replace)
    (progn
      (if (string= (file-truename (buffer-file-name))
                 (file-truename (get-from-alist :file replace)))
        nil

我目前在哪个缓冲区很重要。我之前忽略了 with-current-buffer,所以 buffer-file-name 不知道导致这个问题的当前工作缓冲区。

于 2013-06-14T08:23:58.037 回答