aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNoam Postavsky2017-04-23 22:21:42 -0400
committerNoam Postavsky2017-05-19 18:16:15 -0400
commit267be4bdc28564a99f45da29e84eb98838117b50 (patch)
tree3816b74e945cb1a17a1f4c8ad5e25e4abb0e8206
parentc1c8b67246c4314b302cca2ac43f13a0baba4c16 (diff)
downloademacs-267be4bdc28564a99f45da29e84eb98838117b50.tar.gz
emacs-267be4bdc28564a99f45da29e84eb98838117b50.zip
Refactor lisp eval result printing
* lisp/simple.el (eval-expression-print-format): Don't check `standard-output' or `current-prefix-arg'. (eval-expression-get-print-arguments): New function, centralizes decision about how to print results of `eval-expression' and `eval-last-sexp'. (eval-expression): * lisp/progmodes/elisp-mode.el (elisp--eval-last-sexp-print-value): Use it.
-rw-r--r--lisp/progmodes/elisp-mode.el35
-rw-r--r--lisp/simple.el58
-rw-r--r--test/lisp/progmodes/elisp-mode-tests.el18
-rw-r--r--test/lisp/simple-tests.el42
4 files changed, 97 insertions, 56 deletions
diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el
index 53a0f66439b..c2fdba47a09 100644
--- a/lisp/progmodes/elisp-mode.el
+++ b/lisp/progmodes/elisp-mode.el
@@ -1119,29 +1119,28 @@ current buffer. If EVAL-LAST-SEXP-ARG-INTERNAL is `0', print
1119output with no limit on the length and level of lists, and 1119output with no limit on the length and level of lists, and
1120include additional formats for integers \(octal, hexadecimal, and 1120include additional formats for integers \(octal, hexadecimal, and
1121character)." 1121character)."
1122 (let ((standard-output (if eval-last-sexp-arg-internal (current-buffer) t))) 1122 (pcase-let*
1123 ((`(,insert-value ,no-truncate ,char-print)
1124 (eval-expression-get-print-arguments eval-last-sexp-arg-internal)))
1123 ;; Setup the lexical environment if lexical-binding is enabled. 1125 ;; Setup the lexical environment if lexical-binding is enabled.
1124 (elisp--eval-last-sexp-print-value 1126 (elisp--eval-last-sexp-print-value
1125 (eval (eval-sexp-add-defvars (elisp--preceding-sexp)) lexical-binding) 1127 (eval (eval-sexp-add-defvars (elisp--preceding-sexp)) lexical-binding)
1126 eval-last-sexp-arg-internal))) 1128 (if insert-value (current-buffer) t) no-truncate char-print)))
1127 1129
1128(defun elisp--eval-last-sexp-print-value (value &optional eval-last-sexp-arg-internal) 1130(defun elisp--eval-last-sexp-print-value
1129 (let ((unabbreviated (let ((print-length nil) (print-level nil)) 1131 (value output &optional no-truncate char-print)
1130 (prin1-to-string value))) 1132 (let* ((unabbreviated (let ((print-length nil) (print-level nil))
1131 (print-length (and (not (zerop (prefix-numeric-value 1133 (prin1-to-string value)))
1132 eval-last-sexp-arg-internal))) 1134 (print-length (unless no-truncate eval-expression-print-length))
1133 eval-expression-print-length)) 1135 (print-level (unless no-truncate eval-expression-print-level))
1134 (print-level (and (not (zerop (prefix-numeric-value 1136 (beg (point))
1135 eval-last-sexp-arg-internal))) 1137 end)
1136 eval-expression-print-level))
1137 (beg (point))
1138 end)
1139 (prog1 1138 (prog1
1140 (prin1 value) 1139 (prin1 value output)
1141 (let ((str (eval-expression-print-format value))) 1140 (let ((str (and char-print (eval-expression-print-format value))))
1142 (if str (princ str))) 1141 (if str (princ str output)))
1143 (setq end (point)) 1142 (setq end (point))
1144 (when (and (bufferp standard-output) 1143 (when (and (bufferp output)
1145 (or (not (null print-length)) 1144 (or (not (null print-length))
1146 (not (null print-level))) 1145 (not (null print-level)))
1147 (not (string= unabbreviated 1146 (not (string= unabbreviated
diff --git a/lisp/simple.el b/lisp/simple.el
index 7f13df5006d..3af62657dbf 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -1456,16 +1456,14 @@ This string will typically look like \" (#o1, #x1, ?\\C-a)\".
1456If VALUE is not an integer, nil is returned. 1456If VALUE is not an integer, nil is returned.
1457This function is used by functions like `prin1' that display the 1457This function is used by functions like `prin1' that display the
1458result of expression evaluation." 1458result of expression evaluation."
1459 (if (and (integerp value) 1459 (when (integerp value)
1460 (or (eq standard-output t) 1460 (let ((char-string
1461 (zerop (prefix-numeric-value current-prefix-arg)))) 1461 (and (characterp value)
1462 (let ((char-string 1462 (char-displayable-p value)
1463 (if (and (characterp value) 1463 (prin1-char value))))
1464 (char-displayable-p value)) 1464 (if char-string
1465 (prin1-char value)))) 1465 (format " (#o%o, #x%x, %s)" value value char-string)
1466 (if char-string 1466 (format " (#o%o, #x%x)" value value)))))
1467 (format " (#o%o, #x%x, %s)" value value char-string)
1468 (format " (#o%o, #x%x)" value value)))))
1469 1467
1470(defvar eval-expression-minibuffer-setup-hook nil 1468(defvar eval-expression-minibuffer-setup-hook nil
1471 "Hook run by `eval-expression' when entering the minibuffer.") 1469 "Hook run by `eval-expression' when entering the minibuffer.")
@@ -1484,9 +1482,21 @@ result of expression evaluation."
1484 read-expression-map t 1482 read-expression-map t
1485 'read-expression-history)))) 1483 'read-expression-history))))
1486 1484
1485(defun eval-expression-get-print-arguments (prefix-argument)
1486 "Get arguments for commands that print an expression result.
1487Returns a list (INSERT-VALUE NO-TRUNCATE CHAR-PRINT)
1488based on PREFIX-ARG. This function determines the interpretation
1489of the prefix argument for `eval-expression' and
1490`eval-last-sexp'."
1491 (let ((num (prefix-numeric-value prefix-argument)))
1492 (list (not (memq prefix-argument '(nil)))
1493 (= num 0)
1494 (cond ((not (memq prefix-argument '(0 nil))) nil)
1495 (t t)))))
1496
1487;; We define this, rather than making `eval' interactive, 1497;; We define this, rather than making `eval' interactive,
1488;; for the sake of completion of names like eval-region, eval-buffer. 1498;; for the sake of completion of names like eval-region, eval-buffer.
1489(defun eval-expression (exp &optional insert-value) 1499(defun eval-expression (exp &optional insert-value no-truncate char-print)
1490 "Evaluate EXP and print value in the echo area. 1500 "Evaluate EXP and print value in the echo area.
1491When called interactively, read an Emacs Lisp expression and evaluate it. 1501When called interactively, read an Emacs Lisp expression and evaluate it.
1492Value is also consed on to front of the variable `values'. 1502Value is also consed on to front of the variable `values'.
@@ -1507,8 +1517,8 @@ minibuffer.
1507If `eval-expression-debug-on-error' is non-nil, which is the default, 1517If `eval-expression-debug-on-error' is non-nil, which is the default,
1508this command arranges for all errors to enter the debugger." 1518this command arranges for all errors to enter the debugger."
1509 (interactive 1519 (interactive
1510 (list (read--expression "Eval: ") 1520 (cons (read--expression "Eval: ")
1511 current-prefix-arg)) 1521 (eval-expression-get-print-arguments current-prefix-arg)))
1512 1522
1513 (if (null eval-expression-debug-on-error) 1523 (if (null eval-expression-debug-on-error)
1514 (push (eval exp lexical-binding) values) 1524 (push (eval exp lexical-binding) values)
@@ -1523,23 +1533,15 @@ this command arranges for all errors to enter the debugger."
1523 (unless (eq old-value new-value) 1533 (unless (eq old-value new-value)
1524 (setq debug-on-error new-value)))) 1534 (setq debug-on-error new-value))))
1525 1535
1526 (let ((print-length (and (not (zerop (prefix-numeric-value insert-value))) 1536 (let ((print-length (unless no-truncate eval-expression-print-length))
1527 eval-expression-print-length)) 1537 (print-level (unless no-truncate eval-expression-print-level))
1528 (print-level (and (not (zerop (prefix-numeric-value insert-value)))
1529 eval-expression-print-level))
1530 (deactivate-mark)) 1538 (deactivate-mark))
1531 (if insert-value 1539 (let ((out (if insert-value (current-buffer) t)))
1532 (with-no-warnings
1533 (let ((standard-output (current-buffer)))
1534 (prog1
1535 (prin1 (car values))
1536 (when (zerop (prefix-numeric-value insert-value))
1537 (let ((str (eval-expression-print-format (car values))))
1538 (if str (princ str)))))))
1539 (prog1 1540 (prog1
1540 (prin1 (car values) t) 1541 (prin1 (car values) out)
1541 (let ((str (eval-expression-print-format (car values)))) 1542 (let ((str (and char-print
1542 (if str (princ str t))))))) 1543 (eval-expression-print-format (car values)))))
1544 (when str (princ str out)))))))
1543 1545
1544(defun edit-and-eval-command (prompt command) 1546(defun edit-and-eval-command (prompt command)
1545 "Prompting with PROMPT, let user edit COMMAND and eval result. 1547 "Prompting with PROMPT, let user edit COMMAND and eval result.
diff --git a/test/lisp/progmodes/elisp-mode-tests.el b/test/lisp/progmodes/elisp-mode-tests.el
index 93c428b2d2b..5edb590b1e5 100644
--- a/test/lisp/progmodes/elisp-mode-tests.el
+++ b/test/lisp/progmodes/elisp-mode-tests.el
@@ -114,6 +114,24 @@
114 (should (member "backup-buffer" comps)) 114 (should (member "backup-buffer" comps))
115 (should-not (member "backup-inhibited" comps))))) 115 (should-not (member "backup-inhibited" comps)))))
116 116
117;;; eval-last-sexp
118
119(ert-deftest eval-last-sexp-print-format-sym ()
120 (with-temp-buffer
121 (let ((current-prefix-arg '(4)))
122 (erase-buffer) (insert "t")
123 (call-interactively #'eval-last-sexp)
124 (should (equal (buffer-string) "tt")))))
125
126(ert-deftest eval-last-sexp-print-format-sym-echo ()
127 ;; We can only check the echo area when running interactive.
128 (skip-unless (not noninteractive))
129 (with-temp-buffer
130 (let ((current-prefix-arg nil))
131 (erase-buffer) (insert "t") (message nil)
132 (call-interactively #'eval-last-sexp)
133 (should (equal (current-message) "t")))))
134
117;;; xref 135;;; xref
118 136
119(defun xref-elisp-test-descr-to-target (xref) 137(defun xref-elisp-test-descr-to-target (xref)
diff --git a/test/lisp/simple-tests.el b/test/lisp/simple-tests.el
index f4849c4b21d..b74e28ccaf1 100644
--- a/test/lisp/simple-tests.el
+++ b/test/lisp/simple-tests.el
@@ -20,6 +20,7 @@
20;;; Code: 20;;; Code:
21 21
22(require 'ert) 22(require 'ert)
23(eval-when-compile (require 'cl-lib))
23 24
24(defmacro simple-test--dummy-buffer (&rest body) 25(defmacro simple-test--dummy-buffer (&rest body)
25 (declare (indent 0) 26 (declare (indent 0)
@@ -35,6 +36,8 @@
35 (buffer-substring (point) (point-max)))))) 36 (buffer-substring (point) (point-max))))))
36 37
37 38
39
40;;; `transpose-sexps'
38(defmacro simple-test--transpositions (&rest body) 41(defmacro simple-test--transpositions (&rest body)
39 (declare (indent 0) 42 (declare (indent 0)
40 (debug t)) 43 (debug t))
@@ -46,6 +49,13 @@
46 (cons (buffer-substring (point-min) (point)) 49 (cons (buffer-substring (point-min) (point))
47 (buffer-substring (point) (point-max))))) 50 (buffer-substring (point) (point-max)))))
48 51
52;;; Transposition with negative args (bug#20698, bug#21885)
53(ert-deftest simple-transpose-subr ()
54 (should (equal (simple-test--transpositions (transpose-sexps -1))
55 '("(s1) (s2) (s4)" . " (s3) (s5)")))
56 (should (equal (simple-test--transpositions (transpose-sexps -2))
57 '("(s1) (s4)" . " (s2) (s3) (s5)"))))
58
49 59
50;;; `newline' 60;;; `newline'
51(ert-deftest newline () 61(ert-deftest newline ()
@@ -239,8 +249,8 @@
239 (should (equal ?\s (char-syntax ?\f))) 249 (should (equal ?\s (char-syntax ?\f)))
240 (should (equal ?\s (char-syntax ?\n)))))) 250 (should (equal ?\s (char-syntax ?\n))))))
241 251
242 252
243;;; auto-boundary tests 253;;; undo auto-boundary tests
244(ert-deftest undo-auto-boundary-timer () 254(ert-deftest undo-auto-boundary-timer ()
245 (should 255 (should
246 undo-auto-current-boundary-timer)) 256 undo-auto-current-boundary-timer))
@@ -269,14 +279,6 @@
269 (insert "hello") 279 (insert "hello")
270 (undo-auto--boundaries 'test)))) 280 (undo-auto--boundaries 'test))))
271 281
272;;; Transposition with negative args (bug#20698, bug#21885)
273(ert-deftest simple-transpose-subr ()
274 (should (equal (simple-test--transpositions (transpose-sexps -1))
275 '("(s1) (s2) (s4)" . " (s3) (s5)")))
276 (should (equal (simple-test--transpositions (transpose-sexps -2))
277 '("(s1) (s4)" . " (s2) (s3) (s5)"))))
278
279
280;; Test for a regression introduced by undo-auto--boundaries changes. 282;; Test for a regression introduced by undo-auto--boundaries changes.
281;; https://lists.gnu.org/archive/html/emacs-devel/2015-11/msg01652.html 283;; https://lists.gnu.org/archive/html/emacs-devel/2015-11/msg01652.html
282(defun undo-test-kill-c-a-then-undo () 284(defun undo-test-kill-c-a-then-undo ()
@@ -374,5 +376,25 @@ See Bug#21722."
374 (undo) 376 (undo)
375 (point))))) 377 (point)))))
376 378
379
380;;; `eval-expression'
381
382(ert-deftest eval-expression-print-format-sym ()
383 (with-temp-buffer
384 (cl-letf (((symbol-function 'read--expression) (lambda (&rest _) t)))
385 (let ((current-prefix-arg '(4)))
386 (call-interactively #'eval-expression)
387 (should (equal (buffer-string) "t"))))))
388
389(ert-deftest eval-expression-print-format-sym-echo ()
390 ;; We can only check the echo area when running interactive.
391 (skip-unless (not noninteractive))
392 (with-temp-buffer
393 (cl-letf (((symbol-function 'read--expression) (lambda (&rest _) t)))
394 (let ((current-prefix-arg nil))
395 (message nil)
396 (call-interactively #'eval-expression)
397 (should (equal (current-message) "t"))))))
398
377(provide 'simple-test) 399(provide 'simple-test)
378;;; simple-test.el ends here 400;;; simple-test.el ends here