From: Steve Yegge <steve.yegge@gmail.com>
Subject: show-buffer-local-variables
Date: Sat, 1 Oct 2005 06:02:07 -0700 [thread overview]
Message-ID: <d494cb8f0510010602i1318f7f5re95b64ca59aa5444@mail.gmail.com> (raw)
[-- Attachment #1.1: Type: text/plain, Size: 1097 bytes --]
Hello Emacs developers,
I noticed this entry in emacs/etc/TODO:
** Add a command to make a local variables list in the current buffer
and/or add a variable to the list.
I recently wrote a function that does the former, if I understand the
entry correctly. It shows an apropos-style listing of the current
buffer's local variables.
I've cleaned up the function and included it in the attached file,
`show-buffer.el'. If you think it may be a useful addition to
Emacs, I'd be happy to contribute it. I'm also open to suggestions
for improving it.
On a related topic, I think `apropos.el' ought to be rewritten
with an eye towards reusability. I've got several other packages
underway that provide apropos-like commands. It would be nice to
reuse `apropos-print' to display the results, for a consistent
user experience. But both `apropos' and `apropos-print' are rather
monolithic, so I'm forced to copy and paste a lot of the code.
I will gladly volunteer for refactoring `apropos.el', if you think
it would be worthwhile.
Cheers,
Steve Yegge
stevey@gmail.com
[-- Attachment #1.2: Type: text/html, Size: 1299 bytes --]
[-- Attachment #2: show-buffer.el --]
[-- Type: application/octet-stream, Size: 5634 bytes --]
;;; show-buffer.el --- buffer-local variable commands and functions
;; Copyright (C) 2005 Steve Yegge
;; Author: Steve Yegge (steve.yegge@gmail.com)
;; Keywords: help
;; This file is not part of GNU Emacs.
;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License
;; as published by the Free Software Foundation; either version 2
;; of the License, or any later version.
;; This program 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.
;; <http://www.gnu.org/copyleft/gpl.html>.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;; Commentary:
;; This file should be byte-compiled for speed.
;;; TODO(stevey):
;; - would be nice to show variable (value) types
;;; History:
;;; Code:
(require 'apropos)
(eval-when-compile (require 'cl))
(defvar show-buffer-local-value-preview-length 64
"Maximum length of the buffer-local-variable value preview line.")
(defvar show-buffer-local-skip-boring-plists t
"Nil to print plists with only a `variable-documentation' property.
If non-nil, such uninteresting plists are elided.")
;;;###autoload
(defun show-buffer-local-variables (&optional buf)
"Show an `apropos'-style list of buffer-local variables for BUF."
(interactive)
(or buf (setq buf (current-buffer)))
(with-output-to-temp-buffer "*buffer-locals*"
(set-buffer standard-output)
(let* ((vars (sort (mapcar (lambda (e)
(if (consp e) (car e) e))
(buffer-local-variables buf))
#'string<))
(len (length vars)))
(princ
(format "%d buffer-local variable%s for buffer %s:\n\n"
len
(if (eq 1 len) "" "s")
(buffer-name buf)))
(if (null vars)
(princ "\n(none)")
(progn
(dolist (symbol vars)
(show-buffer-print-var-doc symbol))
(setq buffer-read-only t)
(apropos-mode))))))
(defun show-buffer-print-var-doc (sym)
"Prints apropos-style docs for SYM to standard output.
Includes a 1-line preview of the variable's value."
(let (p1 p2 value trunc)
(show-buffer-make-apropos-args sym)
;; apropos-print-doc doesn't handle the symbol (sigh)
(princ sym)
(setq p1 (point-at-bol) p2 (point))
(terpri)
(put-text-property p1 p2 'item (car apropos-item))
(if apropos-symbol-face
(put-text-property p1 p2 'face apropos-symbol-face))
;; print a truncated 1-line representation of the value
(setq value (format "%s"
(if (boundp sym)
(symbol-value sym)
"(locally unbound)")))
(setq trunc
(truncate-string-to-width
value show-buffer-local-value-preview-length))
(if (string< trunc value)
(setq value (concat trunc " [...]")))
(princ (format " Value: %s" value))
(terpri)
;; use apropos printing functions for the rest
(apropos-print-doc 'describe-variable 2 "Variable" t)
(apropos-print-doc 'customize-group-other-window 6 "Group" t)
(apropos-print-doc 'describe-face 5 "Face" t)
(apropos-print-doc 'widget-browse-other-window 4 "Widget" t)
(apropos-print-doc 'apropos-describe-plist 3 "Plist" nil)))
;; this function is mostly copied out of `apropos-print',
;; which isn't factored well enough to reuse without copying.
;; It does some things differently, however.
(defun show-buffer-make-apropos-args (sym)
"Constructs the `apropos-print' documentation list for SYM.
Sets '(symbol fn-doc var-doc plist-doc widget-doc face-doc custom-doc)
as the value of the `apropos-item' global variable."
(let ((unknown "(not documented") symbol doc)
(setq
apropos-item
(list
sym ; variable name
nil ; don't show function bindings
;; variable documentation, if any
(if (boundp sym)
(if (setq doc (documentation-property
sym 'variable-documentation t))
(substring doc 0 (string-match "\n" doc)))
unknown)
;; plist names
(loop for s in (symbol-plist sym)
by #'cddr ;; prop names are every odd element in plist
collect s into props
finally return
(and props
(not (and show-buffer-local-skip-boring-plists
(eq 1 (length props))
(eq (car props) 'variable-documentation)))
(mapconcat #'symbol-name props " ")))
;; remaining doc types for VAR, if any
(when (get sym 'widget-type)
(if (setq doc (documentation-property
sym 'widget-documentation t))
(substring doc 0 (string-match "\n" doc))
unknown))
(when (facep sym)
(if (setq doc (documentation-property
sym 'face-documentation t))
(substring doc 0 (string-match "\n" doc))
unknown))
(when (get sym 'custom-group)
(if (setq doc (documentation-property
sym 'group-documentation t))
(substring doc 0 (string-match "\n" doc))
unknown))))))
(provide 'show-buffer)
;;; show-buffer.el ends here
[-- Attachment #3: Type: text/plain, Size: 142 bytes --]
_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-devel
next reply other threads:[~2005-10-01 13:02 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-10-01 13:02 Steve Yegge [this message]
2005-10-01 23:26 ` show-buffer-local-variables Richard M. Stallman
2005-10-02 20:22 ` show-buffer-local-variables Juri Linkov
2005-10-03 14:42 ` show-buffer-local-variables Stefan Monnier
2005-10-04 5:02 ` show-buffer-local-variables Richard M. Stallman
2005-10-02 21:15 ` show-buffer-local-variables Ken Manheimer
2005-10-03 15:34 ` show-buffer-local-variables Richard M. Stallman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=d494cb8f0510010602i1318f7f5re95b64ca59aa5444@mail.gmail.com \
--to=steve.yegge@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).