Subject: Re: bug#59730: gdb-mi.el: Local variables reordering

From: Gustaf Waldemarson <[email-masked]>
Date: Sun, 4 Dec 2022 15:26:22 +0100

> I'm uncomfortable with backward-incompatible change in behavior for which
> there's no way of getting the old behavior.  So please add another
defcustom
> that could be used to get the original order of type/name/value.

> There also should be a NEWS entry about these new options, and the text
> there should explain how to get back old behavior before these changes.

Hmm, this turned out to be a bit harder change, and I did not particularly
like
the thought of having 3 defcustoms control this behavior. So I spent a bit
of time
to refactor things a bit.

So, this new version only uses a single defcustom,
`gdb-locals-table-row-config',
which is an alist the user can change to specify the truncation and order
of the
local variable properties (i.e., name, type, value).

I have set this to '((name . 20)(type . 20)(value . 100)), so to get the
old behavior
one would change this to '(type . 0)(name . 0)(value . 0).

Additionally, I found a minor bug in `gdb-locals-value-filter' which did
not work
properly when the value was nil. There I also noticed that that the
`gdb-locals-value-limit'
has become redundant with this change. Unfortunately, I wasn't able to
figure out how
to mark that defcustom as deprecated, is there some kind of macro that
should be done
for that, or should I just remove it?

I also added content to the `etc/NEWS`, as requested but I haven't actually
done that
before, so I may very well have messed up the formatting, so feel free to
double check
things there

Best regards,
Gustaf

Den lör 3 dec. 2022 kl 20:59 skrev Eli Zaretskii <[email-masked]>:

> > From: Gustaf Waldemarson <[email-masked]>
> > Date: Thu, 1 Dec 2022 22:53:26 +0100
> > Cc: [email-masked]
> >
> > The updated patch is attached to this mail.
>
> Thanks.  I have a couple of minor comments:
>
> > +(defcustom gdb-locals-max-type-length 20
> > +  "Maximum number of character to display in the local variables type
> column."
> > +  :type 'integer
> > +  :group 'gud
> > +  :version "30.0")
>
> This should be "30.1".  We don't release NN.o versions of Emacs.
>
> > +(defcustom gdb-locals-max-name-length 20
> > +  "Maximum number of character to display in the local variables name
> column."
> > +  :type 'integer
> > +  :group 'gud
> > +  :version "30.0")
>
> Likewise.
>
> Also, please add more detailed description of what these options control.
> The first line of the doc string is fine, but please add more text
> explaining that this setting is for displaying the variables in the
> "Locals"
> buffer.
>
> > -          (propertize type 'font-lock-face font-lock-type-face)
> > -          (propertize name 'font-lock-face font-lock-variable-name-face)
> > +          (propertize (string-truncate-left name
> gdb-locals-max-name-length)
> > +                      'font-lock-face font-lock-variable-name-face
> > +                      'help-echo name)
> > +          (propertize (string-truncate-left type
> gdb-locals-max-type-length)
> > +                      'font-lock-face font-lock-type-face
> > +                      'help-echo type)
>
> I'm uncomfortable with backward-incompatible change in behavior for which
> there's no way of getting the old behavior.  So please add another
> defcustom
> that could be used to get the original order of type/name/value.
>
> There also should be a NEWS entry about these new options, and the text
> there should explain how to get back old behavior before these changes.
>
From e65276fb92a1e7a86d2ce894482eaf5c53b7a34e Mon Sep 17 00:00:00 2001
From: Gustaf Waldemarson <[email-masked]>
Date: Tue, 29 Nov 2022 23:40:23 +0100
Subject: [PATCH] gdb-mi.el: Configure variable order and length.

This changes allows users to configure the order of various properties
as well as truncating their length. The full description of each
property is available as a help-text (tooltip).
---
 etc/NEWS                 | 17 +++++++++++++
 lisp/progmodes/gdb-mi.el | 53 ++++++++++++++++++++++++++++++++--------
 2 files changed, 60 insertions(+), 10 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index 9b8edde5155..473d427e757 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -40,6 +40,23 @@ connection.
 
 
 * Changes in Specialized Modes and Packages in Emacs 30.1
+---
+** Variable order and truncation can now be configured in gdb-many-window mode.
+The new variable `gdb-locals-table-row-config' allows users to
+configure the order and max length of various properties in the local
+variables frame.
+
+By default, this variable is set to write the properties in the order:
+name, type and value. Where name and type are truncated to 20
+characters, and the value is truncated to 100.
+
+In order to restore the old display behavior, set
+`gdb-locals-table-row-config' to '((type . 0)(name . 0)(value . 0)).
+
+Additionally, this behavior encompasses the actions of the old
+`gdb-locals-value-limit' variable, which is no longer used and marked
+deprecated.
+
 
 
 * New Modes and Packages in Emacs 30.1
diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el
index e8d8f9104e4..80950fec77e 100644
--- a/lisp/progmodes/gdb-mi.el
+++ b/lisp/progmodes/gdb-mi.el
@@ -4355,6 +4355,24 @@ gdb-locals-value-limit
   :group 'gud
   :version "29.1")
 
+(defcustom gdb-locals-table-row-config '((name . 20)
+                                         (type . 20)
+                                         (value . 100))
+  "Configuration for table rows in the local variable display.
+
+An alist that controls the display of the name, type and value of
+local variables inside the currently active stack-frame.  The key
+controls which column to change whereas the value determines the
+maximum number of characters to display in each column.  A value
+of 0 means there is no limit.
+
+Additionally, the order the element in the alist determines the
+left-to-right display order of the properties."
+  :type '(alist :key-type 'symbol :value-type 'integer)
+  :group 'gud
+  :version "30.1")
+
+
 (defvar gdb-locals-values-table (make-hash-table :test #'equal)
   "Mapping of local variable names to a string with their value.")
 
@@ -4384,12 +4402,9 @@ gdb-edit-locals-map-1
 
 (defun gdb-locals-value-filter (value)
   "Filter function for the local variable VALUE."
-  (let* ((no-nl (replace-regexp-in-string "\n" " " value))
-         (str (replace-regexp-in-string "[[:space:]]+" " " no-nl))
-         (limit gdb-locals-value-limit))
-    (if (>= (length str) limit)
-        (concat (substring str 0 limit) "...")
-      str)))
+  (let* ((no-nl (replace-regexp-in-string "\n" " " (or value "<Unknown>")))
+         (str (replace-regexp-in-string "[[:space:]]+" " " no-nl)))
+    str))
 
 (defun gdb-edit-locals-value (&optional event)
   "Assign a value to a variable displayed in the locals buffer."
@@ -4403,6 +4418,22 @@ gdb-edit-locals-value
       (gud-basic-call
        (concat  "-gdb-set variable " var " = " value)))))
 
+
+(defun gdb-locals-table-columns-list (alist)
+  "Format and arrange the columns in locals display based on ALIST."
+  (let (columns)
+    (dolist (config gdb-locals-table-row-config columns)
+      (let* ((key  (car config))
+             (max  (cdr config))
+             (prop (alist-get key alist)))
+        (when prop
+          (if (and (> max 0) (length> prop max))
+              (push (propertize (string-truncate-left prop max) 'help-echo prop)
+                    columns)
+            (push prop columns)))))
+    (nreverse columns)))
+
+
 ;; Complex data types are looked up in `gdb-locals-values-table'.
 (defun gdb-locals-handler-custom ()
   "Handler to rebuild the local variables table buffer."
@@ -4431,12 +4462,14 @@ gdb-locals-handler-custom
                                             help-echo "mouse-2: edit value"
                                             local-map ,gdb-edit-locals-map-1)
                                value))
+        (setf (gdb-table-right-align table) t)
+        (setq name (propertize name 'font-lock-face font-lock-variable-name-face))
+        (setq type (propertize type 'font-lock-face font-lock-type-face))
         (gdb-table-add-row
          table
-         (list
-          (propertize type 'font-lock-face font-lock-type-face)
-          (propertize name 'font-lock-face font-lock-variable-name-face)
-          value)
+         (gdb-locals-table-columns-list `((name  . ,name)
+                                          (type  . ,type)
+                                          (value . ,value)))
          `(gdb-local-variable ,local))))
     (insert (gdb-table-string table " "))
     (setq mode-name
-- 
2.34.1