Subject: bug#15747: Patch to optionally display raw bytes in hexadecimal

From: Nathan Trapuzzano <[email-masked]>
Date: Tue, 29 Oct 2013 09:52:55 -0400

I never understood why raw bytes in emacs are displayed as octal escapes
rather than hexadecimal.  The latter is much more intuitive to my mind.

The attached patch adds the option to display these bytes in hex rather
than octal.  If it's not accepted, please advise what changes I can make
to give it a better chance.

Nathan

>From 3938a8a7225e5644cadb14d39d24fc18a33cfd3e Mon Sep 17 00:00:00 2001
From: Nathan Trapuzzano <[email-masked]>
Date: Thu, 25 Jul 2013 15:47:23 -0400
Subject: [PATCH] Define and implement `display-raw-bytes-as-hex' variable.

This allows raw bytes to be displayed with hexadecimal escape
sequences rather than octal.
---
 doc/emacs/ChangeLog      |  4 ++++
 doc/emacs/display.texi   |  4 ++++
 doc/lispref/ChangeLog    |  4 ++++
 doc/lispref/display.texi | 30 ++++++++++++++++++++----------
 lisp/ChangeLog           |  4 ++++
 lisp/cus-start.el        |  1 +
 src/ChangeLog            |  5 +++++
 src/xdisp.c              |  8 +++++++-
 8 files changed, 49 insertions(+), 11 deletions(-)

diff --git a/doc/emacs/ChangeLog b/doc/emacs/ChangeLog
index eafe608..595eef3 100644
--- a/doc/emacs/ChangeLog
+++ b/doc/emacs/ChangeLog
@@ -1,3 +1,7 @@
+2013-10-29  Nathan Trapuzzano  <[email-masked]>
+
+	* display.texi (Text Display): Document `display-raw-bytes-as-hex'.
+
 2013-10-23  Glenn Morris  <[email-masked]>
 
 	* files.texi, glossary.texi, killing.texi, search.texi, sending.texi:
diff --git a/doc/emacs/display.texi b/doc/emacs/display.texi
index 80dffe2..0ffa79d 100644
--- a/doc/emacs/display.texi
+++ b/doc/emacs/display.texi
@@ -1400,6 +1400,7 @@ character, @code{U+0001}, is displayed as @samp{^A}.
 
 @cindex octal escapes
 @vindex ctl-arrow
+@vindex display-raw-bytes-as-hex
   The raw bytes with codes @code{U+0080} (octal 200) through
 @code{U+009F} (octal 237) are displayed as @dfn{octal escape
 sequences}, with the @code{escape-glyph} face.  For instance,
@@ -1407,6 +1408,9 @@ character code @code{U+0098} (octal 230) is displayed as @samp{\230}.
 If you change the buffer-local variable @code{ctl-arrow} to
 @code{nil}, the @acronym{ASCII} control characters are also displayed
 as octal escape sequences instead of caret escape sequences.
+Moreover, setting @code{display-raw-bytes-as-hex} to non-@code{nil}
+causes Emacs to display hexadecimal, rather than octal, escape
+sequences.
 
 @vindex nobreak-char-display
 @cindex non-breaking space
diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog
index 6416991..e51c3f9 100644
--- a/doc/lispref/ChangeLog
+++ b/doc/lispref/ChangeLog
@@ -1,3 +1,7 @@
+2013-10-29  Nathan Trapuzzano  <[email-masked]>
+
+	* display.texi (Usual Display): Document `display-raw-bytes-as-hex'.
+
 2013-10-29  Xue Fuqiao  <[email-masked]>
 
 	* display.texi (Showing Images): Add an index for image-size.
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index 1194e26..77e3c43 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -5906,11 +5906,13 @@ conversion (@pxref{Coding System Basics}).
 @cindex octal escapes
 @item
 @dfn{Raw bytes} are non-@acronym{ASCII} characters with codes 128
-through 255 (@pxref{Text Representations}).  These characters display
-as @dfn{octal escapes}: sequences of four glyphs, where the first
-glyph is the @acronym{ASCII} code for @samp{\}, and the others are
-digit characters representing the character code in octal.  (A display
-table can specify a glyph to use instead of @samp{\}.)
+through 255 (@pxref{Text Representations}).  By default, these
+characters display as @dfn{octal escapes}: sequences of four glyphs,
+where the first glyph is the @acronym{ASCII} code for @samp{\}, and
+the others are digit characters representing the character code in
+octal.  (A display table can specify a glyph to use instead of
+@samp{\}.)  To display these bytes as hexadecimal escape sequences
+rather than octal, set @code{display-raw-bytes-as-hex} to @code{t}.
 
 @item
 Each non-@acronym{ASCII} character with code above 255 is displayed
@@ -5928,11 +5930,11 @@ table, for any character whose entry in the active display table is
 specify the characters for which you want special behavior.
 
   The following variables affect how certain characters are displayed
-on the screen.  Since they change the number of columns the characters
-occupy, they also affect the indentation functions.  They also affect
-how the mode line is displayed; if you want to force redisplay of the
-mode line using the new values, call the function
-@code{force-mode-line-update} (@pxref{Mode Line Format}).
+on the screen.  Some of these change the number of columns the
+characters occupy, which affects the indentation functions.  These
+also affect the display of characters in the mode line; if you want to
+force redisplay of the mode line using the new values, call the
+function @code{force-mode-line-update} (@pxref{Mode Line Format}).
 
 @defopt ctl-arrow
 @cindex control characters in display
@@ -5951,6 +5953,14 @@ is completely independent of the user-settable tab stops used by the
 command @code{tab-to-tab-stop}.  @xref{Indent Tabs}.
 @end defopt
 
+@defopt display-raw-bytes-as-hex
+Setting this variable to any value other than @code{nil} will cause
+raw bytes to be displayed as hexadecimal escape sequences rather than
+octal.  The two-digit sequences will be prepended with @samp{x}, which
+will in turn be prepended with @samp{\}, or whatever glyph the current
+display table specifies for this purpose.
+@end defopt
+
 @node Display Tables
 @subsection Display Tables
 
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 9519a07..fb82d84 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,7 @@
+2013-10-29  Nathan Trapuzzano  <[email-masked]>
+
+	* cus-start.el: Add `display-raw-bytes-as-hex' to `display' group.
+
 2013-10-29  Daniel Colascione  <[email-masked]>
 
 	* net/tramp.el (tramp-methods): Document new functionality.
diff --git a/lisp/cus-start.el b/lisp/cus-start.el
index 24f8ac3..f15a744 100644
--- a/lisp/cus-start.el
+++ b/lisp/cus-start.el
@@ -71,6 +71,7 @@
 	     (left-margin fill integer)
 	     (tab-width editing-basics integer)
 	     (ctl-arrow display boolean)
+	     (display-raw-bytes-as-hex display boolean)
 	     (truncate-lines display boolean)
 	     (word-wrap display boolean)
 	     (selective-display-ellipses display boolean)
diff --git a/src/ChangeLog b/src/ChangeLog
index c9792e6..a4a4089 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+2013-10-29  Nathan Trapuzzano  <[email-masked]>
+
+	* xdisp.c (Vdisplay_raw_bytes_as_hex, get_next_display_element):
+	Define and implement `display-raw-bytes-as-hex'.
+
 2013-10-29  Dmitry Antipov  <[email-masked]>
 
 	* xterm.h (struct x_output): For 'black_relief' and 'white_relief'
diff --git a/src/xdisp.c b/src/xdisp.c
index d62bc6b..ff074a8 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -6723,6 +6723,7 @@ get_next_display_element (struct it *it)
      function pointer `method' used here turns out to be faster than
      using a sequence of if-statements.  */
   int success_p;
+  const char *disp_format = Vdisplay_raw_bytes_as_hex ? "x%02X" : "%03o";
 
  get_next:
   success_p = GET_NEXT_DISPLAY_ELEMENT (it);
@@ -6927,7 +6928,7 @@ get_next_display_element (struct it *it)
 		if (CHAR_BYTE8_P (c))
 		  /* Display \200 instead of \17777600.  */
 		  c = CHAR_TO_BYTE8 (c);
-		len = sprintf (str, "%03o", c);
+		len = sprintf (str, disp_format, c);
 
 		XSETINT (it->ctl_chars[0], escape_glyph);
 		for (i = 0; i < len; i++)
@@ -29347,6 +29348,11 @@ wide as that tab on the display.  */);
 The face used for trailing whitespace is `trailing-whitespace'.  */);
   Vshow_trailing_whitespace = Qnil;
 
+  DEFVAR_BOOL ("display-raw-bytes-as-hex", Vdisplay_raw_bytes_as_hex,
+    doc: /* Non-nil means display raw 8-bit bytes as hexadecimal
+escape sequences as opposed to the default octal escape sequences.  */);
+  Vdisplay_raw_bytes_as_hex = 0;
+
   DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
     doc: /* Control highlighting of non-ASCII space and hyphen chars.
 If the value is t, Emacs highlights non-ASCII chars which have the
-- 
1.8.4.2