unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* Improving the help interface
@ 2004-05-07 15:11 Andy Wingo
  2004-08-09 20:47 ` Marius Vollmer
  2004-08-09 20:47 ` Marius Vollmer
  0 siblings, 2 replies; 4+ messages in thread
From: Andy Wingo @ 2004-05-07 15:11 UTC (permalink / 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

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2004-08-15 11:41 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-05-07 15:11 Improving the help interface Andy Wingo
2004-08-09 20:47 ` Marius Vollmer
2004-08-09 20:47 ` Marius Vollmer
2004-08-15 11:41   ` Andy Wingo

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).