12

I'm using nrepl.el from git (0.1.6-preview, via el-get recipe), and I would like clojure buffer evals: C-x C-e, C-M-x, C-c C-r for form, top-level form and region respectively, to send themselves to the nrepl buffer and evaluate there, rather than the default behavior of evaluating off-screen with results returned to the echo area.

Is there any way to do this, or is there another set of keybindings for this purpose that I'm not recognizing by their descriptions?

Thanks.

Jeff Kowalczyk
  • 571
  • 6
  • 11

3 Answers3

12

The behavior you described is not presently supported in nrepl.el.

But the good news is you are in emacs-land, so it should be possible to write your own custom handler to direct the output to the nrepl buffer and adjust your key bindings if you like.

For example, this is the equivalent of C-x C-e but sends the result of the evaluation to the repl buffer instead of the minibuffer:

(defun my-interactive-eval-to-repl (form)
  (let ((buffer nrepl-nrepl-buffer))
  (nrepl-send-string form (nrepl-handler buffer) nrepl-buffer-ns)))

(defun my-eval-last-expression-to-repl ()
  (interactive)
  (my-interactive-eval-to-repl (nrepl-last-expression)))
kingtim
  • 121
  • 4
  • 4
    Do you plan to support this feature, since there's a trivial implementation, or do you plan to leave that to users, since you just demonstrated a trivial implementation? – Brighid McDonnell May 02 '13 at 00:12
  • could you elaborate for those new to emacs? when you i try M-x my- it only autocompletes with my-eval and not my-interactive. and how could I bind this properly to work like C-x C-e? – scape Nov 28 '13 at 00:38
  • Christopher Poile provided a nice example of how do this below: `(eval-after-load 'nrepl '(progn (define-key nrepl-interaction-mode-map (kbd "C-x C-e") 'my-eval-last-expression-to-repl)`. – kingtim Dec 02 '13 at 20:49
  • Should this work with Cider, with a setup as described at https://www.braveclojure.com/basic-emacs/ ? I currently have `CIDER 0.8.1 (package: 20141120.1746) (Java 1.8.0_151, Clojure 1.8.0, nREPL 0.2.12)`, I am able to execute the first two defuns but I haven't been able to execute them in clojure-mode. – NikoNyrh Dec 18 '17 at 22:13
1

Here is a version that also sends errors to the correct windows:

(defun my-nrepl-handler (buffer)
  "Make an interactive eval handler for buffer, but emit the value or out to the repl, not the minibuffer."
  (nrepl-make-response-handler buffer
                               (lambda (buffer value)
                                 (progn
                                   (nrepl-emit-result (nrepl-current-repl-buffer) value t)
                                   (nrepl-emit-prompt (nrepl-current-repl-buffer))))
                               (lambda (buffer out)
                                 (nrepl-emit-interactive-output out)
                                 (nrepl-emit-prompt (nrepl-current-repl-buffer)))
                               (lambda (buffer err)
                                 (message "%s" err)
                                 (nrepl-highlight-compilation-errors buffer err))
                               (lambda (buffer)
                                 (nrepl-emit-prompt buffer))))

(defun my-interactive-eval-to-repl (form)
  "Evaluate the given FORM and print value in the repl."
  (remove-overlays (point-min) (point-max) 'nrepl-note-p t)
  (let ((buffer (current-buffer)))
    (nrepl-send-string form (my-nrepl-handler buffer) (nrepl-current-ns))))

(defun my-eval-last-expression-to-repl ()
  (interactive)
  (my-interactive-eval-to-repl (nrepl-last-expression)))

(eval-after-load 'nrepl
  '(progn 
     (define-key nrepl-interaction-mode-map (kbd "C-x C-e") 'my-eval-last-expression-to-repl)))
Christopher Poile
  • 985
  • 1
  • 11
  • 17
0

Since none of the solutions provided here work with the version I have, I came up with my own implementation:

(defun eval-in-nrepl ()
  (interactive)
  (let ((exp (nrepl-last-expression)))
    (with-current-buffer (nrepl-current-repl-buffer)
      (nrepl-replace-input exp)
      (nrepl-return))))

(eval-after-load 'nrepl
  '(define-key nrepl-interaction-mode-map
     (kbd "C-x C-.")
     'eval-in-nrepl))

It binds C-x C-. to the desired behavior.

Leon Grapenthin
  • 9,246
  • 24
  • 37