diff options
| author | Alex Branham | 2018-12-17 12:15:09 +0100 |
|---|---|---|
| committer | Michael Albinus | 2018-12-17 12:15:09 +0100 |
| commit | 36b05dc84247db1391a423df94e4b9a478e29dc5 (patch) | |
| tree | 6dff27f40a20402aceec355ffc9551d4e3e3525a | |
| parent | 09a6cc4778d4b90a0bb8da646425d04d8f8a6ec9 (diff) | |
| download | emacs-36b05dc84247db1391a423df94e4b9a478e29dc5.tar.gz emacs-36b05dc84247db1391a423df94e4b9a478e29dc5.zip | |
New function flatten-tree
Co-authored-by: Basil L. Contovounesios <contovob@tcd.ie>
* doc/lispref/lists.texi: Document `flatten-tree'.
* lisp/progmodes/js.el (js--maybe-join):
* lisp/printing.el (pr-switches):
* lisp/lpr.el (lpr-print-region):
* lisp/gnus/nnimap.el (nnimap-find-wanted-parts):
* lisp/gnus/message.el (message-talkative-question):
* lisp/gnus/gnus-sum.el (gnus-remove-thread)
(gnus-thread-highest-number, gnus-thread-latest-date):
* lisp/eshell/esh-util.el (eshell-flatten-and-stringify):
* lisp/eshell/esh-opt.el (eshell-eval-using-options):
* lisp/eshell/esh-ext.el (eshell-external-command):
* lisp/eshell/em-xtra.el (eshell/expr):
* lisp/eshell/em-unix.el (eshell/rm, eshell-mvcpln-template)
(eshell/cat, eshell/make, eshell-poor-mans-grep, eshell-grep)
(eshell/du, eshell/time, eshell/diff, eshell/locate):
* lisp/eshell/em-tramp.el (eshell/su, eshell/sudo):
* lisp/eshell/em-term.el (eshell-exec-visual):
* lisp/eshell/em-dirs.el (eshell-dirs-substitute-cd, eshell/cd):
* lisp/eshell/em-basic.el (eshell/printnl):
Use new flatten-tree.
* lisp/progmodes/js.el (js--flatten-list):
* lisp/lpr.el (lpr-flatten-list):
* lisp/gnus/message.el (message-flatten-list):
* lisp/eshell/esh-util.el (eshell-flatten-list):
Obsolete in favor of Emacs-wide `flatten-tree'.
* lisp/subr.el (flatten-list): Alias to `flatten-tree' for
discoverability.
* lisp/subr.el (flatten-tree): New defun.
* test/lisp/subr-tests.el (subr-tests-flatten-tree): New test.
| -rw-r--r-- | doc/lispref/lists.texi | 12 | ||||
| -rw-r--r-- | etc/NEWS | 6 | ||||
| -rw-r--r-- | lisp/eshell/em-basic.el | 2 | ||||
| -rw-r--r-- | lisp/eshell/em-dirs.el | 4 | ||||
| -rw-r--r-- | lisp/eshell/em-term.el | 2 | ||||
| -rw-r--r-- | lisp/eshell/em-tramp.el | 4 | ||||
| -rw-r--r-- | lisp/eshell/em-unix.el | 22 | ||||
| -rw-r--r-- | lisp/eshell/em-xtra.el | 2 | ||||
| -rw-r--r-- | lisp/eshell/esh-ext.el | 2 | ||||
| -rw-r--r-- | lisp/eshell/esh-opt.el | 4 | ||||
| -rw-r--r-- | lisp/eshell/esh-util.el | 12 | ||||
| -rw-r--r-- | lisp/gnus/gnus-sum.el | 10 | ||||
| -rw-r--r-- | lisp/gnus/message.el | 12 | ||||
| -rw-r--r-- | lisp/gnus/nnimap.el | 2 | ||||
| -rw-r--r-- | lisp/lpr.el | 20 | ||||
| -rw-r--r-- | lisp/printing.el | 2 | ||||
| -rw-r--r-- | lisp/progmodes/js.el | 8 | ||||
| -rw-r--r-- | lisp/subr.el | 25 | ||||
| -rw-r--r-- | test/lisp/subr-tests.el | 17 |
19 files changed, 96 insertions, 72 deletions
diff --git a/doc/lispref/lists.texi b/doc/lispref/lists.texi index 69f93009520..31cc3190854 100644 --- a/doc/lispref/lists.texi +++ b/doc/lispref/lists.texi | |||
| @@ -667,6 +667,18 @@ non-@code{nil}, it copies vectors too (and operates recursively on | |||
| 667 | their elements). | 667 | their elements). |
| 668 | @end defun | 668 | @end defun |
| 669 | 669 | ||
| 670 | @defun flatten-tree tree | ||
| 671 | Take @var{tree} and "flatten" it. | ||
| 672 | This always returns a list containing all the terminal nodes, or | ||
| 673 | leaves, of @var{tree}. Dotted pairs are flattened as well, and nil | ||
| 674 | elements are removed. | ||
| 675 | @end defun | ||
| 676 | |||
| 677 | @example | ||
| 678 | (flatten-tree '(1 (2 . 3) nil (4 5 (6)) 7)) | ||
| 679 | @result{}(1 2 3 4 5 6 7) | ||
| 680 | @end example | ||
| 681 | |||
| 670 | @defun number-sequence from &optional to separation | 682 | @defun number-sequence from &optional to separation |
| 671 | This returns a list of numbers starting with @var{from} and | 683 | This returns a list of numbers starting with @var{from} and |
| 672 | incrementing by @var{separation}, and ending at or just before | 684 | incrementing by @var{separation}, and ending at or just before |
| @@ -1359,6 +1359,12 @@ are implemented in C using the Jansson library. | |||
| 1359 | ** New function 'ring-resize'. | 1359 | ** New function 'ring-resize'. |
| 1360 | 'ring-resize' can be used to grow or shrink a ring. | 1360 | 'ring-resize' can be used to grow or shrink a ring. |
| 1361 | 1361 | ||
| 1362 | +++ | ||
| 1363 | ** New function 'flatten-tree'. | ||
| 1364 | 'flatten-list' is provided as an alias. These functions take a tree | ||
| 1365 | and 'flatten' it such that the result is a list of all the terminal | ||
| 1366 | nodes. | ||
| 1367 | |||
| 1362 | ** Mailcap | 1368 | ** Mailcap |
| 1363 | 1369 | ||
| 1364 | --- | 1370 | --- |
diff --git a/lisp/eshell/em-basic.el b/lisp/eshell/em-basic.el index 5201076f485..4a99d838579 100644 --- a/lisp/eshell/em-basic.el +++ b/lisp/eshell/em-basic.el | |||
| @@ -118,7 +118,7 @@ or `eshell-printn' for display." | |||
| 118 | 118 | ||
| 119 | (defun eshell/printnl (&rest args) | 119 | (defun eshell/printnl (&rest args) |
| 120 | "Print out each of the arguments, separated by newlines." | 120 | "Print out each of the arguments, separated by newlines." |
| 121 | (let ((elems (eshell-flatten-list args))) | 121 | (let ((elems (flatten-tree args))) |
| 122 | (while elems | 122 | (while elems |
| 123 | (eshell-printn (eshell-echo (list (car elems)))) | 123 | (eshell-printn (eshell-echo (list (car elems)))) |
| 124 | (setq elems (cdr elems))))) | 124 | (setq elems (cdr elems))))) |
diff --git a/lisp/eshell/em-dirs.el b/lisp/eshell/em-dirs.el index 853382888c9..b47f76fbfb2 100644 --- a/lisp/eshell/em-dirs.el +++ b/lisp/eshell/em-dirs.el | |||
| @@ -259,7 +259,7 @@ Thus, this does not include the current directory.") | |||
| 259 | (if (> (length args) 1) | 259 | (if (> (length args) 1) |
| 260 | (error "%s: command not found" (car args)) | 260 | (error "%s: command not found" (car args)) |
| 261 | (throw 'eshell-replace-command | 261 | (throw 'eshell-replace-command |
| 262 | (eshell-parse-command "cd" (eshell-flatten-list args))))) | 262 | (eshell-parse-command "cd" (flatten-tree args))))) |
| 263 | 263 | ||
| 264 | (defun eshell-parse-user-reference () | 264 | (defun eshell-parse-user-reference () |
| 265 | "An argument beginning with ~ is a filename to be expanded." | 265 | "An argument beginning with ~ is a filename to be expanded." |
| @@ -353,7 +353,7 @@ in the minibuffer: | |||
| 353 | 353 | ||
| 354 | (defun eshell/cd (&rest args) ; all but first ignored | 354 | (defun eshell/cd (&rest args) ; all but first ignored |
| 355 | "Alias to extend the behavior of `cd'." | 355 | "Alias to extend the behavior of `cd'." |
| 356 | (setq args (eshell-flatten-list args)) | 356 | (setq args (flatten-tree args)) |
| 357 | (let ((path (car args)) | 357 | (let ((path (car args)) |
| 358 | (subpath (car (cdr args))) | 358 | (subpath (car (cdr args))) |
| 359 | (case-fold-search (eshell-under-windows-p)) | 359 | (case-fold-search (eshell-under-windows-p)) |
diff --git a/lisp/eshell/em-term.el b/lisp/eshell/em-term.el index ddde47f73d6..fdf40cae85d 100644 --- a/lisp/eshell/em-term.el +++ b/lisp/eshell/em-term.el | |||
| @@ -175,7 +175,7 @@ allowed." | |||
| 175 | (let* (eshell-interpreter-alist | 175 | (let* (eshell-interpreter-alist |
| 176 | (interp (eshell-find-interpreter (car args) (cdr args))) | 176 | (interp (eshell-find-interpreter (car args) (cdr args))) |
| 177 | (program (car interp)) | 177 | (program (car interp)) |
| 178 | (args (eshell-flatten-list | 178 | (args (flatten-tree |
| 179 | (eshell-stringify-list (append (cdr interp) | 179 | (eshell-stringify-list (append (cdr interp) |
| 180 | (cdr args))))) | 180 | (cdr args))))) |
| 181 | (term-buf | 181 | (term-buf |
diff --git a/lisp/eshell/em-tramp.el b/lisp/eshell/em-tramp.el index 9475f4ed949..f77b84d851b 100644 --- a/lisp/eshell/em-tramp.el +++ b/lisp/eshell/em-tramp.el | |||
| @@ -62,7 +62,7 @@ | |||
| 62 | "Alias \"su\" to call TRAMP. | 62 | "Alias \"su\" to call TRAMP. |
| 63 | 63 | ||
| 64 | Uses the system su through TRAMP's su method." | 64 | Uses the system su through TRAMP's su method." |
| 65 | (setq args (eshell-stringify-list (eshell-flatten-list args))) | 65 | (setq args (eshell-stringify-list (flatten-tree args))) |
| 66 | (let ((orig-args (copy-tree args))) | 66 | (let ((orig-args (copy-tree args))) |
| 67 | (eshell-eval-using-options | 67 | (eshell-eval-using-options |
| 68 | "su" args | 68 | "su" args |
| @@ -100,7 +100,7 @@ Become another USER during a login session.") | |||
| 100 | "Alias \"sudo\" to call Tramp. | 100 | "Alias \"sudo\" to call Tramp. |
| 101 | 101 | ||
| 102 | Uses the system sudo through TRAMP's sudo method." | 102 | Uses the system sudo through TRAMP's sudo method." |
| 103 | (setq args (eshell-stringify-list (eshell-flatten-list args))) | 103 | (setq args (eshell-stringify-list (flatten-tree args))) |
| 104 | (let ((orig-args (copy-tree args))) | 104 | (let ((orig-args (copy-tree args))) |
| 105 | (eshell-eval-using-options | 105 | (eshell-eval-using-options |
| 106 | "sudo" args | 106 | "sudo" args |
diff --git a/lisp/eshell/em-unix.el b/lisp/eshell/em-unix.el index 3aecebc2ebf..e46e1c417d4 100644 --- a/lisp/eshell/em-unix.el +++ b/lisp/eshell/em-unix.el | |||
| @@ -231,7 +231,7 @@ Otherwise, Emacs will attempt to use rsh to invoke du on the remote machine." | |||
| 231 | This is implemented to call either `delete-file', `kill-buffer', | 231 | This is implemented to call either `delete-file', `kill-buffer', |
| 232 | `kill-process', or `unintern', depending on the nature of the | 232 | `kill-process', or `unintern', depending on the nature of the |
| 233 | argument." | 233 | argument." |
| 234 | (setq args (eshell-flatten-list args)) | 234 | (setq args (flatten-tree args)) |
| 235 | (eshell-eval-using-options | 235 | (eshell-eval-using-options |
| 236 | "rm" args | 236 | "rm" args |
| 237 | '((?h "help" nil nil "show this usage screen") | 237 | '((?h "help" nil nil "show this usage screen") |
| @@ -481,7 +481,7 @@ Remove the DIRECTORY(ies), if they are empty.") | |||
| 481 | (error "%s: missing destination file or directory" ,command)) | 481 | (error "%s: missing destination file or directory" ,command)) |
| 482 | (if (= len 1) | 482 | (if (= len 1) |
| 483 | (nconc args '("."))) | 483 | (nconc args '("."))) |
| 484 | (setq args (eshell-stringify-list (eshell-flatten-list args))) | 484 | (setq args (eshell-stringify-list (flatten-tree args))) |
| 485 | (if (and ,(not (equal command "ln")) | 485 | (if (and ,(not (equal command "ln")) |
| 486 | (string-match eshell-tar-regexp (car (last args))) | 486 | (string-match eshell-tar-regexp (car (last args))) |
| 487 | (or (> (length args) 2) | 487 | (or (> (length args) 2) |
| @@ -606,7 +606,7 @@ with `--symbolic'. When creating hard links, each TARGET must exist.") | |||
| 606 | "Implementation of cat in Lisp. | 606 | "Implementation of cat in Lisp. |
| 607 | If in a pipeline, or the file is not a regular file, directory or | 607 | If in a pipeline, or the file is not a regular file, directory or |
| 608 | symlink, then revert to the system's definition of cat." | 608 | symlink, then revert to the system's definition of cat." |
| 609 | (setq args (eshell-stringify-list (eshell-flatten-list args))) | 609 | (setq args (eshell-stringify-list (flatten-tree args))) |
| 610 | (if (or eshell-in-pipeline-p | 610 | (if (or eshell-in-pipeline-p |
| 611 | (catch 'special | 611 | (catch 'special |
| 612 | (dolist (arg args) | 612 | (dolist (arg args) |
| @@ -670,7 +670,7 @@ Fallback to standard make when called synchronously." | |||
| 670 | (compile (concat "make " (eshell-flatten-and-stringify args)))) | 670 | (compile (concat "make " (eshell-flatten-and-stringify args)))) |
| 671 | (throw 'eshell-replace-command | 671 | (throw 'eshell-replace-command |
| 672 | (eshell-parse-command "*make" (eshell-stringify-list | 672 | (eshell-parse-command "*make" (eshell-stringify-list |
| 673 | (eshell-flatten-list args)))))) | 673 | (flatten-tree args)))))) |
| 674 | 674 | ||
| 675 | (put 'eshell/make 'eshell-no-numeric-conversions t) | 675 | (put 'eshell/make 'eshell-no-numeric-conversions t) |
| 676 | 676 | ||
| @@ -705,7 +705,7 @@ available..." | |||
| 705 | (erase-buffer) | 705 | (erase-buffer) |
| 706 | (occur-mode) | 706 | (occur-mode) |
| 707 | (let ((files (eshell-stringify-list | 707 | (let ((files (eshell-stringify-list |
| 708 | (eshell-flatten-list (cdr args)))) | 708 | (flatten-tree (cdr args)))) |
| 709 | (inhibit-redisplay t) | 709 | (inhibit-redisplay t) |
| 710 | string) | 710 | string) |
| 711 | (when (car args) | 711 | (when (car args) |
| @@ -750,11 +750,11 @@ external command." | |||
| 750 | (throw 'eshell-replace-command | 750 | (throw 'eshell-replace-command |
| 751 | (eshell-parse-command (concat "*" command) | 751 | (eshell-parse-command (concat "*" command) |
| 752 | (eshell-stringify-list | 752 | (eshell-stringify-list |
| 753 | (eshell-flatten-list args)))) | 753 | (flatten-tree args)))) |
| 754 | (let* ((args (mapconcat 'identity | 754 | (let* ((args (mapconcat 'identity |
| 755 | (mapcar 'shell-quote-argument | 755 | (mapcar 'shell-quote-argument |
| 756 | (eshell-stringify-list | 756 | (eshell-stringify-list |
| 757 | (eshell-flatten-list args))) | 757 | (flatten-tree args))) |
| 758 | " ")) | 758 | " ")) |
| 759 | (cmd (progn | 759 | (cmd (progn |
| 760 | (set-text-properties 0 (length args) | 760 | (set-text-properties 0 (length args) |
| @@ -876,7 +876,7 @@ external command." | |||
| 876 | (defun eshell/du (&rest args) | 876 | (defun eshell/du (&rest args) |
| 877 | "Implementation of \"du\" in Lisp, passing ARGS." | 877 | "Implementation of \"du\" in Lisp, passing ARGS." |
| 878 | (setq args (if args | 878 | (setq args (if args |
| 879 | (eshell-stringify-list (eshell-flatten-list args)) | 879 | (eshell-stringify-list (flatten-tree args)) |
| 880 | '("."))) | 880 | '("."))) |
| 881 | (let ((ext-du (eshell-search-path "du"))) | 881 | (let ((ext-du (eshell-search-path "du"))) |
| 882 | (if (and ext-du | 882 | (if (and ext-du |
| @@ -976,7 +976,7 @@ Show wall-clock time elapsed during execution of COMMAND.") | |||
| 976 | (eshell-parse-command (car time-args) | 976 | (eshell-parse-command (car time-args) |
| 977 | ;;; https://lists.gnu.org/r/bug-gnu-emacs/2007-08/msg00205.html | 977 | ;;; https://lists.gnu.org/r/bug-gnu-emacs/2007-08/msg00205.html |
| 978 | (eshell-stringify-list | 978 | (eshell-stringify-list |
| 979 | (eshell-flatten-list (cdr time-args)))))))) | 979 | (flatten-tree (cdr time-args)))))))) |
| 980 | 980 | ||
| 981 | (defun eshell/whoami (&rest _args) | 981 | (defun eshell/whoami (&rest _args) |
| 982 | "Make \"whoami\" Tramp aware." | 982 | "Make \"whoami\" Tramp aware." |
| @@ -1000,7 +1000,7 @@ Show wall-clock time elapsed during execution of COMMAND.") | |||
| 1000 | 1000 | ||
| 1001 | (defun eshell/diff (&rest args) | 1001 | (defun eshell/diff (&rest args) |
| 1002 | "Alias \"diff\" to call Emacs `diff' function." | 1002 | "Alias \"diff\" to call Emacs `diff' function." |
| 1003 | (let ((orig-args (eshell-stringify-list (eshell-flatten-list args)))) | 1003 | (let ((orig-args (eshell-stringify-list (flatten-tree args)))) |
| 1004 | (if (or eshell-plain-diff-behavior | 1004 | (if (or eshell-plain-diff-behavior |
| 1005 | (not (and (eshell-interactive-output-p) | 1005 | (not (and (eshell-interactive-output-p) |
| 1006 | (not eshell-in-pipeline-p) | 1006 | (not eshell-in-pipeline-p) |
| @@ -1056,7 +1056,7 @@ Show wall-clock time elapsed during execution of COMMAND.") | |||
| 1056 | (string-match "^-" (car args)))) | 1056 | (string-match "^-" (car args)))) |
| 1057 | (throw 'eshell-replace-command | 1057 | (throw 'eshell-replace-command |
| 1058 | (eshell-parse-command "*locate" (eshell-stringify-list | 1058 | (eshell-parse-command "*locate" (eshell-stringify-list |
| 1059 | (eshell-flatten-list args)))) | 1059 | (flatten-tree args)))) |
| 1060 | (save-selected-window | 1060 | (save-selected-window |
| 1061 | (let ((locate-history-list (list (car args)))) | 1061 | (let ((locate-history-list (list (car args)))) |
| 1062 | (locate-with-filter (car args) (cadr args)))))) | 1062 | (locate-with-filter (car args) (cadr args)))))) |
diff --git a/lisp/eshell/em-xtra.el b/lisp/eshell/em-xtra.el index cc84d198544..eb9847c60c3 100644 --- a/lisp/eshell/em-xtra.el +++ b/lisp/eshell/em-xtra.el | |||
| @@ -51,7 +51,7 @@ naturally accessible within Emacs." | |||
| 51 | "Implementation of expr, using the calc package." | 51 | "Implementation of expr, using the calc package." |
| 52 | (if (not (fboundp 'calc-eval)) | 52 | (if (not (fboundp 'calc-eval)) |
| 53 | (throw 'eshell-replace-command | 53 | (throw 'eshell-replace-command |
| 54 | (eshell-parse-command "*expr" (eshell-flatten-list args))) | 54 | (eshell-parse-command "*expr" (flatten-tree args))) |
| 55 | ;; to fool the byte-compiler... | 55 | ;; to fool the byte-compiler... |
| 56 | (let ((func 'calc-eval)) | 56 | (let ((func 'calc-eval)) |
| 57 | (funcall func (eshell-flatten-and-stringify args))))) | 57 | (funcall func (eshell-flatten-and-stringify args))))) |
diff --git a/lisp/eshell/esh-ext.el b/lisp/eshell/esh-ext.el index 244cc7ff1f3..9e7d8bb608e 100644 --- a/lisp/eshell/esh-ext.el +++ b/lisp/eshell/esh-ext.el | |||
| @@ -222,7 +222,7 @@ causing the user to wonder if anything's really going on..." | |||
| 222 | 222 | ||
| 223 | (defun eshell-external-command (command args) | 223 | (defun eshell-external-command (command args) |
| 224 | "Insert output from an external COMMAND, using ARGS." | 224 | "Insert output from an external COMMAND, using ARGS." |
| 225 | (setq args (eshell-stringify-list (eshell-flatten-list args))) | 225 | (setq args (eshell-stringify-list (flatten-tree args))) |
| 226 | (let ((interp (eshell-find-interpreter | 226 | (let ((interp (eshell-find-interpreter |
| 227 | command | 227 | command |
| 228 | args | 228 | args |
diff --git a/lisp/eshell/esh-opt.el b/lisp/eshell/esh-opt.el index d7a449450f9..69d10b4ccfc 100644 --- a/lisp/eshell/esh-opt.el +++ b/lisp/eshell/esh-opt.el | |||
| @@ -77,7 +77,7 @@ arguments, some do not. The recognized :KEYWORDS are: | |||
| 77 | arguments. | 77 | arguments. |
| 78 | 78 | ||
| 79 | :preserve-args | 79 | :preserve-args |
| 80 | If present, do not pass MACRO-ARGS through `eshell-flatten-list' | 80 | If present, do not pass MACRO-ARGS through `flatten-tree' |
| 81 | and `eshell-stringify-list'. | 81 | and `eshell-stringify-list'. |
| 82 | 82 | ||
| 83 | :parse-leading-options-only | 83 | :parse-leading-options-only |
| @@ -106,7 +106,7 @@ let-bound variable `args'." | |||
| 106 | ,(if (memq ':preserve-args (cadr options)) | 106 | ,(if (memq ':preserve-args (cadr options)) |
| 107 | macro-args | 107 | macro-args |
| 108 | (list 'eshell-stringify-list | 108 | (list 'eshell-stringify-list |
| 109 | (list 'eshell-flatten-list macro-args)))) | 109 | (list 'flatten-tree macro-args)))) |
| 110 | (processed-args (eshell--do-opts ,name ,options temp-args)) | 110 | (processed-args (eshell--do-opts ,name ,options temp-args)) |
| 111 | ,@(delete-dups | 111 | ,@(delete-dups |
| 112 | (delq nil (mapcar (lambda (opt) | 112 | (delq nil (mapcar (lambda (opt) |
diff --git a/lisp/eshell/esh-util.el b/lisp/eshell/esh-util.el index 8fe8c461fdb..b55f8733802 100644 --- a/lisp/eshell/esh-util.el +++ b/lisp/eshell/esh-util.el | |||
| @@ -285,15 +285,7 @@ Prepend remote identification of `default-directory', if any." | |||
| 285 | ,@forms) | 285 | ,@forms) |
| 286 | (setq list-iter (cdr list-iter))))) | 286 | (setq list-iter (cdr list-iter))))) |
| 287 | 287 | ||
| 288 | (defun eshell-flatten-list (args) | 288 | (define-obsolete-function-alias 'eshell-flatten-list #'flatten-tree "27.1") |
| 289 | "Flatten any lists within ARGS, so that there are no sublists." | ||
| 290 | (let ((new-list (list t))) | ||
| 291 | (dolist (a args) | ||
| 292 | (if (and (listp a) | ||
| 293 | (listp (cdr a))) | ||
| 294 | (nconc new-list (eshell-flatten-list a)) | ||
| 295 | (nconc new-list (list a)))) | ||
| 296 | (cdr new-list))) | ||
| 297 | 289 | ||
| 298 | (defun eshell-uniquify-list (l) | 290 | (defun eshell-uniquify-list (l) |
| 299 | "Remove occurring multiples in L. You probably want to sort first." | 291 | "Remove occurring multiples in L. You probably want to sort first." |
| @@ -330,7 +322,7 @@ Prepend remote identification of `default-directory', if any." | |||
| 330 | 322 | ||
| 331 | (defsubst eshell-flatten-and-stringify (&rest args) | 323 | (defsubst eshell-flatten-and-stringify (&rest args) |
| 332 | "Flatten and stringify all of the ARGS into a single string." | 324 | "Flatten and stringify all of the ARGS into a single string." |
| 333 | (mapconcat 'eshell-stringify (eshell-flatten-list args) " ")) | 325 | (mapconcat 'eshell-stringify (flatten-tree args) " ")) |
| 334 | 326 | ||
| 335 | (defsubst eshell-directory-files (regexp &optional directory) | 327 | (defsubst eshell-directory-files (regexp &optional directory) |
| 336 | "Return a list of files in the given DIRECTORY matching REGEXP." | 328 | "Return a list of files in the given DIRECTORY matching REGEXP." |
diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el index 4baf4bc8263..3f5362ba17a 100644 --- a/lisp/gnus/gnus-sum.el +++ b/lisp/gnus/gnus-sum.el | |||
| @@ -4773,7 +4773,7 @@ If LINE, insert the rebuilt thread starting on line LINE." | |||
| 4773 | (let (headers thread last-id) | 4773 | (let (headers thread last-id) |
| 4774 | ;; First go up in this thread until we find the root. | 4774 | ;; First go up in this thread until we find the root. |
| 4775 | (setq last-id (gnus-root-id id) | 4775 | (setq last-id (gnus-root-id id) |
| 4776 | headers (message-flatten-list (gnus-id-to-thread last-id))) | 4776 | headers (flatten-tree (gnus-id-to-thread last-id))) |
| 4777 | ;; We have now found the real root of this thread. It might have | 4777 | ;; We have now found the real root of this thread. It might have |
| 4778 | ;; been gathered into some loose thread, so we have to search | 4778 | ;; been gathered into some loose thread, so we have to search |
| 4779 | ;; through the threads to find the thread we wanted. | 4779 | ;; through the threads to find the thread we wanted. |
| @@ -5069,7 +5069,7 @@ Unscored articles will be counted as having a score of zero." | |||
| 5069 | "Return the highest article number in THREAD." | 5069 | "Return the highest article number in THREAD." |
| 5070 | (apply 'max (mapcar (lambda (header) | 5070 | (apply 'max (mapcar (lambda (header) |
| 5071 | (mail-header-number header)) | 5071 | (mail-header-number header)) |
| 5072 | (message-flatten-list thread)))) | 5072 | (flatten-tree thread)))) |
| 5073 | 5073 | ||
| 5074 | (defun gnus-article-sort-by-most-recent-date (h1 h2) | 5074 | (defun gnus-article-sort-by-most-recent-date (h1 h2) |
| 5075 | "Sort articles by number." | 5075 | "Sort articles by number." |
| @@ -5087,9 +5087,9 @@ Unscored articles will be counted as having a score of zero." | |||
| 5087 | "Return the highest article date in THREAD." | 5087 | "Return the highest article date in THREAD." |
| 5088 | (apply 'max | 5088 | (apply 'max |
| 5089 | (mapcar (lambda (header) (float-time | 5089 | (mapcar (lambda (header) (float-time |
| 5090 | (gnus-date-get-time | 5090 | (gnus-date-get-time |
| 5091 | (mail-header-date header)))) | 5091 | (mail-header-date header)))) |
| 5092 | (message-flatten-list thread)))) | 5092 | (flatten-tree thread)))) |
| 5093 | 5093 | ||
| 5094 | (defun gnus-thread-total-score-1 (root) | 5094 | (defun gnus-thread-total-score-1 (root) |
| 5095 | ;; This function find the total score of the thread below ROOT. | 5095 | ;; This function find the total score of the thread below ROOT. |
diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el index fdaa4e82727..03f80616d9e 100644 --- a/lisp/gnus/message.el +++ b/lisp/gnus/message.el | |||
| @@ -8051,7 +8051,7 @@ regular text mode tabbing command." | |||
| 8051 | If SHOW is non-nil, the arguments TEXT... are displayed in a temp buffer. | 8051 | If SHOW is non-nil, the arguments TEXT... are displayed in a temp buffer. |
| 8052 | The following arguments may contain lists of values." | 8052 | The following arguments may contain lists of values." |
| 8053 | (if (and show | 8053 | (if (and show |
| 8054 | (setq text (message-flatten-list text))) | 8054 | (setq text (flatten-tree text))) |
| 8055 | (save-window-excursion | 8055 | (save-window-excursion |
| 8056 | (with-output-to-temp-buffer " *MESSAGE information message*" | 8056 | (with-output-to-temp-buffer " *MESSAGE information message*" |
| 8057 | (with-current-buffer " *MESSAGE information message*" | 8057 | (with-current-buffer " *MESSAGE information message*" |
| @@ -8061,15 +8061,7 @@ The following arguments may contain lists of values." | |||
| 8061 | (funcall ask question)) | 8061 | (funcall ask question)) |
| 8062 | (funcall ask question))) | 8062 | (funcall ask question))) |
| 8063 | 8063 | ||
| 8064 | (defun message-flatten-list (list) | 8064 | (define-obsolete-function-alias 'message-flatten-list #'flatten-tree "27.1") |
| 8065 | "Return a new, flat list that contains all elements of LIST. | ||
| 8066 | |||
| 8067 | \(message-flatten-list \\='(1 (2 3 (4 5 (6))) 7)) | ||
| 8068 | => (1 2 3 4 5 6 7)" | ||
| 8069 | (cond ((consp list) | ||
| 8070 | (apply 'append (mapcar 'message-flatten-list list))) | ||
| 8071 | (list | ||
| 8072 | (list list)))) | ||
| 8073 | 8065 | ||
| 8074 | (defun message-generate-new-buffer-clone-locals (name &optional varstr) | 8066 | (defun message-generate-new-buffer-clone-locals (name &optional varstr) |
| 8075 | "Create and return a buffer with name based on NAME using `generate-new-buffer'. | 8067 | "Create and return a buffer with name based on NAME using `generate-new-buffer'. |
diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el index 1a3b05ddb37..adbce25530d 100644 --- a/lisp/gnus/nnimap.el +++ b/lisp/gnus/nnimap.el | |||
| @@ -804,7 +804,7 @@ textual parts.") | |||
| 804 | (insert "\n--" boundary "--\n"))) | 804 | (insert "\n--" boundary "--\n"))) |
| 805 | 805 | ||
| 806 | (defun nnimap-find-wanted-parts (structure) | 806 | (defun nnimap-find-wanted-parts (structure) |
| 807 | (message-flatten-list (nnimap-find-wanted-parts-1 structure ""))) | 807 | (flatten-tree (nnimap-find-wanted-parts-1 structure ""))) |
| 808 | 808 | ||
| 809 | (defun nnimap-find-wanted-parts-1 (structure prefix) | 809 | (defun nnimap-find-wanted-parts-1 (structure prefix) |
| 810 | (let ((num 1) | 810 | (let ((num 1) |
diff --git a/lisp/lpr.el b/lisp/lpr.el index 33b8da8d760..969b57d6444 100644 --- a/lisp/lpr.el +++ b/lisp/lpr.el | |||
| @@ -258,7 +258,7 @@ for further customization of the printer command." | |||
| 258 | 258 | ||
| 259 | (defun lpr-print-region (start end switches name) | 259 | (defun lpr-print-region (start end switches name) |
| 260 | (let ((buf (current-buffer)) | 260 | (let ((buf (current-buffer)) |
| 261 | (nswitches (lpr-flatten-list | 261 | (nswitches (flatten-tree |
| 262 | (mapcar #'lpr-eval-switch ; Dynamic evaluation | 262 | (mapcar #'lpr-eval-switch ; Dynamic evaluation |
| 263 | switches))) | 263 | switches))) |
| 264 | (switch-string (if switches | 264 | (switch-string (if switches |
| @@ -336,23 +336,7 @@ The characters tab, linefeed, space, return and formfeed are not affected." | |||
| 336 | ((consp arg) (apply (car arg) (cdr arg))) | 336 | ((consp arg) (apply (car arg) (cdr arg))) |
| 337 | (t nil))) | 337 | (t nil))) |
| 338 | 338 | ||
| 339 | ;; `lpr-flatten-list' is defined here (copied from "message.el" and | 339 | (define-obsolete-function-alias 'lpr-flatten-list #'flatten-tree "27.1") |
| 340 | ;; enhanced to handle dotted pairs as well) until we can get some | ||
| 341 | ;; sensible autoloads, or `flatten-list' gets put somewhere decent. | ||
| 342 | |||
| 343 | ;; (lpr-flatten-list '((a . b) c (d . e) (f g h) i . j)) | ||
| 344 | ;; => (a b c d e f g h i j) | ||
| 345 | |||
| 346 | (defun lpr-flatten-list (&rest list) | ||
| 347 | (lpr-flatten-list-1 list)) | ||
| 348 | |||
| 349 | (defun lpr-flatten-list-1 (list) | ||
| 350 | (cond | ||
| 351 | ((null list) nil) | ||
| 352 | ((consp list) | ||
| 353 | (append (lpr-flatten-list-1 (car list)) | ||
| 354 | (lpr-flatten-list-1 (cdr list)))) | ||
| 355 | (t (list list)))) | ||
| 356 | 340 | ||
| 357 | (provide 'lpr) | 341 | (provide 'lpr) |
| 358 | 342 | ||
diff --git a/lisp/printing.el b/lisp/printing.el index 2fc2323028f..c1a73df14c1 100644 --- a/lisp/printing.el +++ b/lisp/printing.el | |||
| @@ -5672,7 +5672,7 @@ If menu binding was not done, calls `pr-menu-bind'." | |||
| 5672 | (defun pr-switches (switches mess) | 5672 | (defun pr-switches (switches mess) |
| 5673 | (or (listp switches) | 5673 | (or (listp switches) |
| 5674 | (error "%S should have a list of strings" mess)) | 5674 | (error "%S should have a list of strings" mess)) |
| 5675 | (lpr-flatten-list ; dynamic evaluation | 5675 | (flatten-tree ; dynamic evaluation |
| 5676 | (mapcar #'lpr-eval-switch switches))) | 5676 | (mapcar #'lpr-eval-switch switches))) |
| 5677 | 5677 | ||
| 5678 | 5678 | ||
diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index cec48a82a20..ddba7636b4a 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el | |||
| @@ -623,11 +623,7 @@ then the \".\"s will be lined up: | |||
| 623 | "Parse state at `js--last-parse-pos'.") | 623 | "Parse state at `js--last-parse-pos'.") |
| 624 | (make-variable-buffer-local 'js--state-at-last-parse-pos) | 624 | (make-variable-buffer-local 'js--state-at-last-parse-pos) |
| 625 | 625 | ||
| 626 | (defun js--flatten-list (list) | 626 | (define-obsolete-function-alias 'js--flatten-list #'flatten-tree "27.1") |
| 627 | (cl-loop for item in list | ||
| 628 | nconc (cond ((consp item) | ||
| 629 | (js--flatten-list item)) | ||
| 630 | (item (list item))))) | ||
| 631 | 627 | ||
| 632 | (defun js--maybe-join (prefix separator suffix &rest list) | 628 | (defun js--maybe-join (prefix separator suffix &rest list) |
| 633 | "Helper function for `js--update-quick-match-re'. | 629 | "Helper function for `js--update-quick-match-re'. |
| @@ -636,7 +632,7 @@ elements, separated by SEPARATOR, prefixed by PREFIX, and ended | |||
| 636 | with SUFFIX as with `concat'. Otherwise, if LIST is empty, return | 632 | with SUFFIX as with `concat'. Otherwise, if LIST is empty, return |
| 637 | nil. If any element in LIST is itself a list, flatten that | 633 | nil. If any element in LIST is itself a list, flatten that |
| 638 | element." | 634 | element." |
| 639 | (setq list (js--flatten-list list)) | 635 | (setq list (flatten-tree list)) |
| 640 | (when list | 636 | (when list |
| 641 | (concat prefix (mapconcat #'identity list separator) suffix))) | 637 | (concat prefix (mapconcat #'identity list separator) suffix))) |
| 642 | 638 | ||
diff --git a/lisp/subr.el b/lisp/subr.el index d3bc007293b..7a7c175db4a 100644 --- a/lisp/subr.el +++ b/lisp/subr.el | |||
| @@ -5448,5 +5448,30 @@ This function is called from lisp/Makefile and leim/Makefile." | |||
| 5448 | (setq file (concat (substring file 1 2) ":" (substring file 2)))) | 5448 | (setq file (concat (substring file 1 2) ":" (substring file 2)))) |
| 5449 | file) | 5449 | file) |
| 5450 | 5450 | ||
| 5451 | (defun flatten-tree (tree) | ||
| 5452 | "Take TREE and \"flatten\" it. | ||
| 5453 | This always returns a list containing all the terminal nodes, or | ||
| 5454 | \"leaves\", of TREE. Dotted pairs are flattened as well, and nil | ||
| 5455 | elements are removed. | ||
| 5456 | |||
| 5457 | \(flatten-tree \\='(1 (2 . 3) nil (4 5 (6)) 7)) | ||
| 5458 | => (1 2 3 4 5 6 7) | ||
| 5459 | |||
| 5460 | TREE can be anything that can be made into a list. For each | ||
| 5461 | element in TREE, if it is a cons cell return its car | ||
| 5462 | recursively. Otherwise return the element." | ||
| 5463 | (let (elems) | ||
| 5464 | (setq tree (list tree)) | ||
| 5465 | (while (let ((elem (pop tree))) | ||
| 5466 | (cond ((consp elem) | ||
| 5467 | (setq tree (cons (car elem) (cons (cdr elem) tree)))) | ||
| 5468 | (elem | ||
| 5469 | (push elem elems))) | ||
| 5470 | tree)) | ||
| 5471 | (nreverse elems))) | ||
| 5472 | |||
| 5473 | ;; Technically, `flatten-list' is a misnomer, but we provide it here | ||
| 5474 | ;; for discoverability: | ||
| 5475 | (defalias 'flatten-list 'flatten-tree) | ||
| 5451 | 5476 | ||
| 5452 | ;;; subr.el ends here | 5477 | ;;; subr.el ends here |
diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el index f218a7663e0..08f9a697a3c 100644 --- a/test/lisp/subr-tests.el +++ b/test/lisp/subr-tests.el | |||
| @@ -372,5 +372,22 @@ See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=19350." | |||
| 372 | (shell-quote-argument "%ca%"))) | 372 | (shell-quote-argument "%ca%"))) |
| 373 | "without-caret %ca%")))) | 373 | "without-caret %ca%")))) |
| 374 | 374 | ||
| 375 | (ert-deftest subr-tests-flatten-tree () | ||
| 376 | "Test `flatten-tree' behavior." | ||
| 377 | (should (equal (flatten-tree '(1 (2 . 3) nil (4 5 (6)) 7)) | ||
| 378 | '(1 2 3 4 5 6 7))) | ||
| 379 | (should (equal (flatten-tree '((1 . 2))) | ||
| 380 | '(1 2))) | ||
| 381 | (should (equal (flatten-tree '(1 nil 2)) | ||
| 382 | '(1 2))) | ||
| 383 | (should (equal (flatten-tree 42) | ||
| 384 | '(42))) | ||
| 385 | (should (equal (flatten-tree t) | ||
| 386 | '(t))) | ||
| 387 | (should (equal (flatten-tree nil) | ||
| 388 | nil)) | ||
| 389 | (should (equal (flatten-tree '(1 ("foo" "bar") 2)) | ||
| 390 | '(1 "foo" "bar" 2)))) | ||
| 391 | |||
| 375 | (provide 'subr-tests) | 392 | (provide 'subr-tests) |
| 376 | ;;; subr-tests.el ends here | 393 | ;;; subr-tests.el ends here |