diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a2ba4efc..3b5c52bc0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### New features +* [#956](https://github.com/clojure-emacs/cider/pull/956): Use `load-file` (again) for interactive evaluation commands. * Trigger Grimoire doc lookup from doc buffers by pressing g (in Emacs) and G (in browser). * [#903](https://github.com/clojure-emacs/cider/pull/903): Isolate `nrepl-client` connection logic from CIDER. New hooks `cider-connected-hook` diff --git a/cider-interaction.el b/cider-interaction.el index 91d13247e..96439b2e3 100644 --- a/cider-interaction.el +++ b/cider-interaction.el @@ -1269,12 +1269,11 @@ otherwise fall back to \"user\"." #'identity) "Function to translate Emacs filenames to nREPL namestrings.") -(defun cider-interactive-source-tracking-eval (form &optional start-pos callback) +(defun cider-interactive-eval (form &optional start-pos callback) "Evaluate FORM and dispatch the response to CALLBACK. -START-POS is a starting position of the form in the original context. -Unlike `cider-interactive-eval' this command will set proper metadata for var -definitions. If CALLBACK -is nil use `cider-interactive-eval-handler'." +START-POS is a starting position of the form in the original context with +the default of 1. If CALLBACK is nil use +`cider-interactive-eval-handler'." (cider--clear-compilation-highlights) (-when-let (error-win (get-buffer-window cider-error-buffer)) (quit-window nil error-win)) @@ -1286,36 +1285,25 @@ is nil use `cider-interactive-eval-handler'." (file-name-nondirectory filename) (or callback (cider-interactive-eval-handler))))) -(defun cider-interactive-eval (form &optional callback) - "Evaluate FORM and dispatch the response to CALLBACK. -This function is the main entry point in CIDER's interactive evaluation -API. Most other interactive eval functions should rely on this function. -If CALLBACK is nil use `cider-interactive-eval-handler'." - (cider--clear-compilation-highlights) - (-when-let (error-win (get-buffer-window cider-error-buffer)) - (quit-window nil error-win)) - ;; always eval ns forms in the user namespace - ;; otherwise trying to eval ns form for the first time will produce an error - (let ((ns (if (cider-ns-form-p form) - "user" - (cider-current-ns)))) - (nrepl-request:eval - form - (or callback (cider-interactive-eval-handler)) - ns))) +(defvar-local cider--cached-ns-form nil + "Cached ns-form for the current buffer.") -(defun cider--dummy-file-contents (form start-pos) +(defun cider--dummy-file-contents (form &optional start-pos) "Wrap FORM to make it suitable for `cider-request:load-file'. START-POS is a starting position of the form in the original context." - (let* ((ns-form (if (cider-ns-form-p form) - "" - (or (-when-let (form (cider-ns-form)) - (replace-regexp-in-string ":reload\\(-all\\)?\\>" "" form)) - (format "(ns %s)" (cider-current-ns))))) + (let* ((cur-ns-form (cider-ns-form)) + (ns-form (cond + ((or (null cur-ns-form) + (cider-ns-form-p form)) + "") + ((string= cur-ns-form cider--cached-ns-form) + (format "(ns %s)" (cider-current-ns))) + (t (replace-regexp-in-string ":reload\\(-all\\)?\\>" "" cur-ns-form)))) (ns-form-lines (length (split-string ns-form "\n"))) (start-pos (or start-pos 1)) (start-line (line-number-at-pos start-pos)) (start-column (save-excursion (goto-char start-pos) (current-column)))) + (setq cider--cached-ns-form cur-ns-form) (concat ns-form (make-string (max 0 (- start-line ns-form-lines)) ?\n) @@ -1326,7 +1314,7 @@ START-POS is a starting position of the form in the original context." "Evaluate the region between START and END." (interactive "r") (let ((code (buffer-substring-no-properties start end))) - (cider-interactive-source-tracking-eval code start))) + (cider-interactive-eval code start))) (defun cider-eval-buffer () "Evaluate the current buffer." @@ -1337,7 +1325,7 @@ START-POS is a starting position of the form in the original context." "Evaluate the expression preceding point. If invoked with a PREFIX argument, print the result in the current buffer." (interactive "P") - (cider-interactive-eval (cider-last-sexp) + (cider-interactive-eval (cider-last-sexp) (cider-last-sexp-start-pos) (when prefix (cider-eval-print-handler)))) (defun cider-eval-last-sexp-and-replace () @@ -1349,13 +1337,13 @@ If invoked with a PREFIX argument, print the result in the current buffer." (nrepl-sync-request:eval last-sexp) ;; seems like the sexp is valid, so we can safely kill it (backward-kill-sexp) - (cider-interactive-eval last-sexp (cider-eval-print-handler)))) + (cider-interactive-eval last-sexp start-pos (cider-eval-print-handler)))) (defun cider-eval-last-sexp-to-repl (&optional prefix) "Evaluate the expression preceding point and insert its result in the REPL. If invoked with a PREFIX argument, switch to the REPL buffer." (interactive "P") - (cider-interactive-eval (cider-last-sexp) + (cider-interactive-eval (cider-last-sexp) (cider-last-sexp-start-pos) (cider-insert-eval-handler (cider-current-repl-buffer))) (when prefix (cider-switch-to-repl-buffer))) @@ -1364,27 +1352,27 @@ If invoked with a PREFIX argument, switch to the REPL buffer." "Evaluate the expression preceding point. Print its value into the current buffer." (interactive) - (cider-interactive-eval (cider-last-sexp) + (cider-interactive-eval (cider-last-sexp) (cider-last-sexp-start-pos) (cider-eval-print-handler))) -(defun cider--pprint-eval-form (form) - "Pretty print FORM in popup buffer." +(defun cider--pprint-eval-form (form start-pos) + "Pretty print FORM starting at START-POS in popup buffer." (let* ((result-buffer (cider-popup-buffer cider-result-buffer nil 'clojure-mode)) (right-margin (max fill-column (1- (window-width (get-buffer-window result-buffer)))))) - (cider-interactive-eval (cider-format-pprint-eval form right-margin) + (cider-interactive-eval (cider-format-pprint-eval form right-margin) start-pos (cider-popup-eval-out-handler result-buffer)))) (defun cider-pprint-eval-last-sexp () "Evaluate the sexp preceding point and pprint its value in a popup buffer." (interactive) - (cider--pprint-eval-form (cider-last-sexp))) + (cider--pprint-eval-form (cider-last-sexp) (cider-last-sexp-start-pos))) (defun cider-eval-defun-at-point (&optional prefix) "Evaluate the current toplevel form, and print result in the minibuffer. With a PREFIX argument, print the result in the current buffer." (interactive "P") - (cider-interactive-source-tracking-eval + (cider-interactive-eval (cider-defun-at-point) (cider-defun-at-point-start-pos) (when prefix (cider-eval-print-handler)))) @@ -1412,8 +1400,9 @@ With a PREFIX argument, print the result in the current buffer." (clojure-mode) (unless (string= "" ns-form) (insert ns-form "\n\n")) - (insert form) - (cider-interactive-eval form)))) + (let ((start-pos (point))) + (insert form) + (cider-interactive-eval form start-pos))))) ;; Connection and REPL @@ -1700,6 +1689,7 @@ under point, prompts for a var." (cider--clear-compilation-highlights) (-when-let (error-win (get-buffer-window cider-error-buffer)) (quit-window nil error-win)) + (setq cider--cached-ns-form (cider-ns-form)) (cider-request:load-file (cider-file-string filename) (funcall cider-to-nrepl-filename-function (cider--server-filename filename))