2001-07-16 12:23:00 +00:00
|
|
|
|
;;; cust-print.el --- handles print-level and print-circle
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
2009-07-21 04:40:17 +00:00
|
|
|
|
;; Copyright (C) 1992, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
|
2010-01-13 00:35:10 -08:00
|
|
|
|
;; 2009, 2010 Free Software Foundation, Inc.
|
1992-07-22 04:22:30 +00:00
|
|
|
|
|
2000-08-15 12:39:23 +00:00
|
|
|
|
;; Author: Daniel LaLiberte <liberte@holonexus.org>
|
1992-07-16 21:47:34 +00:00
|
|
|
|
;; Adapted-By: ESR
|
1993-03-18 21:29:42 +00:00
|
|
|
|
;; Keywords: extensions
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
1994-03-24 20:26:05 +00:00
|
|
|
|
;; LCD Archive Entry:
|
2000-08-15 12:39:23 +00:00
|
|
|
|
;; cust-print|Daniel LaLiberte|liberte@holonexus.org
|
1994-03-24 20:26:05 +00:00
|
|
|
|
;; |Handle print-level, print-circle and more.
|
|
|
|
|
|
1992-05-30 18:52:42 +00:00
|
|
|
|
;; This file is part of GNU Emacs.
|
|
|
|
|
|
2008-05-06 03:21:21 +00:00
|
|
|
|
;; GNU Emacs is free software: you can redistribute it and/or modify
|
1992-05-30 18:52:42 +00:00
|
|
|
|
;; it under the terms of the GNU General Public License as published by
|
2008-05-06 03:21:21 +00:00
|
|
|
|
;; the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
;; (at your option) any later version.
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
|
|
|
|
;; GNU Emacs is distributed in the hope that it will be useful,
|
|
|
|
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
;; GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
;; You should have received a copy of the GNU General Public License
|
2008-05-06 03:21:21 +00:00
|
|
|
|
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
1994-03-24 20:26:05 +00:00
|
|
|
|
|
1992-07-16 21:47:34 +00:00
|
|
|
|
;;; Commentary:
|
|
|
|
|
|
1992-05-30 18:52:42 +00:00
|
|
|
|
;; This package provides a general print handler for prin1 and princ
|
|
|
|
|
;; that supports print-level and print-circle, and by the way,
|
|
|
|
|
;; print-length since the standard routines are being replaced. Also,
|
|
|
|
|
;; to print custom types constructed from lists and vectors, use
|
|
|
|
|
;; custom-print-list and custom-print-vector. See the documentation
|
2003-02-04 13:24:35 +00:00
|
|
|
|
;; strings of these variables for more details.
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
|
|
|
|
;; If the results of your expressions contain circular references to
|
|
|
|
|
;; other parts of the same structure, the standard Emacs print
|
|
|
|
|
;; subroutines may fail to print with an untrappable error,
|
|
|
|
|
;; "Apparently circular structure being printed". If you only use cdr
|
|
|
|
|
;; circular lists (where cdrs of lists point back; what is the right
|
|
|
|
|
;; term here?), you can limit the length of printing with
|
|
|
|
|
;; print-length. But car circular lists and circular vectors generate
|
1994-03-24 20:26:05 +00:00
|
|
|
|
;; the above mentioned error in Emacs version 18. Version
|
|
|
|
|
;; 19 supports print-level, but it is often useful to get a better
|
|
|
|
|
;; print representation of circular and shared structures; the print-circle
|
1992-05-30 18:52:42 +00:00
|
|
|
|
;; option may be used to print more concise representations.
|
|
|
|
|
|
1994-03-24 20:26:05 +00:00
|
|
|
|
;; There are three main ways to use this package. First, you may
|
1992-05-30 18:52:42 +00:00
|
|
|
|
;; replace prin1, princ, and some subroutines that use them by calling
|
1994-03-24 20:26:05 +00:00
|
|
|
|
;; install-custom-print so that any use of these functions in
|
|
|
|
|
;; Lisp code will be affected; you can later reset with
|
|
|
|
|
;; uninstall-custom-print. Second, you may temporarily install
|
|
|
|
|
;; these functions with the macro with-custom-print. Third, you
|
|
|
|
|
;; could call the custom routines directly, thus only affecting the
|
|
|
|
|
;; printing that requires them.
|
|
|
|
|
|
|
|
|
|
;; Note that subroutines which call print subroutines directly will
|
|
|
|
|
;; not use the custom print functions. In particular, the evaluation
|
1992-05-30 18:52:42 +00:00
|
|
|
|
;; functions like eval-region call the print subroutines directly.
|
1994-03-24 20:26:05 +00:00
|
|
|
|
;; Therefore, if you evaluate (aref circ-list 0), where circ-list is a
|
|
|
|
|
;; circular list rather than an array, aref calls error directly which
|
|
|
|
|
;; will jump to the top level instead of printing the circular list.
|
|
|
|
|
|
|
|
|
|
;; Uninterned symbols are recognized when print-circle is non-nil,
|
|
|
|
|
;; but they are not printed specially here. Use the cl-packages package
|
|
|
|
|
;; to print according to print-gensym.
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
1994-03-24 20:26:05 +00:00
|
|
|
|
;; Obviously the right way to implement this custom-print facility is
|
|
|
|
|
;; in C or with hooks into the standard printer. Please volunteer
|
|
|
|
|
;; since I don't have the time or need. More CL-like printing
|
|
|
|
|
;; capabilities could be added in the future.
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
|
|
|
|
;; Implementation design: we want to use the same list and vector
|
|
|
|
|
;; processing algorithm for all versions of prin1 and princ, since how
|
|
|
|
|
;; the processing is done depends on print-length, print-level, and
|
|
|
|
|
;; print-circle. For circle printing, a preprocessing step is
|
|
|
|
|
;; required before the final printing. Thanks to Jamie Zawinski
|
|
|
|
|
;; for motivation and algorithms.
|
|
|
|
|
|
1994-03-24 20:26:05 +00:00
|
|
|
|
|
|
|
|
|
;;; Code:
|
1999-11-21 14:50:21 +00:00
|
|
|
|
|
|
|
|
|
(defgroup cust-print nil
|
|
|
|
|
"Handles print-level and print-circle."
|
|
|
|
|
:prefix "print-"
|
|
|
|
|
:group 'lisp
|
|
|
|
|
:group 'extensions)
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
1994-03-24 20:26:05 +00:00
|
|
|
|
;; If using cl-packages:
|
|
|
|
|
|
|
|
|
|
'(defpackage "cust-print"
|
|
|
|
|
(:nicknames "CP" "custom-print")
|
|
|
|
|
(:use "el")
|
|
|
|
|
(:export
|
|
|
|
|
print-level
|
|
|
|
|
print-circle
|
|
|
|
|
|
1994-04-05 21:05:09 +00:00
|
|
|
|
custom-print-install
|
|
|
|
|
custom-print-uninstall
|
1994-03-24 20:26:05 +00:00
|
|
|
|
custom-print-installed-p
|
|
|
|
|
with-custom-print
|
|
|
|
|
|
|
|
|
|
custom-prin1
|
|
|
|
|
custom-princ
|
|
|
|
|
custom-prin1-to-string
|
|
|
|
|
custom-print
|
|
|
|
|
custom-format
|
|
|
|
|
custom-message
|
|
|
|
|
custom-error
|
|
|
|
|
|
|
|
|
|
custom-printers
|
|
|
|
|
add-custom-printer
|
|
|
|
|
))
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
1994-03-24 20:26:05 +00:00
|
|
|
|
'(in-package cust-print)
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
1999-11-21 14:50:21 +00:00
|
|
|
|
;; Emacs 18 doesn't have defalias.
|
1994-03-24 20:26:05 +00:00
|
|
|
|
;; Provide def for byte compiler.
|
1994-04-09 22:19:10 +00:00
|
|
|
|
(eval-and-compile
|
|
|
|
|
(or (fboundp 'defalias) (fset 'defalias 'fset)))
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
1994-03-24 20:26:05 +00:00
|
|
|
|
|
|
|
|
|
;; Variables:
|
|
|
|
|
;;=========================================================
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
|
|
|
|
;;(defvar print-length nil
|
|
|
|
|
;; "*Controls how many elements of a list, at each level, are printed.
|
|
|
|
|
;;This is defined by emacs.")
|
|
|
|
|
|
1999-11-21 14:50:21 +00:00
|
|
|
|
(defcustom print-level nil
|
2009-07-21 04:40:17 +00:00
|
|
|
|
"Controls how many levels deep a nested data object will print.
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
|
|
|
|
If nil, printing proceeds recursively and may lead to
|
1994-03-24 20:26:05 +00:00
|
|
|
|
max-lisp-eval-depth being exceeded or an error may occur:
|
1992-10-07 09:09:19 +00:00
|
|
|
|
`Apparently circular structure being printed.'
|
|
|
|
|
Also see `print-length' and `print-circle'.
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
1992-10-07 09:09:19 +00:00
|
|
|
|
If non-nil, components at levels equal to or greater than `print-level'
|
1992-10-08 06:44:24 +00:00
|
|
|
|
are printed simply as `#'. The object to be printed is at level 0,
|
1992-05-30 18:52:42 +00:00
|
|
|
|
and if the object is a list or vector, its top-level components are at
|
1999-11-21 14:50:21 +00:00
|
|
|
|
level 1."
|
|
|
|
|
:type '(choice (const nil) integer)
|
|
|
|
|
:group 'cust-print)
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
|
|
|
|
|
1999-11-21 14:50:21 +00:00
|
|
|
|
(defcustom print-circle nil
|
2009-07-21 04:40:17 +00:00
|
|
|
|
"Controls the printing of recursive structures.
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
|
|
|
|
If nil, printing proceeds recursively and may lead to
|
1994-03-24 20:26:05 +00:00
|
|
|
|
`max-lisp-eval-depth' being exceeded or an error may occur:
|
1992-05-30 18:52:42 +00:00
|
|
|
|
\"Apparently circular structure being printed.\" Also see
|
1992-10-07 09:09:19 +00:00
|
|
|
|
`print-length' and `print-level'.
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
|
|
|
|
If non-nil, shared substructures anywhere in the structure are printed
|
1993-06-09 11:59:12 +00:00
|
|
|
|
with `#N=' before the first occurrence (in the order of the print
|
|
|
|
|
representation) and `#N#' in place of each subsequent occurrence,
|
1992-10-07 09:09:19 +00:00
|
|
|
|
where N is a positive decimal integer.
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
1994-03-24 20:26:05 +00:00
|
|
|
|
There is no way to read this representation in standard Emacs,
|
1999-11-21 14:50:21 +00:00
|
|
|
|
but if you need to do so, try the cl-read.el package."
|
|
|
|
|
:type 'boolean
|
|
|
|
|
:group 'cust-print)
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
|
|
|
|
|
1999-11-21 14:50:21 +00:00
|
|
|
|
(defcustom custom-print-vectors nil
|
2009-07-21 04:40:17 +00:00
|
|
|
|
"Non-nil if printing of vectors should obey `print-level' and `print-length'."
|
1999-11-21 14:50:21 +00:00
|
|
|
|
:type 'boolean
|
|
|
|
|
:group 'cust-print)
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
1994-03-24 20:26:05 +00:00
|
|
|
|
|
|
|
|
|
;; Custom printers
|
|
|
|
|
;;==========================================================
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
2004-11-21 03:27:39 +00:00
|
|
|
|
(defvar custom-printers nil
|
1994-03-24 20:26:05 +00:00
|
|
|
|
;; e.g. '((symbolp . pkg::print-symbol))
|
|
|
|
|
"An alist for custom printing of any type.
|
|
|
|
|
Pairs are of the form (PREDICATE . PRINTER). If PREDICATE is true
|
|
|
|
|
for an object, then PRINTER is called with the object.
|
|
|
|
|
PRINTER should print to `standard-output' using cust-print-original-princ
|
|
|
|
|
if the standard printer is sufficient, or cust-print-prin for complex things.
|
|
|
|
|
The PRINTER should return the object being printed.
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
1994-03-24 20:26:05 +00:00
|
|
|
|
Don't modify this variable directly. Use `add-custom-printer' and
|
|
|
|
|
`delete-custom-printer'")
|
|
|
|
|
;; Should cust-print-original-princ and cust-print-prin be exported symbols?
|
|
|
|
|
;; Or should the standard printers functions be replaced by
|
1999-11-21 14:50:21 +00:00
|
|
|
|
;; CP ones in Emacs Lisp so that CP internal functions need not be called?
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
1994-03-24 20:26:05 +00:00
|
|
|
|
(defun add-custom-printer (pred printer)
|
|
|
|
|
"Add a pair of PREDICATE and PRINTER to `custom-printers'.
|
1992-05-30 18:52:42 +00:00
|
|
|
|
Any pair that has the same PREDICATE is first removed."
|
2003-02-04 13:24:35 +00:00
|
|
|
|
(setq custom-printers (cons (cons pred printer)
|
1994-03-24 20:26:05 +00:00
|
|
|
|
(delq (assq pred custom-printers)
|
|
|
|
|
custom-printers)))
|
|
|
|
|
;; Rather than updating here, we could wait until cust-print-top-level is called.
|
|
|
|
|
(cust-print-update-custom-printers))
|
|
|
|
|
|
|
|
|
|
(defun delete-custom-printer (pred)
|
|
|
|
|
"Delete the custom printer associated with PREDICATE."
|
|
|
|
|
(setq custom-printers (delq (assq pred custom-printers)
|
|
|
|
|
custom-printers))
|
|
|
|
|
(cust-print-update-custom-printers))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(defun cust-print-use-custom-printer (object)
|
|
|
|
|
;; Default function returns nil.
|
|
|
|
|
nil)
|
|
|
|
|
|
|
|
|
|
(defun cust-print-update-custom-printers ()
|
|
|
|
|
;; Modify the definition of cust-print-use-custom-printer
|
|
|
|
|
(defalias 'cust-print-use-custom-printer
|
1999-11-21 14:50:21 +00:00
|
|
|
|
;; We don't really want to require the byte-compiler.
|
1994-03-24 20:26:05 +00:00
|
|
|
|
;; (byte-compile
|
1999-11-21 14:50:21 +00:00
|
|
|
|
`(lambda (object)
|
|
|
|
|
(cond
|
2003-02-04 13:24:35 +00:00
|
|
|
|
,@(mapcar (function
|
1999-11-21 14:50:21 +00:00
|
|
|
|
(lambda (pair)
|
2003-02-04 13:24:35 +00:00
|
|
|
|
`((,(car pair) object)
|
1999-11-21 14:50:21 +00:00
|
|
|
|
(,(cdr pair) object))))
|
|
|
|
|
custom-printers)
|
|
|
|
|
;; Otherwise return nil.
|
|
|
|
|
(t nil)
|
|
|
|
|
))
|
|
|
|
|
;; )
|
|
|
|
|
))
|
1994-03-24 20:26:05 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;; Saving and restoring emacs printing routines.
|
1992-05-30 18:52:42 +00:00
|
|
|
|
;;====================================================
|
|
|
|
|
|
1992-10-07 09:09:19 +00:00
|
|
|
|
(defun cust-print-set-function-cell (symbol-pair)
|
2003-02-04 13:24:35 +00:00
|
|
|
|
(defalias (car symbol-pair)
|
1994-03-24 20:26:05 +00:00
|
|
|
|
(symbol-function (car (cdr symbol-pair)))))
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
1994-03-24 20:26:05 +00:00
|
|
|
|
(defun cust-print-original-princ (object &optional stream)) ; dummy def
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
1994-03-24 20:26:05 +00:00
|
|
|
|
;; Save emacs routines.
|
|
|
|
|
(if (not (fboundp 'cust-print-original-prin1))
|
2007-09-26 00:11:21 +00:00
|
|
|
|
(mapc 'cust-print-set-function-cell
|
|
|
|
|
'((cust-print-original-prin1 prin1)
|
|
|
|
|
(cust-print-original-princ princ)
|
|
|
|
|
(cust-print-original-print print)
|
|
|
|
|
(cust-print-original-prin1-to-string prin1-to-string)
|
|
|
|
|
(cust-print-original-format format)
|
|
|
|
|
(cust-print-original-message message)
|
|
|
|
|
(cust-print-original-error error))))
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
|
|
|
|
|
1994-04-05 21:05:09 +00:00
|
|
|
|
(defun custom-print-install ()
|
1992-10-07 09:09:19 +00:00
|
|
|
|
"Replace print functions with general, customizable, Lisp versions.
|
2006-11-06 02:37:41 +00:00
|
|
|
|
The Emacs subroutines are saved away, and you can reinstall them
|
1994-04-05 21:05:09 +00:00
|
|
|
|
by running `custom-print-uninstall'."
|
1992-05-30 18:52:42 +00:00
|
|
|
|
(interactive)
|
2007-09-26 00:11:21 +00:00
|
|
|
|
(mapc 'cust-print-set-function-cell
|
|
|
|
|
'((prin1 custom-prin1)
|
|
|
|
|
(princ custom-princ)
|
|
|
|
|
(print custom-print)
|
|
|
|
|
(prin1-to-string custom-prin1-to-string)
|
|
|
|
|
(format custom-format)
|
|
|
|
|
(message custom-message)
|
|
|
|
|
(error custom-error)
|
|
|
|
|
))
|
1994-03-24 20:26:05 +00:00
|
|
|
|
t)
|
2003-02-04 13:24:35 +00:00
|
|
|
|
|
1994-04-05 21:05:09 +00:00
|
|
|
|
(defun custom-print-uninstall ()
|
2006-11-06 02:37:41 +00:00
|
|
|
|
"Reset print functions to their Emacs subroutines."
|
1992-05-30 18:52:42 +00:00
|
|
|
|
(interactive)
|
2007-09-26 00:11:21 +00:00
|
|
|
|
(mapc 'cust-print-set-function-cell
|
|
|
|
|
'((prin1 cust-print-original-prin1)
|
|
|
|
|
(princ cust-print-original-princ)
|
|
|
|
|
(print cust-print-original-print)
|
|
|
|
|
(prin1-to-string cust-print-original-prin1-to-string)
|
|
|
|
|
(format cust-print-original-format)
|
|
|
|
|
(message cust-print-original-message)
|
|
|
|
|
(error cust-print-original-error)
|
|
|
|
|
))
|
1994-03-24 20:26:05 +00:00
|
|
|
|
t)
|
|
|
|
|
|
|
|
|
|
(defalias 'custom-print-funcs-installed-p 'custom-print-installed-p)
|
|
|
|
|
(defun custom-print-installed-p ()
|
|
|
|
|
"Return t if custom-print is currently installed, nil otherwise."
|
|
|
|
|
(eq (symbol-function 'custom-prin1) (symbol-function 'prin1)))
|
|
|
|
|
|
|
|
|
|
(put 'with-custom-print-funcs 'edebug-form-spec '(body))
|
|
|
|
|
(put 'with-custom-print 'edebug-form-spec '(body))
|
|
|
|
|
|
|
|
|
|
(defalias 'with-custom-print-funcs 'with-custom-print)
|
|
|
|
|
(defmacro with-custom-print (&rest body)
|
|
|
|
|
"Temporarily install the custom print package while executing BODY."
|
1999-11-21 14:50:21 +00:00
|
|
|
|
`(unwind-protect
|
|
|
|
|
(progn
|
|
|
|
|
(custom-print-install)
|
|
|
|
|
,@body)
|
|
|
|
|
(custom-print-uninstall)))
|
1994-03-24 20:26:05 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;; Lisp replacements for prin1 and princ, and for some subrs that use them
|
1992-05-30 18:52:42 +00:00
|
|
|
|
;;===============================================================
|
1994-03-24 20:26:05 +00:00
|
|
|
|
;; - so far only the printing and formatting subrs.
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
|
|
|
|
(defun custom-prin1 (object &optional stream)
|
1994-03-24 20:26:05 +00:00
|
|
|
|
"Output the printed representation of OBJECT, any Lisp object.
|
1992-05-30 18:52:42 +00:00
|
|
|
|
Quoting characters are printed when needed to make output that `read'
|
|
|
|
|
can handle, whenever this is possible.
|
1994-03-24 20:26:05 +00:00
|
|
|
|
Output stream is STREAM, or value of `standard-output' (which see).
|
|
|
|
|
|
|
|
|
|
This is the custom-print replacement for the standard `prin1'. It
|
|
|
|
|
uses the appropriate printer depending on the values of `print-level'
|
|
|
|
|
and `print-circle' (which see)."
|
|
|
|
|
(cust-print-top-level object stream 'cust-print-original-prin1))
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(defun custom-princ (object &optional stream)
|
1994-03-24 20:26:05 +00:00
|
|
|
|
"Output the printed representation of OBJECT, any Lisp object.
|
|
|
|
|
No quoting characters are used; no delimiters are printed around
|
|
|
|
|
the contents of strings.
|
|
|
|
|
Output stream is STREAM, or value of `standard-output' (which see).
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
1994-03-24 20:26:05 +00:00
|
|
|
|
This is the custom-print replacement for the standard `princ'."
|
|
|
|
|
(cust-print-top-level object stream 'cust-print-original-princ))
|
1992-10-08 06:44:24 +00:00
|
|
|
|
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
1999-11-21 14:50:21 +00:00
|
|
|
|
(defun custom-prin1-to-string (object &optional noescape)
|
1994-03-24 20:26:05 +00:00
|
|
|
|
"Return a string containing the printed representation of OBJECT,
|
|
|
|
|
any Lisp object. Quoting characters are used when needed to make output
|
1999-11-21 14:50:21 +00:00
|
|
|
|
that `read' can handle, whenever this is possible, unless the optional
|
|
|
|
|
second argument NOESCAPE is non-nil.
|
1994-03-24 20:26:05 +00:00
|
|
|
|
|
|
|
|
|
This is the custom-print replacement for the standard `prin1-to-string'."
|
|
|
|
|
(let ((buf (get-buffer-create " *custom-print-temp*")))
|
2003-02-04 13:24:35 +00:00
|
|
|
|
;; We must erase the buffer before printing in case an error
|
1999-11-21 14:50:21 +00:00
|
|
|
|
;; occurred during the last prin1-to-string and we are in debugger.
|
* textmodes/two-column.el (2C-split):
* textmodes/texnfo-upd.el (texinfo-multi-file-included-list):
* textmodes/tex-mode.el (tex-set-buffer-directory):
* textmodes/spell.el (spell-region, spell-string):
* textmodes/reftex.el (reftex-erase-buffer):
(reftex-get-file-buffer-force, reftex-kill-temporary-buffers):
* textmodes/reftex-toc.el (reftex-toc-promote-action):
* textmodes/reftex-sel.el (reftex-get-offset, reftex-insert-docstruct)
(reftex-select-item):
* textmodes/reftex-ref.el (reftex-label-info-update)
(reftex-offer-label-menu):
* textmodes/reftex-index.el (reftex-index-change-entry)
(reftex-index-phrases-info):
* textmodes/reftex-global.el (reftex-create-tags-file)
(reftex-save-all-document-buffers, reftex-ensure-write-access):
* textmodes/reftex-dcr.el (reftex-echo-ref, reftex-echo-cite)
(reftex-view-crossref-from-bibtex):
* textmodes/reftex-cite.el (reftex-bibtex-selection-callback)
(reftex-extract-bib-entries-from-thebibliography)
(reftex-all-used-citation-keys, reftex-create-bibtex-file):
* textmodes/refbib.el (r2b-capitalize-title):
(r2b-convert-buffer, r2b-help):
* textmodes/page-ext.el (pages-directory)
(pages-directory-goto-with-mouse):
* textmodes/bibtex.el (bibtex-validate-globally):
* textmodes/bib-mode.el (bib-capitalize-title):
* textmodes/artist.el (artist-clear-buffer, artist-system):
* progmodes/xscheme.el (global-set-scheme-interaction-buffer):
(local-set-scheme-interaction-buffer, xscheme-process-filter)
(verify-xscheme-buffer, xscheme-enter-interaction-mode)
(xscheme-enter-debugger-mode, xscheme-debugger-mode-p)
(xscheme-send-control-g-interrupt, xscheme-start-process)
(xscheme-process-sentinel, xscheme-cd):
* progmodes/verilog-mode.el (verilog-read-always-signals)
(verilog-set-define, verilog-getopt-file)
(verilog-module-inside-filename-p):
* progmodes/sh-script.el:
* progmodes/python.el (python-pdbtrack-get-source-buffer)
(python-pdbtrack-grub-for-buffer, python-execute-file):
* progmodes/octave-inf.el (inferior-octave):
* progmodes/idlwave.el (idlwave-scan-user-lib-files)
(idlwave-shell-compile-helper-routines, idlwave-set-local)
(idlwave-display-completion-list-xemacs, idlwave-list-abbrevs)
(idlwave-display-completion-list-emacs, idlwave-list-load-path-shadows)
(idlwave-completion-fontify-classes, idlwave-display-calling-sequence):
* progmodes/idlw-shell.el (idlwave-shell-examine-display-clear)
(idlwave-shell-filter, idlwave-shell-examine-highlight)
(idlwave-shell-sentinel, idlwave-shell-filter-directory)
(idlwave-shell-display-line, idlwave-shell-set-bp-in-module)
(idlwave-shell-examine-display, idlwave-shell-run-region)
(idlwave-shell-filter-bp, idlwave-shell-save-and-action)
(idlwave-shell-sources-filter, idlwave-shell-goto-next-error):
* progmodes/idlw-help.el (idlwave-help-get-special-help)
(idlwave-help-get-help-buffer):
* progmodes/gud.el (gud-basic-call, gud-find-class)
(gud-tooltip-activate-mouse-motions-if-enabled):
* progmodes/gdb-mi.el (gdb-mouse-toggle-breakpoint-fringe):
* progmodes/ebrowse.el (ebrowse-member-table, ebrowse-save-tree-as)
(ebrowse-view-exit-fn, ebrowse-tags-list-members-in-file)
(ebrowse-tags-next-file):
* progmodes/ebnf2ps.el (ebnf-generate-eps, ebnf-generate-eps)
(ebnf-eps-production-list, ebnf-begin-file, ebnf-log)
(ebnf-eps-finish-and-write):
* progmodes/cpp.el (cpp-edit-save):
* progmodes/cperl-mode.el (cperl-pod-to-manpage):
* progmodes/cc-defs.el (c-emacs-features):
* progmodes/antlr-mode.el (antlr-invalidate-context-cache)
(antlr-directory-dependencies):
* progmodes/ada-xref.el (ada-gnat-parse-gpr, ada-get-ali-file-name)
(ada-run-application, ada-find-in-src-path, ada-goto-parent)
(ada-find-any-references, ada-make-filename-from-adaname)
(ada-make-body-gnatstub):
* obsolete/rnews.el (news-list-news-groups):
* obsolete/resume.el (resume-suspend-hook,resume-write-buffer-to-file):
* obsolete/iso-acc.el (iso-acc-minibuf-setup):
* net/rcirc.el (rcirc-debug):
* net/newst-treeview.el (newsticker--treeview-list-add-item)
(newsticker--treeview-list-clear, newsticker-treeview-browse-url)
(newsticker--treeview-list-update-faces, newsticker-treeview-save)
(newsticker--treeview-item-show-text, newsticker--treeview-item-show)
(newsticker--treeview-tree-update-tag,newsticker--treeview-buffer-init)
(newsticker-treeview-show-item, newsticker--treeview-unfold-node)
(newsticker--treeview-list-clear-highlight)
(newsticker--treeview-list-update-highlight)
(newsticker--treeview-list-highlight-start)
(newsticker--treeview-tree-update-highlight)
(newsticker--treeview-get-selected-item)
(newsticker-treeview-mark-list-items-old)
(newsticker--treeview-set-current-node):
* net/newst-plainview.el (newsticker--buffer-set-uptodate):
* net/newst-backend.el (newsticker--get-news-by-funcall)
(newsticker--get-news-by-wget, newsticker--image-get)
(newsticker--image-sentinel):
* net/mairix.el (mairix-rmail-fetch-field, mairix-gnus-fetch-field):
* net/eudcb-ph.el (eudc-ph-do-request, eudc-ph-open-session):
(eudc-ph-close-session):
* net/eudc.el (eudc-save-options):
* language/thai-word.el (thai-update-word-table):
* language/japan-util.el (japanese-string-conversion):
* international/titdic-cnv.el (tsang-quick-converter)
(ziranma-converter, ctlau-converter):
* international/mule-cmds.el (describe-language-environment):
* international/ja-dic-cnv.el (skkdic-convert-okuri-ari)
(skkdic-convert-postfix, skkdic-convert-prefix):
(skkdic-convert-okuri-nasi, skkdic-convert):
* emacs-lisp/re-builder.el (reb-update-overlays):
* emacs-lisp/pp.el (pp-to-string, pp-display-expression):
* emacs-lisp/gulp.el (gulp-send-requests):
* emacs-lisp/find-gc.el (trace-call-tree):
* emacs-lisp/eieio-opt.el (eieio-browse, eieio-describe-class)
(eieio-describe-generic):
* emacs-lisp/eieio-base.el (eieio-persistent-read):
* emacs-lisp/edebug.el (edebug-outside-excursion):
* emacs-lisp/debug.el (debugger-make-xrefs):
* emacs-lisp/cust-print.el (custom-prin1-to-string):
* emacs-lisp/chart.el (chart-new-buffer):
* emacs-lisp/authors.el (authors-scan-el, authors-scan-change-log):
Use with-current-buffer.
* textmodes/artist.el (artist-system): Don't call
copy-sequence on a fresh string.
* progmodes/idlw-shell.el (easymenu setup): Use dolist.
2009-10-31 02:38:34 +00:00
|
|
|
|
(with-current-buffer buf
|
1994-03-24 20:26:05 +00:00
|
|
|
|
(erase-buffer))
|
|
|
|
|
;; We must be in the current-buffer when the print occurs.
|
1999-11-21 14:50:21 +00:00
|
|
|
|
(if noescape
|
|
|
|
|
(custom-princ object buf)
|
|
|
|
|
(custom-prin1 object buf))
|
* textmodes/two-column.el (2C-split):
* textmodes/texnfo-upd.el (texinfo-multi-file-included-list):
* textmodes/tex-mode.el (tex-set-buffer-directory):
* textmodes/spell.el (spell-region, spell-string):
* textmodes/reftex.el (reftex-erase-buffer):
(reftex-get-file-buffer-force, reftex-kill-temporary-buffers):
* textmodes/reftex-toc.el (reftex-toc-promote-action):
* textmodes/reftex-sel.el (reftex-get-offset, reftex-insert-docstruct)
(reftex-select-item):
* textmodes/reftex-ref.el (reftex-label-info-update)
(reftex-offer-label-menu):
* textmodes/reftex-index.el (reftex-index-change-entry)
(reftex-index-phrases-info):
* textmodes/reftex-global.el (reftex-create-tags-file)
(reftex-save-all-document-buffers, reftex-ensure-write-access):
* textmodes/reftex-dcr.el (reftex-echo-ref, reftex-echo-cite)
(reftex-view-crossref-from-bibtex):
* textmodes/reftex-cite.el (reftex-bibtex-selection-callback)
(reftex-extract-bib-entries-from-thebibliography)
(reftex-all-used-citation-keys, reftex-create-bibtex-file):
* textmodes/refbib.el (r2b-capitalize-title):
(r2b-convert-buffer, r2b-help):
* textmodes/page-ext.el (pages-directory)
(pages-directory-goto-with-mouse):
* textmodes/bibtex.el (bibtex-validate-globally):
* textmodes/bib-mode.el (bib-capitalize-title):
* textmodes/artist.el (artist-clear-buffer, artist-system):
* progmodes/xscheme.el (global-set-scheme-interaction-buffer):
(local-set-scheme-interaction-buffer, xscheme-process-filter)
(verify-xscheme-buffer, xscheme-enter-interaction-mode)
(xscheme-enter-debugger-mode, xscheme-debugger-mode-p)
(xscheme-send-control-g-interrupt, xscheme-start-process)
(xscheme-process-sentinel, xscheme-cd):
* progmodes/verilog-mode.el (verilog-read-always-signals)
(verilog-set-define, verilog-getopt-file)
(verilog-module-inside-filename-p):
* progmodes/sh-script.el:
* progmodes/python.el (python-pdbtrack-get-source-buffer)
(python-pdbtrack-grub-for-buffer, python-execute-file):
* progmodes/octave-inf.el (inferior-octave):
* progmodes/idlwave.el (idlwave-scan-user-lib-files)
(idlwave-shell-compile-helper-routines, idlwave-set-local)
(idlwave-display-completion-list-xemacs, idlwave-list-abbrevs)
(idlwave-display-completion-list-emacs, idlwave-list-load-path-shadows)
(idlwave-completion-fontify-classes, idlwave-display-calling-sequence):
* progmodes/idlw-shell.el (idlwave-shell-examine-display-clear)
(idlwave-shell-filter, idlwave-shell-examine-highlight)
(idlwave-shell-sentinel, idlwave-shell-filter-directory)
(idlwave-shell-display-line, idlwave-shell-set-bp-in-module)
(idlwave-shell-examine-display, idlwave-shell-run-region)
(idlwave-shell-filter-bp, idlwave-shell-save-and-action)
(idlwave-shell-sources-filter, idlwave-shell-goto-next-error):
* progmodes/idlw-help.el (idlwave-help-get-special-help)
(idlwave-help-get-help-buffer):
* progmodes/gud.el (gud-basic-call, gud-find-class)
(gud-tooltip-activate-mouse-motions-if-enabled):
* progmodes/gdb-mi.el (gdb-mouse-toggle-breakpoint-fringe):
* progmodes/ebrowse.el (ebrowse-member-table, ebrowse-save-tree-as)
(ebrowse-view-exit-fn, ebrowse-tags-list-members-in-file)
(ebrowse-tags-next-file):
* progmodes/ebnf2ps.el (ebnf-generate-eps, ebnf-generate-eps)
(ebnf-eps-production-list, ebnf-begin-file, ebnf-log)
(ebnf-eps-finish-and-write):
* progmodes/cpp.el (cpp-edit-save):
* progmodes/cperl-mode.el (cperl-pod-to-manpage):
* progmodes/cc-defs.el (c-emacs-features):
* progmodes/antlr-mode.el (antlr-invalidate-context-cache)
(antlr-directory-dependencies):
* progmodes/ada-xref.el (ada-gnat-parse-gpr, ada-get-ali-file-name)
(ada-run-application, ada-find-in-src-path, ada-goto-parent)
(ada-find-any-references, ada-make-filename-from-adaname)
(ada-make-body-gnatstub):
* obsolete/rnews.el (news-list-news-groups):
* obsolete/resume.el (resume-suspend-hook,resume-write-buffer-to-file):
* obsolete/iso-acc.el (iso-acc-minibuf-setup):
* net/rcirc.el (rcirc-debug):
* net/newst-treeview.el (newsticker--treeview-list-add-item)
(newsticker--treeview-list-clear, newsticker-treeview-browse-url)
(newsticker--treeview-list-update-faces, newsticker-treeview-save)
(newsticker--treeview-item-show-text, newsticker--treeview-item-show)
(newsticker--treeview-tree-update-tag,newsticker--treeview-buffer-init)
(newsticker-treeview-show-item, newsticker--treeview-unfold-node)
(newsticker--treeview-list-clear-highlight)
(newsticker--treeview-list-update-highlight)
(newsticker--treeview-list-highlight-start)
(newsticker--treeview-tree-update-highlight)
(newsticker--treeview-get-selected-item)
(newsticker-treeview-mark-list-items-old)
(newsticker--treeview-set-current-node):
* net/newst-plainview.el (newsticker--buffer-set-uptodate):
* net/newst-backend.el (newsticker--get-news-by-funcall)
(newsticker--get-news-by-wget, newsticker--image-get)
(newsticker--image-sentinel):
* net/mairix.el (mairix-rmail-fetch-field, mairix-gnus-fetch-field):
* net/eudcb-ph.el (eudc-ph-do-request, eudc-ph-open-session):
(eudc-ph-close-session):
* net/eudc.el (eudc-save-options):
* language/thai-word.el (thai-update-word-table):
* language/japan-util.el (japanese-string-conversion):
* international/titdic-cnv.el (tsang-quick-converter)
(ziranma-converter, ctlau-converter):
* international/mule-cmds.el (describe-language-environment):
* international/ja-dic-cnv.el (skkdic-convert-okuri-ari)
(skkdic-convert-postfix, skkdic-convert-prefix):
(skkdic-convert-okuri-nasi, skkdic-convert):
* emacs-lisp/re-builder.el (reb-update-overlays):
* emacs-lisp/pp.el (pp-to-string, pp-display-expression):
* emacs-lisp/gulp.el (gulp-send-requests):
* emacs-lisp/find-gc.el (trace-call-tree):
* emacs-lisp/eieio-opt.el (eieio-browse, eieio-describe-class)
(eieio-describe-generic):
* emacs-lisp/eieio-base.el (eieio-persistent-read):
* emacs-lisp/edebug.el (edebug-outside-excursion):
* emacs-lisp/debug.el (debugger-make-xrefs):
* emacs-lisp/cust-print.el (custom-prin1-to-string):
* emacs-lisp/chart.el (chart-new-buffer):
* emacs-lisp/authors.el (authors-scan-el, authors-scan-change-log):
Use with-current-buffer.
* textmodes/artist.el (artist-system): Don't call
copy-sequence on a fresh string.
* progmodes/idlw-shell.el (easymenu setup): Use dolist.
2009-10-31 02:38:34 +00:00
|
|
|
|
(with-current-buffer buf
|
1994-03-24 20:26:05 +00:00
|
|
|
|
(buffer-string)
|
|
|
|
|
;; We could erase the buffer again, but why bother?
|
|
|
|
|
)))
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(defun custom-print (object &optional stream)
|
1994-03-24 20:26:05 +00:00
|
|
|
|
"Output the printed representation of OBJECT, with newlines around it.
|
|
|
|
|
Quoting characters are printed when needed to make output that `read'
|
|
|
|
|
can handle, whenever this is possible.
|
|
|
|
|
Output stream is STREAM, or value of `standard-output' (which see).
|
|
|
|
|
|
|
|
|
|
This is the custom-print replacement for the standard `print'."
|
|
|
|
|
(cust-print-original-princ "\n" stream)
|
1992-05-30 18:52:42 +00:00
|
|
|
|
(custom-prin1 object stream)
|
1994-03-24 20:26:05 +00:00
|
|
|
|
(cust-print-original-princ "\n" stream))
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(defun custom-format (fmt &rest args)
|
2003-02-04 13:24:35 +00:00
|
|
|
|
"Format a string out of a control-string and arguments.
|
1994-03-24 20:26:05 +00:00
|
|
|
|
The first argument is a control string. It, and subsequent arguments
|
|
|
|
|
substituted into it, become the value, which is a string.
|
|
|
|
|
It may contain %s or %d or %c to substitute successive following arguments.
|
|
|
|
|
%s means print an argument as a string, %d means print as number in decimal,
|
|
|
|
|
%c means print a number as a single character.
|
|
|
|
|
The argument used by %s must be a string or a symbol;
|
|
|
|
|
the argument used by %d, %b, %o, %x or %c must be a number.
|
|
|
|
|
|
|
|
|
|
This is the custom-print replacement for the standard `format'. It
|
2006-11-06 02:37:41 +00:00
|
|
|
|
calls the Emacs `format' after first making strings for list,
|
1994-03-24 20:26:05 +00:00
|
|
|
|
vector, or symbol args. The format specification for such args should
|
|
|
|
|
be `%s' in any case, so a string argument will also work. The string
|
|
|
|
|
is generated with `custom-prin1-to-string', which quotes quotable
|
|
|
|
|
characters."
|
|
|
|
|
(apply 'cust-print-original-format fmt
|
1992-05-30 18:52:42 +00:00
|
|
|
|
(mapcar (function (lambda (arg)
|
1994-03-24 20:26:05 +00:00
|
|
|
|
(if (or (listp arg) (vectorp arg) (symbolp arg))
|
1992-05-30 18:52:42 +00:00
|
|
|
|
(custom-prin1-to-string arg)
|
|
|
|
|
arg)))
|
|
|
|
|
args)))
|
2003-02-04 13:24:35 +00:00
|
|
|
|
|
|
|
|
|
|
1992-05-30 18:52:42 +00:00
|
|
|
|
(defun custom-message (fmt &rest args)
|
1994-03-24 20:26:05 +00:00
|
|
|
|
"Print a one-line message at the bottom of the screen.
|
|
|
|
|
The first argument is a control string.
|
|
|
|
|
It may contain %s or %d or %c to print successive following arguments.
|
|
|
|
|
%s means print an argument as a string, %d means print as number in decimal,
|
|
|
|
|
%c means print a number as a single character.
|
|
|
|
|
The argument used by %s must be a string or a symbol;
|
|
|
|
|
the argument used by %d or %c must be a number.
|
|
|
|
|
|
|
|
|
|
This is the custom-print replacement for the standard `message'.
|
|
|
|
|
See `custom-format' for the details."
|
|
|
|
|
;; It doesn't work to princ the result of custom-format as in:
|
|
|
|
|
;; (cust-print-original-princ (apply 'custom-format fmt args))
|
1992-05-30 18:52:42 +00:00
|
|
|
|
;; because the echo area requires special handling
|
2003-02-04 13:24:35 +00:00
|
|
|
|
;; to avoid duplicating the output.
|
1994-03-24 20:26:05 +00:00
|
|
|
|
;; cust-print-original-message does it right.
|
|
|
|
|
(apply 'cust-print-original-message fmt
|
1992-05-30 18:52:42 +00:00
|
|
|
|
(mapcar (function (lambda (arg)
|
1994-03-24 20:26:05 +00:00
|
|
|
|
(if (or (listp arg) (vectorp arg) (symbolp arg))
|
1992-05-30 18:52:42 +00:00
|
|
|
|
(custom-prin1-to-string arg)
|
|
|
|
|
arg)))
|
|
|
|
|
args)))
|
2003-02-04 13:24:35 +00:00
|
|
|
|
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
|
|
|
|
(defun custom-error (fmt &rest args)
|
1994-03-24 20:26:05 +00:00
|
|
|
|
"Signal an error, making error message by passing all args to `format'.
|
|
|
|
|
|
|
|
|
|
This is the custom-print replacement for the standard `error'.
|
|
|
|
|
See `custom-format' for the details."
|
1992-05-30 18:52:42 +00:00
|
|
|
|
(signal 'error (list (apply 'custom-format fmt args))))
|
|
|
|
|
|
|
|
|
|
|
1994-03-24 20:26:05 +00:00
|
|
|
|
|
1992-05-30 18:52:42 +00:00
|
|
|
|
;; Support for custom prin1 and princ
|
1994-03-24 20:26:05 +00:00
|
|
|
|
;;=========================================
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
1994-03-24 20:26:05 +00:00
|
|
|
|
;; Defs to quiet byte-compiler.
|
1992-10-08 06:44:24 +00:00
|
|
|
|
(defvar circle-table)
|
1994-03-24 20:26:05 +00:00
|
|
|
|
(defvar cust-print-current-level)
|
|
|
|
|
|
|
|
|
|
(defun cust-print-original-printer (object)) ; One of the standard printers.
|
|
|
|
|
(defun cust-print-low-level-prin (object)) ; Used internally.
|
|
|
|
|
(defun cust-print-prin (object)) ; Call this to print recursively.
|
1992-10-08 06:44:24 +00:00
|
|
|
|
|
1994-03-24 20:26:05 +00:00
|
|
|
|
(defun cust-print-top-level (object stream emacs-printer)
|
|
|
|
|
;; Set up for printing.
|
1992-05-30 18:52:42 +00:00
|
|
|
|
(let ((standard-output (or stream standard-output))
|
1994-03-24 20:26:05 +00:00
|
|
|
|
;; circle-table will be non-nil if anything is circular.
|
2003-02-04 13:24:35 +00:00
|
|
|
|
(circle-table (and print-circle
|
1994-03-24 20:26:05 +00:00
|
|
|
|
(cust-print-preprocess-circle-tree object)))
|
|
|
|
|
(cust-print-current-level (or print-level -1)))
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
1994-03-24 20:26:05 +00:00
|
|
|
|
(defalias 'cust-print-original-printer emacs-printer)
|
2003-02-04 13:24:35 +00:00
|
|
|
|
(defalias 'cust-print-low-level-prin
|
1994-03-24 20:26:05 +00:00
|
|
|
|
(cond
|
|
|
|
|
((or custom-printers
|
|
|
|
|
circle-table
|
|
|
|
|
print-level ; comment out for version 19
|
|
|
|
|
;; Emacs doesn't use print-level or print-length
|
|
|
|
|
;; for vectors, but custom-print can.
|
|
|
|
|
(if custom-print-vectors
|
|
|
|
|
(or print-level print-length)))
|
|
|
|
|
'cust-print-print-object)
|
|
|
|
|
(t 'cust-print-original-printer)))
|
2003-02-04 13:24:35 +00:00
|
|
|
|
(defalias 'cust-print-prin
|
1994-03-24 20:26:05 +00:00
|
|
|
|
(if circle-table 'cust-print-print-circular 'cust-print-low-level-prin))
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
1992-10-07 09:09:19 +00:00
|
|
|
|
(cust-print-prin object)
|
1992-05-30 18:52:42 +00:00
|
|
|
|
object))
|
|
|
|
|
|
|
|
|
|
|
1994-03-24 20:26:05 +00:00
|
|
|
|
(defun cust-print-print-object (object)
|
|
|
|
|
;; Test object type and print accordingly.
|
1992-10-07 09:09:19 +00:00
|
|
|
|
;; Could be called as either cust-print-low-level-prin or cust-print-prin.
|
2003-02-04 13:24:35 +00:00
|
|
|
|
(cond
|
1994-03-24 20:26:05 +00:00
|
|
|
|
((null object) (cust-print-original-printer object))
|
|
|
|
|
((cust-print-use-custom-printer object) object)
|
1992-10-07 09:09:19 +00:00
|
|
|
|
((consp object) (cust-print-list object))
|
|
|
|
|
((vectorp object) (cust-print-vector object))
|
1992-05-30 18:52:42 +00:00
|
|
|
|
;; All other types, just print.
|
1994-03-24 20:26:05 +00:00
|
|
|
|
(t (cust-print-original-printer object))))
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
|
|
|
|
|
1994-03-24 20:26:05 +00:00
|
|
|
|
(defun cust-print-print-circular (object)
|
|
|
|
|
;; Printer for `prin1' and `princ' that handles circular structures.
|
|
|
|
|
;; If OBJECT appears multiply, and has not yet been printed,
|
|
|
|
|
;; prefix with label; if it has been printed, use `#N#' instead.
|
|
|
|
|
;; Otherwise, print normally.
|
1992-05-30 18:52:42 +00:00
|
|
|
|
(let ((tag (assq object circle-table)))
|
|
|
|
|
(if tag
|
|
|
|
|
(let ((id (cdr tag)))
|
|
|
|
|
(if (> id 0)
|
|
|
|
|
(progn
|
|
|
|
|
;; Already printed, so just print id.
|
1994-03-24 20:26:05 +00:00
|
|
|
|
(cust-print-original-princ "#")
|
|
|
|
|
(cust-print-original-princ id)
|
|
|
|
|
(cust-print-original-princ "#"))
|
1992-05-30 18:52:42 +00:00
|
|
|
|
;; Not printed yet, so label with id and print object.
|
|
|
|
|
(setcdr tag (- id)) ; mark it as printed
|
1994-03-24 20:26:05 +00:00
|
|
|
|
(cust-print-original-princ "#")
|
|
|
|
|
(cust-print-original-princ (- id))
|
|
|
|
|
(cust-print-original-princ "=")
|
1992-10-07 09:09:19 +00:00
|
|
|
|
(cust-print-low-level-prin object)
|
1992-05-30 18:52:42 +00:00
|
|
|
|
))
|
|
|
|
|
;; Not repeated in structure.
|
1992-10-07 09:09:19 +00:00
|
|
|
|
(cust-print-low-level-prin object))))
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;================================================
|
|
|
|
|
;; List and vector processing for print functions.
|
|
|
|
|
|
1992-10-07 09:09:19 +00:00
|
|
|
|
(defun cust-print-list (list)
|
1994-03-24 20:26:05 +00:00
|
|
|
|
;; Print a list using print-length, print-level, and print-circle.
|
|
|
|
|
(if (= cust-print-current-level 0)
|
|
|
|
|
(cust-print-original-princ "#")
|
|
|
|
|
(let ((cust-print-current-level (1- cust-print-current-level)))
|
|
|
|
|
(cust-print-original-princ "(")
|
1992-05-30 18:52:42 +00:00
|
|
|
|
(let ((length (or print-length 0)))
|
|
|
|
|
|
|
|
|
|
;; Print the first element always (even if length = 0).
|
1992-10-07 09:09:19 +00:00
|
|
|
|
(cust-print-prin (car list))
|
1992-05-30 18:52:42 +00:00
|
|
|
|
(setq list (cdr list))
|
1994-03-24 20:26:05 +00:00
|
|
|
|
(if list (cust-print-original-princ " "))
|
1992-05-30 18:52:42 +00:00
|
|
|
|
(setq length (1- length))
|
|
|
|
|
|
|
|
|
|
;; Print the rest of the elements.
|
|
|
|
|
(while (and list (/= 0 length))
|
|
|
|
|
(if (and (listp list)
|
|
|
|
|
(not (assq list circle-table)))
|
|
|
|
|
(progn
|
1992-10-07 09:09:19 +00:00
|
|
|
|
(cust-print-prin (car list))
|
1992-05-30 18:52:42 +00:00
|
|
|
|
(setq list (cdr list)))
|
|
|
|
|
|
|
|
|
|
;; cdr is not a list, or it is in circle-table.
|
1994-03-24 20:26:05 +00:00
|
|
|
|
(cust-print-original-princ ". ")
|
1992-10-07 09:09:19 +00:00
|
|
|
|
(cust-print-prin list)
|
1992-05-30 18:52:42 +00:00
|
|
|
|
(setq list nil))
|
|
|
|
|
|
|
|
|
|
(setq length (1- length))
|
1994-03-24 20:26:05 +00:00
|
|
|
|
(if list (cust-print-original-princ " ")))
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
1994-03-24 20:26:05 +00:00
|
|
|
|
(if (and list (= length 0)) (cust-print-original-princ "..."))
|
|
|
|
|
(cust-print-original-princ ")"))))
|
1992-05-30 18:52:42 +00:00
|
|
|
|
list)
|
|
|
|
|
|
|
|
|
|
|
1992-10-07 09:09:19 +00:00
|
|
|
|
(defun cust-print-vector (vector)
|
1994-03-24 20:26:05 +00:00
|
|
|
|
;; Print a vector according to print-length, print-level, and print-circle.
|
|
|
|
|
(if (= cust-print-current-level 0)
|
|
|
|
|
(cust-print-original-princ "#")
|
|
|
|
|
(let ((cust-print-current-level (1- cust-print-current-level))
|
1992-05-30 18:52:42 +00:00
|
|
|
|
(i 0)
|
|
|
|
|
(len (length vector)))
|
1994-03-24 20:26:05 +00:00
|
|
|
|
(cust-print-original-princ "[")
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
|
|
|
|
(if print-length
|
|
|
|
|
(setq len (min print-length len)))
|
|
|
|
|
;; Print the elements
|
|
|
|
|
(while (< i len)
|
1992-10-07 09:09:19 +00:00
|
|
|
|
(cust-print-prin (aref vector i))
|
1992-05-30 18:52:42 +00:00
|
|
|
|
(setq i (1+ i))
|
1994-03-24 20:26:05 +00:00
|
|
|
|
(if (< i (length vector)) (cust-print-original-princ " ")))
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
1994-03-24 20:26:05 +00:00
|
|
|
|
(if (< i (length vector)) (cust-print-original-princ "..."))
|
|
|
|
|
(cust-print-original-princ "]")
|
1992-05-30 18:52:42 +00:00
|
|
|
|
))
|
|
|
|
|
vector)
|
|
|
|
|
|
|
|
|
|
|
1994-03-24 20:26:05 +00:00
|
|
|
|
|
1992-05-30 18:52:42 +00:00
|
|
|
|
;; Circular structure preprocessing
|
1994-03-24 20:26:05 +00:00
|
|
|
|
;;==================================
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
1992-10-07 09:09:19 +00:00
|
|
|
|
(defun cust-print-preprocess-circle-tree (object)
|
2003-02-04 13:24:35 +00:00
|
|
|
|
;; Fill up the table.
|
1992-05-30 18:52:42 +00:00
|
|
|
|
(let (;; Table of tags for each object in an object to be printed.
|
|
|
|
|
;; A tag is of the form:
|
|
|
|
|
;; ( <object> <nil-t-or-id-number> )
|
|
|
|
|
;; The id-number is generated after the entire table has been computed.
|
|
|
|
|
;; During walk through, the real circle-table lives in the cdr so we
|
|
|
|
|
;; can use setcdr to add new elements instead of having to setq the
|
|
|
|
|
;; variable sometimes (poor man's locf).
|
|
|
|
|
(circle-table (list nil)))
|
1992-10-07 09:09:19 +00:00
|
|
|
|
(cust-print-walk-circle-tree object)
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
|
|
|
|
;; Reverse table so it is in the order that the objects will be printed.
|
|
|
|
|
;; This pass could be avoided if we always added to the end of the
|
|
|
|
|
;; table with setcdr in walk-circle-tree.
|
|
|
|
|
(setcdr circle-table (nreverse (cdr circle-table)))
|
|
|
|
|
|
|
|
|
|
;; Walk through the table, assigning id-numbers to those
|
|
|
|
|
;; objects which will be printed using #N= syntax. Delete those
|
|
|
|
|
;; objects which will be printed only once (to speed up assq later).
|
|
|
|
|
(let ((rest circle-table)
|
|
|
|
|
(id -1))
|
|
|
|
|
(while (cdr rest)
|
|
|
|
|
(let ((tag (car (cdr rest))))
|
|
|
|
|
(cond ((cdr tag)
|
|
|
|
|
(setcdr tag id)
|
|
|
|
|
(setq id (1- id))
|
|
|
|
|
(setq rest (cdr rest)))
|
|
|
|
|
;; Else delete this object.
|
|
|
|
|
(t (setcdr rest (cdr (cdr rest))))))
|
|
|
|
|
))
|
|
|
|
|
;; Drop the car.
|
|
|
|
|
(cdr circle-table)
|
|
|
|
|
))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1992-10-07 09:09:19 +00:00
|
|
|
|
(defun cust-print-walk-circle-tree (object)
|
1992-05-30 18:52:42 +00:00
|
|
|
|
(let (read-equivalent-p tag)
|
|
|
|
|
(while object
|
2003-02-04 13:24:35 +00:00
|
|
|
|
(setq read-equivalent-p
|
|
|
|
|
(or (numberp object)
|
1994-03-24 20:26:05 +00:00
|
|
|
|
(and (symbolp object)
|
|
|
|
|
;; Check if it is uninterned.
|
|
|
|
|
(eq object (intern-soft (symbol-name object)))))
|
1992-05-30 18:52:42 +00:00
|
|
|
|
tag (and (not read-equivalent-p)
|
|
|
|
|
(assq object (cdr circle-table))))
|
|
|
|
|
(cond (tag
|
|
|
|
|
;; Seen this object already, so note that.
|
|
|
|
|
(setcdr tag t))
|
|
|
|
|
|
|
|
|
|
((not read-equivalent-p)
|
|
|
|
|
;; Add a tag for this object.
|
|
|
|
|
(setcdr circle-table
|
|
|
|
|
(cons (list object)
|
|
|
|
|
(cdr circle-table)))))
|
|
|
|
|
(setq object
|
2003-02-04 13:24:35 +00:00
|
|
|
|
(cond
|
1992-05-30 18:52:42 +00:00
|
|
|
|
(tag ;; No need to descend since we have already.
|
|
|
|
|
nil)
|
|
|
|
|
|
|
|
|
|
((consp object)
|
|
|
|
|
;; Walk the car of the list recursively.
|
1992-10-07 09:09:19 +00:00
|
|
|
|
(cust-print-walk-circle-tree (car object))
|
1992-05-30 18:52:42 +00:00
|
|
|
|
;; But walk the cdr with the above while loop
|
|
|
|
|
;; to avoid problems with max-lisp-eval-depth.
|
|
|
|
|
;; And it should be faster than recursion.
|
|
|
|
|
(cdr object))
|
|
|
|
|
|
|
|
|
|
((vectorp object)
|
|
|
|
|
;; Walk the vector.
|
|
|
|
|
(let ((i (length object))
|
|
|
|
|
(j 0))
|
|
|
|
|
(while (< j i)
|
1992-10-07 09:09:19 +00:00
|
|
|
|
(cust-print-walk-circle-tree (aref object j))
|
1992-05-30 18:52:42 +00:00
|
|
|
|
(setq j (1+ j))))))))))
|
|
|
|
|
|
1994-03-24 20:26:05 +00:00
|
|
|
|
|
|
|
|
|
;; Example.
|
|
|
|
|
;;=======================================
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
1994-03-24 20:26:05 +00:00
|
|
|
|
'(progn
|
|
|
|
|
(progn
|
|
|
|
|
;; Create some circular structures.
|
|
|
|
|
(setq circ-sym (let ((x (make-symbol "FOO"))) (list x x)))
|
|
|
|
|
(setq circ-list (list 'a 'b (vector 1 2 3 4) 'd 'e 'f))
|
|
|
|
|
(setcar (nthcdr 3 circ-list) circ-list)
|
|
|
|
|
(aset (nth 2 circ-list) 2 circ-list)
|
|
|
|
|
(setq dotted-circ-list (list 'a 'b 'c))
|
|
|
|
|
(setcdr (cdr (cdr dotted-circ-list)) dotted-circ-list)
|
|
|
|
|
(setq circ-vector (vector 1 2 3 4 (list 'a 'b 'c 'd) 6 7))
|
|
|
|
|
(aset circ-vector 5 (make-symbol "-gensym-"))
|
|
|
|
|
(setcar (cdr (aref circ-vector 4)) (aref circ-vector 5))
|
|
|
|
|
nil)
|
|
|
|
|
|
|
|
|
|
(install-custom-print)
|
|
|
|
|
;; (setq print-circle t)
|
|
|
|
|
|
|
|
|
|
(let ((print-circle t))
|
|
|
|
|
(or (equal (prin1-to-string circ-list) "#1=(a b [1 2 #1# 4] #1# e f)")
|
|
|
|
|
(error "circular object with array printing")))
|
|
|
|
|
|
|
|
|
|
(let ((print-circle t))
|
|
|
|
|
(or (equal (prin1-to-string dotted-circ-list) "#1=(a b c . #1#)")
|
|
|
|
|
(error "circular object with array printing")))
|
|
|
|
|
|
|
|
|
|
(let* ((print-circle t)
|
|
|
|
|
(x (list 'p 'q))
|
|
|
|
|
(y (list (list 'a 'b) x 'foo x)))
|
|
|
|
|
(setcdr (cdr (cdr (cdr y))) (cdr y))
|
|
|
|
|
(or (equal (prin1-to-string y) "((a b) . #1=(#2=(p q) foo #2# . #1#))"
|
|
|
|
|
)
|
|
|
|
|
(error "circular list example from CL manual")))
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
1994-03-24 20:26:05 +00:00
|
|
|
|
(let ((print-circle nil))
|
|
|
|
|
;; cl-packages.el is required to print uninterned symbols like #:FOO.
|
|
|
|
|
;; (require 'cl-packages)
|
|
|
|
|
(or (equal (prin1-to-string circ-sym) "(#:FOO #:FOO)")
|
|
|
|
|
(error "uninterned symbols in list")))
|
|
|
|
|
(let ((print-circle t))
|
|
|
|
|
(or (equal (prin1-to-string circ-sym) "(#1=FOO #1#)")
|
|
|
|
|
(error "circular uninterned symbols in list")))
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
1994-03-24 20:26:05 +00:00
|
|
|
|
(uninstall-custom-print)
|
|
|
|
|
)
|
1992-10-08 06:44:24 +00:00
|
|
|
|
|
1994-03-24 20:26:05 +00:00
|
|
|
|
(provide 'cust-print)
|
1992-05-30 18:52:42 +00:00
|
|
|
|
|
2008-04-10 14:10:46 +00:00
|
|
|
|
;; arch-tag: 3a5a8650-622c-48c4-87d8-e01bf72ec580
|
1992-07-17 08:15:29 +00:00
|
|
|
|
;;; cust-print.el ends here
|