Mercurial > hg > xemacs-beta
comparison lisp/utils/pp.el @ 0:376386a54a3c r19-14
Import from CVS: tag r19-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:45:50 +0200 |
parents | |
children | ac2d302a0011 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:376386a54a3c |
---|---|
1 ;;; pp.el --- pretty printer for Emacs Lisp | |
2 | |
3 ;; Keywords: lisp, tools, language, extensions | |
4 | |
5 ;; Copyright (C) 1989, 1993 Free Software Foundation, Inc. | |
6 | |
7 ;; Author: Randal Schwartz <merlyn@ora.com> | |
8 | |
9 ;; This file is part of XEmacs. | |
10 | |
11 ;; XEmacs is free software; you can redistribute it and/or modify it | |
12 ;; under the terms of the GNU General Public License as published by | |
13 ;; the Free Software Foundation; either version 2, or (at your option) | |
14 ;; any later version. | |
15 | |
16 ;; XEmacs is distributed in the hope that it will be useful, but | |
17 ;; WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
19 ;; General Public License for more details. | |
20 | |
21 ;; You should have received a copy of the GNU General Public License | |
22 ;; along with XEmacs; see the file COPYING. If not, write to the Free | |
23 ;; Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | |
24 | |
25 ;;; Synched up with: FSF 19.28. | |
26 | |
27 ;;; Code: | |
28 | |
29 (defvar pp-escape-newlines t | |
30 "*Value of `print-escape-newlines' used by pp-* functions.") | |
31 (defvar pp-print-readably t | |
32 "*Value of `print-readably' used by pp-* functions.") | |
33 | |
34 ;;;###autoload | |
35 (defun pp (object &optional stream) | |
36 "Output the pretty-printed representation of OBJECT, any Lisp object. | |
37 Quoting characters are printed when needed to make output that `read' | |
38 can handle, whenever this is possible. | |
39 Output stream is STREAM, or value of `standard-output' (which see)." | |
40 (princ (pp-to-string object) (or stream standard-output))) | |
41 | |
42 ;;;###autoload | |
43 (defalias 'pprint 'pp) | |
44 | |
45 (defun pp-to-string (object) | |
46 "Return a string containing the pretty-printed representation of OBJECT, | |
47 any Lisp object. Quoting characters are used when needed to make output | |
48 that `read' can handle, whenever this is possible." | |
49 (save-excursion | |
50 (set-buffer (generate-new-buffer " pp-to-string")) | |
51 (unwind-protect | |
52 (progn | |
53 (emacs-lisp-mode) | |
54 (let ((print-escape-newlines pp-escape-newlines) | |
55 (print-readably pp-print-readably)) | |
56 (prin1 object (current-buffer))) | |
57 (goto-char (point-min)) | |
58 (while (not (eobp)) | |
59 ;; (message "%06d" (- (point-max) (point))) | |
60 (cond | |
61 ((looking-at "\\s\(") | |
62 (while (looking-at "\\s(") | |
63 (forward-char 1))) | |
64 ((and (looking-at "\\(quote[ \t]+\\)\\([^.)]\\)") | |
65 (> (match-beginning 1) 1) | |
66 (= ?\( (char-after (1- (match-beginning 1)))) | |
67 ;; Make sure this is a two-element list. | |
68 (save-excursion | |
69 (goto-char (match-beginning 2)) | |
70 (forward-sexp) | |
71 ;; (looking-at "[ \t]*\)") | |
72 ;; Avoid mucking with match-data; does this test work? | |
73 (char-equal ?\) (char-after (point))))) | |
74 ;; -1 gets the paren preceding the quote as well. | |
75 (delete-region (1- (match-beginning 1)) (match-end 1)) | |
76 (insert "'") | |
77 (forward-sexp 1) | |
78 (if (looking-at "[ \t]*\)") | |
79 (delete-region (match-beginning 0) (match-end 0)) | |
80 (error "Malformed quote")) | |
81 (backward-sexp 1)) | |
82 ((condition-case err-var | |
83 (prog1 t (down-list 1)) | |
84 (error nil)) | |
85 (backward-char 1) | |
86 (skip-chars-backward " \t") | |
87 (delete-region | |
88 (point) | |
89 (progn (skip-chars-forward " \t") (point))) | |
90 (if (not (char-equal ?' (char-after (1- (point))))) | |
91 (insert ?\n))) | |
92 ((condition-case err-var | |
93 (prog1 t (up-list 1)) | |
94 (error nil)) | |
95 (while (looking-at "\\s)") | |
96 (forward-char 1)) | |
97 (skip-chars-backward " \t") | |
98 (delete-region | |
99 (point) | |
100 (progn (skip-chars-forward " \t") (point))) | |
101 (if (not (char-equal ?' (char-after (1- (point))))) | |
102 (insert ?\n))) | |
103 (t (goto-char (point-max))))) | |
104 (goto-char (point-min)) | |
105 (indent-sexp) | |
106 (buffer-string)) | |
107 (kill-buffer (current-buffer))))) | |
108 | |
109 (defun pp-eval-expression (expression) | |
110 "Evaluate EXPRESSION and pretty-print value into a new display buffer. | |
111 If the pretty-printed value fits on one line, the message line is used | |
112 instead. Value is also consed on to front of variable values 's | |
113 value." | |
114 (interactive "xPp-eval: ") | |
115 (setq values (cons (eval expression) values)) | |
116 (let* ((old-show-hook | |
117 (or (let ((sym (if (> (string-to-int emacs-version) 18) | |
118 'temp-buffer-show-function | |
119 'temp-buffer-show-hook))) | |
120 (and (boundp 'sym) (symbol-value sym))) | |
121 'display-buffer)) | |
122 (temp-buffer-show-hook | |
123 (function | |
124 (lambda (buf) | |
125 (save-excursion | |
126 (set-buffer buf) | |
127 (goto-char (point-min)) | |
128 (end-of-line 1) | |
129 (if (or (< (1+ (point)) (point-max)) | |
130 (>= (- (point) (point-min)) (screen-width))) | |
131 (progn | |
132 (goto-char (point-min)) ; expected by some hooks ... | |
133 (funcall old-show-hook buf)) | |
134 (message "%s" (buffer-substring (point-min) (point))) | |
135 (delete-windows-on buf) ; no need to kill it | |
136 ))))) | |
137 (temp-buffer-show-function temp-buffer-show-hook)) ; emacs19 name | |
138 (with-output-to-temp-buffer "*Pp Eval Output*" | |
139 (pp (car values))) | |
140 (save-excursion | |
141 (set-buffer "*Pp Eval Output*") | |
142 (emacs-lisp-mode)))) | |
143 | |
144 (defun pp-eval-last-sexp (arg) | |
145 "Run `pp-eval-expression' on sexp before point (which see). | |
146 With argument, pretty-print output into current buffer. | |
147 Ignores leading comment characters." | |
148 (interactive "P") | |
149 (let ((stab (syntax-table)) (pt (point)) start exp) | |
150 (set-syntax-table emacs-lisp-mode-syntax-table) | |
151 (save-excursion | |
152 (forward-sexp -1) | |
153 ;; If first line is commented, ignore all leading comments: | |
154 (if (save-excursion (beginning-of-line) (looking-at "[ \t]*;")) | |
155 (progn | |
156 (setq exp (buffer-substring (point) pt)) | |
157 (while (string-match "\n[ \t]*;+" exp start) | |
158 (setq start (1+ (match-beginning 0)) | |
159 exp (concat (substring exp 0 start) | |
160 (substring exp (match-end 0))))) | |
161 (setq exp (read exp))) | |
162 (setq exp (read (current-buffer))))) | |
163 (set-syntax-table stab) | |
164 (if arg | |
165 (insert (pp-to-string (eval exp))) | |
166 (pp-eval-expression exp)))) | |
167 | |
168 ;;; Test cases for quote | |
169 ;; (pp-eval-expression ''(quote quote)) | |
170 ;; (pp-eval-expression ''((quote a) (quote b))) | |
171 ;; (pp-eval-expression ''('a 'b)) ; same as above | |
172 ;; (pp-eval-expression ''((quote (quote quote)) (quote quote))) | |
173 ;; These do not satisfy the quote test. | |
174 ;; (pp-eval-expression ''quote) | |
175 ;; (pp-eval-expression ''(quote)) | |
176 ;; (pp-eval-expression ''(quote . quote)) | |
177 ;; (pp-eval-expression ''(quote a b)) | |
178 ;; (pp-eval-expression ''(quotefoo)) | |
179 ;; (pp-eval-expression ''(a b)) | |
180 | |
181 (provide 'pp) ; so (require 'pp) works | |
182 | |
183 ;;; pp.el ends here. |