]> git.eshelyaron.com Git - emacs.git/commitdiff
Allow 'pp' to limit the line widths
authorLars Ingebrigtsen <larsi@gnus.org>
Fri, 5 Nov 2021 14:27:03 +0000 (15:27 +0100)
committerLars Ingebrigtsen <larsi@gnus.org>
Fri, 5 Nov 2021 14:27:08 +0000 (15:27 +0100)
* lisp/emacs-lisp/pp.el (pp-max-width, pp-use-max-width): New user
options (bug#11934).
(pp-to-string): Use it.
(pp--insert-lisp): Tweak whether to use standard-output or not.
(pp--max-width): New function.

etc/NEWS
lisp/emacs-lisp/pp.el
test/lisp/emacs-lisp/pp-resources/code-formats.erts

index 08ff1f1e697ab1492e4762489b6db73191cb493c..9b4112a8f2b1c5a3c9343aa91310aef4391a33bb 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -422,6 +422,11 @@ Use 'exif-parse-file' and 'exif-field' instead.
 \f
 * Lisp Changes in Emacs 29.1
 
+---
+*** New user option 'pp-use-max-width'.
+If non-nil, 'pp' will attempt to limit the line length when formatting
+long lists and vectors.
+
 ---
 *** New function 'pp-emacs-lisp-code'.
 'pp' formats general Lisp sexps.  This function does much the same,
index ffaa2aeb93a58bb1c021fe55a3a6c0aaf5065222..8ef5979a27072a2860d1310157f5eaf229794981 100644 (file)
 
 (defcustom pp-escape-newlines t
   "Value of `print-escape-newlines' used by pp-* functions."
+  :type 'boolean)
+
+(defcustom pp-max-width t
+  "Max width to use when formatting.
+If nil, there's no max width.  If t, use the window width.
+Otherwise this should be a number."
+  :type '(choice (const :tag "none" nil)
+                 (const :tag "window width" t)
+                 number)
+  :version "29.1")
+
+(defcustom pp-use-max-width nil
+  "If non-nil, `pp'-related functions will try to fold lines.
+The target width is given by the `pp-max-width' variable."
   :type 'boolean
-  :group 'pp)
+  :version "29.1")
+
+(defvar pp--inhibit-function-formatting nil)
 
 ;;;###autoload
 (defun pp-to-string (object)
   "Return a string containing the pretty-printed representation of OBJECT.
 OBJECT can be any Lisp object.  Quoting characters are used as needed
 to make output that `read' can handle, whenever this is possible."
-  (with-temp-buffer
-    (lisp-mode-variables nil)
-    (set-syntax-table emacs-lisp-mode-syntax-table)
-    (let ((print-escape-newlines pp-escape-newlines)
-          (print-quoted t))
-      (prin1 object (current-buffer)))
-    (pp-buffer)
-    (buffer-string)))
+  (if pp-use-max-width
+      (let ((pp--inhibit-function-formatting t))
+        (with-temp-buffer
+          (pp-emacs-lisp-code object)
+          (buffer-string)))
+    (with-temp-buffer
+      (lisp-mode-variables nil)
+      (set-syntax-table emacs-lisp-mode-syntax-table)
+      (let ((print-escape-newlines pp-escape-newlines)
+            (print-quoted t))
+        (prin1 object (current-buffer)))
+      (pp-buffer)
+      (buffer-string))))
 
 ;;;###autoload
 (defun pp-buffer ()
@@ -56,7 +77,6 @@ to make output that `read' can handle, whenever this is possible."
   (interactive)
   (goto-char (point-min))
   (while (not (eobp))
-    ;; (message "%06d" (- (point-max) (point)))
     (cond
      ((ignore-errors (down-list 1) t)
       (save-excursion
@@ -86,6 +106,9 @@ can handle, whenever this is possible.
 This function does not apply special formatting rules for Emacs
 Lisp code.  See `pp-emacs-lisp-code' instead.
 
+By default, this function won't limit the line length of lists
+and vectors.  Bind `pp-use-max-width' to a non-nil value to do so.
+
 Output stream is STREAM, or value of `standard-output' (which see)."
   (princ (pp-to-string object) (or stream standard-output)))
 
