From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Thuna Newsgroups: gmane.emacs.bugs Subject: bug#56345: 29.0.50; [PATCH] Add column hiding to tabulated-list Date: Sat, 02 Jul 2022 01:43:26 +0300 Message-ID: <87r134ihdd.fsf@gmail.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="10907"; mail-complaints-to="usenet@ciao.gmane.io" To: 56345@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sat Jul 02 00:44:12 2022 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1o7PMx-0002jR-VG for geb-bug-gnu-emacs@m.gmane-mx.org; Sat, 02 Jul 2022 00:44:12 +0200 Original-Received: from localhost ([::1]:35968 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1o7PMw-0002Wo-HV for geb-bug-gnu-emacs@m.gmane-mx.org; Fri, 01 Jul 2022 18:44:10 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:35250) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1o7PMo-0002WL-GR for bug-gnu-emacs@gnu.org; Fri, 01 Jul 2022 18:44:02 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:45420) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1o7PMo-0005dS-8O for bug-gnu-emacs@gnu.org; Fri, 01 Jul 2022 18:44:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1o7PMo-0001BM-5C for bug-gnu-emacs@gnu.org; Fri, 01 Jul 2022 18:44:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Thuna Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Fri, 01 Jul 2022 22:44:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 56345 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch X-Debbugs-Original-To: bug-gnu-emacs@gnu.org Original-Received: via spool by submit@debbugs.gnu.org id=B.16567154184494 (code B ref -1); Fri, 01 Jul 2022 22:44:01 +0000 Original-Received: (at submit) by debbugs.gnu.org; 1 Jul 2022 22:43:38 +0000 Original-Received: from localhost ([127.0.0.1]:39317 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1o7PMP-0001AP-AP for submit@debbugs.gnu.org; Fri, 01 Jul 2022 18:43:38 -0400 Original-Received: from lists.gnu.org ([209.51.188.17]:33720) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1o7PMN-0001AG-SH for submit@debbugs.gnu.org; Fri, 01 Jul 2022 18:43:36 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:35186) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1o7PMN-0002UM-Hs for bug-gnu-emacs@gnu.org; Fri, 01 Jul 2022 18:43:35 -0400 Original-Received: from mail-ed1-x533.google.com ([2a00:1450:4864:20::533]:34655) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1o7PML-0005a2-84 for bug-gnu-emacs@gnu.org; Fri, 01 Jul 2022 18:43:35 -0400 Original-Received: by mail-ed1-x533.google.com with SMTP id z41so4616582ede.1 for ; Fri, 01 Jul 2022 15:43:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:mime-version; bh=0nb26BVKRVxbY0oAlwlQ36IUt1CcRKrbMa6mYIkH2FI=; b=YBfsMcEpgr0mldEm2dsFOAxkRyDvPo0ZrNVxSr4juYJ7/PJ9tdtIupsPXEJOUNNrFs 7F8PFF+9/BKlagSFL8qsiDe78DKS9Ha8FssJpFyyO9V/cwyMvr00z4LFFPauJ5uD3laf bzec0MYlQtuDdLqimQPYJaW8sPW55DIpTfzqZ1QPNuLbT29mdLlWH5UTr/mlYQiWIbV/ wuFl7dd6idmwkznDqoarVMP8jlIgiZnLBKsrhTIYePSuyAv+sjtxUF0npPpQnXTsip7Y wUYdf9iG0SU6Gcb0bur11VSAGST35aQyFb3+1m5rxcsEurByyc76wl6Iec6noV0uF+CS gGVw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:mime-version; bh=0nb26BVKRVxbY0oAlwlQ36IUt1CcRKrbMa6mYIkH2FI=; b=lRiWvwKA/83YkeqWniqmaUk2Of1/94pGYoXmOS95l5W46GiqmANimVDn07MR/G21qD PSrNDwk0Z+tlo5Q31XTYAvLG8b9ZPeuV/Zz4nOCJZP2+yMeFm2dZxMEQKuwGLPfKZvUR 7nXW6a5qVi1B0DCJoYMYVRi0QS2BwnACV/qvh8if5LEBStjxONnM0JLp5QEsfvCt3I8Y OVwbECtqV2rERf2ruKoKgC++kHfgfGzHqA/+oNsW+FtOKQewh58waa0YsNi6ng2ASymm GjUtaDGAIw3O+pE1RltRr70yytUc2wHcLGcQjnFTPprdp5M+BEssfPMAxxPtNfO/YRyv o4Ew== X-Gm-Message-State: AJIora/vUzbX9sjwBtjRCxmFviHHVfq3dMZ1gLIyveR1Ot7Us+CO7/mB x9HqzOwlPtmERjSJiskxnWDdHqbKAK3UYY+d X-Google-Smtp-Source: AGRyM1uFmIEbhLoZyA8TOFHpOiEu846ksiE04K3nGwQDGKbJVHvvuX2T/EmkB11anvZ0IJGvgPsiFw== X-Received: by 2002:a05:6402:328f:b0:435:7f7a:7666 with SMTP id f15-20020a056402328f00b004357f7a7666mr3676414eda.168.1656715410057; Fri, 01 Jul 2022 15:43:30 -0700 (PDT) Original-Received: from thuna ([85.106.112.123]) by smtp.gmail.com with ESMTPSA id y21-20020a170906559500b00726dbb16b8dsm5262380ejp.65.2022.07.01.15.43.27 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Jul 2022 15:43:28 -0700 (PDT) Received-SPF: pass client-ip=2a00:1450:4864:20::533; envelope-from=thuna.cing@gmail.com; helo=mail-ed1-x533.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:235842 Archived-At: --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Add-column-hiding-to-tabulated-list-mode.patch Content-Description: Actual patch >From b49d5876afa3d969ce82df0d723a8a8b766009a0 Mon Sep 17 00:00:00 2001 From: Thuna Date: Fri, 1 Jul 2022 18:19:52 +0300 Subject: [PATCH 1/2] Add column hiding to tabulated-list-mode Add the keyword `:hidden' to `tabulated-list-format' for controlling the visibility of a specific column. Introduce the commands `tabulated-list-hide-current-column' and `tabulated-list-make-column-visible' for interactively changing the `:hidden' property of the column. The commands are bound to "." and "+" respectively. Change calculations involving other columns to account for the `:hidden' property. Make the current column calculation into its own function named `tabulated-list-get-column'. Make `tabulated-list-widen-current-column' use that instead. Use the text property `tabulated-list-column-name' to find the current tabulated-list column instead of `current-column'. --- lisp/emacs-lisp/tabulated-list.el | 273 +++++++++++++++++------------- 1 file changed, 153 insertions(+), 120 deletions(-) diff --git a/lisp/emacs-lisp/tabulated-list.el b/lisp/emacs-lisp/tabulated-list.el index 7d815a3ced..868ed141ec 100644 --- a/lisp/emacs-lisp/tabulated-list.el +++ b/lisp/emacs-lisp/tabulated-list.el @@ -104,7 +104,8 @@ tabulated-list-format Currently supported properties are: - `:right-align': If non-nil, the column should be right-aligned. - `:pad-right': Number of additional padding spaces to the - right of the column (defaults to 1 if omitted).") + right of the column (defaults to 1 if omitted). + - `:hidden': If non-nil, the column should not be visible.") (put 'tabulated-list-format 'permanent-local t) (defvar-local tabulated-list-use-header-line t @@ -179,6 +180,11 @@ tabulated-list-get-entry no entry at POS. POS, if omitted or nil, defaults to point." (get-text-property (or pos (point)) 'tabulated-list-entry)) +(defun tabulated-list-get-column (&optional pos) + "Return the column name of the Tabulated List cell at POS. +POS, if omitted or nil, defaults to point." + (get-text-property (or pos (point)) 'tabulated-list-column-name)) + (defun tabulated-list-put-tag (tag &optional advance) "Put TAG in the padding area of the current line. TAG should be a string, with length <= `tabulated-list-padding'. @@ -228,6 +234,8 @@ tabulated-list-mode-map (define-key map "S" 'tabulated-list-sort) (define-key map "}" 'tabulated-list-widen-current-column) (define-key map "{" 'tabulated-list-narrow-current-column) + (define-key map "." 'tabulated-list-hide-current-column) + (define-key map "+" 'tabulated-list-make-column-visible) (define-key map [follow-link] 'mouse-face) (define-key map [mouse-2] 'mouse-select-window) map) @@ -290,7 +298,7 @@ tabulated-list-init-header cols) (dotimes (n len) (let* ((col (aref tabulated-list-format n)) - (not-last-col (< n (1- len))) + (not-last-col (tabulated-list--next-visible-column n)) (label (nth 0 col)) (lablen (length label)) (pname label) @@ -298,62 +306,64 @@ tabulated-list-init-header (props (nthcdr 3 col)) (pad-right (or (plist-get props :pad-right) 1)) (right-align (plist-get props :right-align)) + (hidden (plist-get props :hidden)) (next-x (+ x pad-right width)) (available-space (and not-last-col (if right-align width (tabulated-list--available-space width n))))) - (when (and (>= lablen 3) - not-last-col - (> lablen available-space)) - (setq label (truncate-string-to-width label available-space - nil nil t))) - (push - (cond - ;; An unsortable column - ((not (nth 2 col)) - (propertize label 'tabulated-list-column-name pname)) - ;; The selected sort column - ((equal (car col) (car tabulated-list-sort-key)) - (apply 'propertize - (concat label - (cond - ((and (< lablen 3) not-last-col) "") - ((cdr tabulated-list-sort-key) - (format " %c" - tabulated-list-gui-sort-indicator-desc)) - (t (format " %c" - tabulated-list-gui-sort-indicator-asc)))) - 'face 'bold - 'tabulated-list-column-name pname - button-props)) - ;; Unselected sortable column. - (t (apply 'propertize label - 'tabulated-list-column-name pname - button-props))) - cols) - (when right-align - (let ((shift (- width (string-width (car cols))))) - (when (> shift 0) - (setq cols - (cons (car cols) - (cons - (propertize - (make-string shift ?\s) - 'display - `(space :align-to - (+ header-line-indent-width ,(+ x shift)))) - (cdr cols)))) - (setq x (+ x shift))))) - (if (>= pad-right 0) - (push (propertize - " " - 'display `(space :align-to - (+ header-line-indent-width ,next-x)) - 'face 'fixed-pitch) - cols)) - (setq x next-x))) + (unless hidden + (when (and (>= lablen 3) + not-last-col + (> lablen available-space)) + (setq label (truncate-string-to-width label available-space + nil nil t))) + (push + (cond + ;; An unsortable column + ((not (nth 2 col)) + (propertize label 'tabulated-list-column-name pname)) + ;; The selected sort column + ((equal (car col) (car tabulated-list-sort-key)) + (apply 'propertize + (concat label + (cond + ((and (< lablen 3) not-last-col) "") + ((cdr tabulated-list-sort-key) + (format " %c" + tabulated-list-gui-sort-indicator-desc)) + (t (format " %c" + tabulated-list-gui-sort-indicator-asc)))) + 'face 'bold + 'tabulated-list-column-name pname + button-props)) + ;; Unselected sortable column. + (t (apply 'propertize label + 'tabulated-list-column-name pname + button-props))) + cols) + (when right-align + (let ((shift (- width (string-width (car cols))))) + (when (> shift 0) + (setq cols + (cons (car cols) + (cons + (propertize + (make-string shift ?\s) + 'display + `(space :align-to + (+ header-line-indent-width ,(+ x shift)))) + (cdr cols)))) + (setq x (+ x shift))))) + (if (>= pad-right 0) + (push (propertize + " " + 'display `(space :align-to + (+ header-line-indent-width ,next-x)) + 'face 'fixed-pitch) + cols)) + (setq x next-x)))) (setq cols (apply 'concat (nreverse cols))) (if tabulated-list-use-header-line (setq header-line-format (list "" 'header-line-indent cols)) @@ -535,15 +545,29 @@ tabulated-list-print-entry beg (point) `(tabulated-list-id ,id tabulated-list-entry ,cols)))) +(defun tabulated-list--next-visible-column (n) + (let ((len (length tabulated-list-format)) + (col-nb (1+ n)) + found) + (while (and (< col-nb len) + (not found)) + (if (plist-get (nthcdr 3 (aref tabulated-list-format col-nb)) + :hidden) + (setq col-nb (1+ col-nb)) + (setq found t))) + (when (< col-nb len) + col-nb))) + (defun tabulated-list--available-space (width n) - (let* ((next-col-format (aref tabulated-list-format (1+ n))) + (let* ((next-col (tabulated-list--next-visible-column n)) + (next-col-format (aref tabulated-list-format next-col)) (next-col-right-align (plist-get (nthcdr 3 next-col-format) :right-align)) (next-col-width (nth 1 next-col-format))) (if next-col-right-align (- (+ width next-col-width) (min next-col-width - (tabulated-list--col-local-max-widths (1+ n)))) + (tabulated-list--col-local-max-widths next-col))) width))) (defun tabulated-list-print-col (n col-desc x) @@ -557,50 +581,52 @@ tabulated-list-print-col (props (nthcdr 3 format)) (pad-right (or (plist-get props :pad-right) 1)) (right-align (plist-get props :right-align)) + (hidden (plist-get props :hidden)) (label (cond ((stringp col-desc) col-desc) ((eq (car col-desc) 'image) " ") (t (car col-desc)))) (label-width (string-width label)) (help-echo (concat (car format) ": " label)) (opoint (point)) - (not-last-col (< (1+ n) (length tabulated-list-format))) + (not-last-col (tabulated-list--next-visible-column n)) (available-space (and not-last-col (if right-align width (tabulated-list--available-space width n))))) - ;; Truncate labels if necessary (except last column). - ;; Don't truncate to `width' if the next column is align-right - ;; and has some space left, truncate to `available-space' instead. - (when (and not-last-col - (> label-width available-space)) - (setq label (truncate-string-to-width - label available-space nil nil t t) - label-width available-space)) - (setq label (bidi-string-mark-left-to-right label)) - (when (and right-align (> width label-width)) - (let ((shift (- width label-width))) - (insert (propertize (make-string shift ?\s) - 'display `(space :align-to ,(+ x shift)))) - (setq width (- width shift)) - (setq x (+ x shift)))) - (cond ((stringp col-desc) - (insert (if (get-text-property 0 'help-echo label) - label - (propertize label 'help-echo help-echo)))) - ((eq (car col-desc) 'image) - (insert (propertize " " - 'display col-desc - 'help-echo help-echo))) - ((apply 'insert-text-button label (cdr col-desc)))) - (let ((next-x (+ x pad-right width))) - ;; No need to append any spaces if this is the last column. - (when not-last-col - (when (> pad-right 0) (insert (make-string pad-right ?\s))) - (insert (propertize - (make-string (- width (min width label-width)) ?\s) - 'display `(space :align-to ,next-x)))) - (put-text-property opoint (point) 'tabulated-list-column-name name) - next-x))) + (if hidden x + ;; Truncate labels if necessary (except last column). + ;; Don't truncate to `width' if the next column is align-right + ;; and has some space left, truncate to `available-space' instead. + (when (and not-last-col + (> label-width available-space)) + (setq label (truncate-string-to-width + label available-space nil nil t t) + label-width available-space)) + (setq label (bidi-string-mark-left-to-right label)) + (when (and right-align (> width label-width)) + (let ((shift (- width label-width))) + (insert (propertize (make-string shift ?\s) + 'display `(space :align-to ,(+ x shift)))) + (setq width (- width shift)) + (setq x (+ x shift)))) + (cond ((stringp col-desc) + (insert (if (get-text-property 0 'help-echo label) + label + (propertize label 'help-echo help-echo)))) + ((eq (car col-desc) 'image) + (insert (propertize " " + 'display col-desc + 'help-echo help-echo))) + ((apply 'insert-text-button label (cdr col-desc)))) + (let ((next-x (+ x pad-right width))) + ;; No need to append any spaces if this is the last column. + (when not-last-col + (when (> pad-right 0) (insert (make-string pad-right ?\s))) + (insert (propertize + (make-string (- width (min width label-width)) ?\s) + 'display `(space :align-to ,next-x)))) + (put-text-property opoint (point) 'tabulated-list-column-name name) + next-x)))) (defun tabulated-list-delete-entry () "Delete the Tabulated List entry at point. @@ -731,38 +757,16 @@ tabulated-list-widen-current-column Interactively, N is the prefix numeric argument, and defaults to 1." (interactive "p") - (let ((start (current-column)) - (entry (tabulated-list-get-entry)) - (nb-cols (length tabulated-list-format)) - (col-nb 0) - (total-width 0) - (found nil) - col-width) - (while (and (not found) - (< col-nb nb-cols)) - (if (>= start - (setq total-width - (+ total-width - (max (setq col-width - (cadr (aref tabulated-list-format - col-nb))) - (let ((desc (aref entry col-nb))) - (string-width (if (stringp desc) - desc - (car desc))))) - (or (plist-get (nthcdr 3 (aref tabulated-list-format - col-nb)) - :pad-right) - 1)))) - (setq col-nb (1+ col-nb)) - (setq found t) - ;; `tabulated-list-format' may be a constant (sharing list - ;; structures), so copy it before mutating. - (setq tabulated-list-format (copy-tree tabulated-list-format t)) - (setf (cadr (aref tabulated-list-format col-nb)) - (max 1 (+ col-width n))) - (tabulated-list-print t) - (tabulated-list-init-header))))) + (let* ((col-nb (tabulated-list--column-number + (tabulated-list-get-column))) + (col-width (cadr (aref tabulated-list-format col-nb)))) + ;; `tabulated-list-format' may be a constant (sharing list + ;; structures), so copy it before mutating. + (setq tabulated-list-format (copy-tree tabulated-list-format t)) + (setf (cadr (aref tabulated-list-format col-nb)) + (max 1 (+ col-width n))) + (tabulated-list-print t) + (tabulated-list-init-header))) (defun tabulated-list-narrow-current-column (&optional n) "Narrow the current tabulated list column by N chars. @@ -771,6 +775,35 @@ tabulated-list-narrow-current-column (interactive "p") (tabulated-list-widen-current-column (- n))) +(defun tabulated-list-hide-current-column () + "Hide the current tabulated list column." + (interactive) + (let ((col-nb (tabulated-list--column-number + (tabulated-list-get-column)))) + (setf (nthcdr 3 (aref tabulated-list-format col-nb)) + (plist-put (nthcdr 3 (aref tabulated-list-format col-nb)) + :hidden t))) + (tabulated-list-init-header) + (tabulated-list-print t t)) + +(defun tabulated-list-make-column-visible (name) + "Make the tabulated list column NAME visible. +Interactively, NAME is a hidden column propmted for with +`completing-read'." + (interactive + (list + (completing-read "Colummn name: " + (append tabulated-list-format nil) + (lambda (col) + (plist-get (nthcdr 3 col) :hidden)) + t))) + (let ((col-nb (tabulated-list--column-number name))) + (setf (nthcdr 3 (aref tabulated-list-format col-nb)) + (plist-put (nthcdr 3 (aref tabulated-list-format col-nb)) + :hidden nil))) + (tabulated-list-init-header) + (tabulated-list-print t t)) + (defun tabulated-list-next-column (&optional arg) "Go to the start of the next column after point on the current line. If ARG is provided, move that many columns." -- 2.35.1 --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0002-Fix-tabulated-list-format-sharing-list-structures.patch Content-Description: fix >From 3348b627bc1ad8d0d187a0c8bd0ce45f6a769d33 Mon Sep 17 00:00:00 2001 From: Thuna Date: Sat, 2 Jul 2022 00:03:38 +0300 Subject: [PATCH 2/2] Fix `tabulated-list-format' sharing list structures * tabulated-list.el (tabulated-list-hide-current-column tabulated-list-make-column-visible): Copy tabulated-list-format recursively before mutating it. --- lisp/emacs-lisp/tabulated-list.el | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lisp/emacs-lisp/tabulated-list.el b/lisp/emacs-lisp/tabulated-list.el index 868ed141ec..4e0b3b9e95 100644 --- a/lisp/emacs-lisp/tabulated-list.el +++ b/lisp/emacs-lisp/tabulated-list.el @@ -780,6 +780,9 @@ tabulated-list-hide-current-column (interactive) (let ((col-nb (tabulated-list--column-number (tabulated-list-get-column)))) + ;; `tabulated-list-format' may be a constant (sharing list + ;; structures), so copy it before mutating. + (setq tabulated-list-format (copy-tree tabulated-list-format t)) (setf (nthcdr 3 (aref tabulated-list-format col-nb)) (plist-put (nthcdr 3 (aref tabulated-list-format col-nb)) :hidden t))) @@ -798,6 +801,9 @@ tabulated-list-make-column-visible (plist-get (nthcdr 3 col) :hidden)) t))) (let ((col-nb (tabulated-list--column-number name))) + ;; `tabulated-list-format' may be a constant (sharing list + ;; structures), so copy it before mutating. + (setq tabulated-list-format (copy-tree tabulated-list-format t)) (setf (nthcdr 3 (aref tabulated-list-format col-nb)) (plist-put (nthcdr 3 (aref tabulated-list-format col-nb)) :hidden nil))) -- 2.35.1 --=-=-= Content-Type: text/plain The attached patches introduce column hiding to tabulated-list-mode, which works by adding the keyword `:hidden' to `tabulated-list-format'. Patch 0001 is the actual patch itself while 0002 is a bug fix. 0001 compiled fine for me but I did not test 0002, though it should be perfectly safe. I went through tabulated-list.el and fixed everything I could find that would be affected by the visibility of columns. I don't believe I missed anything but it is possible. --=-=-=--