unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
From: Andy Wingo <wingo@pobox.com>
Subject: Improving the help interface
Date: Fri, 07 May 2004 16:11:56 +0100	[thread overview]
Message-ID: <1083942714.953.427.camel@localhost> (raw)

[-- Attachment #1: Type: text/plain, Size: 2527 bytes --]

Hey folks,

I've been working a bit on the (help ...) interface. I'll explain why
changes are needed, and what my proposed solution does.

I have an app that has a command-line interface and a graphical
interface. The graphical interface has a repl in it, as well as some
other things. One part of the graphical interface is a help browser[0].
It's a traditional tree-on-left, docs-on-right browser that can import
texinfo. In addition to that, it can show help for modules by putting
the commentary (which can have texinfo markup) on top, and individual
help for variables, functions, etc following that. The
object-documentation of the variables can be normal text, texinfo, or my
own ghetto sexp markup, which is nice for programmatic doc construction.

[0] Pretty nifty screenshot:
http://ambient.2y.net/soundscrape/shots/17-dec-2003.png

The problem is that you want (help myvar) to show text in the
command-line mode, and to open the help window to the appropriate node
in graphical mode. It might need to convert the object-documentation to
normal text for the command-line mode.

Furthermore, particular packages might have their own ways of
documenting things; GOOPS objects should be documented using `describe',
for instance.

In conclusion, the help system needs points of extensibility. There are
two points at which customization would be nice: processing the
unevaluated input to `help', and documenting a value (found in a module,
for instance). This patch deals with the latter point.

The attached patch implements "value help handlers" (as opposed to the
former "variable help handlers" or such). A value help handler is a proc
that takes a value. If it returns #f, help keeps looking for
documentation, perhaps falling back on its normal behavior. If it
returns a string, that string is taken to be its help. If it returns #t,
it means that the help has been handled in some other way (graphically,
perhaps), and `help' has nothing else to do. Value help handlers are
added with `add-value-help-handler!', and removed in a similar way.

Thoughts? I'd like this in sometime soon. In the meantime I'm throwing
it in my branch of guile-lib, with handlers for texinfo and stext in
(text structured help). This mechanism could be a way to enable more
literate programming, with the docstrings for scheme code already marked
up as texinfo, and presented in whatever format is appropriate. At
least, that's what I do with it.

ps. It's small, but I don't have papers in for Guile.
-- 
Andy Wingo <wingo@pobox.com>

[-- Attachment #2: session.scm.diff --]
[-- Type: text/x-patch, Size: 5912 bytes --]

--- src/scheme/session.scm	2004-05-07 14:50:23.000000000 +0100
+++ /usr/share/guile/1.6/ice-9/session.scm	2003-08-29 21:26:15.000000000 +0100
@@ -1,4 +1,4 @@
-;;;; 	Copyright (C) 1997, 2000, 2001, 2004 Free Software Foundation, Inc.
+;;;; 	Copyright (C) 1997, 2000, 2001 Free Software Foundation, Inc.
 ;;;;
 ;;;; 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
@@ -45,35 +45,12 @@
   :use-module (ice-9 documentation)
   :use-module (ice-9 regex)
   :use-module (ice-9 rdelim)
-  :export (help add-value-help-handler! remove-value-help-handler!
-           apropos apropos-internal apropos-fold apropos-fold-accessible
-           apropos-fold-exported apropos-fold-all source arity
-           system-module))
+  :export (help apropos apropos-internal apropos-fold
+	   apropos-fold-accessible apropos-fold-exported apropos-fold-all
+	   source arity system-module))
 
 \f
 
-(define *value-help-handlers* '())
-
-(define (add-value-help-handler! proc)
-  "Adds a handler for performing `help' on a value.
-
-`proc' will be called with the value as an argument. `proc' should
-return #t to indicate that it has performed help, a string to override
-the default object documentation, or #f to try the other handlers,
-potentially falling back on the normal behavior for `help'."
-  (set! *value-help-handlers* (cons proc *value-help-handlers*)))
-
-(define (remove-value-help-handler! proc)
-  "Removes a handler for performing `help' on a value.
-
-See the documentation for `add-value-help-handler' for more
-information."
-  (set! *value-help-handlers* (delete! proc *value-help-handlers*)))
-
-(define (try-value-help value)
-  (or-map (lambda (proc) (proc value)) *value-help-handlers*))
-
-
 ;;; Documentation
 ;;;
 (define help
@@ -108,12 +85,10 @@
                 ((and (list? name)
                       (= (length name) 2)
                       (eq? (car name) 'unquote))
-                 (let ((value (local-eval (cadr name) env)))
-                   (cond ((try-value-help value)
-                          => noop)
-                         ((object-documentation value)
-                          => write-line)
-                         (else (not-found 'documentation (cadr name))))))
+                 (cond ((object-documentation
+                         (local-eval (cadr name) env))
+                        => write-line)
+                       (else (not-found 'documentation (cadr name)))))
 
                 ;; (quote SYMBOL)
                 ((and (list? name)
@@ -159,8 +134,7 @@
   (let ((entries (apropos-fold (lambda (module name object data)
 				 (cons (list module
 					     name
-					     (or (try-value-help object)
-                                                 (object-documentation object))
+					     (object-documentation object)
 					     (cond ((closure? object)
 						    "a procedure")
 						   ((procedure? object)
@@ -186,28 +160,22 @@
                                                #f "~S: ~S\n"
                                                (module-name (module entry))
                                                (name entry))))
-                           (cond
-                            ((eq? (doc entry) #t)
-                             ;; a value help handler has already handled
-                             ;; this entry -- don't do anything
-                             #t)
-                            ((doc entry)
-                             (set! documented-entries
-                                   (cons entry-summary documented-entries))
-                             ;; *fixme*: set up a handler in goops.scm
-                             ;; to use `describe'
-                             (set! documentations
-                                   (cons (simple-format
-                                          #f "`~S' is ~A in the ~S module.\n\n~A\n"
-                                          (name entry)
-                                          (type entry)
-                                          (module-name (module entry))
-                                          (doc entry))
-                                         documentations)))
-                            (else
-                             (set! undocumented-entries
-                                   (cons entry-summary
-                                         undocumented-entries))))))
+                           (if (doc entry)
+                               (begin
+                                 (set! documented-entries
+                                       (cons entry-summary documented-entries))
+                                 ;; *fixme*: Use `describe' when we have GOOPS?
+                                 (set! documentations
+                                       (cons (simple-format
+                                              #f "`~S' is ~A in the ~S module.\n\n~A\n"
+                                              (name entry)
+                                              (type entry)
+                                              (module-name (module entry))
+                                              (doc entry))
+                                             documentations)))
+                               (set! undocumented-entries
+                                     (cons entry-summary
+                                           undocumented-entries)))))
                        entries)
 
              (if (and (not (null? documented-entries))
@@ -528,5 +496,4 @@
 	 (string-append "Module " (symbol->string (module-name m))
 			" is now a " (if s "system" "user") " module."))))))
 
-;;; arch-tag: 5348c264-6261-4b1e-b29d-c19bb0fbc94e
 ;;; session.scm ends here

[-- Attachment #3: Type: text/plain, Size: 142 bytes --]

_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel

             reply	other threads:[~2004-05-07 15:11 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-05-07 15:11 Andy Wingo [this message]
2004-08-09 20:47 ` Improving the help interface Marius Vollmer
2004-08-09 20:47 ` Marius Vollmer
2004-08-15 11:41   ` Andy Wingo

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/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1083942714.953.427.camel@localhost \
    --to=wingo@pobox.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.
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).