]>
git.zerfleddert.de Git - micropolis/blob - src/tclx/tclsrc/help.tcl
4 # Tcl help command. (see TclX manual)
6 #------------------------------------------------------------------------------
7 # Copyright 1992 Karl Lehenbauer and Mark Diekhans.
9 # Permission to use, copy, modify, and distribute this software and its
10 # documentation for any purpose and without fee is hereby granted, provided
11 # that the above copyright notice appear in all copies. Karl Lehenbauer and
12 # Mark Diekhans make no representations about the suitability of this
13 # software for any purpose. It is provided "as is" without express or
15 #------------------------------------------------------------------------------
16 # $Id: help.tcl,v 2.0 1992/10/16 04:52:01 markd Rel $
17 #------------------------------------------------------------------------------
20 #@package: TclX-help help helpcd helppwd apropos
22 #------------------------------------------------------------------------------
23 # Take a path name which might have . and .. elements and flatten them out.
25 proc help
:flattenPath
{pathName
} {
27 foreach element
[split $pathName /] {
28 if {"$element" == "."} {
31 if {"$element" == ".."} {
32 if {[llength [join $newPath /]] == 0} {
33 error "Help: name goes above subject directory root"}
34 lvarpop newPath
[expr [llength $newPath]-1]
37 lappend newPath
$element
39 set newPath
[join $newPath /]
41 # Take care of the case where we started with something line "/" or "/."
43 if {("$newPath" == "") && [string match
"/*" $pathName]} {
49 #------------------------------------------------------------------------------
50 # Take the help current directory and a path and evaluate it into a help root-
53 proc help
:EvalPath
{pathName
} {
56 if {![string match
"/*" $pathName]} {
57 if {"$pathName" == ""} {
58 return $TCLENV(help
:curDir
)}
59 if {"$TCLENV(help:curDir)" == "/"} {
60 set pathName
"/$pathName"
62 set pathName
"$TCLENV(help:curDir)/$pathName"
65 set pathName
[help
:flattenPath
$pathName]
66 if {[string match
"*/" $pathName] && ($pathName != "/")} {
67 set pathName
[csubstr
$pathName 0 [expr [length
$pathName]-1]]}
72 #------------------------------------------------------------------------------
73 # Display a line of output, pausing waiting for input before displaying if the
74 # screen size has been reached. Return 1 if output is to continue, return
75 # 0 if no more should be outputed, indicated by input other than return.
78 proc help
:Display
{line
} {
80 if {$TCLENV(help
:lineCnt
) >= 23} {
81 set TCLENV
(help
:lineCnt
) 0
82 puts stdout
":" nonewline
85 if {![lempty
$response]} {
89 incr TCLENV
(help
:lineCnt
)
92 #------------------------------------------------------------------------------
95 proc help
:DisplayFile
{filepath
} {
97 set inFH
[open $filepath r
]
98 while {[gets $inFH fileBuf
] >= 0} {
99 if {![help
:Display
$fileBuf]} {
106 #------------------------------------------------------------------------------
107 # Procedure to return contents of a directory. A list is returned, consisting
108 # of two lists. The first list are all the directories (subjects) in the
109 # specified directory. The second is all of the help files. Eash sub-list
110 # is sorted in alphabetical order.
113 proc help
:ListDir
{dirPath
} {
116 if {[catch {set dirFiles
[glob $dirPath/*]}] != 0} {
117 error "No files in subject directory: $dirPath"}
118 foreach fileName
$dirFiles {
119 if [file isdirectory
$fileName] {
120 lappend dirList
"[file tail $fileName]/"
122 lappend fileList
[file tail
$fileName]
125 return [list [lsort $dirList] [lsort $fileList]]
128 #------------------------------------------------------------------------------
129 # Display a list of file names in a column format. This use columns of 14
130 # characters 3 blanks.
132 proc help
:DisplayColumns
{nameList
} {
135 foreach name
$nameList {
139 if {[incr count
] < 4} {
140 set padLen
[expr 17-[clength
$name]]
143 append outLine
[replicate
" " $padLen]
145 if {![help
:Display
$outLine]} {
152 help
:Display
$outLine}
157 #------------------------------------------------------------------------------
160 proc help
{{subject
{}}} {
163 set TCLENV
(help
:lineCnt
) 0
165 # Special case "help help", so we can get it at any level.
167 if {($subject == "help") ||
($subject == "?")} {
168 help
:DisplayFile
"$TCLENV(help:root)/help"
172 set request
[help
:EvalPath
$subject]
173 set requestPath
"$TCLENV(help:root)$request"
175 if {![file exists
$requestPath]} {
176 error "Help:\"$request\" does not exist"}
178 if [file isdirectory
$requestPath] {
179 set dirList
[help
:ListDir
$requestPath]
180 set subList
[lindex $dirList 0]
181 set fileList
[lindex $dirList 1]
182 if {[llength $subList] != 0} {
183 help
:Display
"\nSubjects available in $request:"
184 help
:DisplayColumns
$subList
186 if {[llength $fileList] != 0} {
187 help
:Display
"\nHelp files available in $request:"
188 help
:DisplayColumns
$fileList
191 help
:DisplayFile
$requestPath
197 #------------------------------------------------------------------------------
200 # The name of the new current directory is assembled from the current
201 # directory and the argument. The name will be flatten and any trailing
202 # "/" will be removed, unless the name is just "/".
204 proc helpcd
{{dir
/}} {
207 set request
[help
:EvalPath
$dir]
208 set requestPath
"$TCLENV(help:root)$request"
210 if {![file exists
$requestPath]} {
211 error "Helpcd: \"$request\" does not exist"}
213 if {![file isdirectory
$requestPath]} {
214 error "Helpcd: \"$request\" is not a directory"}
216 set TCLENV
(help
:curDir
) $request
220 #------------------------------------------------------------------------------
225 echo
"Current help subject directory: $TCLENV(help:curDir)"
228 #==============================================================================
229 # Tcl apropos command. (see Tcl shell manual)
230 #------------------------------------------------------------------------------
232 proc apropos
{name
} {
235 set TCLENV
(help
:lineCnt
) 0
237 set aproposCT
[scancontext create
]
238 scanmatch
-nocase $aproposCT $name {
239 set path
[lindex $matchInfo(line
) 0]
240 set desc
[lrange $matchInfo(line
) 1 end
]
241 if {![help
:Display
[format "%s - %s" $path $desc]]} {
244 foreach brief
[glob -nocomplain $TCLENV(help
:root
)/*.brf
] {
245 set briefFH
[open $brief]
246 scanfile
$aproposCT $briefFH
249 scancontext delete
$aproposCT
252 #------------------------------------------------------------------------------
253 # One time initialization done when the file is sourced.
255 global TCLENV TCLPATH
257 set TCLENV
(help
:root
) [searchpath
$TCLPATH help
]
258 set TCLENV
(help
:curDir
) "/"
259 set TCLENV
(help
:outBuf
) {}