unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#16828: 24.3.50; eval-expression, character representation of integer results time-consuming
@ 2014-02-21 10:01 Anders Lindgren
  2014-02-21 10:29 ` Eli Zaretskii
  0 siblings, 1 reply; 24+ messages in thread
From: Anders Lindgren @ 2014-02-21 10:01 UTC (permalink / raw)
  To: 16828

[-- Attachment #1: Type: text/plain, Size: 3120 bytes --]

The command `eval-expression' prints integer results both as decimal, hex,
octal, and (sometimes) as a character.

Some integers take a very long time to print, probably due to the fact that
it takes a long time to find a suitable font to render the character
variant in. The slow-down typically only occur once.

Steps to repeat:

    M-: 3200 RET

Here, it takes 22.5 seconds for Emacs to respond: 3200 (#o6200, #xc80)

Under 24.3 this was fast (well under a second).

This is on OS X 10.9 -- I haven't got access to any other system to test
this on.


In addition, sometimes it looks like the echo area splits the text into two
parts, effective only showing the second part. Unfortunately, I haven't
figured out when and how this occurs. Anyway, when it does, the *Messages*
buffer look like:


3200
 (#o6200, #xc80)
3200 (#o6200, #xc80) [2 times]

A simple solution would be to suppress printing of characters outside the
0-255 range (or at least give the user an option to do so).

Sincerely,
    Anders Lindgren

In GNU Emacs 24.3.50.2 (x86_64-apple-darwin13.0.0, NS apple-appkit-1265.00)
 of 2014-02-16 on macpro.lan
Repository revision: 116451
jan.h.d@swipnet.se-20140216095141-cop794qd0bf30tmt
Windowing system distributor `Apple', version 10.3.1265
Configured using:
 `configure --with-ns'

Important settings:
  value of $LC_CTYPE: UTF-8
  locale-coding-system: utf-8-unix

Major mode: Lisp Interaction

Minor modes in effect:
  tooltip-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  tool-bar-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  line-number-mode: t
  transient-mark-mode: t

Recent input:
<escape> : 3 2 0 0 <return> <escape> x r e p o s r
t - <backspace> <backspace> <backspace> t <backspace>
<backspace> r t - e m <tab> <return>

Recent messages:
For information about GNU Emacs and the GNU system, type C-h C-a.
3200 (#o6200, #xc80)
<s-backspace> is undefined [2 times]
s-b is undefined

Load-path shadows:
None found.

Features:
(shadow sort gnus-util mail-extr emacsbug message format-spec rfc822 mml
easymenu mml-sec mm-decode mm-bodies mm-encode mail-parse rfc2231
mailabbrev gmm-utils mailheader sendmail rfc2047 rfc2045 ietf-drums
mm-util help-fns mail-prsvr mail-utils mule-util time-date tooltip
electric uniquify ediff-hook vc-hooks lisp-float-type mwheel ns-win
tool-bar dnd fontset image regexp-opt fringe tabulated-list newcomment
lisp-mode prog-mode register page menu-bar rfn-eshadow timer select
scroll-bar mouse jit-lock font-lock syntax facemenu font-core frame cham
georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao
korean japanese hebrew greek romanian slovak czech european ethiopic
indian cyrillic chinese case-table epa-hook jka-cmpr-hook help simple
abbrev minibuffer nadvice loaddefs button faces cus-face macroexp files
text-properties overlay sha1 md5 base64 format env code-pages mule
custom widget hashtable-print-readable backquote make-network-process
cocoa ns multi-tty emacs)

[-- Attachment #2: Type: text/html, Size: 4243 bytes --]

^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#16828: 24.3.50; eval-expression, character representation of integer results time-consuming
  2014-02-21 10:01 bug#16828: 24.3.50; eval-expression, character representation of integer results time-consuming Anders Lindgren
@ 2014-02-21 10:29 ` Eli Zaretskii
  2014-02-22 12:49   ` Anders Lindgren
  0 siblings, 1 reply; 24+ messages in thread
From: Eli Zaretskii @ 2014-02-21 10:29 UTC (permalink / raw)
  To: Anders Lindgren; +Cc: 16828

> Date: Fri, 21 Feb 2014 11:01:36 +0100
> From: Anders Lindgren <andlind@gmail.com>
> 
> Some integers take a very long time to print, probably due to the fact that
> it takes a long time to find a suitable font to render the character
> variant in. The slow-down typically only occur once.

Yes, this is because Emacs looks for and loads a suitable font.





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#16828: 24.3.50; eval-expression, character representation of integer results time-consuming
  2014-02-21 10:29 ` Eli Zaretskii
@ 2014-02-22 12:49   ` Anders Lindgren
  2014-02-22 13:11     ` Eli Zaretskii
  0 siblings, 1 reply; 24+ messages in thread
From: Anders Lindgren @ 2014-02-22 12:49 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 16828@debbugs.gnu.org

[-- Attachment #1: Type: text/plain, Size: 719 bytes --]

Ok, good, then we know what caused the problem. The question now it what
should be done about it.

Personally, I see little value of always seeing the char representation of
integers >255, and if that comes at the cost of a 22 second delay I don't
see that it's worth it.

   -- Anders

On Friday, February 21, 2014, Eli Zaretskii <eliz@gnu.org> wrote:
>> Date: Fri, 21 Feb 2014 11:01:36 +0100
>> From: Anders Lindgren <andlind@gmail.com>
>>
>> Some integers take a very long time to print, probably due to the fact
that
>> it takes a long time to find a suitable font to render the character
>> variant in. The slow-down typically only occur once.
>
> Yes, this is because Emacs looks for and loads a suitable font.
>

[-- Attachment #2: Type: text/html, Size: 917 bytes --]

^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#16828: 24.3.50; eval-expression, character representation of integer results time-consuming
  2014-02-22 12:49   ` Anders Lindgren
@ 2014-02-22 13:11     ` Eli Zaretskii
  2014-02-22 18:53       ` Stephen Berman
  0 siblings, 1 reply; 24+ messages in thread
From: Eli Zaretskii @ 2014-02-22 13:11 UTC (permalink / raw)
  To: Anders Lindgren; +Cc: 16828

> Date: Sat, 22 Feb 2014 13:49:24 +0100
> From: Anders Lindgren <andlind@gmail.com>
> Cc: "16828@debbugs.gnu.org" <16828@debbugs.gnu.org>
> 
> Personally, I see little value of always seeing the char representation of
> integers >255, and if that comes at the cost of a 22 second delay I don't
> see that it's worth it.

A user option should be a good compromise (we could argue about its
default value later ;-).





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#16828: 24.3.50; eval-expression, character representation of integer results time-consuming
  2014-02-22 13:11     ` Eli Zaretskii
@ 2014-02-22 18:53       ` Stephen Berman
  2014-02-22 21:00         ` Eli Zaretskii
  0 siblings, 1 reply; 24+ messages in thread
From: Stephen Berman @ 2014-02-22 18:53 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 16828, Anders Lindgren

On Sat, 22 Feb 2014 15:11:05 +0200 Eli Zaretskii <eliz@gnu.org> wrote:

>> Date: Sat, 22 Feb 2014 13:49:24 +0100
>> From: Anders Lindgren <andlind@gmail.com>
>> Cc: "16828@debbugs.gnu.org" <16828@debbugs.gnu.org>
>> 
>> Personally, I see little value of always seeing the char representation of
>> integers >255, and if that comes at the cost of a 22 second delay I don't
>> see that it's worth it.
>
> A user option should be a good compromise (we could argue about its
> default value later ;-).

An option for whether to show the character representation of integers
higher than 255 may be the easiest way to deal with this issue, but the
problem has wider scope (at least for me): it happens with any command
that makes Emacs look for and load a suitable font, e.g. `C-h h' or
opening an email or newsgroup posting that contains such a character.
In my case the delay can be as long as ~90 (ninety!) seconds.  Even
though this happens only once per session, such a long delay, during
which Emacs is effectively frozen, is quite annoying, especially when
reading mail or news, where it is typically unexpected.  Could the
option be a timeout, say if the font isn't found within X seconds (with
a low default), then just some placeholder will be shown, and maybe a
message indicating the failure to find the font in that time?

Steve Berman





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#16828: 24.3.50; eval-expression, character representation of integer results time-consuming
  2014-02-22 18:53       ` Stephen Berman
@ 2014-02-22 21:00         ` Eli Zaretskii
  2014-02-23  9:06           ` Achim Gratz
  0 siblings, 1 reply; 24+ messages in thread
From: Eli Zaretskii @ 2014-02-22 21:00 UTC (permalink / raw)
  To: Stephen Berman; +Cc: 16828, andlind

> From: Stephen Berman <stephen.berman@gmx.net>
> Cc: Anders Lindgren <andlind@gmail.com>,  16828@debbugs.gnu.org
> Date: Sat, 22 Feb 2014 19:53:13 +0100
> 
> In my case the delay can be as long as ~90 (ninety!) seconds.  Even
> though this happens only once per session, such a long delay, during
> which Emacs is effectively frozen, is quite annoying, especially when
> reading mail or news, where it is typically unexpected.  Could the
> option be a timeout, say if the font isn't found within X seconds (with
> a low default), then just some placeholder will be shown, and maybe a
> message indicating the failure to find the font in that time?

I don't think the time this takes is spend _looking_ for a font, I
think it's spend loading a font.  But someone will have to trace and
profile this, and then come up with an analysis.





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#16828: 24.3.50; eval-expression, character representation of integer results time-consuming
  2014-02-22 21:00         ` Eli Zaretskii
@ 2014-02-23  9:06           ` Achim Gratz
  2014-02-25  0:42             ` Katsumi Yamaoka
  0 siblings, 1 reply; 24+ messages in thread
From: Achim Gratz @ 2014-02-23  9:06 UTC (permalink / raw)
  To: 16828

Eli Zaretskii writes:
> I don't think the time this takes is spend _looking_ for a font, I
> think it's spend loading a font.  But someone will have to trace and
> profile this, and then come up with an analysis.

Like Stephen I am fairly certain that most of the time is indeed spent
looking for a suitable font, based on the disk noises that indicate
seeking through many directories.


Regards,
Achim.
-- 
+<[Q+ Matrix-12 WAVE#46+305 Neuron microQkb Andromeda XTk Blofeld]>+

SD adaptation for Waldorf rackAttack V1.04R1:
http://Synth.Stromeko.net/Downloads.html#WaldorfSDada






^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#16828: 24.3.50; eval-expression, character representation of integer results time-consuming
  2014-02-23  9:06           ` Achim Gratz
@ 2014-02-25  0:42             ` Katsumi Yamaoka
  2014-02-26 10:16               ` martin rudalics
  0 siblings, 1 reply; 24+ messages in thread
From: Katsumi Yamaoka @ 2014-02-25  0:42 UTC (permalink / raw)
  To: 16828

Achim Gratz wrote:
> Eli Zaretskii writes:
>> I don't think the time this takes is spend _looking_ for a font, I
>> think it's spend loading a font.  But someone will have to trace and
>> profile this, and then come up with an analysis.

> Like Stephen I am fairly certain that most of the time is indeed spent
> looking for a suitable font, based on the disk noises that indicate
> seeking through many directories.

Especially on Cygwin, it's very annoying when edebugging.  Displaying
a character for the number of a point or a result of a calculation is
useless.  I use:

(if (eq system-type 'cygwin)
    (defadvice eval-expression-print-format
	(around dont-try-to-convert-char-to-string-when-edebugging
		(value) activate)
      "Don't try to convert char to string when edebugging."
      (if (and (boundp 'edebug-active) (eval 'edebug-active))
	  (if (and (integerp value)
		   (or (eq standard-output t)
		       (zerop (prefix-numeric-value current-prefix-arg))))
	      (format " (#o%o, #x%x)" value value))
	ad-do-it)))





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#16828: 24.3.50; eval-expression, character representation of integer results time-consuming
  2014-02-25  0:42             ` Katsumi Yamaoka
@ 2014-02-26 10:16               ` martin rudalics
  2017-03-26  3:45                 ` npostavs
  0 siblings, 1 reply; 24+ messages in thread
From: martin rudalics @ 2014-02-26 10:16 UTC (permalink / raw)
  To: Katsumi Yamaoka; +Cc: 16828

 > Especially on Cygwin, it's very annoying when edebugging.  Displaying
 > a character for the number of a point or a result of a calculation is
 > useless.

The most annoying aspect here is that it very often finds a character
with a superscript and increases the height of my echo area.  Think of
how valuable this is when debugging code resizing the echo area ;-)

martin





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#16828: 24.3.50; eval-expression, character representation of integer results time-consuming
  2014-02-26 10:16               ` martin rudalics
@ 2017-03-26  3:45                 ` npostavs
  2017-03-26 14:13                   ` Eli Zaretskii
  0 siblings, 1 reply; 24+ messages in thread
From: npostavs @ 2017-03-26  3:45 UTC (permalink / raw)
  To: martin rudalics; +Cc: Katsumi Yamaoka, 16828

[-- Attachment #1: Type: text/plain, Size: 503 bytes --]

tags 16828 patch
quit

martin rudalics <rudalics@gmx.at> writes:

>> Especially on Cygwin, it's very annoying when edebugging.  Displaying
>> a character for the number of a point or a result of a calculation is
>> useless.
>
> The most annoying aspect here is that it very often finds a character
> with a superscript and increases the height of my echo area.  Think of
> how valuable this is when debugging code resizing the echo area ;-)

I wonder how it could take so long to fix this silly thing.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: patch --]
[-- Type: text/x-diff, Size: 3766 bytes --]

From 301202a7963ee377bf0f51f703e0282782c7a6c1 Mon Sep 17 00:00:00 2001
From: Noam Postavsky <npostavs@gmail.com>
Date: Sat, 25 Mar 2017 23:31:11 -0400
Subject: [PATCH v1] Limit integers printed as characters (Bug#16828)

* lisp/simple.el (eval-expression-print-maximum-character): New
variable.
(eval-expression-print-format): Only display value as character if
it's equal or less than `eval-expression-print-maximum-character'.
* doc/emacs/building.texi (Lisp Eval): Document it.
* etc/NEWS: Announce it.
---
 doc/emacs/building.texi |  6 +++++-
 etc/NEWS                |  4 ++++
 lisp/simple.el          | 14 +++++++++++---
 3 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/doc/emacs/building.texi b/doc/emacs/building.texi
index ba8eae0759..2ee08e2505 100644
--- a/doc/emacs/building.texi
+++ b/doc/emacs/building.texi
@@ -1485,7 +1485,8 @@ Lisp Eval
 Emacs Lisp expression preceding point in the buffer, and displays the
 value in the echo area.  When the result of an evaluation is an
 integer, it is displayed together with the value in other formats
-(octal, hexadecimal, and character).
+(octal, hexadecimal, and character if
+@code{eval-expression-print-maximum-character} allows it).
 
   If @kbd{M-:} or @kbd{C-x C-e} is given a prefix argument, it inserts
 the value into the current buffer at point, rather than displaying it
@@ -1524,6 +1525,7 @@ Lisp Eval
 
 @vindex eval-expression-print-level
 @vindex eval-expression-print-length
+@vindex eval-expression-print-maximum-character
 @vindex eval-expression-debug-on-error
   The options @code{eval-expression-print-level} and
 @code{eval-expression-print-length} control the maximum depth and
@@ -1533,6 +1535,8 @@ Lisp Eval
 printed in full.  @code{eval-expression-debug-on-error} controls
 whether evaluation errors invoke the debugger when these commands are
 used; its default is @code{t}.
+@code{eval-expression-print-maximum-character} prevents large integers
+from being displayed as characters.
 
 @node Lisp Interaction
 @section Lisp Interaction Buffers
diff --git a/etc/NEWS b/etc/NEWS
index 62d06f3561..c09cc390bb 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -334,6 +334,10 @@ always restricting the margin to a quarter of the window.
 ** Emacsclient has a new option -u/--suppress-output.  The option
 suppresses display of return values from the server process.
 
++++
+** The new variable 'eval-expression-print-maximum-character' prevents
+large integers from being displayed as characters.
+
 \f
 * Editing Changes in Emacs 26.1
 
diff --git a/lisp/simple.el b/lisp/simple.el
index 681cf83807..599c7ebf30 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -1450,6 +1450,13 @@ eval-expression-debug-on-error
   :type 'boolean
   :version "21.1")
 
+(defcustom eval-expression-print-maximum-character 127
+  "The largest integer that will be displayed as a character.
+This affects printing by `eval-expression-print-format'."
+  :group 'lisp
+  :type 'integer
+  :version "26.1")
+
 (defun eval-expression-print-format (value)
   "If VALUE in an integer, return a specially formatted string.
 This string will typically look like \" (#o1, #x1, ?\\C-a)\".
@@ -1460,9 +1467,10 @@ eval-expression-print-format
 	   (or (eq standard-output t)
 	       (zerop (prefix-numeric-value current-prefix-arg))))
       (let ((char-string
-	     (if (and (characterp value)
-		      (char-displayable-p value))
-		 (prin1-char value))))
+             (and (characterp value)
+                  (<= value eval-expression-print-maximum-character)
+                  (char-displayable-p value)
+                  (prin1-char value))))
         (if char-string
             (format " (#o%o, #x%x, %s)" value value char-string)
           (format " (#o%o, #x%x)" value value)))))
-- 
2.11.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* bug#16828: 24.3.50; eval-expression, character representation of integer results time-consuming
  2017-03-26  3:45                 ` npostavs
@ 2017-03-26 14:13                   ` Eli Zaretskii
  2017-03-26 14:19                     ` Noam Postavsky
  0 siblings, 1 reply; 24+ messages in thread
From: Eli Zaretskii @ 2017-03-26 14:13 UTC (permalink / raw)
  To: npostavs; +Cc: yamaoka, 16828

> From: npostavs@users.sourceforge.net
> Date: Sat, 25 Mar 2017 23:45:22 -0400
> Cc: Katsumi Yamaoka <yamaoka@jpl.org>, 16828@debbugs.gnu.org
> 
> martin rudalics <rudalics@gmx.at> writes:
> 
> >> Especially on Cygwin, it's very annoying when edebugging.  Displaying
> >> a character for the number of a point or a result of a calculation is
> >> useless.
> >
> > The most annoying aspect here is that it very often finds a character
> > with a superscript and increases the height of my echo area.  Think of
> > how valuable this is when debugging code resizing the echo area ;-)
> 
> I wonder how it could take so long to fix this silly thing.

It isn't silly IME, I actually use this feature.

So, under this proposal, is there any way to get the character for a
single invocation of M-:, without setting the option, if I only need
that sometimes?  Should there be such a way?

Thanks.





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#16828: 24.3.50; eval-expression, character representation of integer results time-consuming
  2017-03-26 14:13                   ` Eli Zaretskii
@ 2017-03-26 14:19                     ` Noam Postavsky
  2017-03-26 14:37                       ` Eli Zaretskii
  0 siblings, 1 reply; 24+ messages in thread
From: Noam Postavsky @ 2017-03-26 14:19 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Katsumi Yamaoka, 16828

On Sun, Mar 26, 2017 at 10:13 AM, Eli Zaretskii <eliz@gnu.org> wrote:
>
> So, under this proposal, is there any way to get the character for a
> single invocation of M-:, without setting the option, if I only need
> that sometimes?  Should there be such a way?

Isn't M-: (prin1-char value) sufficient?





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#16828: 24.3.50; eval-expression, character representation of integer results time-consuming
  2017-03-26 14:19                     ` Noam Postavsky
@ 2017-03-26 14:37                       ` Eli Zaretskii
  2017-03-26 14:55                         ` npostavs
  0 siblings, 1 reply; 24+ messages in thread
From: Eli Zaretskii @ 2017-03-26 14:37 UTC (permalink / raw)
  To: Noam Postavsky; +Cc: yamaoka, 16828

> From: Noam Postavsky <npostavs@users.sourceforge.net>
> Date: Sun, 26 Mar 2017 10:19:50 -0400
> Cc: Katsumi Yamaoka <yamaoka@jpl.org>, 16828@debbugs.gnu.org
> 
> On Sun, Mar 26, 2017 at 10:13 AM, Eli Zaretskii <eliz@gnu.org> wrote:
> >
> > So, under this proposal, is there any way to get the character for a
> > single invocation of M-:, without setting the option, if I only need
> > that sometimes?  Should there be such a way?
> 
> Isn't M-: (prin1-char value) sufficient?

No, not after years of using "M-: #xNNNN RET".





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#16828: 24.3.50; eval-expression, character representation of integer results time-consuming
  2017-03-26 14:37                       ` Eli Zaretskii
@ 2017-03-26 14:55                         ` npostavs
  2017-03-26 15:22                           ` Eli Zaretskii
  0 siblings, 1 reply; 24+ messages in thread
From: npostavs @ 2017-03-26 14:55 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 16828

Eli Zaretskii <eliz@gnu.org> writes:

>> >
>> > So, under this proposal, is there any way to get the character for a
>> > single invocation of M-:, without setting the option, if I only need
>> > that sometimes?  Should there be such a way?
>> 
>> Isn't M-: (prin1-char value) sufficient?
>
> No, not after years of using "M-: #xNNNN RET".

If you want to keep muscle memory,

    (setq eval-expression-print-maximum-character most-positive-fixnum)

should give you back the old behaviour.  If you only want this only some
of the time, perhaps we should add a toggle-print-maximum-character
command?





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#16828: 24.3.50; eval-expression, character representation of integer results time-consuming
  2017-03-26 14:55                         ` npostavs
@ 2017-03-26 15:22                           ` Eli Zaretskii
  2017-03-26 17:39                             ` npostavs
  0 siblings, 1 reply; 24+ messages in thread
From: Eli Zaretskii @ 2017-03-26 15:22 UTC (permalink / raw)
  To: npostavs; +Cc: 16828

> From: npostavs@users.sourceforge.net
> Cc: 16828@debbugs.gnu.org
> Date: Sun, 26 Mar 2017 10:55:44 -0400
> 
> Eli Zaretskii <eliz@gnu.org> writes:
> 
> >> >
> >> > So, under this proposal, is there any way to get the character for a
> >> > single invocation of M-:, without setting the option, if I only need
> >> > that sometimes?  Should there be such a way?
> >> 
> >> Isn't M-: (prin1-char value) sufficient?
> >
> > No, not after years of using "M-: #xNNNN RET".
> 
> If you want to keep muscle memory,
> 
>     (setq eval-expression-print-maximum-character most-positive-fixnum)
> 
> should give you back the old behaviour.  If you only want this only some
> of the time, perhaps we should add a toggle-print-maximum-character
> command?

What about a special value of prefix argument, like zero?  If that's
OK, it's more convenient than any of the above.






^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#16828: 24.3.50; eval-expression, character representation of integer results time-consuming
  2017-03-26 15:22                           ` Eli Zaretskii
@ 2017-03-26 17:39                             ` npostavs
  2017-03-26 17:51                               ` Eli Zaretskii
  0 siblings, 1 reply; 24+ messages in thread
From: npostavs @ 2017-03-26 17:39 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 16828

Eli Zaretskii <eliz@gnu.org> writes:

>> From: npostavs@users.sourceforge.net
>> Cc: 16828@debbugs.gnu.org
>> Date: Sun, 26 Mar 2017 10:55:44 -0400
>> 
>> Eli Zaretskii <eliz@gnu.org> writes:
>> 
>> >> >
>> >> > So, under this proposal, is there any way to get the character for a
>> >> > single invocation of M-:, without setting the option, if I only need
>> >> > that sometimes?  Should there be such a way?
>> >> 
>> >> Isn't M-: (prin1-char value) sufficient?
>> >
>> > No, not after years of using "M-: #xNNNN RET".
>> 
>> If you want to keep muscle memory,
>> 
>>     (setq eval-expression-print-maximum-character most-positive-fixnum)
>> 
>> should give you back the old behaviour.  If you only want this only some
>> of the time, perhaps we should add a toggle-print-maximum-character
>> command?
>
> What about a special value of prefix argument, like zero?  If that's
> OK, it's more convenient than any of the above.

Sure, it's just a matter of deciding how to fit this in with the
existing interpretation of the prefix argument.  Right now, a non-nil
prefix argument means to insert the result into the buffer.





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#16828: 24.3.50; eval-expression, character representation of integer results time-consuming
  2017-03-26 17:39                             ` npostavs
@ 2017-03-26 17:51                               ` Eli Zaretskii
  2017-03-26 18:16                                 ` npostavs
  0 siblings, 1 reply; 24+ messages in thread
From: Eli Zaretskii @ 2017-03-26 17:51 UTC (permalink / raw)
  To: npostavs; +Cc: 16828

> From: npostavs@users.sourceforge.net
> Cc: 16828@debbugs.gnu.org
> Date: Sun, 26 Mar 2017 13:39:52 -0400
> 
> > What about a special value of prefix argument, like zero?  If that's
> > OK, it's more convenient than any of the above.
> 
> Sure, it's just a matter of deciding how to fit this in with the
> existing interpretation of the prefix argument.  Right now, a non-nil
> prefix argument means to insert the result into the buffer.

Yes, I propose that the current behavior wrt the argument will be left
unchanged, except when the argument is zero, i.e. "C-u 0".





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#16828: 24.3.50; eval-expression, character representation of integer results time-consuming
  2017-03-26 17:51                               ` Eli Zaretskii
@ 2017-03-26 18:16                                 ` npostavs
  2017-03-26 18:40                                   ` Eli Zaretskii
  0 siblings, 1 reply; 24+ messages in thread
From: npostavs @ 2017-03-26 18:16 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 16828

Eli Zaretskii <eliz@gnu.org> writes:

>> From: npostavs@users.sourceforge.net
>> Cc: 16828@debbugs.gnu.org
>> Date: Sun, 26 Mar 2017 13:39:52 -0400
>> 
>> > What about a special value of prefix argument, like zero?  If that's
>> > OK, it's more convenient than any of the above.
>> 
>> Sure, it's just a matter of deciding how to fit this in with the
>> existing interpretation of the prefix argument.  Right now, a non-nil
>> prefix argument means to insert the result into the buffer.
>
> Yes, I propose that the current behavior wrt the argument will be left
> unchanged, except when the argument is zero, i.e. "C-u 0".

Currently, zero also means no truncation, keeping that meaning seems
important too.  Perhaps a negative argument would be a better choice?

Excerpt from current docstring:

    Optional argument INSERT-VALUE non-nil (interactively, with
    prefix argument) means insert the result into the current buffer
    instead of printing it in the echo area.

    Normally, this function truncates long output according to the value
    of the variables `eval-expression-print-length' and
    `eval-expression-print-level'.  With a prefix argument of zero,
    however, there is no such truncation.






^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#16828: 24.3.50; eval-expression, character representation of integer results time-consuming
  2017-03-26 18:16                                 ` npostavs
@ 2017-03-26 18:40                                   ` Eli Zaretskii
  2017-05-18 23:56                                     ` npostavs
  0 siblings, 1 reply; 24+ messages in thread
From: Eli Zaretskii @ 2017-03-26 18:40 UTC (permalink / raw)
  To: npostavs; +Cc: 16828

> From: npostavs@users.sourceforge.net
> Cc: 16828@debbugs.gnu.org
> Date: Sun, 26 Mar 2017 14:16:52 -0400
> 
> > Yes, I propose that the current behavior wrt the argument will be left
> > unchanged, except when the argument is zero, i.e. "C-u 0".
> 
> Currently, zero also means no truncation, keeping that meaning seems
> important too.  Perhaps a negative argument would be a better choice?

Yes, that'd be fine with me.  Thanks.





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#16828: 24.3.50; eval-expression, character representation of integer results time-consuming
  2017-03-26 18:40                                   ` Eli Zaretskii
@ 2017-05-18 23:56                                     ` npostavs
  2017-05-19  6:34                                       ` Eli Zaretskii
  0 siblings, 1 reply; 24+ messages in thread
From: npostavs @ 2017-05-18 23:56 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 16828

[-- Attachment #1: Type: text/plain, Size: 558 bytes --]

Eli Zaretskii <eliz@gnu.org> writes:
>> 
>> > Yes, I propose that the current behavior wrt the argument will be left
>> > unchanged, except when the argument is zero, i.e. "C-u 0".
>> 
>> Currently, zero also means no truncation, keeping that meaning seems
>> important too.  Perhaps a negative argument would be a better choice?
>
> Yes, that'd be fine with me.  Thanks.

I added `-' to echo in character format, and `-1' to print it to the
buffer.  I split the patch in 2 parts, the first just refactors the
printing code, the 2nd adds the new behaviour.


[-- Attachment #2: patch --]
[-- Type: text/plain, Size: 11110 bytes --]

From f5ebfc7e1d352e63794264cf971993c5c0d564b2 Mon Sep 17 00:00:00 2001
From: Noam Postavsky <npostavs@gmail.com>
Date: Sun, 23 Apr 2017 22:21:42 -0400
Subject: [PATCH v2 1/2] 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.
---
 lisp/progmodes/elisp-mode.el            | 35 ++++++++++----------
 lisp/simple.el                          | 58 +++++++++++++++++----------------
 test/lisp/progmodes/elisp-mode-tests.el | 18 ++++++++++
 test/lisp/simple-tests.el               | 42 ++++++++++++++++++------
 4 files changed, 97 insertions(+), 56 deletions(-)

diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el
index 53a0f66439..c2fdba47a0 100644
--- a/lisp/progmodes/elisp-mode.el
+++ b/lisp/progmodes/elisp-mode.el
@@ -1119,29 +1119,28 @@ elisp--eval-last-sexp
 output with no limit on the length and level of lists, and
 include additional formats for integers \(octal, hexadecimal, and
 character)."
-  (let ((standard-output (if eval-last-sexp-arg-internal (current-buffer) t)))
+  (pcase-let*
+      ((`(,insert-value ,no-truncate ,char-print)
+        (eval-expression-get-print-arguments eval-last-sexp-arg-internal)))
     ;; Setup the lexical environment if lexical-binding is enabled.
     (elisp--eval-last-sexp-print-value
      (eval (eval-sexp-add-defvars (elisp--preceding-sexp)) lexical-binding)
-     eval-last-sexp-arg-internal)))
-
-(defun elisp--eval-last-sexp-print-value (value &optional eval-last-sexp-arg-internal)
-  (let ((unabbreviated (let ((print-length nil) (print-level nil))
-			 (prin1-to-string value)))
-	(print-length (and (not (zerop (prefix-numeric-value
-					eval-last-sexp-arg-internal)))
-			   eval-expression-print-length))
-	(print-level (and (not (zerop (prefix-numeric-value
-				       eval-last-sexp-arg-internal)))
-			  eval-expression-print-level))
-	(beg (point))
-	end)
+     (if insert-value (current-buffer) t) no-truncate char-print)))
+
+(defun elisp--eval-last-sexp-print-value
+    (value output &optional no-truncate char-print)
+  (let* ((unabbreviated (let ((print-length nil) (print-level nil))
+                          (prin1-to-string value)))
+         (print-length (unless no-truncate eval-expression-print-length))
+         (print-level  (unless no-truncate eval-expression-print-level))
+         (beg (point))
+         end)
     (prog1
-	(prin1 value)
-      (let ((str (eval-expression-print-format value)))
-	(if str (princ str)))
+	(prin1 value output)
+      (let ((str (and char-print (eval-expression-print-format value))))
+	(if str (princ str output)))
       (setq end (point))
-      (when (and (bufferp standard-output)
+      (when (and (bufferp output)
 		 (or (not (null print-length))
 		     (not (null print-level)))
 		 (not (string= unabbreviated
diff --git a/lisp/simple.el b/lisp/simple.el
index 082406bdc4..68208118f1 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -1460,16 +1460,14 @@ eval-expression-print-format
 If VALUE is not an integer, nil is returned.
 This function is used by functions like `prin1' that display the
 result of expression evaluation."
-  (if (and (integerp value)
-	   (or (eq standard-output t)
-	       (zerop (prefix-numeric-value current-prefix-arg))))
-      (let ((char-string
-	     (if (and (characterp value)
-		      (char-displayable-p value))
-		 (prin1-char value))))
-        (if char-string
-            (format " (#o%o, #x%x, %s)" value value char-string)
-          (format " (#o%o, #x%x)" value value)))))
+  (when (integerp value)
+    (let ((char-string
+           (and (characterp value)
+                (char-displayable-p value)
+                (prin1-char value))))
+      (if char-string
+          (format " (#o%o, #x%x, %s)" value value char-string)
+        (format " (#o%o, #x%x)" value value)))))
 
 (defvar eval-expression-minibuffer-setup-hook nil
   "Hook run by `eval-expression' when entering the minibuffer.")
@@ -1488,9 +1486,21 @@ read--expression
                             read-expression-map t
                             'read-expression-history))))
 
+(defun eval-expression-get-print-arguments (prefix-argument)
+  "Get arguments for commands that print an expression result.
+Returns a list (INSERT-VALUE NO-TRUNCATE CHAR-PRINT)
+based on PREFIX-ARG.  This function determines the interpretation
+of the prefix argument for `eval-expression' and
+`eval-last-sexp'."
+  (let ((num (prefix-numeric-value prefix-argument)))
+    (list (not (memq prefix-argument '(nil)))
+          (= num 0)
+          (cond ((not (memq prefix-argument '(0 nil))) nil)
+                (t t)))))
+
 ;; We define this, rather than making `eval' interactive,
 ;; for the sake of completion of names like eval-region, eval-buffer.
-(defun eval-expression (exp &optional insert-value)
+(defun eval-expression (exp &optional insert-value no-truncate char-print)
   "Evaluate EXP and print value in the echo area.
 When called interactively, read an Emacs Lisp expression and evaluate it.
 Value is also consed on to front of the variable `values'.
@@ -1511,8 +1521,8 @@ eval-expression
 If `eval-expression-debug-on-error' is non-nil, which is the default,
 this command arranges for all errors to enter the debugger."
   (interactive
-   (list (read--expression "Eval: ")
-	 current-prefix-arg))
+   (cons (read--expression "Eval: ")
+         (eval-expression-get-print-arguments current-prefix-arg)))
 
   (if (null eval-expression-debug-on-error)
       (push (eval exp lexical-binding) values)
@@ -1527,23 +1537,15 @@ eval-expression
       (unless (eq old-value new-value)
 	(setq debug-on-error new-value))))
 
-  (let ((print-length (and (not (zerop (prefix-numeric-value insert-value)))
-			   eval-expression-print-length))
-	(print-level (and (not (zerop (prefix-numeric-value insert-value)))
-			  eval-expression-print-level))
+  (let ((print-length (unless no-truncate eval-expression-print-length))
+        (print-level  (unless no-truncate eval-expression-print-level))
         (deactivate-mark))
-    (if insert-value
-	(with-no-warnings
-	 (let ((standard-output (current-buffer)))
-	   (prog1
-	       (prin1 (car values))
-	     (when (zerop (prefix-numeric-value insert-value))
-	       (let ((str (eval-expression-print-format (car values))))
-		 (if str (princ str)))))))
+    (let ((out (if insert-value (current-buffer) t)))
       (prog1
-          (prin1 (car values) t)
-        (let ((str (eval-expression-print-format (car values))))
-          (if str (princ str t)))))))
+          (prin1 (car values) out)
+        (let ((str (and char-print
+                        (eval-expression-print-format (car values)))))
+          (when str (princ str out)))))))
 
 (defun edit-and-eval-command (prompt command)
   "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 93c428b2d2..5edb590b1e 100644
--- a/test/lisp/progmodes/elisp-mode-tests.el
+++ b/test/lisp/progmodes/elisp-mode-tests.el
@@ -114,6 +114,24 @@ elisp--test-completions
       (should (member "backup-buffer" comps))
       (should-not (member "backup-inhibited" comps)))))
 
+;;; eval-last-sexp
+
+(ert-deftest eval-last-sexp-print-format-sym ()
+  (with-temp-buffer
+    (let ((current-prefix-arg '(4)))
+      (erase-buffer) (insert "t")
+      (call-interactively #'eval-last-sexp)
+      (should (equal (buffer-string) "tt")))))
+
+(ert-deftest eval-last-sexp-print-format-sym-echo ()
+  ;; We can only check the echo area when running interactive.
+  (skip-unless (not noninteractive))
+  (with-temp-buffer
+    (let ((current-prefix-arg nil))
+      (erase-buffer) (insert "t") (message nil)
+      (call-interactively #'eval-last-sexp)
+      (should (equal (current-message) "t")))))
+
 ;;; xref
 
 (defun xref-elisp-test-descr-to-target (xref)
diff --git a/test/lisp/simple-tests.el b/test/lisp/simple-tests.el
index f4849c4b21..b74e28ccaf 100644
--- a/test/lisp/simple-tests.el
+++ b/test/lisp/simple-tests.el
@@ -20,6 +20,7 @@
 ;;; Code:
 
 (require 'ert)
+(eval-when-compile (require 'cl-lib))
 
 (defmacro simple-test--dummy-buffer (&rest body)
   (declare (indent 0)
@@ -35,6 +36,8 @@ simple-test--dummy-buffer
              (buffer-substring (point) (point-max))))))
 
 
+\f
+;;; `transpose-sexps'
 (defmacro simple-test--transpositions (&rest body)
   (declare (indent 0)
            (debug t))
@@ -46,6 +49,13 @@ simple-test--transpositions
      (cons (buffer-substring (point-min) (point))
            (buffer-substring (point) (point-max)))))
 
+;;; Transposition with negative args (bug#20698, bug#21885)
+(ert-deftest simple-transpose-subr ()
+  (should (equal (simple-test--transpositions (transpose-sexps -1))
+                 '("(s1) (s2) (s4)" . " (s3) (s5)")))
+  (should (equal (simple-test--transpositions (transpose-sexps -2))
+                 '("(s1) (s4)" . " (s2) (s3) (s5)"))))
+
 \f
 ;;; `newline'
 (ert-deftest newline ()
@@ -239,8 +249,8 @@ simple-test--transpositions
       (should (equal ?\s (char-syntax ?\f)))
       (should (equal ?\s (char-syntax ?\n))))))
 
-
-;;; auto-boundary tests
+\f
+;;; undo auto-boundary tests
 (ert-deftest undo-auto-boundary-timer ()
   (should
    undo-auto-current-boundary-timer))
@@ -269,14 +279,6 @@ simple-test--transpositions
      (insert "hello")
      (undo-auto--boundaries 'test))))
 
-;;; Transposition with negative args (bug#20698, bug#21885)
-(ert-deftest simple-transpose-subr ()
-  (should (equal (simple-test--transpositions (transpose-sexps -1))
-                 '("(s1) (s2) (s4)" . " (s3) (s5)")))
-  (should (equal (simple-test--transpositions (transpose-sexps -2))
-                 '("(s1) (s4)" . " (s2) (s3) (s5)"))))
-
-
 ;; Test for a regression introduced by undo-auto--boundaries changes.
 ;; https://lists.gnu.org/archive/html/emacs-devel/2015-11/msg01652.html
 (defun undo-test-kill-c-a-then-undo ()
@@ -374,5 +376,25 @@ simple-test-undo-with-switched-buffer
        (undo)
        (point)))))
 
+\f
+;;; `eval-expression'
+
+(ert-deftest eval-expression-print-format-sym ()
+  (with-temp-buffer
+    (cl-letf (((symbol-function 'read--expression) (lambda (&rest _) t)))
+      (let ((current-prefix-arg '(4)))
+        (call-interactively #'eval-expression)
+        (should (equal (buffer-string) "t"))))))
+
+(ert-deftest eval-expression-print-format-sym-echo ()
+  ;; We can only check the echo area when running interactive.
+  (skip-unless (not noninteractive))
+  (with-temp-buffer
+    (cl-letf (((symbol-function 'read--expression) (lambda (&rest _) t)))
+      (let ((current-prefix-arg nil))
+        (message nil)
+        (call-interactively #'eval-expression)
+        (should (equal (current-message) "t"))))))
+
 (provide 'simple-test)
 ;;; simple-test.el ends here
-- 
2.11.1


[-- Attachment #3: patch --]
[-- Type: text/plain, Size: 16349 bytes --]

From cb5c5e64b97aa8add81aa7537bb888ebe651d72d Mon Sep 17 00:00:00 2001
From: Noam Postavsky <npostavs@gmail.com>
Date: Sun, 23 Apr 2017 22:30:20 -0400
Subject: [PATCH v2 2/2] Limit integers printed as characters (Bug#16828)

* lisp/simple.el (eval-expression-print-maximum-character): New
variable.
(eval-expression-print-format): Only display value as character if
it's less than or equal to `eval-expression-print-maximum-character'.
(eval-expression-get-print-arguments): Check
eval-expression-print-maximum-character, allow negative arg to
override it.
(eval-expression):
* lisp/progmodes/elisp-mode.el (elisp--eval-last-sexp):
(elisp--eval-last-sexp-print-value): Handle new variable.
* doc/emacs/building.texi (Lisp Eval): Document new variable and
behavior.
* etc/NEWS: Announce it.
* test/lisp/progmodes/elisp-mode-tests.el
(eval-last-sexp-print-format-small-int):
(eval-last-sexp-print-format-small-int-echo):
(eval-last-sexp-print-format-large-int):
(eval-last-sexp-print-format-large-int-echo):
* test/lisp/simple-tests.el (eval-expression-print-format-small-int):
(eval-expression-print-format-small-int-echo):
(eval-expression-print-format-large-int):
(eval-expression-print-format-large-int-echo): New tests.
---
 doc/emacs/building.texi                 | 12 ++++++--
 etc/NEWS                                |  4 +++
 lisp/progmodes/elisp-mode.el            | 20 ++++++++-----
 lisp/simple.el                          | 53 ++++++++++++++++++++++-----------
 test/lisp/progmodes/elisp-mode-tests.el | 48 +++++++++++++++++++++++++++++
 test/lisp/simple-tests.el               | 52 ++++++++++++++++++++++++++++++++
 6 files changed, 160 insertions(+), 29 deletions(-)

diff --git a/doc/emacs/building.texi b/doc/emacs/building.texi
index ba8eae0759..56bdffbb31 100644
--- a/doc/emacs/building.texi
+++ b/doc/emacs/building.texi
@@ -1485,7 +1485,8 @@ Lisp Eval
 Emacs Lisp expression preceding point in the buffer, and displays the
 value in the echo area.  When the result of an evaluation is an
 integer, it is displayed together with the value in other formats
-(octal, hexadecimal, and character).
+(octal, hexadecimal, and character if
+@code{eval-expression-print-maximum-character} allows it).
 
   If @kbd{M-:} or @kbd{C-x C-e} is given a prefix argument, it inserts
 the value into the current buffer at point, rather than displaying it
@@ -1493,8 +1494,10 @@ Lisp Eval
 is inserted together with its value in other formats (octal,
 hexadecimal, and character).  Such a prefix argument also prevents
 abbreviation of the output according to the variables
-@code{eval-expression-print-level} and @code{eval-expression-print-length}
-(see below).
+@code{eval-expression-print-level} and
+@code{eval-expression-print-length} (see below).  Similarly, a prefix
+argument of @code{-1} overrides the effect of
+@code{eval-expression-print-length}.
 
 @kindex C-M-x @r{(Emacs Lisp mode)}
 @findex eval-defun
@@ -1524,6 +1527,7 @@ Lisp Eval
 
 @vindex eval-expression-print-level
 @vindex eval-expression-print-length
+@vindex eval-expression-print-maximum-character
 @vindex eval-expression-debug-on-error
   The options @code{eval-expression-print-level} and
 @code{eval-expression-print-length} control the maximum depth and
@@ -1533,6 +1537,8 @@ Lisp Eval
 printed in full.  @code{eval-expression-debug-on-error} controls
 whether evaluation errors invoke the debugger when these commands are
 used; its default is @code{t}.
+@code{eval-expression-print-maximum-character} prevents large integers
+from being displayed as characters.
 
 @node Lisp Interaction
 @section Lisp Interaction Buffers
diff --git a/etc/NEWS b/etc/NEWS
index e8f5b2e899..548d55d60d 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -344,6 +344,10 @@ for DNS-querying functions 'nslookup-host', 'dns-lookup-host',
 and 'run-dig'.  Each function now accepts an optional name server
 argument interactively (with a prefix argument) and non-interactively.
 
++++
+** The new variable 'eval-expression-print-maximum-character' prevents
+large integers from being displayed as characters.
+
 \f
 * Editing Changes in Emacs 26.1
 
diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el
index c2fdba47a0..6c6fb92504 100644
--- a/lisp/progmodes/elisp-mode.el
+++ b/lisp/progmodes/elisp-mode.el
@@ -1120,24 +1120,25 @@ elisp--eval-last-sexp
 include additional formats for integers \(octal, hexadecimal, and
 character)."
   (pcase-let*
-      ((`(,insert-value ,no-truncate ,char-print)
+      ((`(,insert-value ,no-truncate ,char-print-limit)
         (eval-expression-get-print-arguments eval-last-sexp-arg-internal)))
     ;; Setup the lexical environment if lexical-binding is enabled.
     (elisp--eval-last-sexp-print-value
      (eval (eval-sexp-add-defvars (elisp--preceding-sexp)) lexical-binding)
-     (if insert-value (current-buffer) t) no-truncate char-print)))
+     (if insert-value (current-buffer) t) no-truncate char-print-limit)))
 
 (defun elisp--eval-last-sexp-print-value
-    (value output &optional no-truncate char-print)
+    (value output &optional no-truncate char-print-limit)
   (let* ((unabbreviated (let ((print-length nil) (print-level nil))
                           (prin1-to-string value)))
+         (eval-expression-print-maximum-character char-print-limit)
          (print-length (unless no-truncate eval-expression-print-length))
          (print-level  (unless no-truncate eval-expression-print-level))
          (beg (point))
          end)
     (prog1
 	(prin1 value output)
-      (let ((str (and char-print (eval-expression-print-format value))))
+      (let ((str (and char-print-limit (eval-expression-print-format value))))
 	(if str (princ str output)))
       (setq end (point))
       (when (and (bufferp output)
@@ -1175,14 +1176,17 @@ eval-sexp-add-defvars
 
 (defun eval-last-sexp (eval-last-sexp-arg-internal)
   "Evaluate sexp before point; print value in the echo area.
-Interactively, with prefix argument, print output into current buffer.
+Interactively, with a non `-' prefix argument, print output into
+current buffer.
 
-Normally, this function truncates long output according to the value
-of the variables `eval-expression-print-length' and
+Normally, this function truncates long output according to the
+value of the variables `eval-expression-print-length' and
 `eval-expression-print-level'.  With a prefix argument of zero,
 however, there is no such truncation.  Such a prefix argument
 also causes integers to be printed in several additional formats
-\(octal, hexadecimal, and character).
+\(octal, hexadecimal, and character when the prefix argument is
+-1 or the integer is `eval-expression-print-maximum-character' or
+less).
 
 If `eval-expression-debug-on-error' is non-nil, which is the default,
 this command arranges for all errors to enter the debugger."
diff --git a/lisp/simple.el b/lisp/simple.el
index 68208118f1..4435da6463 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -1454,6 +1454,13 @@ eval-expression-debug-on-error
   :type 'boolean
   :version "21.1")
 
+(defcustom eval-expression-print-maximum-character 127
+  "The largest integer that will be displayed as a character.
+This affects printing by `eval-expression-print-format'."
+  :group 'lisp
+  :type 'integer
+  :version "26.1")
+
 (defun eval-expression-print-format (value)
   "If VALUE in an integer, return a specially formatted string.
 This string will typically look like \" (#o1, #x1, ?\\C-a)\".
@@ -1463,6 +1470,7 @@ eval-expression-print-format
   (when (integerp value)
     (let ((char-string
            (and (characterp value)
+                (<= value eval-expression-print-maximum-character)
                 (char-displayable-p value)
                 (prin1-char value))))
       (if char-string
@@ -1488,32 +1496,40 @@ read--expression
 
 (defun eval-expression-get-print-arguments (prefix-argument)
   "Get arguments for commands that print an expression result.
-Returns a list (INSERT-VALUE NO-TRUNCATE CHAR-PRINT)
+Returns a list (INSERT-VALUE NO-TRUNCATE CHAR-PRINT-LIMIT)
 based on PREFIX-ARG.  This function determines the interpretation
 of the prefix argument for `eval-expression' and
 `eval-last-sexp'."
   (let ((num (prefix-numeric-value prefix-argument)))
-    (list (not (memq prefix-argument '(nil)))
+    (list (not (memq prefix-argument '(- nil)))
           (= num 0)
-          (cond ((not (memq prefix-argument '(0 nil))) nil)
-                (t t)))))
+          (cond ((not (memq prefix-argument '(0 -1 - nil))) nil)
+                ((= num -1) most-positive-fixnum)
+                (t eval-expression-print-maximum-character)))))
 
 ;; We define this, rather than making `eval' interactive,
 ;; for the sake of completion of names like eval-region, eval-buffer.
-(defun eval-expression (exp &optional insert-value no-truncate char-print)
+(defun eval-expression (exp &optional insert-value no-truncate char-print-limit)
   "Evaluate EXP and print value in the echo area.
-When called interactively, read an Emacs Lisp expression and evaluate it.
-Value is also consed on to front of the variable `values'.
-If the resulting value is an integer, it will be printed in
-several additional formats (octal, hexadecimal, and character).
-Optional argument INSERT-VALUE non-nil (interactively, with
-prefix argument) means insert the result into the current buffer
-instead of printing it in the echo area.
-
-Normally, this function truncates long output according to the value
-of the variables `eval-expression-print-length' and
-`eval-expression-print-level'.  With a prefix argument of zero,
-however, there is no such truncation.
+When called interactively, read an Emacs Lisp expression and
+evaluate it.  Value is also consed on to front of the variable
+`values'.  Optional argument INSERT-VALUE non-nil (interactively,
+with a non `-' prefix argument) means insert the result into the
+current buffer instead of printing it in the echo area.
+
+Normally, this function truncates long output according to the
+value of the variables `eval-expression-print-length' and
+`eval-expression-print-level'.  When NO-TRUNCATE is
+non-nil (interactively, with a prefix argument of zero), however,
+there is no such truncation.
+
+If the resulting value is an integer, and CHAR-PRINT-LIMIT is
+non-nil (interactively, unless given a positive prefix argument)
+it will be printed in several additional formats (octal,
+hexadecimal, and character).  The character format is only used
+if the value is below CHAR-PRINT-LIMIT (interactively, if the
+prefix argument is -1 or the value is below
+`eval-expression-print-maximum-character').
 
 Runs the hook `eval-expression-minibuffer-setup-hook' on entering the
 minibuffer.
@@ -1539,11 +1555,12 @@ eval-expression
 
   (let ((print-length (unless no-truncate eval-expression-print-length))
         (print-level  (unless no-truncate eval-expression-print-level))
+        (eval-expression-print-maximum-character char-print-limit)
         (deactivate-mark))
     (let ((out (if insert-value (current-buffer) t)))
       (prog1
           (prin1 (car values) out)
-        (let ((str (and char-print
+        (let ((str (and char-print-limit
                         (eval-expression-print-format (car values)))))
           (when str (princ str out)))))))
 
diff --git a/test/lisp/progmodes/elisp-mode-tests.el b/test/lisp/progmodes/elisp-mode-tests.el
index 5edb590b1e..03ae8481ee 100644
--- a/test/lisp/progmodes/elisp-mode-tests.el
+++ b/test/lisp/progmodes/elisp-mode-tests.el
@@ -132,6 +132,54 @@ elisp--test-completions
       (call-interactively #'eval-last-sexp)
       (should (equal (current-message) "t")))))
 
+(ert-deftest eval-last-sexp-print-format-small-int ()
+  (with-temp-buffer
+    (let ((current-prefix-arg '(4)))
+      (erase-buffer) (insert "?A")
+      (call-interactively #'eval-last-sexp)
+      (should (equal (buffer-string) "?A65")))
+    (let ((current-prefix-arg 0))
+      (erase-buffer) (insert "?A")
+      (call-interactively #'eval-last-sexp)
+      (should (equal (buffer-string) "?A65 (#o101, #x41, ?A)")))))
+
+(ert-deftest eval-last-sexp-print-format-small-int-echo ()
+  (skip-unless (not noninteractive))
+  (with-temp-buffer
+    (let ((current-prefix-arg nil))
+      (erase-buffer) (insert "?A") (message nil)
+      (call-interactively #'eval-last-sexp)
+      (should (equal (current-message) "65 (#o101, #x41, ?A)")))))
+
+(ert-deftest eval-last-sexp-print-format-large-int ()
+  (with-temp-buffer
+    (let ((eval-expression-print-maximum-character ?A))
+      (let ((current-prefix-arg '(4)))
+        (erase-buffer) (insert "?B")
+        (call-interactively #'eval-last-sexp)
+        (should (equal (buffer-string) "?B66")))
+      (let ((current-prefix-arg 0))
+        (erase-buffer) (insert "?B")
+        (call-interactively #'eval-last-sexp)
+        (should (equal (buffer-string) "?B66 (#o102, #x42)")))
+      (let ((current-prefix-arg -1))
+        (erase-buffer) (insert "?B")
+        (call-interactively #'eval-last-sexp)
+        (should (equal (buffer-string) "?B66 (#o102, #x42, ?B)"))))))
+
+(ert-deftest eval-last-sexp-print-format-large-int-echo ()
+  (skip-unless (not noninteractive))
+  (with-temp-buffer
+    (let ((eval-expression-print-maximum-character ?A))
+      (let ((current-prefix-arg nil))
+        (erase-buffer) (insert "?B") (message nil)
+        (call-interactively #'eval-last-sexp)
+        (should (equal (current-message) "66 (#o102, #x42)")))
+      (let ((current-prefix-arg '-))
+        (erase-buffer) (insert "?B") (message nil)
+        (call-interactively #'eval-last-sexp)
+        (should (equal (current-message) "66 (#o102, #x42, ?B)"))))))
+
 ;;; xref
 
 (defun xref-elisp-test-descr-to-target (xref)
diff --git a/test/lisp/simple-tests.el b/test/lisp/simple-tests.el
index b74e28ccaf..180dcc0a20 100644
--- a/test/lisp/simple-tests.el
+++ b/test/lisp/simple-tests.el
@@ -396,5 +396,57 @@ simple-test-undo-with-switched-buffer
         (call-interactively #'eval-expression)
         (should (equal (current-message) "t"))))))
 
+(ert-deftest eval-expression-print-format-small-int ()
+  (with-temp-buffer
+    (cl-letf (((symbol-function 'read--expression) (lambda (&rest _) ?A)))
+      (let ((current-prefix-arg '(4)))
+        (erase-buffer)
+        (call-interactively #'eval-expression)
+        (should (equal (buffer-string) "65")))
+      (let ((current-prefix-arg 0))
+        (erase-buffer)
+        (call-interactively #'eval-expression)
+        (should (equal (buffer-string) "65 (#o101, #x41, ?A)"))))))
+
+(ert-deftest eval-expression-print-format-small-int-echo ()
+  (skip-unless (not noninteractive))
+  (with-temp-buffer
+    (cl-letf (((symbol-function 'read--expression) (lambda (&rest _) ?A)))
+      (let ((current-prefix-arg nil))
+        (message nil)
+        (call-interactively #'eval-expression)
+        (should (equal (current-message) "65 (#o101, #x41, ?A)"))))))
+
+(ert-deftest eval-expression-print-format-large-int ()
+  (with-temp-buffer
+    (cl-letf (((symbol-function 'read--expression) (lambda (&rest _) ?B))
+              (eval-expression-print-maximum-character ?A))
+      (let ((current-prefix-arg '(4)))
+        (erase-buffer)
+        (call-interactively #'eval-expression)
+        (should (equal (buffer-string) "66")))
+      (let ((current-prefix-arg 0))
+        (erase-buffer)
+        (call-interactively #'eval-expression)
+        (should (equal (buffer-string) "66 (#o102, #x42)")))
+      (let ((current-prefix-arg -1))
+        (erase-buffer)
+        (call-interactively #'eval-expression)
+        (should (equal (buffer-string) "66 (#o102, #x42, ?B)"))))))
+
+(ert-deftest eval-expression-print-format-large-int-echo ()
+  (skip-unless (not noninteractive))
+  (with-temp-buffer
+    (cl-letf (((symbol-function 'read--expression) (lambda (&rest _) ?B))
+              (eval-expression-print-maximum-character ?A))
+      (let ((current-prefix-arg nil))
+        (message nil)
+        (call-interactively #'eval-expression)
+        (should (equal (current-message) "66 (#o102, #x42)")))
+      (let ((current-prefix-arg '-))
+        (message nil)
+        (call-interactively #'eval-expression)
+        (should (equal (current-message) "66 (#o102, #x42, ?B)"))))))
+
 (provide 'simple-test)
 ;;; simple-test.el ends here
-- 
2.11.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* bug#16828: 24.3.50; eval-expression, character representation of integer results time-consuming
  2017-05-18 23:56                                     ` npostavs
@ 2017-05-19  6:34                                       ` Eli Zaretskii
  2017-05-19 20:52                                         ` npostavs
  0 siblings, 1 reply; 24+ messages in thread
From: Eli Zaretskii @ 2017-05-19  6:34 UTC (permalink / raw)
  To: npostavs; +Cc: 16828

> From: npostavs@users.sourceforge.net
> Cc: 16828@debbugs.gnu.org
> Date: Thu, 18 May 2017 19:56:53 -0400
> 
> >> Currently, zero also means no truncation, keeping that meaning seems
> >> important too.  Perhaps a negative argument would be a better choice?
> >
> > Yes, that'd be fine with me.  Thanks.
> 
> I added `-' to echo in character format, and `-1' to print it to the
> buffer.  I split the patch in 2 parts, the first just refactors the
> printing code, the 2nd adds the new behaviour.

Thanks.

A couple of nits regarding the documentation part:

> +(defcustom eval-expression-print-maximum-character 127
> +  "The largest integer that will be displayed as a character.
> +This affects printing by `eval-expression-print-format'."

I would suggest to also mention eval-expression here.

> --- a/doc/emacs/building.texi
> +++ b/doc/emacs/building.texi
> @@ -1485,7 +1485,8 @@ Lisp Eval
>  Emacs Lisp expression preceding point in the buffer, and displays the
>  value in the echo area.  When the result of an evaluation is an
>  integer, it is displayed together with the value in other formats
> -(octal, hexadecimal, and character).
> +(octal, hexadecimal, and character if
> +@code{eval-expression-print-maximum-character} allows it).

Please add a "see below" here, as the description of the variable is
several dozens of lines farther.

> +@code{eval-expression-print-maximum-character} prevents large integers
> +from being displayed as characters.

This is too terse, IMO; please state explicitly that values larger
than this will not be displayed as characters.





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#16828: 24.3.50; eval-expression, character representation of integer results time-consuming
  2017-05-19  6:34                                       ` Eli Zaretskii
@ 2017-05-19 20:52                                         ` npostavs
  2017-05-19 21:09                                           ` Eli Zaretskii
  0 siblings, 1 reply; 24+ messages in thread
From: npostavs @ 2017-05-19 20:52 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 16828

[-- Attachment #1: Type: text/plain, Size: 1705 bytes --]

Eli Zaretskii <eliz@gnu.org> writes:

> I would suggest to also mention eval-expression here.

Right, I also noticed eval-expression-print-format's docstring refers to
`prin1' which seems to be wrong.

 (defcustom eval-expression-print-maximum-character 127
   "The largest integer that will be displayed as a character.
-This affects printing by `eval-expression-print-format'."
+This affects printing by `eval-expression' (via
+`eval-expression-print-format')."
   :group 'lisp
   :type 'integer
   :version "26.1")
 
 (defun eval-expression-print-format (value)
   "If VALUE in an integer, return a specially formatted string.
 This string will typically look like \" (#o1, #x1, ?\\C-a)\".
 If VALUE is not an integer, nil is returned.
-This function is used by functions like `prin1' that display the
-result of expression evaluation."
+This function is used by commands like `eval-expression' that
+display the result of expression evaluation."

>> +(octal, hexadecimal, and character if
>> +@code{eval-expression-print-maximum-character} allows it).
>
> Please add a "see below" here, as the description of the variable is
> several dozens of lines farther.

Right.  Is it okay to have nested parentheses?  I use this quite often
when I write emails and such, but I have the idea it might be frowned
upon in more formal contexts.

+@code{eval-expression-print-maximum-character} (see below) allows it).

>
> This is too terse, IMO; please state explicitly that values larger
> than this will not be displayed as characters.

Yeah, I have a tendency to be overly terse.

+@code{eval-expression-print-maximum-character} prevents integers which
+are larger than it from being displayed as characters.


[-- Attachment #2: patch --]
[-- Type: text/plain, Size: 16605 bytes --]

From eb11632d4db13d80839601c2c972e02fa46cc7f8 Mon Sep 17 00:00:00 2001
From: Noam Postavsky <npostavs@gmail.com>
Date: Sun, 23 Apr 2017 22:30:20 -0400
Subject: [PATCH v3 2/2] Limit integers printed as characters (Bug#16828)

* lisp/simple.el (eval-expression-print-maximum-character): New
variable.
(eval-expression-print-format): Only display value as character if
it's less than or equal to `eval-expression-print-maximum-character'.
(eval-expression-get-print-arguments): Check
eval-expression-print-maximum-character, allow negative arg to
override it.
(eval-expression):
* lisp/progmodes/elisp-mode.el (elisp--eval-last-sexp):
(elisp--eval-last-sexp-print-value): Handle new variable.
* doc/emacs/building.texi (Lisp Eval): Document new variable and
behavior.
* etc/NEWS: Announce it.
* test/lisp/progmodes/elisp-mode-tests.el
(eval-last-sexp-print-format-small-int):
(eval-last-sexp-print-format-small-int-echo):
(eval-last-sexp-print-format-large-int):
(eval-last-sexp-print-format-large-int-echo):
* test/lisp/simple-tests.el (eval-expression-print-format-small-int):
(eval-expression-print-format-small-int-echo):
(eval-expression-print-format-large-int):
(eval-expression-print-format-large-int-echo): New tests.
---
 doc/emacs/building.texi                 | 12 +++++--
 etc/NEWS                                |  4 +++
 lisp/progmodes/elisp-mode.el            | 20 +++++++-----
 lisp/simple.el                          | 58 +++++++++++++++++++++------------
 test/lisp/progmodes/elisp-mode-tests.el | 48 +++++++++++++++++++++++++++
 test/lisp/simple-tests.el               | 52 +++++++++++++++++++++++++++++
 6 files changed, 163 insertions(+), 31 deletions(-)

diff --git a/doc/emacs/building.texi b/doc/emacs/building.texi
index ba8eae0759..5bf10bf97d 100644
--- a/doc/emacs/building.texi
+++ b/doc/emacs/building.texi
@@ -1485,7 +1485,8 @@ Lisp Eval
 Emacs Lisp expression preceding point in the buffer, and displays the
 value in the echo area.  When the result of an evaluation is an
 integer, it is displayed together with the value in other formats
-(octal, hexadecimal, and character).
+(octal, hexadecimal, and character if
+@code{eval-expression-print-maximum-character} (see below) allows it).
 
   If @kbd{M-:} or @kbd{C-x C-e} is given a prefix argument, it inserts
 the value into the current buffer at point, rather than displaying it
@@ -1493,8 +1494,10 @@ Lisp Eval
 is inserted together with its value in other formats (octal,
 hexadecimal, and character).  Such a prefix argument also prevents
 abbreviation of the output according to the variables
-@code{eval-expression-print-level} and @code{eval-expression-print-length}
-(see below).
+@code{eval-expression-print-level} and
+@code{eval-expression-print-length} (see below).  Similarly, a prefix
+argument of @code{-1} overrides the effect of
+@code{eval-expression-print-length}.
 
 @kindex C-M-x @r{(Emacs Lisp mode)}
 @findex eval-defun
@@ -1524,6 +1527,7 @@ Lisp Eval
 
 @vindex eval-expression-print-level
 @vindex eval-expression-print-length
+@vindex eval-expression-print-maximum-character
 @vindex eval-expression-debug-on-error
   The options @code{eval-expression-print-level} and
 @code{eval-expression-print-length} control the maximum depth and
@@ -1533,6 +1537,8 @@ Lisp Eval
 printed in full.  @code{eval-expression-debug-on-error} controls
 whether evaluation errors invoke the debugger when these commands are
 used; its default is @code{t}.
+@code{eval-expression-print-maximum-character} prevents integers which
+are larger than it from being displayed as characters.
 
 @node Lisp Interaction
 @section Lisp Interaction Buffers
diff --git a/etc/NEWS b/etc/NEWS
index e8f5b2e899..548d55d60d 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -344,6 +344,10 @@ for DNS-querying functions 'nslookup-host', 'dns-lookup-host',
 and 'run-dig'.  Each function now accepts an optional name server
 argument interactively (with a prefix argument) and non-interactively.
 
++++
+** The new variable 'eval-expression-print-maximum-character' prevents
+large integers from being displayed as characters.
+
 \f
 * Editing Changes in Emacs 26.1
 
diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el
index c2fdba47a0..6c6fb92504 100644
--- a/lisp/progmodes/elisp-mode.el
+++ b/lisp/progmodes/elisp-mode.el
@@ -1120,24 +1120,25 @@ elisp--eval-last-sexp
 include additional formats for integers \(octal, hexadecimal, and
 character)."
   (pcase-let*
-      ((`(,insert-value ,no-truncate ,char-print)
+      ((`(,insert-value ,no-truncate ,char-print-limit)
         (eval-expression-get-print-arguments eval-last-sexp-arg-internal)))
     ;; Setup the lexical environment if lexical-binding is enabled.
     (elisp--eval-last-sexp-print-value
      (eval (eval-sexp-add-defvars (elisp--preceding-sexp)) lexical-binding)
-     (if insert-value (current-buffer) t) no-truncate char-print)))
+     (if insert-value (current-buffer) t) no-truncate char-print-limit)))
 
 (defun elisp--eval-last-sexp-print-value
-    (value output &optional no-truncate char-print)
+    (value output &optional no-truncate char-print-limit)
   (let* ((unabbreviated (let ((print-length nil) (print-level nil))
                           (prin1-to-string value)))
+         (eval-expression-print-maximum-character char-print-limit)
          (print-length (unless no-truncate eval-expression-print-length))
          (print-level  (unless no-truncate eval-expression-print-level))
          (beg (point))
          end)
     (prog1
 	(prin1 value output)
-      (let ((str (and char-print (eval-expression-print-format value))))
+      (let ((str (and char-print-limit (eval-expression-print-format value))))
 	(if str (princ str output)))
       (setq end (point))
       (when (and (bufferp output)
@@ -1175,14 +1176,17 @@ eval-sexp-add-defvars
 
 (defun eval-last-sexp (eval-last-sexp-arg-internal)
   "Evaluate sexp before point; print value in the echo area.
-Interactively, with prefix argument, print output into current buffer.
+Interactively, with a non `-' prefix argument, print output into
+current buffer.
 
-Normally, this function truncates long output according to the value
-of the variables `eval-expression-print-length' and
+Normally, this function truncates long output according to the
+value of the variables `eval-expression-print-length' and
 `eval-expression-print-level'.  With a prefix argument of zero,
 however, there is no such truncation.  Such a prefix argument
 also causes integers to be printed in several additional formats
-\(octal, hexadecimal, and character).
+\(octal, hexadecimal, and character when the prefix argument is
+-1 or the integer is `eval-expression-print-maximum-character' or
+less).
 
 If `eval-expression-debug-on-error' is non-nil, which is the default,
 this command arranges for all errors to enter the debugger."
diff --git a/lisp/simple.el b/lisp/simple.el
index 68208118f1..be12c315c8 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -1454,15 +1454,24 @@ eval-expression-debug-on-error
   :type 'boolean
   :version "21.1")
 
+(defcustom eval-expression-print-maximum-character 127
+  "The largest integer that will be displayed as a character.
+This affects printing by `eval-expression' (via
+`eval-expression-print-format')."
+  :group 'lisp
+  :type 'integer
+  :version "26.1")
+
 (defun eval-expression-print-format (value)
   "If VALUE in an integer, return a specially formatted string.
 This string will typically look like \" (#o1, #x1, ?\\C-a)\".
 If VALUE is not an integer, nil is returned.
-This function is used by functions like `prin1' that display the
-result of expression evaluation."
+This function is used by commands like `eval-expression' that
+display the result of expression evaluation."
   (when (integerp value)
     (let ((char-string
            (and (characterp value)
+                (<= value eval-expression-print-maximum-character)
                 (char-displayable-p value)
                 (prin1-char value))))
       (if char-string
@@ -1488,32 +1497,40 @@ read--expression
 
 (defun eval-expression-get-print-arguments (prefix-argument)
   "Get arguments for commands that print an expression result.
-Returns a list (INSERT-VALUE NO-TRUNCATE CHAR-PRINT)
+Returns a list (INSERT-VALUE NO-TRUNCATE CHAR-PRINT-LIMIT)
 based on PREFIX-ARG.  This function determines the interpretation
 of the prefix argument for `eval-expression' and
 `eval-last-sexp'."
   (let ((num (prefix-numeric-value prefix-argument)))
-    (list (not (memq prefix-argument '(nil)))
+    (list (not (memq prefix-argument '(- nil)))
           (= num 0)
-          (cond ((not (memq prefix-argument '(0 nil))) nil)
-                (t t)))))
+          (cond ((not (memq prefix-argument '(0 -1 - nil))) nil)
+                ((= num -1) most-positive-fixnum)
+                (t eval-expression-print-maximum-character)))))
 
 ;; We define this, rather than making `eval' interactive,
 ;; for the sake of completion of names like eval-region, eval-buffer.
-(defun eval-expression (exp &optional insert-value no-truncate char-print)
+(defun eval-expression (exp &optional insert-value no-truncate char-print-limit)
   "Evaluate EXP and print value in the echo area.
-When called interactively, read an Emacs Lisp expression and evaluate it.
-Value is also consed on to front of the variable `values'.
-If the resulting value is an integer, it will be printed in
-several additional formats (octal, hexadecimal, and character).
-Optional argument INSERT-VALUE non-nil (interactively, with
-prefix argument) means insert the result into the current buffer
-instead of printing it in the echo area.
-
-Normally, this function truncates long output according to the value
-of the variables `eval-expression-print-length' and
-`eval-expression-print-level'.  With a prefix argument of zero,
-however, there is no such truncation.
+When called interactively, read an Emacs Lisp expression and
+evaluate it.  Value is also consed on to front of the variable
+`values'.  Optional argument INSERT-VALUE non-nil (interactively,
+with a non `-' prefix argument) means insert the result into the
+current buffer instead of printing it in the echo area.
+
+Normally, this function truncates long output according to the
+value of the variables `eval-expression-print-length' and
+`eval-expression-print-level'.  When NO-TRUNCATE is
+non-nil (interactively, with a prefix argument of zero), however,
+there is no such truncation.
+
+If the resulting value is an integer, and CHAR-PRINT-LIMIT is
+non-nil (interactively, unless given a positive prefix argument)
+it will be printed in several additional formats (octal,
+hexadecimal, and character).  The character format is only used
+if the value is below CHAR-PRINT-LIMIT (interactively, if the
+prefix argument is -1 or the value is below
+`eval-expression-print-maximum-character').
 
 Runs the hook `eval-expression-minibuffer-setup-hook' on entering the
 minibuffer.
@@ -1539,11 +1556,12 @@ eval-expression
 
   (let ((print-length (unless no-truncate eval-expression-print-length))
         (print-level  (unless no-truncate eval-expression-print-level))
+        (eval-expression-print-maximum-character char-print-limit)
         (deactivate-mark))
     (let ((out (if insert-value (current-buffer) t)))
       (prog1
           (prin1 (car values) out)
-        (let ((str (and char-print
+        (let ((str (and char-print-limit
                         (eval-expression-print-format (car values)))))
           (when str (princ str out)))))))
 
diff --git a/test/lisp/progmodes/elisp-mode-tests.el b/test/lisp/progmodes/elisp-mode-tests.el
index 5edb590b1e..03ae8481ee 100644
--- a/test/lisp/progmodes/elisp-mode-tests.el
+++ b/test/lisp/progmodes/elisp-mode-tests.el
@@ -132,6 +132,54 @@ elisp--test-completions
       (call-interactively #'eval-last-sexp)
       (should (equal (current-message) "t")))))
 
+(ert-deftest eval-last-sexp-print-format-small-int ()
+  (with-temp-buffer
+    (let ((current-prefix-arg '(4)))
+      (erase-buffer) (insert "?A")
+      (call-interactively #'eval-last-sexp)
+      (should (equal (buffer-string) "?A65")))
+    (let ((current-prefix-arg 0))
+      (erase-buffer) (insert "?A")
+      (call-interactively #'eval-last-sexp)
+      (should (equal (buffer-string) "?A65 (#o101, #x41, ?A)")))))
+
+(ert-deftest eval-last-sexp-print-format-small-int-echo ()
+  (skip-unless (not noninteractive))
+  (with-temp-buffer
+    (let ((current-prefix-arg nil))
+      (erase-buffer) (insert "?A") (message nil)
+      (call-interactively #'eval-last-sexp)
+      (should (equal (current-message) "65 (#o101, #x41, ?A)")))))
+
+(ert-deftest eval-last-sexp-print-format-large-int ()
+  (with-temp-buffer
+    (let ((eval-expression-print-maximum-character ?A))
+      (let ((current-prefix-arg '(4)))
+        (erase-buffer) (insert "?B")
+        (call-interactively #'eval-last-sexp)
+        (should (equal (buffer-string) "?B66")))
+      (let ((current-prefix-arg 0))
+        (erase-buffer) (insert "?B")
+        (call-interactively #'eval-last-sexp)
+        (should (equal (buffer-string) "?B66 (#o102, #x42)")))
+      (let ((current-prefix-arg -1))
+        (erase-buffer) (insert "?B")
+        (call-interactively #'eval-last-sexp)
+        (should (equal (buffer-string) "?B66 (#o102, #x42, ?B)"))))))
+
+(ert-deftest eval-last-sexp-print-format-large-int-echo ()
+  (skip-unless (not noninteractive))
+  (with-temp-buffer
+    (let ((eval-expression-print-maximum-character ?A))
+      (let ((current-prefix-arg nil))
+        (erase-buffer) (insert "?B") (message nil)
+        (call-interactively #'eval-last-sexp)
+        (should (equal (current-message) "66 (#o102, #x42)")))
+      (let ((current-prefix-arg '-))
+        (erase-buffer) (insert "?B") (message nil)
+        (call-interactively #'eval-last-sexp)
+        (should (equal (current-message) "66 (#o102, #x42, ?B)"))))))
+
 ;;; xref
 
 (defun xref-elisp-test-descr-to-target (xref)
diff --git a/test/lisp/simple-tests.el b/test/lisp/simple-tests.el
index b74e28ccaf..180dcc0a20 100644
--- a/test/lisp/simple-tests.el
+++ b/test/lisp/simple-tests.el
@@ -396,5 +396,57 @@ simple-test-undo-with-switched-buffer
         (call-interactively #'eval-expression)
         (should (equal (current-message) "t"))))))
 
+(ert-deftest eval-expression-print-format-small-int ()
+  (with-temp-buffer
+    (cl-letf (((symbol-function 'read--expression) (lambda (&rest _) ?A)))
+      (let ((current-prefix-arg '(4)))
+        (erase-buffer)
+        (call-interactively #'eval-expression)
+        (should (equal (buffer-string) "65")))
+      (let ((current-prefix-arg 0))
+        (erase-buffer)
+        (call-interactively #'eval-expression)
+        (should (equal (buffer-string) "65 (#o101, #x41, ?A)"))))))
+
+(ert-deftest eval-expression-print-format-small-int-echo ()
+  (skip-unless (not noninteractive))
+  (with-temp-buffer
+    (cl-letf (((symbol-function 'read--expression) (lambda (&rest _) ?A)))
+      (let ((current-prefix-arg nil))
+        (message nil)
+        (call-interactively #'eval-expression)
+        (should (equal (current-message) "65 (#o101, #x41, ?A)"))))))
+
+(ert-deftest eval-expression-print-format-large-int ()
+  (with-temp-buffer
+    (cl-letf (((symbol-function 'read--expression) (lambda (&rest _) ?B))
+              (eval-expression-print-maximum-character ?A))
+      (let ((current-prefix-arg '(4)))
+        (erase-buffer)
+        (call-interactively #'eval-expression)
+        (should (equal (buffer-string) "66")))
+      (let ((current-prefix-arg 0))
+        (erase-buffer)
+        (call-interactively #'eval-expression)
+        (should (equal (buffer-string) "66 (#o102, #x42)")))
+      (let ((current-prefix-arg -1))
+        (erase-buffer)
+        (call-interactively #'eval-expression)
+        (should (equal (buffer-string) "66 (#o102, #x42, ?B)"))))))
+
+(ert-deftest eval-expression-print-format-large-int-echo ()
+  (skip-unless (not noninteractive))
+  (with-temp-buffer
+    (cl-letf (((symbol-function 'read--expression) (lambda (&rest _) ?B))
+              (eval-expression-print-maximum-character ?A))
+      (let ((current-prefix-arg nil))
+        (message nil)
+        (call-interactively #'eval-expression)
+        (should (equal (current-message) "66 (#o102, #x42)")))
+      (let ((current-prefix-arg '-))
+        (message nil)
+        (call-interactively #'eval-expression)
+        (should (equal (current-message) "66 (#o102, #x42, ?B)"))))))
+
 (provide 'simple-test)
 ;;; simple-test.el ends here
-- 
2.11.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* bug#16828: 24.3.50; eval-expression, character representation of integer results time-consuming
  2017-05-19 20:52                                         ` npostavs
@ 2017-05-19 21:09                                           ` Eli Zaretskii
  2017-05-19 22:28                                             ` npostavs
  0 siblings, 1 reply; 24+ messages in thread
From: Eli Zaretskii @ 2017-05-19 21:09 UTC (permalink / raw)
  To: npostavs; +Cc: 16828

> From: npostavs@users.sourceforge.net
> Cc: 16828@debbugs.gnu.org
> Date: Fri, 19 May 2017 16:52:20 -0400
> 
> >> +(octal, hexadecimal, and character if
> >> +@code{eval-expression-print-maximum-character} allows it).
> >
> > Please add a "see below" here, as the description of the variable is
> > several dozens of lines farther.
> 
> Right.  Is it okay to have nested parentheses?

Personally, I prefer to use commas in these cases:

 +(octal, hexadecimal, and character if
 +@code{eval-expression-print-maximum-character}, described below, allows it).

Thanks, the new version is fine with me.





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#16828: 24.3.50; eval-expression, character representation of integer results time-consuming
  2017-05-19 21:09                                           ` Eli Zaretskii
@ 2017-05-19 22:28                                             ` npostavs
  0 siblings, 0 replies; 24+ messages in thread
From: npostavs @ 2017-05-19 22:28 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 16828

tags 16828 fixed
close 16828 26.1
quit

Eli Zaretskii <eliz@gnu.org> writes:

> Thanks, the new version is fine with me.

Pushed to master [1: acd58c9198] [2: 267be4bdc2].

[1: acd58c9198]: 2017-05-19 18:16:38 -0400
  Limit integers printed as characters (Bug#16828)
  http://git.savannah.gnu.org/cgit/emacs.git/commit/?id=acd58c9198c08c3eb631a3f036b4f95073f7fe10

[2: 267be4bdc2]: 2017-05-19 18:16:15 -0400
  Refactor lisp eval result printing
  http://git.savannah.gnu.org/cgit/emacs.git/commit/?id=267be4bdc28564a99f45da29e84eb98838117b50





^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2017-05-19 22:28 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-02-21 10:01 bug#16828: 24.3.50; eval-expression, character representation of integer results time-consuming Anders Lindgren
2014-02-21 10:29 ` Eli Zaretskii
2014-02-22 12:49   ` Anders Lindgren
2014-02-22 13:11     ` Eli Zaretskii
2014-02-22 18:53       ` Stephen Berman
2014-02-22 21:00         ` Eli Zaretskii
2014-02-23  9:06           ` Achim Gratz
2014-02-25  0:42             ` Katsumi Yamaoka
2014-02-26 10:16               ` martin rudalics
2017-03-26  3:45                 ` npostavs
2017-03-26 14:13                   ` Eli Zaretskii
2017-03-26 14:19                     ` Noam Postavsky
2017-03-26 14:37                       ` Eli Zaretskii
2017-03-26 14:55                         ` npostavs
2017-03-26 15:22                           ` Eli Zaretskii
2017-03-26 17:39                             ` npostavs
2017-03-26 17:51                               ` Eli Zaretskii
2017-03-26 18:16                                 ` npostavs
2017-03-26 18:40                                   ` Eli Zaretskii
2017-05-18 23:56                                     ` npostavs
2017-05-19  6:34                                       ` Eli Zaretskii
2017-05-19 20:52                                         ` npostavs
2017-05-19 21:09                                           ` Eli Zaretskii
2017-05-19 22:28                                             ` npostavs

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).