/share/tcltk: add private .gitignore
[msysgit.git] / mingw / lib / tcl8.4 / history.tcl
blobb8e27ce2283d59bc5ce052ccdb284f6f2ee5da2a
1 # history.tcl --
3 # Implementation of the history command.
5 # RCS: @(#) $Id: history.tcl,v 1.5.14.1 2005/07/22 21:59:40 dgp Exp $
7 # Copyright (c) 1997 Sun Microsystems, Inc.
9 # See the file "license.terms" for information on usage and redistribution
10 # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13 # The tcl::history array holds the history list and
14 # some additional bookkeeping variables.
16 # nextid the index used for the next history list item.
17 # keep the max size of the history list
18 # oldest the index of the oldest item in the history.
20 namespace eval tcl {
21 variable history
22 if {![info exists history]} {
23 array set history {
24 nextid 0
25 keep 20
26 oldest -20
31 # history --
33 # This is the main history command. See the man page for its interface.
34 # This does argument checking and calls helper procedures in the
35 # history namespace.
37 proc history {args} {
38 set len [llength $args]
39 if {$len == 0} {
40 return [tcl::HistInfo]
42 set key [lindex $args 0]
43 set options "add, change, clear, event, info, keep, nextid, or redo"
44 switch -glob -- $key {
45 a* { # history add
47 if {$len > 3} {
48 return -code error "wrong # args: should be \"history add event ?exec?\""
50 if {![string match $key* add]} {
51 return -code error "bad option \"$key\": must be $options"
53 if {$len == 3} {
54 set arg [lindex $args 2]
55 if {! ([string match e* $arg] && [string match $arg* exec])} {
56 return -code error "bad argument \"$arg\": should be \"exec\""
59 return [tcl::HistAdd [lindex $args 1] [lindex $args 2]]
61 ch* { # history change
63 if {($len > 3) || ($len < 2)} {
64 return -code error "wrong # args: should be \"history change newValue ?event?\""
66 if {![string match $key* change]} {
67 return -code error "bad option \"$key\": must be $options"
69 if {$len == 2} {
70 set event 0
71 } else {
72 set event [lindex $args 2]
75 return [tcl::HistChange [lindex $args 1] $event]
77 cl* { # history clear
79 if {($len > 1)} {
80 return -code error "wrong # args: should be \"history clear\""
82 if {![string match $key* clear]} {
83 return -code error "bad option \"$key\": must be $options"
85 return [tcl::HistClear]
87 e* { # history event
89 if {$len > 2} {
90 return -code error "wrong # args: should be \"history event ?event?\""
92 if {![string match $key* event]} {
93 return -code error "bad option \"$key\": must be $options"
95 if {$len == 1} {
96 set event -1
97 } else {
98 set event [lindex $args 1]
100 return [tcl::HistEvent $event]
102 i* { # history info
104 if {$len > 2} {
105 return -code error "wrong # args: should be \"history info ?count?\""
107 if {![string match $key* info]} {
108 return -code error "bad option \"$key\": must be $options"
110 return [tcl::HistInfo [lindex $args 1]]
112 k* { # history keep
114 if {$len > 2} {
115 return -code error "wrong # args: should be \"history keep ?count?\""
117 if {$len == 1} {
118 return [tcl::HistKeep]
119 } else {
120 set limit [lindex $args 1]
121 if {[catch {expr {~$limit}}] || ($limit < 0)} {
122 return -code error "illegal keep count \"$limit\""
124 return [tcl::HistKeep $limit]
127 n* { # history nextid
129 if {$len > 1} {
130 return -code error "wrong # args: should be \"history nextid\""
132 if {![string match $key* nextid]} {
133 return -code error "bad option \"$key\": must be $options"
135 return [expr {$tcl::history(nextid) + 1}]
137 r* { # history redo
139 if {$len > 2} {
140 return -code error "wrong # args: should be \"history redo ?event?\""
142 if {![string match $key* redo]} {
143 return -code error "bad option \"$key\": must be $options"
145 return [tcl::HistRedo [lindex $args 1]]
147 default {
148 return -code error "bad option \"$key\": must be $options"
153 # tcl::HistAdd --
155 # Add an item to the history, and optionally eval it at the global scope
157 # Parameters:
158 # command the command to add
159 # exec (optional) a substring of "exec" causes the
160 # command to be evaled.
161 # Results:
162 # If executing, then the results of the command are returned
164 # Side Effects:
165 # Adds to the history list
167 proc tcl::HistAdd {command {exec {}}} {
168 variable history
170 # Do not add empty commands to the history
171 if {[string trim $command] eq ""} {
172 return ""
175 set i [incr history(nextid)]
176 set history($i) $command
177 set j [incr history(oldest)]
178 unset -nocomplain history($j)
179 if {[string match e* $exec]} {
180 return [uplevel #0 $command]
181 } else {
182 return {}
186 # tcl::HistKeep --
188 # Set or query the limit on the length of the history list
190 # Parameters:
191 # limit (optional) the length of the history list
193 # Results:
194 # If no limit is specified, the current limit is returned
196 # Side Effects:
197 # Updates history(keep) if a limit is specified
199 proc tcl::HistKeep {{limit {}}} {
200 variable history
201 if {$limit eq ""} {
202 return $history(keep)
203 } else {
204 set oldold $history(oldest)
205 set history(oldest) [expr {$history(nextid) - $limit}]
206 for {} {$oldold <= $history(oldest)} {incr oldold} {
207 unset -nocomplain history($oldold)
209 set history(keep) $limit
213 # tcl::HistClear --
215 # Erase the history list
217 # Parameters:
218 # none
220 # Results:
221 # none
223 # Side Effects:
224 # Resets the history array, except for the keep limit
226 proc tcl::HistClear {} {
227 variable history
228 set keep $history(keep)
229 unset history
230 array set history [list \
231 nextid 0 \
232 keep $keep \
233 oldest -$keep \
237 # tcl::HistInfo --
239 # Return a pretty-printed version of the history list
241 # Parameters:
242 # num (optional) the length of the history list to return
244 # Results:
245 # A formatted history list
247 proc tcl::HistInfo {{num {}}} {
248 variable history
249 if {$num eq ""} {
250 set num [expr {$history(keep) + 1}]
252 set result {}
253 set newline ""
254 for {set i [expr {$history(nextid) - $num + 1}]} \
255 {$i <= $history(nextid)} {incr i} {
256 if {![info exists history($i)]} {
257 continue
259 set cmd [string map [list \n \n\t] [string trimright $history($i) \ \n]]
260 append result $newline[format "%6d %s" $i $cmd]
261 set newline \n
263 return $result
266 # tcl::HistRedo --
268 # Fetch the previous or specified event, execute it, and then
269 # replace the current history item with that event.
271 # Parameters:
272 # event (optional) index of history item to redo. Defaults to -1,
273 # which means the previous event.
275 # Results:
276 # Those of the command being redone.
278 # Side Effects:
279 # Replaces the current history list item with the one being redone.
281 proc tcl::HistRedo {{event -1}} {
282 variable history
283 if {$event eq ""} {
284 set event -1
286 set i [HistIndex $event]
287 if {$i == $history(nextid)} {
288 return -code error "cannot redo the current event"
290 set cmd $history($i)
291 HistChange $cmd 0
292 uplevel #0 $cmd
295 # tcl::HistIndex --
297 # Map from an event specifier to an index in the history list.
299 # Parameters:
300 # event index of history item to redo.
301 # If this is a positive number, it is used directly.
302 # If it is a negative number, then it counts back to a previous
303 # event, where -1 is the most recent event.
304 # A string can be matched, either by being the prefix of
305 # a command or by matching a command with string match.
307 # Results:
308 # The index into history, or an error if the index didn't match.
310 proc tcl::HistIndex {event} {
311 variable history
312 if {[catch {expr {~$event}}]} {
313 for {set i [expr {$history(nextid)-1}]} {[info exists history($i)]} \
314 {incr i -1} {
315 if {[string match $event* $history($i)]} {
316 return $i;
318 if {[string match $event $history($i)]} {
319 return $i;
322 return -code error "no event matches \"$event\""
323 } elseif {$event <= 0} {
324 set i [expr {$history(nextid) + $event}]
325 } else {
326 set i $event
328 if {$i <= $history(oldest)} {
329 return -code error "event \"$event\" is too far in the past"
331 if {$i > $history(nextid)} {
332 return -code error "event \"$event\" hasn't occured yet"
334 return $i
337 # tcl::HistEvent --
339 # Map from an event specifier to the value in the history list.
341 # Parameters:
342 # event index of history item to redo. See index for a
343 # description of possible event patterns.
345 # Results:
346 # The value from the history list.
348 proc tcl::HistEvent {event} {
349 variable history
350 set i [HistIndex $event]
351 if {[info exists history($i)]} {
352 return [string trimright $history($i) \ \n]
353 } else {
354 return "";
358 # tcl::HistChange --
360 # Replace a value in the history list.
362 # Parameters:
363 # cmd The new value to put into the history list.
364 # event (optional) index of history item to redo. See index for a
365 # description of possible event patterns. This defaults
366 # to 0, which specifies the current event.
368 # Side Effects:
369 # Changes the history list.
371 proc tcl::HistChange {cmd {event 0}} {
372 variable history
373 set i [HistIndex $event]
374 set history($i) $cmd