@@ -191,17 +214,19 @@ Ignores leading comment characters."
 
 ;;;###autoload
 (defun pp-emacs-lisp-code (sexp)
-  "Insert SEXP into the current buffer, formatted as Emacs Lisp code."
+  "Insert SEXP into the current buffer, formatted as Emacs Lisp code.
+Use the `pp-max-width' variable to control the desired line length."
   (require 'edebug)
-  (let ((standard-output (current-buffer)))
-    (save-restriction
-      (narrow-to-region (point) (point))
+  (let ((obuf (current-buffer)))
+    (with-temp-buffer
+      (emacs-lisp-mode)
       (pp--insert-lisp sexp)
       (insert "\n")
       (goto-char (point-min))
       (indent-sexp)
       (while (re-search-forward " +$" nil t)
-        (replace-match "")))))
+        (replace-match ""))
+      (insert-into-buffer obuf))))
 
 (defun pp--insert-lisp (sexp)
   (cl-case (type-of sexp)
@@ -213,30 +238,35 @@ Ignores leading comment characters."
                 (cond
                  ((symbolp (cadr sexp))
                   (let ((print-quoted t))
-                    (prin1 sexp)))
+                    (prin1 sexp (current-buffer))))
                  ((consp (cadr sexp))
                   (insert "'")
                   (pp--format-list (cadr sexp)
                                    (set-marker (make-marker) (1- (point))))))
               (pp--format-list sexp)))
            (t
-            (princ sexp))))
+            (princ sexp (current-buffer)))))
     ;; Print some of the smaller integers as characters, perhaps?
     (integer
      (if (<= ?0 sexp ?z)
          (let ((print-integers-as-characters t))
-           (princ sexp))
-       (princ sexp)))
+           (princ sexp (current-buffer)))
+       (princ sexp (current-buffer))))
     (string
      (let ((print-escape-newlines t))
-       (prin1 sexp)))
-    (otherwise (princ sexp))))
+       (prin1 sexp (current-buffer))))
+    (otherwise (princ sexp (current-buffer)))))
 
 (defun pp--format-vector (sexp)
-  (prin1 sexp))
+  (insert "[")
+  (cl-loop for i from 0
+           for element across sexp
+           do (pp--insert (and (> i 0) " ") element))
+  (insert "]"))
 
 (defun pp--format-list (sexp &optional start)
   (if (and (symbolp (car sexp))
+           (not pp--inhibit-function-formatting)
            (not (keywordp (car sexp))))
       (pp--format-function sexp)
     (insert "(")
@@ -292,7 +322,7 @@ Ignores leading comment characters."
     (cl-decf indent))
   (when (stringp (car sexp))
     (insert "\n")
-    (prin1 (pop sexp)))
+    (prin1 (pop sexp) (current-buffer)))
   ;; Then insert the rest with line breaks before each form.
   (while sexp
     (insert "\n")
@@ -329,7 +359,7 @@ Ignores leading comment characters."
       (pp--insert-lisp thing))
     ;; We need to indent what we have so far to see if we have to fold.
     (pp--indent-buffer)
-    (when (> (current-column) (window-width))
+    (when (> (current-column) (pp--max-width))
       (save-excursion
         (goto-char start)
         (unless (looking-at "[ \t]+$")
@@ -338,13 +368,23 @@ Ignores leading comment characters."
         (goto-char (point-max))
         ;; If we're still too wide, then go up one step and try to
         ;; insert a newline there.
-        (when (> (current-column) (window-width))
+        (when (> (current-column) (pp--max-width))
           (condition-case ()
               (backward-up-list 1)
             (:success (when (looking-back " " 2)
                         (insert "\n")))
             (error nil)))))))
 
+(defun pp--max-width ()
+  (cond ((numberp pp-max-width)
+         pp-max-width)
+        ((null pp-max-width)
+         most-positive-fixnum)
+        ((eq pp-max-width t)
+         (window-width))
+        (t
+         (error "Invalid pp-max-width value: %s" pp-max-width))))
+
 (defun pp--indent-buffer ()
   (goto-char (point-min))
   (while (not (eobp))
index c2733d84daec4723cc760f6670e5769f3634b1ec..2b2001d09640e8141fa13b78c39f8758ea26ef16 100644 (file)
@@ -114,3 +114,11 @@ Name: code-formats10
                      "+"
                      (string-replace " " "+" query)))
 =-=-=
+
+
+Name: code-formats11
+
+=-=
+(lambda ()
+  [(foo bar) (foo bar)])
+=-=-=