[patch][help] Additional function information
[1/6] from: ingo::2b1::de at: 21-Nov-2003 0:29
Hi All,
while looking into the vim syntx file for rebol, I thought ... "Wouldn't
it be nice to autogenerate this?".
But to do this efficiently, I need some more info within the function, so
I started to look at 'help and was amazed to find the following code snippets:
if rtype [print ["^/RETURNS:^/^-" rtype]]
and
all [set-word? :item :item = first [return:] block? first args
rtype: first args]
Well, this is the result of what happened later ;-)
>> help help
USAGE:
HELP 'word
DESCRIPTION:
Prints information about words and values.
*PATCHED* iho
Returns additional info on functions
HELP is a function value.
ARGUMENTS:
word -- (Type: any-type)
RETURNS:
does not return a value
CATEGORIES:
help
Any comments appreciated!
Ingo
-- Attached file included as plaintext by Ecartis --
-- File: help-system.r
REBOL [
Title: "Help Patch"
Author: "Ingo Hohmann"
Version: 0.0.1
File: %help-system.r
library: [
level: 'intermediate
platform: 'all
type: [ tool patch ]
domain: [patch]
tested-under: [view linux]
support: none
license: none
]
TODO: {
add todo and date fields?
}
]
func: func [
{Defines a user function with given spec and body.
*PATCHED* iho
Allows in the spec the following additional info:
return: [list of types]
category: [list of categories]
author: [author info]
these additiona are purely informational
}
[catch]
spec [block!] {Help string (opt) followed by arg words (and opt type and string)}
body [block!] "The body block of the function"
/local returns categories author fun pos
][
if all [pos: find spec first [return:] block? next pos] [
returns: pos/2
remove/part pos 2
]
if all [pos: find spec first [category:] block? next pos] [
categories: pos/2
remove/part pos 2
]
if all [pos: find spec first [author:] block? next pos] [
author: pos/2
remove/part pos 2
]
fun: throw-on-error [make function! spec body]
pos: any [find third :fun /local tail third :fun ]
if returns [insert pos compose/only [return: (returns)]]
if categories [insert pos compose/only [category: (categories)]]
if author [insert pos compose/only [author: (author)]]
:fun
]
add-function-info: func [
{Add additional info to an already defined function}
[catch]
:fun [function! native! action!] "The function to add info to"
info [block!] "block of info blocks"
return: [none]
category: [help]
author: ["Ingo Hohmann"]
/local pos
][
either parse info [
some [
set-word! block!
]
][
insert any [find third :fun /local tail third :fun] info
][
throw make error! "info block has wrong contents"
]
]
add-function-info func [
return: [function!]
category: [development]
Author: [RT "Ingo Hohmann"]
]
help: func [
{Prints information about words and values.
*PATCHED* iho
Returns additional info on functions
}
'word [any-type!]
return: ["Does not return a value"]
category: [help]
author: [RT "Ingo Hohmann"]
/local value args item name refmode types attrs rtype categorized author
][
if unset? get/any 'word [
print trim/auto {
^-^-^-^-To use HELP, supply a word or value as its
^-^-^-^-argument:
^-^-^-^-
^-^-^-^-^-help insert
^-^-^-^-^-help system
^-^-^-^-^-help system/script
^-^-^-^-To view all words that match a pattern use a
^-^-^-^-string or partial word:
^-^-^-^-^-help "path"
^-^-^-^-^-help to-
^-^-^-^-To see words with values of a specific datatype:
^-^-^-^-^-help native!
^-^-^-^-^-help datatype!
^-^-^-^-Word completion:
^-^-^-^-^-The command line can perform word
^-^-^-^-^-completion. Type a few chars and press TAB
^-^-^-^-^-to complete the word. If nothing happens,
^-^-^-^-^-there may be more than one word that
^-^-^-^-^-matches. Press TAB again to see choices.
^-^-^-^-^-Local filenames can also be completed.
^-^-^-^-^-Begin the filename with a %.
^-^-^-^-Other useful functions:
^-^-^-^-^-about - see general product info
^-^-^-^-^-usage - view program options
^-^-^-^-^-license - show terms of user license
^-^-^-^-^-source func - view source of a function
^-^-^-^-^-upgrade - updates your copy of REBOL
^-^-^-^-
^-^-^-^-More information: http://www.rebol.com/docs.html
^-^-^-}
exit
]
if all [word? :word not value? :word] [word: mold :word]
if any [string? :word all [word? :word datatype? get :word]] [
types: dump-obj/match system/words :word
sort types
if not empty? types [
print ["Found these words:" newline types]
exit
]
print ["No information on" word "(word has no value)"]
exit
]
type-name: func [value] [
value: mold type? :value
clear back tail value
join either find "aeiou" first value ["an "] ["a "] value
]
if not any [word? :word path? :word] [
print [mold :word "is" type-name :word]
exit
]
value: either path? :word [first reduce reduce [word]] [get :word]
if not any-function? :value [
prin [uppercase mold word "is" type-name :value "of value: "]
print either object? value [print "" dump-obj value] [mold :value]
exit
]
args: third :value
prin "USAGE:^/^-"
if not op? :value [prin append uppercase mold word " "]
while [not tail? args] [
item: first args
if :item = /local [break]
if any [all [any-word? :item not set-word? :item] refinement? :item] [
prin append mold :item " "
if op? :value [prin append uppercase mold word " " value: none]
]
args: next args
]
print ""
args: head args
value: get word
print "^/DESCRIPTION:"
either string? pick args 1 [
print [tab first args newline tab uppercase mold word "is" type-name :value "value."]
args: next args
] [
print "^-(undocumented)"
]
if block? pick args 1 [
attrs: first args
args: next args
]
if tail? args [exit]
while [not tail? args] [
item: first args
args: next args
if :item = /local [break]
either not refinement? :item [
all [set-word? :item :item = first [return:] block? first args rtype: first args]
all [set-word? :item :item = first [category:] block? first args categorized: first args]
all [set-word? :item :item = first [author:] block? first args author: first args]
if none? refmode [
print "^/ARGUMENTS:"
refmode: 'args
]
] [
if refmode <> 'refs [
print "^/REFINEMENTS:"
refmode: 'refs
]
]
either refinement? :item [
prin [tab mold item]
if string? pick args 1 [prin [" --" first args] args: next args]
print ""
] [
if all [any-word? :item not set-word? :item] [
if refmode = 'refs [prin tab]
prin [tab :item "-- "]
types: if block? pick args 1 [args: next args first back args]
if string? pick args 1 [prin [first args ""] args: next args]
if not types [types: 'any]
prin rejoin ["(Type: " types ")"]
print ""
]
]
]
if rtype [print ["^/RETURNS:^/^-" rtype]]
if categorized [print ["^/CATEGORIES:^/^-" categorized]]
if attrs [
print "^/(SPECIAL ATTRIBUTES)"
while [not tail? attrs] [
value: first attrs
attrs: next attrs
if any-word? value [
prin [tab value]
if string? pick attrs 1 [
prin [" -- " first attrs]
attrs: next attrs
]
print ""
]
]
]
exit
]
[2/6] from: antonr:iinet:au at: 21-Nov-2003 18:09
That's very interesting!
As this code shows, however, the "return:" has
not been used in any global functions as yet:
foreach word first system/words [
if all [
v: attempt [get in system/words word]
function? :v
find third :v first [return:]
][print [word mold third :v]]
]
;== none
Anton.
[3/6] from: ingo:2b1 at: 21-Nov-2003 8:39
Right,
so far it hasn't been possible to use it, make function! does not allow
it, and the original 'func does not work around this (like my patched
version does).
Ingo
Anton Rolls wrote:
[4/6] from: g:santilli:tiscalinet:it at: 21-Nov-2003 10:38
Hi Anton,
On Friday, November 21, 2003, 8:09:04 AM, you wrote:
AR> As this code shows, however, the "return:" has
AR> not been used in any global functions as yet:
return:
is used on routine!s.
Regards,
Gabriele.
--
Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer
Amiga Group Italia sez. L'Aquila --- SOON: http://www.rebol.it/
[5/6] from: nitsch-lists:netcologne at: 21-Nov-2003 15:35
How about using /return to mark return-values, like we do with /local?
demo: func[a b /return "the result of this demo-function" /local c d e][]
-Volker
Am Freitag, 21. November 2003 08:39 schrieb Ingo Hohmann:
[6/6] from: ingo:2b1 at: 22-Nov-2003 0:19
Hi Volker,
Volker Nitsch wrote:
> How about using /return to mark return-values, like we do with /local?
> demo: func[a b /return "the result of this demo-function" /local c d e][]
Well, return: [] is already used (for routine!s, as Gabriele pointed out,
and /return would make /return unavailable as a refinement.
Kind regards,
Ingo