Overview
Comment: | tclreadline.c tclreadlineCompleter.tcl |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
ea4e9a080fed5d5a1bdb87cacefeb7c9 |
User & Date: | johannes@zellner.org on 1999-09-13 00:21:47 |
Other Links: | manifest | tags |
Context
1999-09-13
| ||
16:33 | .tclshrc .vimrc Modified Files: Makefile.in configure.in sample.tclshrc tclreadline.c tclreadline.h.in Added Files: config.h.in check-in: 0d1401e9c1 user: johannes@zellner.org tags: trunk | |
00:21 | tclreadline.c tclreadlineCompleter.tcl check-in: ea4e9a080f user: johannes@zellner.org tags: trunk | |
1999-09-10
| ||
19:01 | Modified Files: Tag: 2.0 GPL README TODO configure.in pkgIndex.tcl.in sample.tclshrc sources tclreadline.h.in tclreadline.n.in tclreadlineCompleter.tcl tclreadlineSetup.tcl.in aux/config.guess aux/config.sub aux/install-sh aux/mkinstalldirs aux/tcltags aux/vimtags Added Files: Tag: 2.0 Makefile.in tclreadline.c tclreadlineConfig.sh.in tclreadlineInit.tcl.in check-in: e0dfd309af user: johannes@zellner.org tags: trunk | |
Changes
Modified tclreadline.c from [19dbcdadd7] to [3d6f99eaa5].
1 1 2 2 /* ================================================================== 3 3 4 4 FILE: "/home/joze/src/tclreadline/tclreadline.c" 5 - LAST MODIFICATION: "Fri Sep 10 02:57:55 1999 (joze)" 5 + LAST MODIFICATION: "Mon Sep 13 02:21:35 1999 (joze)" 6 6 (C) 1998, 1999 by Johannes Zellner, <johannes@zellner.org> 7 7 $Id$ 8 8 --- 9 9 10 10 tclreadline -- gnu readline for tcl 11 11 Copyright (C) 1999 Johannes Zellner 12 12 ................................................................................ 472 472 * default is " \t\n\"\\'`@$><=;|&{(" 473 473 * removed "(" <-- arrays 474 474 * removed "{" <-- `${' variables 475 475 * removed "<" <-- completion lists with < ... > 476 476 * added "[]" 477 477 * added "}" 478 478 */ 479 - rl_basic_word_break_characters = " \t\n\"\\@$}>=;|&[]"; 479 + /* 11.Sep rl_basic_word_break_characters = " \t\n\"\\@$}=;|&[]"; */ 480 + /* besser (11. Sept) 2. (removed \") */ 481 + /* rl_basic_word_break_characters = " \t\n\\@$}=;|&[]"; */ 482 + /* besser (11. Sept) 3. (removed }) */ 483 + rl_basic_word_break_characters = " \t\n\\@$=;|&[]"; 480 484 // rl_basic_quote_characters = "\"{"; // XXX ??? XXX 481 485 // rl_completer_quote_characters = "\""; 482 486 /* 483 487 rl_filename_quote_characters 484 488 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 485 489 486 490 rl_filename_quoting_function ................................................................................ 522 526 523 527 char** 524 528 TclReadlineCompletion(char* text, int start, int end) 525 529 { 526 530 char** matches = (char**) NULL; 527 531 int status; 528 532 // rl_attempted_completion_over = 0; 533 + rl_completion_append_character = ' '; /* reset, just in case ... */ 529 534 530 535 #if 0 531 536 fprintf(stderr, "DEBUG> TclReadlineCompletion: text=|%s|\n", text); 532 537 fprintf(stderr, "DEBUG> TclReadlineCompletion: start=|%d|\n", start); 533 538 fprintf(stderr, "DEBUG> TclReadlineCompletion: end=|%d|\n", end); 534 539 #endif 535 540 ................................................................................ 624 629 return (char**) NULL; 625 630 } 626 631 /* 627 632 fprintf (stderr, "(TclReadlineCompletion) len[%s]=%d\n", 628 633 matches[i], strlen(matches[i])); 629 634 */ 630 635 } 636 + 637 + /** 638 + * this is a special one: 639 + * if the script returns exactly two arguments 640 + * and the second argument is the empty string, 641 + * the rl_completion_append_character is set 642 + * temporaryly to NULL. 643 + */ 644 + if (2 == objc && !strlen(matches[1])) { 645 + i--; 646 + FREE(matches[1]); 647 + rl_completion_append_character = '\0'; 648 + } 649 + 631 650 matches[i] = (char*) NULL; /* terminate */ 632 651 } 633 652 Tcl_ResetResult(tclrl_interp); /* clear result space */ 634 653 } 635 654 636 655 if (!matches && tclrl_use_builtin_completer) { 637 656 matches = completion_matches(text, TclReadline0generator);
Modified tclreadlineCompleter.tcl from [d03579b986] to [6becbaf62d].
1 1 #!/usr/locanl/bin/tclsh 2 2 # FILE: "/home/joze/src/tclreadline/tclreadlineCompleter.tcl" 3 -# LAST MODIFICATION: "Fri Sep 10 03:06:31 1999 (joze)" 3 +# LAST MODIFICATION: "Mon Sep 13 02:21:21 1999 (joze)" 4 4 # (C) 1998, 1999 by Johannes Zellner, <johannes@zellner.org> 5 5 # $Id$ 6 6 # --- 7 7 # 8 8 # tclreadline -- gnu readline for tcl 9 9 # Copyright (C) 1999 Johannes Zellner 10 10 # ................................................................................ 23 23 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 24 24 # 25 25 # johannes@zellner.org 26 26 # http://www.zellner.org/tclreadline/ 27 27 # 28 28 # ================================================================== 29 29 30 -# done: 31 -# 32 -# - after 33 -# - append 34 -# - array 35 -# - bgerror 36 -# - binary 37 -# - break 38 -# - catch 39 -# - cd 40 -# - clock 41 -# - close 42 -# - concat 43 -# - continue 44 -# - (ddd is only on M$) 45 -# - encoding 46 -# - eof 47 -# - error 48 -# - eval 49 -# - exec 50 -# - exit 51 -# - expr 52 -# - fblocked 53 -# - fconfigure 54 -# - fcopy 55 -# - file 56 -# - fileevent 57 -# - flush 58 -# - for # TODO 59 -# - foreach # TODO 60 -# - format # TODO 61 -# - gets 62 -# - glob 63 -# - global 64 -# - if # TODO 65 -# - incr 66 -# - index 67 -# - info 68 -# - interp 69 -# - join 70 -# - lappend 71 -# - llength 72 -# - linsert 73 -# - list 74 -# - load 75 -# - lrange 76 -# - lreplace 77 -# - lsearch 78 -# - lsort 79 -# - history 80 -# - load 81 -# - namespace 82 -# - open 83 -# - package 84 -# - pkg_mkIndex 85 -# - proc 86 -# - puts 87 -# - pwd 88 -# - pid 89 -# - read 90 -# - regexp 91 -# - (registry is only on M$) 92 -# - regsub 93 -# - rename 94 -# - (resource is on mac only) 95 -# - return 96 -# - scan # TODO 97 -# - seek 98 -# - socket 99 -# - source 100 -# - split # TODO 101 -# - string 102 -# - subst 103 -# - switch 104 -# - tell 105 -# - time # TODO ?? 106 -# - trace 107 -# - set 108 -# - unknown 109 -# - unset 110 -# - update 111 -# - uplevel 112 -# - upvar 113 -# - variable 114 -# - vwait 115 -# - while # TODO 116 -# 30 + 31 +# TODO: 32 +# 33 +# - tcltest is missing 34 +# 35 +# - last try: as for widgets 36 +# 37 + 117 38 118 39 119 40 namespace eval tclreadline { 120 41 42 +namespace export \ 43 +TryFromList CompleteFromList DisplayHints Rehash \ 44 +PreviousWord CommandCompletion RemoveUsedOptions \ 45 +HostList ChannelId InChannelId OutChannelId \ 46 +Lindex Llength CompleteBoolean 47 + 48 +#** 121 49 # TryFromList will return an empty string, if 122 50 # the text typed so far does not match any of the 123 51 # elements in list. This might be used to allow 124 52 # subsequent filename completion by the builtin 125 53 # completer. 126 54 # 127 -proc TryFromList {text lst} { 55 +proc TryFromList {text lst {allow ""}} { 128 56 129 57 # puts stderr "(CompleteFromList) \ntext=|$text|" 130 58 # puts stderr "(CompleteFromList) lst=|$lst|" 131 59 set pre [GetQuotedPrefix ${text}] 132 - set matches [MatchesFromList $text $lst] 60 + set matches [MatchesFromList $text $lst $allow] 133 61 134 62 # puts stderr "(CompleteFromList) matches=|$matches|" 135 63 if {1 == [llength $matches]} { ; # unique match 136 64 # puts stderr \nunique=$matches\n 137 65 # puts stderr "\n|${pre}${matches}[Right ${pre}]|\n" 138 - return [string trim ${pre}${matches}[Right ${pre}]] 66 + set null [string index $matches 0] 67 + if {"<" == $null || "?" == $null} { 68 + return [string trim "[list $text] $lst"] 69 + } else { 70 + return [string trim ${pre}${matches}[Right ${pre}]] 71 + } 139 72 } elseif {"" != ${matches}} { 140 73 # puts stderr \nmore=$matches\n 141 74 set longest [CompleteLongest ${matches}] 142 75 # puts stderr longest=|$longest| 143 76 if {"" == $longest} { 144 77 return [string trim "[list $text] ${matches}"] 145 78 } else { ................................................................................ 146 79 return [string trim "${pre}${longest} ${matches}"] 147 80 } 148 81 } else { 149 82 return ""; # nothing to complete 150 83 } 151 84 } 152 85 86 +#** 153 87 # CompleteFromList will never return an empty string. 154 88 # completes, if a completion can be done, or ring 155 89 # the bell if not. 156 90 # 157 91 proc CompleteFromList {text lst} { 158 92 set result [TryFromList ${text} ${lst}] 159 93 if {![llength ${result}]} { 160 94 Alert 161 95 # return [string trim [list ${text}] ${lst}"] 162 - return [string trim "${text} ${lst}"] 96 + if {[llength ${lst}]} { 97 + return [string trim "${text} ${lst}"] 98 + } else { 99 + return [string trim [list ${text} {}]] 100 + } 163 101 } else { 164 102 return ${result} 165 103 } 166 104 } 167 105 168 -proc MenuFromList {text lst} { 169 - return [CompleteFromList $text $lst] 106 +#** 107 +# CompleteBoolean does a CompleteFromList 108 +# with a list of all valid boolean values. 109 +# 110 +proc CompleteBoolean {text} { 111 + return [CompleteFromList $text {yes no true false 1 0}] 170 112 } 171 -# ??????? 113 + 114 +#** 115 +# build a list of all executables which can be 116 +# found in $env(PATH). This is (naturally) a bit 117 +# slow, and should not called frequently. Instead 118 +# it is a good idea to check if the variable 119 +# `executables' exists and then just use it's 120 +# content instead of calling Rehash. 121 +# (see complete(exec)). 172 122 # 173 -# proc MenuFromList {text lst} { 174 -# if {![llength ${text}]} { 175 -# return [string trim "{} ${lst}"] 176 -# } else { 177 -# return [TryFromList ${text} ${lst}] 178 -# } 179 -# } 123 +proc Rehash {} { 124 + 125 + global env 126 + variable executables 127 + 128 + if {![info exists env] || ![array exists env]} { 129 + return 130 + } 131 + if {![info exists env(PATH)]} { 132 + return 133 + } 134 + 135 + set executables 0 136 + foreach dir [split $env(PATH) :] { 137 + if {[catch [list set files [glob -nocomplain ${dir}/*]]]} { continue } 138 + foreach file $files { 139 + if {[file executable $file]} { 140 + lappend executables [file tail $file] 141 + } 142 + } 143 + } 144 +} 145 + 146 +#** 147 +# build a list hosts from the /etc/hosts file. 148 +# this is only done once. This is sort of a 149 +# dirty hack, /etc/hosts is hardcoded ... 180 150 # 181 - 151 +proc HostList {} { 152 + # read the host table only once. 153 + # 154 + variable hosts 155 + if {![info exists hosts]} { 156 + catch { 157 + set id [open /etc/hosts r] 158 + set hosts "" 159 + if {0 != ${id}} { 160 + while {-1 != [gets ${id} line]} { 161 + regsub {#.*} ${line} {} line 162 + if {[llength ${line}] >= 2} { 163 + lappend hosts [lindex ${line} 1] 164 + } 165 + } 166 + close $id 167 + } 168 + } 169 + } 170 + return $hosts 171 +} 182 172 183 173 #** 184 174 # never return an empty string, never complete. 185 175 # This is useful for showing options lists for example. 186 176 # 187 177 proc DisplayHints {lst} { 188 178 return [string trim "{} ${lst}"] 189 179 } 190 180 191 181 #** 192 -# find (partial) matches for `text' in `lst'. 193 -# Ring the bell and return the whole list, if 194 -# the user tries to complete ?..? options or 195 -# <..> hints. 182 +# find (partial) matches for `text' in `lst'. Ring 183 +# the bell and return the whole list, if the user 184 +# tries to complete ?..? options or <..> hints. 196 185 # 197 -proc MatchesFromList {text lst} { 186 +# MatchesFromList returns a list which is not suitable 187 +# for passing to the readline completer. Thus, 188 +# MatchesFromList should not be called directly but 189 +# from formatting routines as TryFromList. 190 +# 191 +proc MatchesFromList {text lst {allow ""}} { 198 192 set result "" 199 193 set text [StripPrefix $text] 200 194 set null [string index $text 0] 201 - if {"<" == $null || "?" == $null} { 202 - Alert 203 - return $lst 195 + foreach char {< ?} { 196 + if {$char == $null && -1 == [string first $char $allow]} { 197 + Alert 198 + return $lst 199 + } 204 200 } 205 201 # puts stderr "(MatchesFromList) text=$text" 206 202 # puts stderr "(MatchesFromList) lst=$lst" 207 203 foreach word $lst { 208 204 if {[string match ${text}* ${word}]} { 209 205 lappend result ${word} 210 206 } ................................................................................ 224 220 return ${expr_pos} 225 221 } 226 222 227 223 proc RemoveUsedOptions {line opts {terminate {}}} { 228 224 if {[llength ${terminate}]} { 229 225 if {[regexp -- ${terminate} ${line}]} { 230 226 return "" 227 + # return ${terminate} 231 228 } 232 229 } 233 230 set new "" 234 231 foreach word ${opts} { 235 - if {![regexp -- ${word} ${line}]} { 232 + if {-1 == [string first ${word} ${line}]} { 236 233 lappend new ${word} 237 234 } 238 235 } 239 236 return [string trim ${new}] 240 237 } 241 238 242 239 proc Alert {} { 243 240 puts -nonewline \a 244 241 flush stdout 245 242 } 246 243 247 - 244 +#** 248 245 # get the longest common completion 249 246 # e.g. str == {tcl_version tclreadline_version tclreadline_library} 250 247 # --> [CompleteLongest ${str}] == "tcl" 251 248 # 252 249 proc CompleteLongest {str} { 253 250 # puts stderr str=$str 254 251 set match0 [lindex ${str} 0] ................................................................................ 320 317 if {1 < [llength $value] && "" == $right} { 321 318 return [list \"${value}\"] 322 319 } else { 323 320 return [list ${left}${value}${right}] 324 321 } 325 322 } 326 323 327 -proc InChannelId {text} { 328 - # return [ChannelId ${text} inChannel {stdin}] 329 - return [ChannelId ${text} inChannel] 324 +# the following two channel proc's make use of 325 +# the brandnew (Sep 99) `file channels' command 326 +# but have some fallback behaviour for older 327 +# tcl version. 328 +# 329 +proc InChannelId {text {switches ""}} { 330 + if [catch {set chs [file channels]}] { 331 + set chs {stdin} 332 + } 333 + set result "" 334 + foreach ch $chs { 335 + if {![catch {fileevent $ch readable}]} { 336 + lappend result $ch 337 + } 338 + } 339 + return [ChannelId ${text} <inChannel> $result $switches] 330 340 } 331 341 332 -proc OutChannelId {text} { 333 - # return [ChannelId ${text} outChannel {stdout stderr}] 334 - return [ChannelId ${text} outChannel] 342 +proc OutChannelId {text {switches ""}} { 343 + if [catch {set chs [file channels]}] { 344 + set chs {stdout stderr} 345 + } 346 + set result "" 347 + foreach ch $chs { 348 + if {![catch {fileevent $ch writable}]} { 349 + lappend result $ch 350 + } 351 + } 352 + return [ChannelId ${text} <outChannel> $result $switches] 335 353 } 336 354 337 -proc ChannelId {text {descript channelId} {chs ""}} { 355 +proc ChannelId {text {descript <channelId>} {chs ""} {switches ""}} { 338 356 if {"" == ${chs}} { 339 357 # the `file channels' command is present 340 358 # only in pretty new versions. 341 359 # 342 360 if [catch {set chs [file channels]}] { 343 361 set chs {stdin stdout stderr} 344 362 } 345 363 } 346 - if {[llength [set channel [MatchesFromList ${text} ${chs}]]]} { 364 + if {[llength [set channel [TryFromList ${text} "${chs} ${switches}"]]]} { 347 365 return ${channel} 348 366 } else { 349 - return [DisplayHints ${descript}] 367 + return [DisplayHints [string trim "${descript} ${switches}"]] 350 368 } 351 369 } 352 370 353 371 proc QuoteQuotes {line} { 354 372 regsub -all -- \" $line {\"} line 355 373 regsub -all -- \{ $line {\{} line; # \}\} (keep the editor happy) 356 374 return $line ................................................................................ 400 418 # return [llength $pre_text] 401 419 # 402 420 } 403 421 404 422 proc Right {left} { 405 423 # puts left=$left 406 424 if {"\"" == $left} { 407 - return {\"} 425 + return "\"" 408 426 } elseif {"\\\"" == $left} { 409 427 return "\\\"" 410 428 } elseif {"\{" == $left} { 411 429 return "\}" 412 430 } elseif {"\\\{" == $left} { 413 431 return "\\\}" 414 432 } ................................................................................ 430 448 set pos 0 431 449 while {-1 != [set pos [string first $char $line $pos]]} { 432 450 incr pos 433 451 incr found 434 452 } 435 453 return $found 436 454 } 455 + 456 +#** 457 +# make a proper tcl list from an icomplete 458 +# string, that is: remove the junk. This is 459 +# complementary to `IncompleteListRemainder'. 460 +# e.g.: 461 +# for {set i 1} " 462 +# --> for {set i 1} 463 +# 464 +proc ProperList {line} { 465 + set last [expr [string length $line] - 1] 466 + for {set i $last} {$i >= 0} {incr i -1} { 467 + if {![catch {llength [string range $line 0 $i]}]} { 468 + break 469 + } 470 + } 471 + return [string range $line 0 $i] 472 +} 473 + 474 +#** 475 +# return the last part of a line which 476 +# prevents the line from beeing a list. 477 +# This is complementary to `ProperList'. 478 +# 479 +proc IncompleteListRemainder {line} { 480 + set last [expr [string length $line] - 1] 481 + for {set i $last} {$i >= 0} {incr i -1} { 482 + if {![catch {llength [string range $line 0 $i]}]} { 483 + break 484 + } 485 + } 486 + incr i 487 + return [string range $line $i end] 488 +} 437 489 438 490 #** 439 491 # save `lindex'. works also for non-complete lines 440 492 # with opening parentheses or quotes. 441 493 # usage as `lindex'. 494 +# Eventually returns the Rest of an incomplete line, 495 +# if the index is `end' or == [Llength $line]. 442 496 # 443 497 proc Lindex {line pos} { 444 498 if {[catch [list set sub [lindex $line $pos]]]} { 445 - set diff [expr [CountChar $line \{] - [CountChar $line \}]] 446 - # puts stderr diff=$diff 447 - for {set i 0} {$i < $diff} {incr i} { ; # \{ keep the editor happy 448 - append line \} 499 + if {"end" == $pos || [Llength $line] == $pos} { 500 + return [IncompleteListRemainder $line] 449 501 } 450 - # puts stderr line=$line 451 - if {!$diff || [catch [list set sub [lindex $line $pos]]]} { 452 - if {[expr [CountChar $line \"] % 2]} { append line \" } 453 - } 502 + set line [ProperList $line] 503 + # puts stderr \nproper_line=|$proper_line| 454 504 if {[catch [list set sub [lindex $line $pos]]]} { return {} } 455 505 } 456 506 return $sub 457 507 } 458 508 459 509 #** 460 510 # save `llength' (see above). 461 511 # 462 512 proc Llength {line} { 463 - set diff 0 464 513 if {[catch [list set len [llength $line]]]} { 465 - set diff [expr [CountChar $line \{] - [CountChar $line \}]] 466 - # puts stderr diff=$diff 467 - for {set i 0} {$i < $diff} {incr i} { ; # \{ keep the editor happy 468 - append line \} 469 - } 470 - if {$diff < 0} { 471 - set diff 0 472 - } 473 - # puts stderr line=$line 474 - if {!$diff || [catch [list set len [llength $line]]]} { 475 - incr diff 476 - if {[expr [CountChar $line \"] % 2]} { append line \" } 477 - } 514 + set line [ProperList $line] 478 515 if {[catch [list set len [llength $line]]]} { return {} } 479 516 } 480 - return [expr $len - $diff] 517 + # puts stderr \nline=$line 518 + return $len 481 519 } 482 520 483 521 proc StripPrefix {text} { 484 522 # puts "(StripPrefix) text=|$text|" 485 523 set null [string index $text 0] 486 524 if {"\"" == $null || "\{" == $null} { 487 525 return [string range $text 1 end] 488 526 } else { 489 527 return $text 490 528 } 491 529 } 492 530 493 -proc ListCompletion {text {level -1}} { 494 - # TODO 495 - return "" 496 - # return [VarCompletion ${text} ${level}] 497 -} 498 - 499 531 proc VarCompletion {text {level -1}} { 500 532 if {-1 == ${level}} { 501 533 set level [info level] 502 534 } else { 503 535 incr level 504 536 } 505 537 set pre [GetQuotedPrefix ${text}] ................................................................................ 533 565 } 534 566 set namespaces ${new} 535 567 unset new 536 568 } 537 569 set matches \ 538 570 [string trim "[uplevel ${level} info vars ${var}*] ${namespaces}"] 539 571 if {1 == [llength $matches]} { ; # unique match 572 + 540 573 # check if this unique match is an 541 574 # array name, (whith no "(" yet). 542 575 # 543 576 if {[uplevel ${level} array exists $matches]} { 544 577 return [VarCompletion ${matches}( ${level}]; # recursion 545 578 } else { 546 579 return ${pre}${matches}[Right ${pre}] 547 580 } 548 581 } elseif {"" != $matches} { ; # more than one match 549 - #puts stderr "(VarComletion) matches=|$matches|" 550 - #puts stderr "(VarComletion) text=|$text|" 551 -# 552 -# set common [CompleteLongest ${matches}] 553 -# if {"" == ${common}} { 554 -# return [Format ${matches} ${text}] 555 -# } else { 556 -# return [string trim "${pre}${common} ${matches}"] 557 -# } 558 -# 559 582 return [CompleteFromList ${text} ${matches}] 560 583 } else { 561 584 return ""; # nothing to complete 562 585 } 563 586 } 587 + 588 +proc CompleteControlStatement {text start end line pos mod pre new_line} { 589 + set pre [GetQuotedPrefix ${pre}] 590 + set cmd [Lindex $new_line 0] 591 + set diff [expr \ 592 + [string length $line] - [string length $new_line]] 593 + if {$diff == [expr $start + 1]} { 594 + set mod1 $mod 595 + } else { 596 + set mod1 $text 597 + set pre "" 598 + } 599 + set new_end [expr $end - $diff] 600 + set new_start [expr $new_end - [string length $mod1]] 601 + # puts "" 602 + # puts new_start=$new_start 603 + # puts new_end=$new_end 604 + # puts new_line=$new_line 605 + # puts mod1=$mod1 606 + if {$new_start < 0} { 607 + return ""; # when does this occur? 608 + } 609 + # puts stderr "" 610 + # puts stderr start=|$start| 611 + # puts stderr end=|$end| 612 + # puts stderr mod=|$mod| 613 + # puts stderr new_start=|$new_start| 614 + # puts stderr new_end=|$new_end| 615 + # puts stderr new_line=|$new_line| 616 + # puts stderr "" 617 + set res [ScriptCompleter $mod1 $new_start $new_end $new_line] 618 + # puts stderr \n\${pre}\${res}=|${pre}${res}| 619 + if {[string length [Lindex ${res} 0]]} { 620 + return ${pre}${res} 621 + } else { 622 + return ${res} 623 + } 624 + return "" 625 +} 626 + 627 +proc BraceOrControlStatement {text start end line pos mod} { 628 + if {![string length [Lindex $line $pos]]} { 629 + return [list \{ {}]; # \} 630 + } else { 631 + set new_line [string trim [IncompleteListRemainder $line]] 632 + if {![regexp {^([\{\"])(.*)$} $new_line all pre new_line]} { 633 + set pre "" 634 + } 635 + return [CompleteControlStatement $text \ 636 + $start $end $line $pos $mod $pre $new_line] 637 + } 638 +} 564 639 565 640 proc FullQualifiedMatches {qualifier matchlist} { 566 641 set new "" 642 + if {"" != $qualifier && ![regexp ::$ $qualifier]} { 643 + append qualifier :: 644 + } 567 645 foreach entry ${matchlist} { 568 - set full ${qualifier}::${entry} 646 + set full ${qualifier}${entry} 569 647 if {"" != [namespace which ${full}]} { 570 648 lappend new ${full} 571 649 } 572 650 } 573 651 return ${new} 574 652 } 575 653 ................................................................................ 577 655 return [CommandCompletion ${cmd} procs] 578 656 } 579 657 580 658 proc CommandsOnlyCompletion {cmd} { 581 659 return [CommandCompletion ${cmd} commands] 582 660 } 583 661 584 -proc CommandCompletion {cmd {action both} {spc ::}} { 662 +proc CommandCompletion {cmd {action both} {spc ::} {pre UNDEFINED}} { 585 663 # puts stderr "(CommandCompletion) cmd=|$cmd|" 586 664 # puts stderr "(CommandCompletion) action=|$action|" 587 665 # puts stderr "(CommandCompletion) spc=|$spc|" 666 + 667 + # get the leading colons in `cmd'. 668 + if {"UNDEFINED" == $pre} { 669 + regexp {^:*} ${cmd} pre 670 + } 671 + # puts stderr \npre=|$pre| 672 + 673 + set cmd [StripPrefix ${cmd}] 588 674 set quali [namespace qualifiers ${cmd}] 589 - if {[llength ${quali}]} { 590 - set rec [CommandCompletion [namespace tail ${cmd}] ${action} ${quali}] 591 - return [FullQualifiedMatches ${quali} ${rec}] 675 + if {[string length ${quali}]} { 676 + # puts stderr \nquali=|$quali| 677 + set matches [CommandCompletion \ 678 + [namespace tail ${cmd}] ${action} ${spc}${quali} ${pre}] 679 + # puts stderr \nmatches1=|$matches| 680 + return $matches 592 681 } 593 - # puts stderr \ncmd=|$cmd|\n 594 682 set cmd [string trim ${cmd}]* 683 + # puts stderr \ncmd=|$cmd|\n 595 684 if {"procs" != ${action}} { 596 - set commands [namespace eval $spc "info commands [QuoteQuotes ${cmd}]"] 597 - # puts stderr commands=|$commands| 685 + set all_commands [namespace eval $spc [list info commands ${cmd}]] 686 + # puts stderr all_commands=|$all_commands| 687 + set commands "" 688 + foreach command $all_commands { 689 + if {[namespace eval $spc [list namespace origin $command]] == \ 690 + [namespace eval $spc [list namespace which $command]]} { 691 + lappend commands $command 692 + } 693 + } 598 694 } else { 599 695 set commands "" 600 696 } 601 697 if {"commands" != ${action}} { 602 - set procs [namespace eval $spc "info procs [QuoteQuotes ${cmd}]"] 698 + set all_procs [namespace eval $spc [list info procs ${cmd}]] 603 699 # puts stderr procs=|$procs| 700 + set procs "" 701 + foreach proc $all_procs { 702 + if {[namespace eval $spc [list namespace origin $command]] == \ 703 + [namespace eval $spc [list namespace which $command]]} { 704 + lappend procs $command 705 + } 706 + } 604 707 } else { 605 708 set procs "" 606 709 } 607 710 set matches [namespace eval $spc concat ${commands} ${procs}] 608 -# 609 -# foreach match ${matches} { 610 -# set full ${spc}::${match} 611 -# if {"" != [namespace which ${full}]} { 612 -# lappend new bla::${full} 613 -# } 614 -# } 615 -# 616 711 set namespaces [namespace children $spc ${cmd}] 712 + 617 713 if {![llength ${matches}] && 1 == [llength ${namespaces}]} { 618 - set namespaces [string trim ${namespaces}] 619 - regsub {^([^:])} $namespaces {::\1} namespaces 620 - # set matches [namespace eval ${namespaces} \ 621 - # {concat [info commands] [info procs]}] 622 - if {"procs" != ${action}} { 623 - set n_commands [namespace eval ${namespaces} "info commands"] 624 - } else { 625 - set n_commands "" 626 - } 627 - if {"commands" != ${action}} { 628 - set n_procs [namespace eval ${namespaces} "info procs"] 629 - } else { 630 - set n_procs "" 631 - } 632 - set matches [string trim "${n_commands} ${n_procs}"] 633 - if {[llength ${matches}]} { 634 -# 635 -# foreach match ${matches} { 636 -# set full ${namespaces}::${match} 637 -# if {"" != [namespace which ${full}]} { 638 -# lappend new ${namespaces}::${match} 639 -# } 640 -# } 641 -# 642 -# set matches ${new} 643 -# unset new 644 -# 645 - set matches [FullQualifiedMatches ${namespaces} ${matches}] 646 - set namespaces "" 647 - } 648 - return [string trim "${matches} ${namespaces}"] 649 - } else { 650 - return [string trim "${matches} ${namespaces}"] 651 - } 714 + set matches [CommandCompletion {} ${action} ${namespaces} ${pre}] 715 + # puts stderr \nmatches=|$matches| 716 + return $matches 717 + } 718 + 719 + # make `namespaces' having exactly 720 + # the same number of colons as `cmd'. 721 + # 722 + regsub -all {^:*} $spc $pre spc 723 + 724 + set matches [FullQualifiedMatches ${spc} ${matches}] 725 + # puts stderr \nmatches3=|$matches| 726 + return [string trim "${matches} ${namespaces}"] 652 727 } 653 728 654 729 #** 655 730 # check, if the first argument starts with a '[' 656 731 # and must be evaluated before continuing. 657 -# NOTE: eventually modifies all arguments. 732 +# NOTE: trims the `line'. 733 +# eventually modifies all arguments. 658 734 # DATE: Sep-06-1999 659 735 # 660 736 proc EventuallyEvaluateFirst {partT startT endT lineT} { 661 737 # return; # disabled 662 738 upvar $partT part $startT start $endT end $lineT line 739 + 740 + set oldlen [string length ${line}] 663 741 set line [string trim ${line}] 742 + set diff [expr [string length $line] - $oldlen] 743 + incr start $diff 744 + incr end $diff 664 745 665 746 set char [string index ${line} 0] 666 747 if {{[} != ${char} && {$} != ${char}} {return} 667 748 668 749 set pos 0 669 750 while {-1 != [set idx [string first {]} ${line} ${pos}]]} { 670 751 set cmd [string range ${line} 0 ${idx}] ................................................................................ 691 772 # % puts $b<TAB> 692 773 # part == $b 693 774 # start == 5 694 775 # end == 7 695 776 # line == "$puts $b" 696 777 # 697 778 proc ScriptCompleter {part start end line} { 779 + 698 780 # puts stderr "(ScriptCompleter) |$part| $start $end |$line|" 699 - variable known_cmds 781 + 782 + # if the character before the cursor is a terminating 783 + # quote and the user wants completion, we insert a white 784 + # space here. 785 + # 786 + set char [string index $line [expr $end - 1]] 787 + if {"\}" == $char} { 788 + append $part " " 789 + return [list $part] 790 + } 791 + 700 792 if {{$} == [string index $part 0]} { 793 + 701 794 # check for a !$ history event 702 795 # 703 796 if {$start > 0} { 704 797 if {{!} == [string index $line [expr $start - 1]]} { 705 798 return "" 706 799 } 707 800 } 708 801 # variable completion. Check first, if the 709 802 # variable starts with a plain `$' or should 710 803 # be enclosed in braces. 711 804 # 712 805 set var [string range $part 1 end] 713 -# 714 -# if {"\{" == [string index $part 1]} { 715 -# set var [string range $part 2 end] 716 -# set left "\{" 717 -# } else { 718 -# set left "" 719 -# set var [string range $part 1 end] 720 -# } 721 -# 806 + 722 807 # check if $var is an array name, which 723 808 # already has already a "(" somewhere inside. 724 809 # 725 810 if {"" != [set vc [VarCompletion $var]]} { 726 811 if {"" == [lindex $vc 0]} { 727 812 return "\$ [lrange ${vc} 1 end]" 728 813 } else { 729 814 return \$${vc} 730 815 } 731 816 # puts stderr vc=|$vc| 732 817 } else { 733 818 return "" 734 819 } 820 + 735 821 # SCENARIO: 736 822 # 737 823 # % puts bla; put<TAB> $b 738 824 # part == put 739 825 # start == 10 740 826 # end == 13 741 827 # line == "puts bla; put $b" ................................................................................ 749 835 set new_start [lindex $sub 0] 750 836 set new_end [expr $end - ($start - $new_start)] 751 837 set new_line [lindex $sub 1] 752 838 # puts stderr "(SplitLine) $new_start $new_end $new_line" 753 839 return [ScriptCompleter $part $new_start $new_end $new_line] 754 840 } elseif {0 == [set pos [PartPosition part start end line]]} { 755 841 # puts stderr "(PartPosition) $part $start $end $line" 756 - # set matches [array names known_cmds "[string trim ${part}]*"] 757 842 set all [CommandCompletion ${part}] 758 843 # puts stderr "(ScriptCompleter) all=$all" 759 844 #puts \nmatches=$matches\n 760 845 # return [Format $all $part] 761 846 return [TryFromList $part $all] 762 847 } else { 848 + 763 849 # try to use $pos further ... 764 850 # puts stderr |$line| 851 + # 765 852 if {"." == [string index [string trim ${line}] 0]} { 766 853 set alias WIDGET 767 854 } else { 768 - set alias [lindex [QuoteQuotes ${line}] 0] 855 + 856 + # the double `lindex' strips {} or quotes. 857 + # the subst enables variables containing 858 + # command names. 859 + # 860 + set alias [uplevel [info level] \ 861 + subst [lindex [lindex [QuoteQuotes ${line}] 0] 0]] 862 + 863 + # make `alias' a fully qualified name. 864 + # this can raise an error, if alias is 865 + # no valid command. 866 + # 867 + if {[catch [list set alias [namespace origin $alias]]]} { 868 + return "" 869 + } 870 + 871 + # strip leading ::'s. 872 + # 873 + regsub -all {^::} $alias {} alias 874 + set namespc [namespace qualifiers $alias] 875 + set alias [namespace tail $alias] 769 876 } 877 + 770 878 foreach cmd [list ${alias} tclreadline_complete_unknown] { 771 - if {"" != [namespace eval ::tclreadline \ 879 + # puts stderr ${namespc}complete(${cmd}) 880 + if {"" != [namespace eval ::tclreadline::${namespc} \ 772 881 [list info procs complete(${cmd})]] 773 882 } { 883 + # puts found=|complete($cmd)| 774 884 # to be more error-proof, we check here, 775 885 # if complete($cmd) takes exactly 5 arguments. 776 886 # 777 887 if {6 != [set arguments [llength \ 778 - [namespace eval ::tclreadline \ 779 - [list info args complete(${cmd})]]]] 888 + [namespace eval ::tclreadline::${namespc} \ 889 + [list info args complete($cmd)]]]] 780 890 } { 781 891 error [list complete(${cmd}) takes ${arguments} \ 782 892 arguments, but should take exactly 6.] 783 893 } 784 894 785 895 # remove leading quotes 786 896 # 787 897 set mod [StripPrefix $part] 788 898 # puts stderr mod=$mod 789 899 790 900 if {[catch [list set script_result \ 791 - [complete(${cmd}) $part \ 792 - $start $end $line $pos $mod]] ::tclreadline::errorMsg] 901 + [namespace eval ::tclreadline::${namespc} \ 902 + [list complete(${cmd}) $part $start $end $line $pos $mod]]]\ 903 + ::tclreadline::errorMsg] 793 904 } { 794 - error "error during evaluation of `complete(${cmd})'" 905 + error [list error during evaluation of `complete(${cmd})'] 795 906 } 796 907 # puts stderr \nscript_result=|${script_result}| 797 908 return ${script_result} 798 909 } 910 + # set namespc ""; # no qualifiers for tclreadline_complete_unknown 799 911 } 800 912 # no specific command completer found. 801 - if {"" != [array names known_cmds $cmd]} { 802 - set current [lindex $known_cmds($cmd) $pos] 803 - if {"" != $current && "" == [string trim $part]} { 804 - return $current 805 - } else { 806 - return "" 807 - } 808 - } else { 809 - return "" 810 - } 913 + return "" 811 914 } 812 915 error "{NOTREACHED (this is probably an error)}" 813 916 } 814 917 815 918 816 919 # explicit command completers 817 920 # ................................................................................ 826 929 switch -- $pos { 827 930 1 { 828 931 return [CompleteFromList ${text} {<ms> cancel idle info}] 829 932 } 830 933 2 { 831 934 switch -- $sub { 832 935 cancel { 833 - set after_info [after info] 834 - if {![llength $after_info]} { 835 - return [DisplayHints <script>] 836 - } else { 837 - return [CompleteFromList $mod "<script> [after info]"] 838 - } 936 + return [CompleteFromList $text "<script> [after info]"] 839 937 } 840 938 idle { 841 939 return [DisplayHints <script>] 842 940 } 843 941 info { 844 - return [CompleteFromList $mod [after info]] 942 + return [CompleteFromList $text [after info]] 845 943 } 846 944 default { return [DisplayHints ?script?] } 847 945 } 848 946 } 849 947 default { 850 948 switch -- $sub { 851 949 info { return [DisplayHints {}] } ................................................................................ 871 969 anymore donesearch exists get names 872 970 nextelement set size startsearch 873 971 } 874 972 return [CompleteFromList $text $cmds] 875 973 } 876 974 2 { 877 975 set matches "" 878 - set vars [uplevel [info level] info vars ${mod}*] 976 + # set vars [uplevel [info level] info vars ${mod}*] 977 + # 978 + # better: this displays a list of array names if the 979 + # user inters with something which cannot be matched. 980 + # The matching against `text' is done by CompleteFromList. 981 + # 982 + set vars [uplevel [info level] info vars] 879 983 foreach var ${vars} { 880 984 if {[uplevel [info level] array exists ${var}]} { 881 985 lappend matches ${var} 882 986 } 883 987 } 884 988 return [CompleteFromList ${text} ${matches}] 885 989 } 886 - default { 990 + 3 { 887 991 set cmd [Lindex $line 1] 888 992 set array_name [Lindex $line 2] 889 993 switch -- $cmd { 890 994 get - 891 995 names { 892 996 set pattern [Lindex $line 3] 893 997 set matches [uplevel [info level] \ 894 998 array names ${array_name} ${pattern}*] 895 999 if {![llength $matches]} { 896 - return [Menu ?pattern?] 1000 + return [DisplayHints ?pattern?] 897 1001 } else { 898 1002 return [CompleteFromList ${text} ${matches}] 899 1003 } 900 1004 } 901 1005 anymore - 902 1006 donesearch - 903 - nextid { return [Menu <searchId>] } 1007 + nextelement { return [DisplayHints <searchId>] } 904 1008 } 905 1009 } 906 1010 } 907 1011 return "" 908 1012 } 909 1013 910 1014 # proc complete(bgerror) {text start end line pos mod} { ................................................................................ 948 1052 } 949 1053 return "" 950 1054 } 951 1055 952 1056 # proc complete(cd) {text start end line pos mod} { 953 1057 # } 954 1058 955 -proc complete(if) {text start end line pos mod} { 956 - # TODO: this is not good yet. 957 - switch -- $pos { 958 - 1 { return [CompleteFromList $mod {\{}] } 959 - 2 { return [TryFromList $mod {then}] } 960 - default { 961 - set prev [PreviousWord ${start} ${line}] 962 - switch $prev { 963 - then - 964 - else - 965 - elseif { return [CompleteFromList $mod {\{}] } 966 - default { return [TryFromList $text {then else elseif}] } 967 - } 968 - } 969 - } 970 - return "" 971 -} 972 - 973 -proc complete(incr) {text start end line pos mod} { 974 - if {1 == $pos} { 975 - set matches [uplevel 2 info vars "${mod}*"] 976 - set final "" 977 - # check for integers 978 - # 979 - foreach match $matches { 980 - if {[uplevel 2 array exists $match]} { 981 - continue 982 - } 983 - if {[regexp {^[0-9]+$} [uplevel 2 set $match]]} { 984 - lappend final $match 985 - } 986 - } 987 - return [Format ${final} $text] 988 - } 989 -} 990 - 991 1059 proc complete(clock) {text start end line pos mod} { 992 - set cmd [lindex $line 1] 1060 + set cmd [Lindex $line 1] 993 1061 switch -- $pos { 994 1062 1 { 995 - return [TryFromList $text {clicks format scan seconds}] 1063 + return [CompleteFromList $text {clicks format scan seconds}] 996 1064 } 997 1065 2 { 998 1066 switch -- $cmd { 999 - format { return [DisplayHints clockValue] } 1000 - scan { return [DisplayHints dateString] } 1067 + format { return [DisplayHints <clockValue>] } 1068 + scan { return [DisplayHints <dateString>] } 1069 + clicks - 1070 + seconds {} 1071 + } 1072 + } 1073 + 3 - 1074 + 5 { 1075 + switch -- $cmd { 1076 + format { 1077 + set subcmds [RemoveUsedOptions $line {-format -gmt}] 1078 + return [TryFromList $text $subcmds] 1079 + } 1080 + scan { 1081 + set subcmds [RemoveUsedOptions $line {-base -gmt}] 1082 + return [TryFromList $text $subcmds] 1083 + } 1001 1084 clicks - 1002 1085 seconds {} 1003 1086 } 1004 1087 } 1005 - 3 { 1088 + 4 - 1089 + 6 { 1090 + set sub [Lindex $line [expr $pos - 1]] 1006 1091 switch -- $cmd { 1007 1092 format { 1008 - set sub [lindex $line 3] 1009 - set subcmds {-fmt -gmt} 1010 - return [TryFromList $text $subcmds] 1093 + switch -- $sub { 1094 + -format { return [DisplayHints <string>] } 1095 + -gmt { return [DisplayHints <boolean>] } 1096 + } 1011 1097 } 1012 1098 scan { 1013 - set sub [lindex $line 3] 1014 - set subcmds {-base -gmt} 1015 - return [TryFromList $text $subcmds] 1099 + switch -- $sub { 1100 + -base { return [DisplayHints <clockVal>] } 1101 + -gmt { return [DisplayHints <boolean>] } 1102 + } 1016 1103 } 1017 1104 clicks - 1018 1105 seconds {} 1019 1106 } 1020 1107 } 1021 1108 } 1022 1109 return "" 1023 1110 } 1111 + 1112 +proc complete(close) {text start end line pos mod} { 1113 + switch -- $pos { 1114 + 1 { return [ChannelId $text] } 1115 + } 1116 + return "" 1117 +} 1118 + 1119 +proc complete(concat) {text start end line pos mod} { 1120 + return [DisplayHints ?arg?] 1121 +} 1122 + 1123 +# proc complete(continue) {text start end line pos mod} { 1124 +# } 1125 + 1126 +# proc complete(dde) {text start end line pos mod} { 1127 +# We're not on windoze here ... 1128 +# } 1024 1129 1025 1130 proc complete(encoding) {text start end line pos mod} { 1026 - set cmd [lindex $line 1] 1131 + set cmd [Lindex $line 1] 1027 1132 switch -- $pos { 1028 1133 1 { 1029 - return [TryFromList $text {convertfrom convertto names system}] 1134 + return [CompleteFromList $text {convertfrom convertto names system}] 1030 1135 } 1031 1136 2 { 1032 1137 switch -- $cmd { 1033 - names {} 1034 1138 convertfrom - 1035 1139 convertto - 1036 1140 system { 1037 - return [TryFromList ${text} [encoding names]] 1141 + return [CompleteFromList ${text} [encoding names]] 1038 1142 } 1039 1143 } 1040 1144 } 1145 + 3 { 1146 + switch -- $cmd { 1147 + convertfrom { return [DisplayHints <data>] } 1148 + convertto { return [DisplayHints <string>] } 1149 + } 1150 + } 1151 + } 1152 + return "" 1153 +} 1154 + 1155 +proc complete(eof) {text start end line pos mod} { 1156 + switch -- $pos { 1157 + 1 { return [InChannelId $text] } 1158 + } 1159 + return "" 1160 +} 1161 + 1162 +proc complete(error) {text start end line pos mod} { 1163 + switch -- $pos { 1164 + 1 { return [DisplayHints <message>] } 1165 + 2 { return [DisplayHints ?info?] } 1166 + 3 { return [DisplayHints ?code?] } 1167 + } 1168 + return "" 1169 +} 1170 + 1171 +proc complete(eval) {text start end line pos mod} { 1172 + switch -- $pos { 1173 + 1 { return [DisplayHints <arg>] } 1174 + default { return [DisplayHints ?arg?] } 1175 + } 1176 + return "" 1177 +} 1178 + 1179 +proc complete(exec) {text start end line pos mod} { 1180 + set redir [list | |& < <@ << > 2> >& >> 2>> >>& >@ 2>@ >&@] 1181 + variable executables 1182 + if {![info exists executables]} { 1183 + Rehash 1184 + } 1185 + switch -- $pos { 1186 + 1 { 1187 + return [TryFromList $text "-keepnewline -- $executables"] 1188 + } 1189 + default { 1190 + set prev [PreviousWord ${start} ${line}] 1191 + if {"-keepnewline" == $prev && 2 == $pos} { 1192 + return [TryFromList $text "-- $executables"] 1193 + } 1194 + switch -exact -- $prev { 1195 + | - 1196 + |& { return [TryFromList $text $executables] } 1197 + < - 1198 + > - 1199 + 2> - 1200 + >& - 1201 + >> - 1202 + 2>> - 1203 + >>& { return "" } 1204 + <@ - 1205 + >@ - 1206 + 2>@ - 1207 + >&@ { return [ChannelId $text] } 1208 + << { return [DisplayHints <value>] } 1209 + default { return [TryFromList $text $redir "<>"] } 1210 + } 1211 + } 1212 + } 1213 + return "" 1214 +} 1215 + 1216 +proc complete(exit) {text start end line pos mod} { 1217 + switch -- $pos { 1218 + 1 { return [DisplayHints ?returnCode?] } 1041 1219 } 1042 1220 return "" 1043 1221 } 1044 1222 1045 1223 proc complete(expr) {text start end line pos mod} { 1224 + set left $text 1225 + set right "" 1226 + set substitution [regexp -- {(.*)(\(.*)} $text all left right]; #-) 1227 + 1046 1228 set cmds { 1229 + - + ~ ! * / % + - << >> < > <= >= == != & ^ | && || <x?y:z> 1047 1230 acos cos hypot sinh 1048 1231 asin cosh log sqrt 1049 1232 atan exp log10 tan 1050 1233 atan2 floor pow tanh 1051 1234 ceil fmod sin abs 1052 1235 double int rand round 1053 1236 srand 1054 1237 } 1055 - return [TryFromList $text $cmds] 1238 + 1239 + if {")" == [string index $text end] && -1 != [lsearch $cmds $left]} { 1240 + return "$text "; # append a space after a closing ')' 1241 + } 1242 + 1243 + switch -- $left { 1244 + rand { return "rand() " } 1245 + 1246 + abs - 1247 + acos - 1248 + asin - 1249 + atan - 1250 + ceil - 1251 + cos - 1252 + cosh - 1253 + double - 1254 + exp - 1255 + floor - 1256 + int - 1257 + log - 1258 + log10 - 1259 + round - 1260 + sin - 1261 + sinh - 1262 + sqrt - 1263 + srand - 1264 + tan - 1265 + tanh { return [DisplayHints <value>] } 1266 + 1267 + 1268 + atan2 - 1269 + fmod - 1270 + hypot - 1271 + pow { return [DisplayHints <value>,<value>] } 1272 + } 1273 + 1274 + set completions [TryFromList $left $cmds <>] 1275 + if {1 == [llength $completions]} { 1276 + if {!$substitution} { 1277 + if {"rand" == $completions} { 1278 + return "rand() "; # rand() takes no arguments 1279 + } 1280 + append completions (; #-) 1281 + return [list $completions {}] 1282 + } 1283 + } else { 1284 + return $completions 1285 + } 1286 + return "" 1287 +} 1288 + 1289 +proc complete(fblocked) {text start end line pos mod} { 1290 + switch -- $pos { 1291 + 1 { return [InChannelId $text] } 1292 + } 1293 + return "" 1056 1294 } 1057 1295 1058 1296 proc complete(fconfigure) {text start end line pos mod} { 1059 - set cmd [lindex $line 1] 1297 + set cmd [Lindex $line 1] 1060 1298 switch -- $pos { 1061 1299 1 { 1062 - return [ChannelId ${mod}] 1300 + return [ChannelId ${text}] 1063 1301 } 1064 1302 default { 1065 1303 set option [PreviousWord ${start} ${line}] 1066 1304 switch -- $option { 1067 1305 -blocking { 1068 - return [TryFromList ${text} {yes no}] 1306 + return [CompleteBoolean ${text}] 1069 1307 } 1070 1308 -buffering { 1071 - return [TryFromList ${text} {full line none}] 1309 + return [CompleteFromList ${text} {full line none}] 1072 1310 } 1073 1311 -buffersize { 1074 1312 if {![llength ${text}]} { 1075 - return [DisplayHints newSize] 1313 + return [DisplayHints <newSize>] 1076 1314 } 1077 1315 } 1078 1316 -encoding { 1079 - return [TryFromList ${text} [encoding names]] 1317 + return [CompleteFromList ${text} [encoding names]] 1080 1318 } 1081 1319 -eofchar { 1082 - return [DisplayHints {\{inChar\ outChar\}}] 1320 + return [DisplayHints {\{<inChar>\ <outChar>\}}] 1083 1321 } 1084 1322 -translation { 1085 - return [TryFromList ${text} {auto binary cr crlf lf}] 1323 + return [CompleteFromList ${text} {auto binary cr crlf lf}] 1086 1324 } 1087 - default {return [TryFromList $text { 1325 + default {return [CompleteFromList $text \ 1326 + [RemoveUsedOptions $line { 1088 1327 -blocking -buffering -buffersize 1089 - -encoding -eofchar -translation}] 1328 + -encoding -eofchar -translation}]] 1090 1329 } 1091 1330 } 1092 1331 } 1093 1332 } 1094 1333 return "" 1095 1334 } 1096 1335 1097 1336 proc complete(fcopy) {text start end line pos mod} { 1098 1337 switch -- $pos { 1099 1338 1 { 1100 - return [InChannelId ${mod}] 1339 + return [InChannelId ${text}] 1101 1340 } 1102 1341 2 { 1103 - return [OutChannelId ${mod}] 1342 + return [OutChannelId ${text}] 1104 1343 } 1105 1344 default { 1106 1345 set option [PreviousWord ${start} ${line}] 1107 1346 switch -- $option { 1108 - -size { return [DisplayHints size] } 1109 - -command { return [DisplayHints callback] } 1110 - default { return [TryFromList $text {-size -command}] } 1347 + -size { return [DisplayHints <size>] } 1348 + -command { return [DisplayHints <callback>] } 1349 + default { return [CompleteFromList $text \ 1350 + [RemoveUsedOptions $line {-size -command}]] 1351 + } 1111 1352 } 1112 1353 } 1113 1354 } 1114 1355 return "" 1115 1356 } 1116 1357 1117 1358 proc complete(file) {text start end line pos mod} { 1118 1359 switch -- $pos { 1119 1360 1 { 1120 1361 set cmds { 1121 1362 atime attributes copy delete dirname executable exists 1122 - extension isdirectory isfile join lstat mtime mkdir 1363 + extension isdirectory isfile join lstat mkdir mtime 1123 1364 nativename owned pathtype readable readlink rename 1124 1365 rootname size split stat tail type volumes writable 1125 1366 } 1126 1367 return [TryFromList $text $cmds] 1127 1368 } 1128 1369 2 { 1129 - set cmd [lindex $line 1] 1370 + set cmd [Lindex $line 1] 1130 1371 switch -- $cmd { 1131 1372 atime - 1132 1373 attributes - 1133 1374 dirname - 1134 1375 executable - 1135 1376 exists - 1136 1377 extension - ................................................................................ 1155 1396 writable { 1156 1397 return "" 1157 1398 } 1158 1399 1159 1400 copy - 1160 1401 delete - 1161 1402 rename { 1162 - # set match [MenuFromList ${mod} {-force}] 1403 + # return [TryFromList $text "-force [glob *]"] 1404 + # this is not perfect. The `-force' and `--' 1405 + # options will not be displayed. 1163 1406 return "" 1164 1407 } 1165 1408 } 1166 1409 } 1167 1410 } 1168 1411 return "" 1169 1412 } 1170 1413 1171 1414 proc complete(fileevent) {text start end line pos mod} { 1172 1415 switch -- $pos { 1173 1416 1 { 1174 - return [ChannelId ${mod}] 1417 + return [ChannelId ${text}] 1175 1418 } 1176 1419 2 { 1177 - return [MenuFromList ${mod} {readable writable}] 1420 + return [CompleteFromList ${text} {readable writable}] 1421 + } 1422 + 3 { 1423 + return [DisplayHints ?script?] 1178 1424 } 1179 1425 } 1180 1426 return "" 1181 1427 } 1182 1428 1183 1429 proc complete(flush) {text start end line pos mod} { 1184 1430 switch -- $pos { 1185 - 1 { return [ChannelId ${mod}] } 1431 + 1 { return [OutChannelId ${text}] } 1432 + } 1433 + return "" 1434 +} 1435 + 1436 +proc complete(for) {text start end line pos mod} { 1437 + switch -- $pos { 1438 + 1 - 1439 + 2 - 1440 + 3 - 1441 + 4 { 1442 + return [BraceOrControlStatement $text $start $end $line $pos $mod] 1443 + } 1444 + } 1445 + return "" 1446 +} 1447 + 1448 +proc complete(foreach) {text start end line pos mod} { 1449 + switch -- $pos { 1450 + 1 { return [DisplayHints <varname>] } 1451 + 2 { return [DisplayHints <list>] } 1452 + default { 1453 + if {[expr $pos % 2]} { 1454 + return [DisplayHints [list ?varname? <body>]] 1455 + } else { 1456 + return [DisplayHints ?list?] 1457 + } 1458 + } 1459 + } 1460 + return "" 1461 +} 1462 + 1463 +proc complete(format) {text start end line pos mod} { 1464 + switch -- $pos { 1465 + 1 { return [DisplayHints <formatString>] } 1466 + default { return [DisplayHints ?arg?] } 1186 1467 } 1187 1468 return "" 1188 1469 } 1189 1470 1190 1471 proc complete(gets) {text start end line pos mod} { 1191 1472 switch -- $pos { 1192 - 1 { return [InChannelId ${mod}] } 1473 + 1 { return [InChannelId ${text}] } 1474 + 2 { return [VarCompletion ${text}]} 1193 1475 } 1194 1476 return "" 1195 1477 } 1196 1478 1197 1479 proc complete(glob) {text start end line pos mod} { 1198 1480 switch -- $pos { 1199 1481 1 { 1200 - set matches [TryFromList ${mod} {-nocomplain --}] 1201 - if {[llength [string trim ${mod}]] && [llength ${matches}]} { 1482 + # This also is not perfect. 1483 + # This will not display the options as hints! 1484 + set matches [TryFromList ${text} {-nocomplain --}] 1485 + if {[llength [string trim ${text}]] && [llength ${matches}]} { 1202 1486 return ${matches} 1203 1487 } 1204 1488 } 1205 1489 } 1206 1490 return "" 1207 1491 } 1208 1492 1209 1493 proc complete(global) {text start end line pos mod} { 1210 1494 return [VarCompletion ${text}] 1211 1495 } 1212 1496 1213 -proc complete(index) {text start end line pos mod} { 1214 - if {1 == $pos} { 1215 - return [VarCompletion ${text}] 1216 - } elseif {2 == $pos && ![llength ${mod}]} { 1217 - return <index> 1497 +proc complete(history) {text start end line pos mod} { 1498 + switch -- $pos { 1499 + 1 { 1500 + set cmds {add change clear event info keep nextid redo} 1501 + return [TryFromList $text $cmds] 1502 + } 1503 + 2 { 1504 + set cmd [Lindex $line 1] 1505 + switch -- $cmd { 1506 + add { return [DisplayHints <command>] } 1507 + change { return [DisplayHints <newValue>] } 1508 + 1509 + info - 1510 + keep { return [DisplayHints ?count?] } 1511 + 1512 + event - 1513 + redo { return [DisplayHints ?event?] } 1514 + 1515 + clear - 1516 + nextid { return "" } 1517 + } 1518 + } 1519 + } 1520 + return "" 1521 +} 1522 + 1523 +# --- HTTP PACKAGE --- 1524 + 1525 +# create a http namespace inside 1526 +# tclreadline and import some commands. 1527 +# 1528 +namespace eval http { 1529 + catch { 1530 + namespace import \ 1531 + ::tclreadline::DisplayHints ::tclreadline::PreviousWord \ 1532 + ::tclreadline::CompleteFromList ::tclreadline::CommandCompletion \ 1533 + ::tclreadline::RemoveUsedOptions ::tclreadline::HostList \ 1534 + ::tclreadline::ChannelId ::tclreadline::Lindex \ 1535 + ::tclreadline::CompleteBoolean 1536 + } 1537 +} 1538 + 1539 +proc http::complete(config) {text start end line pos mod} { 1540 + set prev [PreviousWord ${start} ${line}] 1541 + switch -- $prev { 1542 + -accept { return [DisplayHints <mimetypes>] } 1543 + -proxyhost { 1544 + return [CompleteFromList $text [HostList]] 1545 + } 1546 + -proxyport { return [DisplayHints <number>] } 1547 + -proxyfilter { 1548 + return [CompleteFromList $text [CommandCompletion $text]] 1549 + } 1550 + -useragent { return [DisplayHints <string>] } 1551 + default { 1552 + return [CompleteFromList $text [RemoveUsedOptions $line { 1553 + -accept -proxyhost -proxyport -proxyfilter -useragent 1554 + }]] 1555 + } 1556 + } 1557 + return "" 1558 +} 1559 + 1560 +proc http::complete(geturl) {text start end line pos mod} { 1561 + switch -- $pos { 1562 + 1 { return [DisplayHints <url>] } 1563 + default { 1564 + set prev [PreviousWord ${start} ${line}] 1565 + switch -- $prev { 1566 + -blocksize { return [DisplayHints <size>] } 1567 + -channel { return [ChannelId ${text}] } 1568 + -command - 1569 + -handler - 1570 + -progress { 1571 + return [CompleteFromList $text [CommandCompletion $text]] 1572 + } 1573 + -headers { return [DisplayHints <keyvaluelist>] } 1574 + -query { return [DisplayHints <query>] } 1575 + -timeout { return [DisplayHints <milliseconds>] } 1576 + -validate { return [CompleteBoolean $text] } 1577 + default { 1578 + return [CompleteFromList $text [RemoveUsedOptions $line { 1579 + -blocksize -channel -command -handler -headers 1580 + -progress -query -timeout -validate 1581 + }]] 1582 + } 1583 + } 1584 + } 1585 + } 1586 + return "" 1587 +} 1588 + 1589 +proc http::complete(formatQuery) {text start end line pos mod} { 1590 + switch -- $pos { 1591 + 1 { return [DisplayHints <key>] } 1592 + 2 { return [DisplayHints <value>] } 1593 + default { 1594 + switch [expr $pos % 2] { 1595 + 0 { return [DisplayHints ?value?] } 1596 + 1 { return [DisplayHints ?key?] } 1597 + } 1598 + } 1599 + } 1600 + return "" 1601 +} 1602 + 1603 +proc http::complete(reset) {text start end line pos mod} { 1604 + switch -- $pos { 1605 + 1 { return [DisplayHints <token>] } 1606 + 2 { return [DisplayHints ?why?] } 1607 + } 1608 + return "" 1609 +} 1610 + 1611 +# the unknown proc handles the rest 1612 +# 1613 +proc \ 1614 +http::complete(tclreadline_complete_unknown) {text start end line pos mod} { 1615 + set cmd [Lindex $line 0] 1616 + regsub -all {^.*::} $cmd "" cmd 1617 + switch -- $pos { 1618 + 1 { 1619 + switch -- $cmd { 1620 + reset - 1621 + wait - 1622 + data - 1623 + status - 1624 + code - 1625 + size - 1626 + cleanup { 1627 + return [DisplayHints <token>] 1628 + } 1629 + } 1630 + } 1631 + } 1632 + return "" 1633 +} 1634 + 1635 +# --- END OF HTTP PACKAGE --- 1636 + 1637 +proc complete(if) {text start end line pos mod} { 1638 + # we don't offer the completion `then': 1639 + # it's optional, more difficult to parse 1640 + # and who uses it anyway? 1641 + # 1642 + switch -- $pos { 1643 + 1 - 1644 + 2 { 1645 + return [BraceOrControlStatement $text $start $end $line $pos $mod] 1646 + } 1647 + default { 1648 + set prev [PreviousWord ${start} ${line}] 1649 + switch -- $prev { 1650 + then - 1651 + else - 1652 + elseif { 1653 + return [BraceOrControlStatement \ 1654 + $text $start $end $line $pos $mod] 1655 + } 1656 + default { 1657 + if {-1 == [lsearch [ProperList $line] else]} { 1658 + return [CompleteFromList $text {else elseif}] 1659 + } 1660 + } 1661 + } 1662 + } 1663 + } 1664 + return "" 1665 +} 1666 + 1667 +proc complete(incr) {text start end line pos mod} { 1668 + switch -- $pos { 1669 + 1 { 1670 + set matches [uplevel [info level] info vars ${mod}*] 1671 + set integers "" 1672 + # check for integers 1673 + # 1674 + foreach match $matches { 1675 + if {[uplevel [info level] array exists $match]} { 1676 + continue 1677 + } 1678 + if {[regexp {^[0-9]+$} [uplevel [info level] set $match]]} { 1679 + lappend integers $match 1680 + } 1681 + } 1682 + return [CompleteFromList ${text} ${integers}] 1683 + } 1684 + 2 { return [DisplayHints ?increment?] } 1218 1685 } 1219 1686 return "" 1220 1687 } 1221 1688 1222 1689 proc complete(info) {text start end line pos mod} { 1223 - if {1 == $pos} { 1224 - set cmds { 1225 - args body cmdcount commands complete default exists 1226 - globals hostname level library loaded locals nameofexecutable 1227 - patchlevel procs script sharedlibextension tclversion vars} 1228 - return [TryFromList $text $cmds] 1229 - } elseif {2 == $pos} { 1230 - set cmd [lindex $line 1] 1231 - switch -- $cmd { 1232 - args - 1233 - body - 1234 - default - 1235 - procs { return [complete(proc) ${text} 0 0 ${line} 1 ${mod}] } 1236 - complete { ; # TODO 1237 - } 1238 - level { ; # TODO 1239 - } 1240 - loaded { ;# TODO 1241 - } 1242 - commands - 1243 - exists - 1244 - globals - 1245 - locals - 1246 - vars { 1247 - if {"exists" == $cmd} { 1248 - set do vars 1249 - } else { 1250 - set do $cmd 1251 - } 1252 - # puts stderr [list complete(info) level = [info level]] 1253 - return \ 1254 - [Format [uplevel 2 info ${do} "${mod}*"] $text] 1690 + set cmd [Lindex $line 1] 1691 + switch -- $pos { 1692 + 1 { 1693 + set cmds { 1694 + args body cmdcount commands complete default exists 1695 + globals hostname level library loaded locals nameofexecutable 1696 + patchlevel procs script sharedlibextension tclversion vars} 1697 + return [CompleteFromList $text $cmds] 1698 + } 1699 + 2 { 1700 + switch -- $cmd { 1701 + args - 1702 + body - 1703 + default - 1704 + procs { return [complete(proc) ${text} 0 0 ${line} 1 ${mod}] } 1705 + complete { return [DisplayHints <command>] } 1706 + level { return [DisplayHints ?number?] } 1707 + loaded { return [DisplayHints ?interp?] } 1708 + commands - 1709 + exists - 1710 + globals - 1711 + locals - 1712 + vars { 1713 + if {"exists" == $cmd} { 1714 + set do vars 1715 + } else { 1716 + set do $cmd 1717 + } 1718 + # puts stderr [list complete(info) level = [info level]] 1719 + return \ 1720 + [CompleteFromList ${text} [uplevel [info level] info ${do}]] 1721 + } 1722 + } 1723 + } 1724 + 3 { 1725 + switch -- $cmd { 1726 + default { 1727 + set proc [Lindex $line 2] 1728 + return [CompleteFromList ${text} \ 1729 + [uplevel [info level] info args $proc]] 1730 + } 1731 + default {} 1732 + } 1733 + } 1734 + 4 { 1735 + switch -- $cmd { 1736 + default { 1737 + return [VarCompletion ${text}] 1738 + } 1739 + default {} 1255 1740 } 1256 1741 } 1257 1742 } 1258 1743 return "" 1259 1744 } 1260 1745 1261 1746 proc complete(interp) {text start end line pos mod} { 1262 - set cmd [lindex $line 1] 1263 - if {1 == $pos} { 1264 - set cmds { 1265 - alias aliases create delete eval exists expose hide hidden 1266 - issafe invokehidden marktrusted slaves share target transfer} 1267 - return [TryFromList $text $cmds] 1268 - } elseif {2 == $pos} { 1269 - switch -- $cmd { 1270 - create { 1271 - return [TryFromList $text {-safe -- ?path?}] 1272 - } 1273 - 1274 - eval - 1275 - exists - 1276 - expose - 1277 - hide - 1278 - hidden - 1279 - invokehidden - 1280 - marktrusted - 1281 - target {if {![llength ${mod}]} { return <path> }} 1282 - 1283 - aliases - 1284 - delete - 1285 - issafe - 1286 - slaves {if {![llength ${mod}]} { return ?path? }} 1287 - 1288 - alias - 1289 - share - 1290 - transfer {if {![llength ${mod}]} { return <srcPath> }} 1291 - } 1292 - } elseif {3 == $pos} { 1293 - switch -- $cmd { 1294 - 1295 - alias {if {![llength ${mod}]} { return <srcCmd> }} 1296 - 1297 - create { 1298 - return [TryFromList $text {-safe -- ?path?}] 1299 - } 1300 - 1301 - eval {if {![llength ${mod}]} { return <arg> }} 1302 - delete {if {![llength ${mod}]} { return ?path? }} 1303 - 1304 - expose {if {![llength ${mod}]} { return <hiddenName> }} 1305 - hide {if {![llength ${mod}]} { return <exposedCmdName> }} 1306 - 1307 - invokehidden { 1308 - return \ 1309 - [TryFromList $text {?-global? <hiddenCmdName}] 1310 - } 1311 - 1312 - target {if {![llength ${mod}]} { return <alias> }} 1313 - 1314 - exists {} 1315 - hidden {} 1316 - marktrusted {} 1317 - aliases {} 1318 - issafe {} 1319 - slaves {} 1320 - 1321 - share - 1322 - tranfer {return [ChannelId ${mod}]} 1323 - } 1324 - } elseif {4 == $pos} { 1325 - switch -- $cmd { 1326 - 1327 - alias {if {![llength ${mod}]} { return <targetPath> }} 1328 - 1329 - create { 1330 - return [TryFromList $text {-safe -- path}] 1331 - } 1332 - 1333 - expose {if {![llength ${mod}]} { return ?exposedCmdName? }} 1334 - hide {if {![llength ${mod}]} { return ?hiddenCmdName? }} 1335 - 1336 - share - 1337 - tranfer {if {![llength ${mod}]} { return ?destPath? }} 1747 + set cmd [Lindex $line 1] 1748 + switch -- $pos { 1749 + 1 { 1750 + set cmds { 1751 + alias aliases create delete eval exists expose hide hidden 1752 + invokehidden issafe marktrusted share slaves target transfer} 1753 + return [TryFromList $text $cmds] 1754 + } 1755 + 2 { 1756 + switch -- $cmd { 1757 + 1758 + create { 1759 + set cmds [RemoveUsedOptions ${line} {-save --} {--}] 1760 + if {[llength $cmds]} { 1761 + return [CompleteFromList $text "$cmds ?path?"] 1762 + } else { 1763 + return [DisplayHints ?path?] 1764 + } 1765 + } 1766 + 1767 + eval - 1768 + exists - 1769 + expose - 1770 + hide - 1771 + hidden - 1772 + invokehidden - 1773 + marktrusted - 1774 + target { return [DisplayHints [interp slaves]] } 1775 + 1776 + aliases - 1777 + delete - 1778 + issafe - 1779 + slaves { return [DisplayHints [interp slaves]] } 1780 + 1781 + alias - 1782 + share - 1783 + transfer { return [DisplayHints <srcPath>] } 1784 + } 1785 + } 1786 + 3 { 1787 + switch -- $cmd { 1788 + 1789 + alias { return [DisplayHints <srcCmd>] } 1790 + 1791 + create { 1792 + set cmds [RemoveUsedOptions ${line} {-save --} {--}] 1793 + if {[llength $cmds]} { 1794 + return [CompleteFromList $text "$cmds ?path?"] 1795 + } else { 1796 + return [DisplayHints ?path?] 1797 + } 1798 + } 1799 + 1800 + eval { return [DisplayHints <arg>] } 1801 + delete { return [DisplayHints [interp slaves]] } 1802 + 1803 + expose { return [DisplayHints <hiddenName>] } 1804 + hide { return [DisplayHints <exposedCmdName>] } 1805 + 1806 + invokehidden { 1807 + return \ 1808 + [CompleteFromList $text {?-global? <hiddenCmdName>}] 1809 + } 1810 + 1811 + target { return [DisplayHints <alias>] } 1812 + 1813 + exists {} 1814 + hidden {} 1815 + marktrusted {} 1816 + aliases {} 1817 + issafe {} 1818 + slaves {} 1819 + 1820 + share - 1821 + transfer {return [ChannelId ${text}]} 1822 + } 1823 + } 1824 + 4 { 1825 + switch -- $cmd { 1826 + 1827 + alias { return [DisplayHints <targetPath>] } 1828 + eval { return [DisplayHints ?arg?] } 1829 + 1830 + invokehidden { 1831 + return [CompleteFromList $text {<hiddenCmdName> ?arg?}] 1832 + } 1833 + 1834 + create { 1835 + set cmds [RemoveUsedOptions ${line} {-save --} {--}] 1836 + if {[llength $cmds]} { 1837 + return [CompleteFromList $text "$cmds ?path?"] 1838 + } else { 1839 + return [DisplayHints ?path?] 1840 + } 1841 + } 1842 + 1843 + expose { return [DisplayHints ?exposedCmdName?] } 1844 + hide { return [DisplayHints ?hiddenCmdName?] } 1845 + 1846 + share - 1847 + transfer { return [DisplayHints [interp slaves]] } 1848 + } 1849 + } 1850 + 5 { 1851 + switch -- $cmd { 1852 + 1853 + alias { return [DisplayHints <targetCmd>] } 1854 + invokehidden - 1855 + eval { return [DisplayHints ?arg?] } 1856 + 1857 + expose { return [DisplayHints ?exposedCmdName?] } 1858 + hide { return [DisplayHints ?hiddenCmdName?] } 1859 + 1860 + share - 1861 + transfer { return [DisplayHints [interp slaves]] } 1862 + } 1338 1863 } 1339 1864 } 1340 1865 return "" 1341 1866 } 1342 1867 1343 1868 proc complete(join) {text start end line pos mod} { 1344 - if {1 == $pos} { 1345 - return [VarCompletion ${text}] 1869 + switch -- $pos { 1870 + 1 { return [DisplayHints <list>] } 1871 + 2 { return [DisplayHints ?joinString?] } 1346 1872 } 1347 1873 return "" 1348 1874 } 1349 1875 1350 1876 proc complete(lappend) {text start end line pos mod} { 1351 - if {1 == $pos} { 1352 - return [ListCompletion ${text}] 1877 + switch -- $pos { 1878 + 1 { return [VarCompletion ${text}] } 1879 + default { return [DisplayHints ?value?] } 1880 + } 1881 + return "" 1882 +} 1883 + 1884 +# the following routines are described in the 1885 +# `library' man page. 1886 +# --- LIBRARY --- 1887 + 1888 +proc complete(auto_execok) {text start end line pos mod} { 1889 + switch -- $pos { 1890 + 1 { return [DisplayHints <cmd>] } 1891 + } 1892 + return "" 1893 +} 1894 + 1895 +proc complete(auto_load) {text start end line pos mod} { 1896 + switch -- $pos { 1897 + 1 { return [DisplayHints <cmd>] } 1898 + } 1899 + return "" 1900 +} 1901 + 1902 +proc complete(auto_mkindex) {text start end line pos mod} { 1903 + switch -- $pos { 1904 + 1 { return "" } 1905 + default { return [DisplayHints ?pattern?] } 1906 + } 1907 + return "" 1908 +} 1909 + 1910 +# proc complete(auto_reset) {text start end line pos mod} { 1911 +# } 1912 + 1913 +proc complete(tcl_findLibrary) {text start end line pos mod} { 1914 + switch -- $pos { 1915 + 1 { return [DisplayHints <basename>] } 1916 + 2 { return [DisplayHints <version>] } 1917 + 3 { return [DisplayHints <patch>] } 1918 + 4 { return [DisplayHints <initScript>] } 1919 + 5 { return [DisplayHints <enVarName>] } 1920 + 6 { return [DisplayHints <varName>] } 1921 + } 1922 + return "" 1923 +} 1924 + 1925 +proc complete(parray) {text start end line pos mod} { 1926 + switch -- $pos { 1927 + 1 { 1928 + set vars [uplevel [info level] info vars] 1929 + foreach var ${vars} { 1930 + if {[uplevel [info level] array exists ${var}]} { 1931 + lappend matches ${var} 1932 + } 1933 + } 1934 + return [CompleteFromList $text $matches] 1935 + } 1936 + } 1937 + return "" 1938 +} 1939 + 1940 +proc complete(tcl_endOfWord) {text start end line pos mod} { 1941 + switch -- $pos { 1942 + 1 { return [DisplayHints <str>] } 1943 + 2 { return [DisplayHints <start>] } 1944 + } 1945 + return "" 1946 +} 1947 + 1948 +proc complete(tcl_startOfNextWord) {text start end line pos mod} { 1949 + return [complete(tcl_endOfWord) $text $start $end $line $pos $mod] 1950 +} 1951 + 1952 +proc complete(tcl_startOfPreviousWord) {text start end line pos mod} { 1953 + return [complete(tcl_endOfWord) $text $start $end $line $pos $mod] 1954 +} 1955 + 1956 +proc complete(tcl_wordBreakAfter) {text start end line pos mod} { 1957 + return [complete(tcl_endOfWord) $text $start $end $line $pos $mod] 1958 +} 1959 + 1960 +proc complete(tcl_wordBreakBefore) {text start end line pos mod} { 1961 + return [complete(tcl_endOfWord) $text $start $end $line $pos $mod] 1962 +} 1963 + 1964 +# --- END OF `LIBRARY' --- 1965 + 1966 +proc complete(lindex) {text start end line pos mod} { 1967 + switch -- $pos { 1968 + 1 { return [DisplayHints <list>] } 1969 + 2 { return [DisplayHints <index>] } 1353 1970 } 1354 1971 return "" 1355 1972 } 1356 1973 1357 1974 proc complete(linsert) {text start end line pos mod} { 1358 - if {1 == $pos} { 1359 - return [ListCompletion ${text}] 1975 + switch -- $pos { 1976 + 1 { return [DisplayHints <list>] } 1977 + 2 { return [DisplayHints <index>] } 1978 + 3 { return [DisplayHints <element>] } 1979 + default { return [DisplayHints ?element?] } 1360 1980 } 1361 1981 return "" 1362 1982 } 1983 + 1984 +proc complete(list) {text start end line pos mod} { 1985 + return [DisplayHints ?arg?] 1986 +} 1363 1987 1364 1988 proc complete(llength) {text start end line pos mod} { 1365 - if {1 == $pos} { 1366 - return [ListCompletion ${text}] 1989 + switch -- $pos { 1990 + 1 { 1991 + return [DisplayHints <list>] 1992 + } 1367 1993 } 1368 1994 return "" 1369 1995 } 1370 1996 1371 1997 proc complete(load) {text start end line pos mod} { 1372 - if {1 == $pos} { 1373 - return ""; # filename 1374 - } elseif {2 == $pos && ![llength ${mod}]} { 1375 - return "<packageName>" 1376 - } elseif {3 == $pos && ![llength ${mod}]} { 1377 - return "<interp>" 1998 + switch -- $pos { 1999 + 1 { 2000 + return ""; # filename 2001 + } 2002 + 2 { 2003 + if {![llength ${mod}]} { 2004 + return [DisplayHints ?packageName?] 2005 + } 2006 + } 2007 + 3 { 2008 + if {![llength ${mod}]} { 2009 + return [DisplayHints ?interp?] 2010 + } 2011 + } 1378 2012 } 1379 2013 return "" 1380 2014 } 1381 2015 1382 2016 proc complete(lrange) {text start end line pos mod} { 1383 - if {1 == $pos} { 1384 - return [ListCompletion ${text}] 1385 - } elseif {2 == $pos && ![llength ${mod}]} { 1386 - return "<first>" 1387 - } elseif {3 == $pos && ![llength ${mod}]} { 1388 - return "<last>" 2017 + switch -- $pos { 2018 + 1 { return [DisplayHints <list>] } 2019 + 2 { return [DisplayHints <first>] } 2020 + 3 { return [DisplayHints <last>] } 1389 2021 } 1390 2022 return "" 1391 2023 } 1392 2024 1393 2025 proc complete(lreplace) {text start end line pos mod} { 1394 - if {1 == $pos} { 1395 - return [ListCompletion ${text}] 1396 - } elseif {2 == $pos && ![llength ${mod}]} { 1397 - return "<first>" 1398 - } elseif {3 == $pos && ![llength ${mod}]} { 1399 - return "<last>" 1400 - } elseif {![llength ${mod}]} { 1401 - return "?element?" 2026 + switch -- $pos { 2027 + 1 { return [DisplayHints <list>] } 2028 + 2 { return [DisplayHints <first>] } 2029 + 3 { return [DisplayHints <last>] } 2030 + default { return [DisplayHints ?element?] } 1402 2031 } 1403 2032 return "" 1404 2033 } 1405 2034 1406 2035 proc complete(lsearch) {text start end line pos mod} { 1407 - if {1 == $pos} { 1408 - set options [MenuFromList ${mod} { 1409 - -exact -glob -regexp <list>}] 1410 - set matches [ListCompletion ${text}] 1411 - return [string trim "${matches} ${options}"] 1412 - } else { 1413 - if {![llength ${mod}]} { 1414 - set opt [lindex ${line} 1] 1415 - if {[llength [MenuFromList ${opt} { 1416 - -exact -glob -regexp }]]} { 2036 + set options {-exact -glob -regexp} 2037 + switch -- $pos { 2038 + 1 { 2039 + return [CompleteFromList ${text} "$options <list>"] 2040 + } 2041 + 2 - 2042 + 3 - 2043 + 4 { 2044 + set sub [Lindex $line 1] 2045 + if {-1 != [lsearch $options $sub]} { 1417 2046 incr pos -1 1418 2047 } 1419 - if {1 == $pos} { 1420 - return <list> 1421 - } elseif {2 == $pos} { 1422 - return <pattern> 2048 + switch -- $pos { 2049 + 1 { return [DisplayHints <list>] } 2050 + 2 { return [DisplayHints <pattern>] } 1423 2051 } 1424 2052 } 1425 2053 } 1426 2054 return "" 1427 2055 } 1428 2056 1429 2057 proc complete(lsort) {text start end line pos mod} { 1430 - set options [DisplayHints ${mod} { 2058 + set options [RemoveUsedOptions ${line} { 1431 2059 -ascii -dictionary -integer -real -command 1432 - -increasing -decreasing -index 2060 + -increasing -decreasing -index <list> 1433 2061 }] 1434 - set matches [ListCompletion ${text}] 1435 - return [string trim "${matches} ${options}"] 1436 -} 1437 - 1438 -proc complete(history) {text start end line pos mod} { 1439 - if {1 == $pos} { 1440 - set cmds {add change clear event info keep nextid redo} 1441 - return [TryFromList $text $cmds] 1442 - } elseif {2 == ${pos}} { 1443 - set cmd [lindex $line 1] 1444 - switch -- $cmd { 1445 - add { if {![llength ${mod}]} { return <newValue> } } 1446 - change { if {![llength ${mod}]} { return <newValue> } } 1447 - 1448 - info - 1449 - keep { if {![llength ${mod}]} { return ?count? } } 1450 - 1451 - event - 1452 - redo { if {![llength ${mod}]} { return ?event? } } 1453 - 1454 - clear - 1455 - nextid { return "" } 1456 - } 1457 - } 1458 - return "" 1459 -} 1460 - 1461 -proc complete(namespace) {text start end line pos mod} { 1462 - regsub {^([^:])} ${mod} {::\1} mod 2062 + switch -- $pos { 2063 + 1 { return [CompleteFromList ${text} ${options}] } 2064 + default { 2065 + switch -- [PreviousWord ${start} ${line}] { 2066 + -command { 2067 + return [CompleteFromList $text [CommandCompletion $text]] 2068 + } 2069 + -index { return [DisplayHints <index>] } 2070 + default { return [CompleteFromList ${text} ${options}] } 2071 + } 2072 + } 2073 + } 2074 + return "" 2075 +} 2076 + 2077 +# --- MSGCAT PACKAGE --- 2078 + 2079 +# create a msgcat namespace inside 2080 +# tclreadline and import some commands. 2081 +# 2082 +namespace eval msgcat { 2083 + catch {namespace import ::tclreadline::DisplayHints} 2084 +} 2085 + 2086 +proc msgcat::complete(mc) {text start end line pos mod} { 2087 + switch -- $pos { 2088 + 1 { return [DisplayHints <src-string>] } 2089 + } 2090 + return "" 2091 +} 2092 + 2093 +proc msgcat::complete(mclocale) {text start end line pos mod} { 2094 + switch -- $pos { 2095 + 1 { return [DisplayHints ?newLocale?] } 2096 + } 2097 + return "" 2098 +} 2099 + 2100 +# proc msgcat::complete(mcpreferences) {text start end line pos mod} { 2101 +# } 2102 + 2103 +proc msgcat::complete(mcload) {text start end line pos mod} { 2104 + switch -- $pos { 2105 + 1 { return [DisplayHints <dirname>] } 2106 + } 2107 + return "" 2108 +} 2109 + 2110 +proc msgcat::complete(mcset) {text start end line pos mod} { 2111 + switch -- $pos { 2112 + 1 { return [DisplayHints <locale>] } 2113 + 2 { return [DisplayHints <src-string>] } 2114 + 3 { return [DisplayHints ?translate-string?] } 2115 + } 2116 + return "" 2117 +} 2118 + 2119 +proc msgcat::complete(mcunknown) {text start end line pos mod} { 2120 + switch -- $pos { 2121 + 1 { return [DisplayHints <locale>] } 2122 + 2 { return [DisplayHints <src-string>] } 2123 + } 2124 + return "" 2125 +} 2126 + 2127 +# --- END OF MSGCAT PACKAGE --- 2128 + 2129 +# TODO import ! -force 2130 +proc complete(namespace) {text start end line pos mod} { 1463 2131 # TODO dosn't work ??? 1464 2132 set space_matches [namespace children :: [string trim ${mod}*]] 1465 2133 # puts \nspace_matches=|${space_matches}| 1466 - set cmd [lindex $line 1] 1467 - if {1 == $pos} { 1468 - set cmds { 1469 - children code current delete eval export forget 1470 - import inscope origin parent qualifiers tail which} 1471 - return [TryFromList $text $cmds] 1472 - } elseif {2 == $pos} { 1473 - switch -- $cmd { 1474 - children - 1475 - delete - 1476 - eval - 1477 - inscope - 1478 - forget - 1479 - parent { return [TryFromList ${mod} $space_matches] } 1480 - code { return "" } 1481 - current {} 1482 - export { return [MenuFromList ${mod} {-clear ?pattern?}] } 1483 - import { 1484 - return [MenuFromList ${mod} {-force $space_matches}] 1485 - } 1486 - origin { if {![llength ${mod}]} { return <command> } } 1487 - qualifiers - 1488 - tail { if {![llength ${mod}]} { return <string> } } 1489 - which { return [MenuFromList ${mod} { 1490 - -command -variable <name>}] } 1491 - } 1492 - # forget { if {![llength ${mod}]} { return ?pattern? } } 1493 - } elseif {3 == $pos && "inscope" == $cmd} { 1494 - if {![llength ${mod}]} { return arg } 1495 - } else { 1496 - switch -- $cmd { 1497 - children { if {![llength ${mod}]} { return ?pattern? } } 1498 - delete { return [TryFromList $text $space_matches] } 1499 - eval { if {![llength ${mod}]} { return ?arg? } } 1500 - inscope { if {![llength ${mod}]} { return ?arg? } } 1501 - parent {} 1502 - code {} 1503 - current {} 1504 - export - 1505 - forget - 1506 - import { return [DisplayHints ?pattern?] } 1507 - origin {} 1508 - qualifiers {} 1509 - tail {} 1510 - which { return [MenuFromList $text { 1511 - -command -variable <name>}] } 2134 + set cmd [Lindex $line 1] 2135 + switch -- $pos { 2136 + 1 { 2137 + set cmds { 2138 + children code current delete eval export forget 2139 + import inscope origin parent qualifiers tail which} 2140 + return [TryFromList $text $cmds] 2141 + } 2142 + 2 { 2143 + switch -- $cmd { 2144 + children - 2145 + delete - 2146 + eval - 2147 + inscope - 2148 + forget - 2149 + parent - 2150 + qualifiers - 2151 + tail { 2152 + regsub {^([^:])} ${mod} {::\1} mod; # full qual. name 2153 + return [TryFromList ${mod} $space_matches] 2154 + } 2155 + code { return [DisplayHints <script> ] } 2156 + current {} 2157 + export { return [CompleteFromList ${text} {-clear ?pattern?}] } 2158 + import { 2159 + if {"-" != [string index ${mod} 0]} { 2160 + regsub {^([^:])} ${mod} {::\1} mod; # full qual. name 2161 + } 2162 + return [CompleteFromList ${mod} "-force $space_matches"] 2163 + } 2164 + origin { return [DisplayHints <command>] } 2165 + # qualifiers - 2166 + # tail { return [DisplayHints <string>] } 2167 + which { return [CompleteFromList ${mod} { 2168 + -command -variable <name>}] } 2169 + } 2170 + } 2171 + 3 { 2172 + switch -- $cmd { 2173 + children - 2174 + export - 2175 + forget - 2176 + import { return [DisplayHints ?pattern?] } 2177 + delete { return [TryFromList ${mod} $space_matches] } 2178 + eval - 2179 + inscope { return [DisplayHints <arg>] } 2180 + which { return [CompleteFromList ${mod} {-variable <name>}] } 2181 + } 2182 + } 2183 + 4 { 2184 + switch -- $cmd { 2185 + export - 2186 + forget - 2187 + import { return [DisplayHints ?pattern?] } 2188 + delete { return [TryFromList ${mod} $space_matches] } 2189 + eval - 2190 + inscope { return [DisplayHints ?arg?] } 2191 + which { return [CompleteFromList ${mod} {<name>}] } 2192 + } 1512 2193 } 1513 2194 } 1514 2195 return "" 1515 2196 } 1516 2197 1517 2198 proc complete(open) {text start end line pos mod} { 1518 - if {![llength ${mod}]} { 1519 - if {2 == $pos} { 1520 - return ?access? 1521 - } elseif {3 == $pos} { 1522 - return ?permissions? 2199 + # 2 { return [DisplayHints ?access?] } 2200 + switch -- $pos { 2201 + 2 { 2202 + set access {r r+ w w+ a a+ 2203 + RDONLY WRONLY RDWR APPEND CREAT EXCL NOCTTY NONBLOCK TRUNC} 2204 + return [CompleteFromList ${text} $access] 1523 2205 } 2206 + 3 { return [DisplayHints ?permissions?] } 1524 2207 } 1525 2208 return "" 1526 2209 } 1527 2210 1528 2211 proc complete(package) {text start end line pos mod} { 1529 - set cmd [lindex $line 1] 1530 - if {1 == $pos} { 1531 - set cmds { 1532 - forget ifneeded names present provide require 1533 - unknown vcompare versions vsatisfies} 1534 - return [TryFromList $text $cmds] 1535 - } elseif {2 == $pos} { 1536 - switch -- $cmd { 1537 - forget - 1538 - ifneeded - 1539 - provide - 1540 - versions { return [MenuFromList ${mod} [package names]] } 1541 - present - 1542 - require { 1543 - return [MenuFromList ${mod} "-exact [package names]"] } 1544 - names {} 1545 - unknown { if {![llength ${mod}]} { return ?command? } } 1546 - vcompare - 1547 - vsatisfies { if {![llength ${mod}]} { return <version1> } } 1548 - } 1549 - } elseif {3 == $pos} { 1550 - switch -- $cmd { 1551 - forget {} 1552 - ifneeded { if {![llength ${mod}]} { return <version> } } 1553 - provide { if {![llength ${mod}]} { return ?version? } } 1554 - versions {} 1555 - present - 1556 - require { 1557 - set prev [PreviousWord ${start} ${line}] 1558 - if {[llength [MenuFromList ${prev} -exact]]} { 1559 - return [MenuFromList ${mod} [package names]] 1560 - } elseif {![llength ${mod}]} { 1561 - return ?version? 1562 - } 1563 - } 1564 - names {} 1565 - unknown {} 1566 - vcompare - 1567 - vsatisfies { if {![llength ${mod}]} { return <version2> } } 1568 - } 1569 - } 1570 - return "" 2212 + set cmd [Lindex $line 1] 2213 + switch -- $pos { 2214 + 1 { 2215 + set cmds { 2216 + forget ifneeded names present provide require 2217 + unknown vcompare versions vsatisfies} 2218 + return [TryFromList $text $cmds] 2219 + } 2220 + 2 { 2221 + switch -- $cmd { 2222 + forget - 2223 + ifneeded - 2224 + provide - 2225 + versions { return [CompleteFromList ${mod} [package names]] } 2226 + present - 2227 + require { 2228 + return [CompleteFromList ${mod} "-exact [package names]"] } 2229 + names {} 2230 + unknown { return [DisplayHints ?command?] } 2231 + vcompare - 2232 + vsatisfies { return [DisplayHints <version1>] } 2233 + } 2234 + } 2235 + 3 { 2236 + switch -- $cmd { 2237 + forget {} 2238 + ifneeded { return [DisplayHints <version>] } 2239 + provide { return [DisplayHints ?version?] } 2240 + versions {} 2241 + present - 2242 + require { 2243 + if {"-exact" == [PreviousWord ${start} ${line}]} { 2244 + return [CompleteFromList ${mod} [package names]] 2245 + } else { 2246 + return [DisplayHints ?version?] 2247 + } 2248 + } 2249 + names {} 2250 + unknown {} 2251 + vcompare - 2252 + vsatisfies { return [DisplayHints <version2>] } 2253 + } 2254 + } 2255 + } 2256 + return "" 2257 +} 2258 + 2259 +proc complete(pid) {text start end line pos mod} { 2260 + switch -- $pos { 2261 + 1 { return [ChannelId ${text}] } 2262 + } 1571 2263 } 1572 2264 1573 2265 proc complete(pkg_mkIndex) {text start end line pos mod} { 1574 2266 set cmds [RemoveUsedOptions ${line} {-direct -load -verbose -- <dir>} {--}] 1575 - set res [string trim [MenuFromList $text $cmds]] 1576 - if {[regexp -- [PreviousWord ${start} ${line}] -load] \ 1577 - && ![llength ${mod}]} { 1578 - return <pkgPat> 2267 + set res [string trim [TryFromList $text $cmds]] 2268 + set prev [PreviousWord ${start} ${line}] 2269 + if {"-load" == $prev} { 2270 + return [DisplayHints <pkgPat>] 2271 + } elseif {"--" == $prev} { 2272 + return [TryFromList ${text} <dir>] 1579 2273 } 1580 - if {![llength [join ${res}]]} { 1581 - return "" 1582 - } else { 1583 - return ${res} 1584 - } 1585 - return "" 2274 + return ${res} 1586 2275 } 1587 2276 1588 2277 proc complete(proc) {text start end line pos mod} { 1589 - # puts known_procs=|${known_procs}| 1590 - if {1 == $pos} { 1591 - set known_procs [ProcsOnlyCompletion ${mod}] 1592 - set common [CompleteLongest ${known_procs}] 1593 - if {"" == ${common}} { 1594 - return [Format ${known_procs} ${text}] 1595 - } else { 1596 - return [string trim "${common} ${known_procs}"] 2278 + switch -- $pos { 2279 + 1 { 2280 + set known_procs [ProcsOnlyCompletion ${text}] 2281 + return [CompleteFromList ${text} ${known_procs}] 1597 2282 } 1598 - } elseif {2 == $pos} { 1599 - set proc [lindex $line 1] 1600 - if {[catch {set args [uplevel 2 info args ${proc}]}]} { 1601 - return "" 1602 - } else { 1603 - return [list "\{${args}\} \{"] 2283 + 2 { 2284 + set proc [Lindex $line 1] 2285 + if {[catch {set args [uplevel [info level] info args ${proc}]}]} { 2286 + return [DisplayHints <args>] 2287 + } else { 2288 + return [list "\{${args}\}"] 2289 + } 2290 + } 2291 + 3 { 2292 + if {![string length [Lindex $line $pos]]} { 2293 + return [list \{ {}]; # \} 2294 + } else { 2295 + return [DisplayHints <body>] 2296 + } 1604 2297 } 1605 2298 } 1606 2299 return "" 1607 2300 } 1608 2301 1609 2302 proc complete(puts) {text start end line pos mod} { 1610 - if {1 == $pos} { 1611 - return [TryFromList ${mod} "-nonewline [OutChannelId ${mod}]"] 1612 - } elseif {2 <= $pos} { 1613 - if {![llength ${mod}]} { 1614 - set opt [lindex ${line} 1] 1615 - if {[llength [MenuFromList ${opt} {-nonewline}]]} { 1616 - incr pos -1 2303 + set cmd [Lindex $line 1] 2304 + switch -- $pos { 2305 + 1 { 2306 + return [OutChannelId ${text} "-nonewline"] 2307 + } 2308 + 2 { 2309 + switch -- $cmd { 2310 + -nonewline { return [OutChannelId ${text}] } 2311 + default { return [DisplayHints <string>] } 1617 2312 } 1618 - if {1 == $pos} { 1619 - return [OutChannelId ${mod}] 1620 - } elseif {2 == $pos} { 1621 - return [DisplayHints <string>] 1622 - return <string> 2313 + } 2314 + 3 { 2315 + switch -- $cmd { 2316 + -nonewline { return [DisplayHints <string>] } 1623 2317 } 1624 2318 } 1625 2319 } 1626 2320 return "" 1627 2321 } 2322 + 2323 +# proc complete(pwd) {text start end line pos mod} { 2324 +# } 1628 2325 1629 2326 proc complete(read) {text start end line pos mod} { 1630 - if {1 == $pos} { 1631 - return [MenuFromList ${mod} {-nonewline [InChannelId ${mod}]}] 1632 - } elseif {2 == $pos} { 1633 - if {![llength ${mod}]} { 1634 - set opt [lindex ${line} 1] 1635 - if {[llength [MenuFromList ${opt} {-nonewline}]]} { 1636 - return [InChannelId ${mod}] 1637 - } elseif {![llength ${mod}]} { 1638 - return [DisplayHints <numBytes>] 2327 + set cmd [Lindex $line 1] 2328 + switch -- $pos { 2329 + 1 { 2330 + return [InChannelId ${text} "-nonewline"] 2331 + } 2332 + 2 { 2333 + switch -- $cmd { 2334 + -nonewline { return [InChannelId ${text}] } 2335 + default { return [DisplayHints <numChars>] } 1639 2336 } 1640 2337 } 1641 2338 } 1642 2339 return "" 1643 2340 } 1644 2341 1645 2342 proc complete(regexp) {text start end line pos mod} { 1646 2343 set prev [PreviousWord ${start} ${line}] 1647 - if {[llength ${prev}] && ("-" == [string index ${prev} 0] || 1 == $pos)} { 2344 + if {[llength ${prev}] && "--" != $prev && \ 2345 + ("-" == [string index ${prev} 0] || 1 == $pos)} { 1648 2346 set cmds [RemoveUsedOptions ${line} { 1649 2347 -nocase -indices -expanded -line 1650 2348 -linestop -lineanchor -about <expression> --} {--}] 1651 2349 if {[llength ${cmds}]} { 1652 - return [string trim [MenuFromList $text $cmds]] 2350 + return [string trim [CompleteFromList $text $cmds]] 1653 2351 } 1654 2352 } else { 1655 2353 set virtual_pos [expr ${pos} - [FirstNonOption ${line}]] 1656 2354 switch -- ${virtual_pos} { 1657 - 1 { if {![llength ${mod}]} { return <string> } } 1658 - 2 { if {![llength ${mod}]} { return ?matchVar? } } 1659 - default { if {![llength ${mod}]} { return ?subMatchVar? } } 2355 + 0 { return [DisplayHints <string>] } 2356 + 1 { return [DisplayHints ?matchVar?] } 2357 + default { return [DisplayHints ?subMatchVar?] } 1660 2358 } 1661 2359 } 1662 2360 return "" 1663 2361 } 2362 + 2363 +# proc complete(regexp) {text start end line pos mod} { 2364 +# We're not on windoze here ... 2365 +# } 1664 2366 1665 2367 proc complete(regsub) {text start end line pos mod} { 1666 2368 set prev [PreviousWord ${start} ${line}] 1667 - if {[llength ${prev}] && ("-" == [string index ${prev} 0] || 1 == $pos)} { 1668 - set cmds [RemoveUsedOptions ${line} {-all -nocase -- <expression>} {--}] 1669 - set res [string trim [MenuFromList ${mod} ${cmds}]] 1670 - if {[llength ${res}]} { 1671 - return ${res} 2369 + if {[llength ${prev}] && "--" != $prev && \ 2370 + ("-" == [string index ${prev} 0] || 1 == $pos)} { 2371 + set cmds [RemoveUsedOptions ${line} { 2372 + -all -nocase --} {--}] 2373 + if {[llength ${cmds}]} { 2374 + return [string trim [CompleteFromList $text $cmds]] 1672 2375 } 1673 2376 } else { 1674 2377 set virtual_pos [expr ${pos} - [FirstNonOption ${line}]] 1675 2378 switch -- ${virtual_pos} { 1676 - 1 { if {![llength ${mod}]} { return <expression> } } 1677 - 2 { if {![llength ${mod}]} { return <string> } } 1678 - 3 { if {![llength ${mod}]} { return <subSpec> } } 1679 - 4 { if {![llength ${mod}]} { return <varName> } } 2379 + 0 { return [DisplayHints <expression>] } 2380 + 1 { return [DisplayHints <string>] } 2381 + 2 { return [DisplayHints <subSpec>] } 2382 + 3 { return [DisplayHints <varName>] } 1680 2383 } 1681 2384 } 1682 2385 return "" 1683 2386 } 1684 2387 1685 2388 proc complete(rename) {text start end line pos mod} { 1686 - if {1 == $pos} { 1687 - # TODO set all [CommandCompletion ${mod}] 1688 - return [Format $all ${mod}] 1689 - } elseif {2 == $pos && ![llength ${mod}]} { 1690 - return <newName> 2389 + switch -- $pos { 2390 + 1 { 2391 + return [CompleteFromList $text [CommandCompletion $text]] 2392 + } 2393 + 2 { 2394 + return [DisplayHints <newName>] 2395 + } 1691 2396 } 1692 2397 return "" 1693 2398 } 2399 + 2400 +# proc complete(resource) {text start end line pos mod} { 2401 +# This is not a mac ... 2402 +# } 1694 2403 1695 2404 proc complete(return) {text start end line pos mod} { 1696 2405 # TODO this is not perfect yet 1697 - set cmds {-code -errorinfo -errorcode <string>} 1698 - set res [MenuFromList [PreviousWord ${start} ${line}] ${cmds}] 1699 - if {1 == [llength ${res}]} { 1700 - switch -- ${res} { 1701 - -errorinfo { if {![llength ${mod}]} { return <info> } } 1702 - -code - 1703 - -errorcode { 1704 - set codes {ok error return break continue} 1705 - return [TryFromList ${mod} ${codes}] 1706 - } 1707 - } 1708 - } 1709 - set cmds [RemoveUsedOptions ${line} ${cmds}] 1710 - set res [string trim [MenuFromList ${mod} ${cmds}]] 1711 - if {[llength ${res}]} { 1712 - return ${res} 2406 + set cmds {-code -errorinfo -errorcode ?string?} 2407 + set res [PreviousWord ${start} ${line}] 2408 + switch -- ${res} { 2409 + -errorinfo { return [DisplayHints <info>] } 2410 + -code - 2411 + -errorcode { 2412 + set codes {ok error return break continue} 2413 + return [TryFromList ${mod} ${codes}] 2414 + } 2415 + } 2416 + return [CompleteFromList ${text} [RemoveUsedOptions ${line} ${cmds}]] 2417 +} 2418 + 2419 +# --- SAFE PACKAGE --- 2420 + 2421 +# create a safe namespace inside 2422 +# tclreadline and import some commands. 2423 +# 2424 +namespace eval safe { 2425 + catch { 2426 + namespace import \ 2427 + ::tclreadline::DisplayHints ::tclreadline::PreviousWord \ 2428 + ::tclreadline::CompleteFromList ::tclreadline::CommandCompletion \ 2429 + ::tclreadline::RemoveUsedOptions ::tclreadline::HostList \ 2430 + ::tclreadline::ChannelId ::tclreadline::Lindex \ 2431 + ::tclreadline::CompleteBoolean 2432 + } 2433 + variable opts 2434 + set opts { 2435 + -accessPath -statics -noStatics -nested -nestedLoadOk -deleteHook 2436 + } 2437 + proc SlaveOrOpts {text start line pos slave} { 2438 + set prev [PreviousWord ${start} ${line}] 2439 + variable opts 2440 + if {$pos > 1} { 2441 + set slave "" 2442 + } 2443 + switch -- $prev { 2444 + -accessPath { return [DisplayHints <directoryList>] } 2445 + -statics { return [CompleteBoolean $text] } 2446 + -nested { return [CompleteBoolean $text] } 2447 + -deleteHook { return [DisplayHints <script>] } 2448 + default { 2449 + return [CompleteFromList ${text} \ 2450 + [RemoveUsedOptions ${line} "${opts} $slave"]] 2451 + } 2452 + } 2453 + } 2454 +} 2455 + 2456 +proc safe::complete(interpCreate) {text start end line pos mod} { 2457 + return [SlaveOrOpts $text $start $line $pos ?slave?] 2458 +} 2459 + 2460 +proc safe::complete(interpInit) {text start end line pos mod} { 2461 + return [SlaveOrOpts $text $start $line $pos [interp slaves]] 2462 +} 2463 + 2464 +proc safe::complete(interpConfigure) {text start end line pos mod} { 2465 + return [SlaveOrOpts $text $start $line $pos [interp slaves]] 2466 +} 2467 + 2468 +proc safe::complete(interpDelete) {text start end line pos mod} { 2469 + return [CompleteFromList $text [interp slaves]] 2470 +} 2471 + 2472 +proc safe::complete(interpAddToAccessPath) {text start end line pos mod} { 2473 + switch -- $pos { 2474 + 1 { return [CompleteFromList $text [interp slaves]] } 2475 + } 2476 +} 2477 + 2478 +proc safe::complete(interpFindInAccessPath) {text start end line pos mod} { 2479 + switch -- $pos { 2480 + 1 { return [CompleteFromList $text [interp slaves]] } 2481 + } 2482 +} 2483 + 2484 +proc safe::complete(setLogCmd) {text start end line pos mod} { 2485 + switch -- $pos { 2486 + 1 { return [DisplayHints ?cmd?] } 2487 + default { return [DisplayHints ?arg?] } 2488 + } 2489 +} 2490 + 2491 +# --- END OF SAFE PACKAGE --- 2492 + 2493 +proc complete(scan) {text start end line pos mod} { 2494 + switch -- $pos { 2495 + 1 { return [DisplayHints <string>] } 2496 + 2 { return [DisplayHints <format>] } 2497 + default { return [VarCompletion ${text}] } 1713 2498 } 1714 2499 return "" 1715 2500 } 1716 2501 1717 2502 proc complete(seek) {text start end line pos mod} { 1718 - if {1 == $pos} { 1719 - return [ChannelId ${mod}] 1720 - } elseif {2 == $pos} { 1721 - return [TryFromList ${mod} {start current end}] 2503 + switch -- $pos { 2504 + 1 { return [ChannelId ${text}] } 2505 + 2 { return [DisplayHints <offset>] } 2506 + 3 { return [TryFromList ${text} {start current end}] } 1722 2507 } 1723 2508 return "" 1724 2509 } 1725 2510 1726 2511 proc complete(set) {text start end line pos mod} { 1727 - # puts stderr "\ntext=|$text| $start $end\n" 1728 - # puts stderr \nline=|$line|\n 1729 - # puts stderr \npos=|$pos|\n 1730 - # puts stderr \nmod=|$mod|\n 1731 - if {1 == $pos} { 1732 - return [VarCompletion ${text}] 1733 - } elseif {2 == $pos && ($text == "" || $text == "\"" || $text == "\{")} { 1734 - set line [QuoteQuotes $line] 1735 - if {[catch "set value [list [uplevel [info level] set [lindex $line 1]]]" msg]} { 1736 - return "" 1737 - } else { 1738 - return [Quote $value ${text}] 2512 + switch -- $pos { 2513 + 1 { return [VarCompletion ${text}] } 2514 + 2 { 2515 + if {$text == "" || $text == "\"" || $text == "\{"} { 2516 + set line [QuoteQuotes $line] 2517 + if {[catch [list set value [list [uplevel [info level] \ 2518 + set [Lindex $line 1]]]] msg] 2519 + } { 2520 + return "" 2521 + } else { 2522 + return [Quote $value ${text}] 2523 + } 2524 + } 1739 2525 } 1740 2526 } 1741 2527 return "" 1742 2528 } 1743 2529 1744 2530 proc complete(socket) {text start end line pos mod} { 1745 - set cmd [lindex ${line} 1] 2531 + set cmd [Lindex ${line} 1] 1746 2532 set prev [PreviousWord ${start} ${line}] 1747 2533 if {"-server" == ${cmd}} { 1748 2534 # server sockets 1749 2535 # 1750 - if {2 == $pos && ![llength ${mod}]} { return <command> } 1751 - switch -- ${prev} { 1752 - -myaddr { if {![llength ${mod}]} { return <addr> } } 2536 + switch -- $pos { 2537 + 2 { return [DisplayHints <command>] } 2538 + default { 2539 + if {"-myaddr" == $prev} { 2540 + return [DisplayHints <addr>] 2541 + } else { 2542 + return [CompleteFromList ${mod} \ 2543 + [RemoveUsedOptions $line {-myaddr -error -sockname <port>}]] 2544 + } 2545 + } 1753 2546 } 1754 - return [TryFromList ${mod} [concat {-error -sockname -peername}]] 1755 2547 } else { 1756 2548 # client sockets 1757 2549 # 1758 2550 switch -- ${prev} { 1759 - -myaddr { if {![llength ${mod}]} { return <addr> } } 1760 - -myport { if {![llength ${mod}]} { return <port> } } 2551 + -myaddr { return [DisplayHints <addr>] } 2552 + -myport { return [DisplayHints <port>] } 1761 2553 } 1762 2554 1763 - # read the host table only once. 1764 - # 1765 - variable hosts 1766 - if {![info exists hosts] && "-server" != ${cmd}} { 1767 - set id [open /etc/hosts r] 1768 - set hosts "" 1769 - if {0 != ${id}} { 1770 - while {-1 != [gets ${id} line]} { 1771 - regsub {#.*} ${line} {} line 1772 - if {[llength ${line}] >= 2} { 1773 - lappend hosts [lindex ${line} 1] 1774 - } 1775 - } 1776 - close $id 1777 - } 1778 - } 2555 + set hosts [HostList] 1779 2556 set cmds {-myaddr -myport -async -myaddr -error -sockname -peername} 1780 2557 if {$pos <= 1} { 1781 2558 lappend cmds -server 1782 2559 } 1783 - return [TryFromList ${mod} [concat ${cmds} ${hosts}]] 2560 + set cmds [RemoveUsedOptions $line $cmds] 2561 + if {-1 != [lsearch $hosts $prev]} { 2562 + return [DisplayHints <port>] 2563 + } else { 2564 + return [CompleteFromList ${mod} [concat ${cmds} ${hosts}]] 2565 + } 1784 2566 } 1785 2567 return "" 1786 2568 } 1787 2569 1788 -proc complete(source) {text start end line pos mod} { 1789 - return ""; # force file name completion 2570 +# proc complete(source) {text start end line pos mod} { 2571 +# } 2572 + 2573 +proc complete(split) {text start end line pos mod} { 2574 + switch -- $pos { 2575 + 1 { return [DisplayHints <string>] } 2576 + 2 { return [DisplayHints ?splitChars?] } 2577 + } 1790 2578 } 1791 2579 1792 2580 proc complete(string) {text start end line pos mod} { 1793 - set cmd [lindex ${line} 1] 2581 + set cmd [Lindex ${line} 1] 2582 + set prev [PreviousWord ${start} ${line}] 1794 2583 set cmds { 1795 - compare first index last length match range tolower 1796 - totitle toupper trim trimleft trimright wordend wordstart} 1797 - if {1 == $pos} { 1798 - return [TryFromList ${mod} ${cmds}] 1799 - } elseif {2 == $pos} { 1800 - switch -- $cmd { 1801 - compare - 1802 - first - 1803 - last { if {![llength ${mod}]} { return <string1> } } 1804 - 1805 - match { if {![llength ${mod}]} { return <pattern> } } 1806 - 1807 - index - 1808 - length - 1809 - range - 1810 - tolower - 1811 - totitle - 1812 - toupper - 1813 - trim - 1814 - trimleft - 1815 - trimright - 1816 - wordend - 1817 - wordstart { if {![llength ${mod}]} { return <string> } } 1818 - } 1819 - } elseif {3 == $pos} { 1820 - switch -- $cmd { 1821 - compare - 1822 - first - 1823 - last { if {![llength ${mod}]} { return <string2> } } 1824 - 1825 - index { if {![llength ${mod}]} { return <charIndex> } } 1826 - length {} 1827 - 1828 - match { if {![llength ${mod}]} { return <string> } } 1829 - 1830 - range { if {![llength ${mod}]} { return <first> } } 1831 - 1832 - tolower - 1833 - totitle - 1834 - toupper {} 1835 - 1836 - trim - 1837 - trimleft { if {![llength ${mod}]} { return ?chars? } } 1838 - trimright - 1839 - wordend - 1840 - wordstart { if {![llength ${mod}]} { return <index> } } 2584 + bytelength compare equal first index is last length map match 2585 + range repeat replace tolower toupper totitle trim trimleft 2586 + trimright wordend wordstart} 2587 + switch -- $pos { 2588 + 1 { 2589 + return [CompleteFromList ${text} ${cmds}] 2590 + } 2591 + 2 { 2592 + switch -- $cmd { 2593 + compare - 2594 + equal { 2595 + return [CompleteFromList ${text} { 2596 + -nocase -length <string> }] 2597 + } 2598 + 2599 + first - 2600 + last { return [DisplayHints <string1>] } 2601 + 2602 + map { return [CompleteFromList ${text} {-nocase <charMap>]} } 2603 + match { return [CompleteFromList ${text} {-nocase <pattern>]} } 2604 + 2605 + is { 2606 + return [CompleteFromList ${text} { 2607 + alnum alpha ascii boolean control digit double 2608 + false graph integer lower print punct space 2609 + true upper wordchar xdigit 2610 + }] 2611 + } 2612 + 2613 + bytelength - 2614 + index - 2615 + length - 2616 + range - 2617 + repeat - 2618 + replace - 2619 + tolower - 2620 + totitle - 2621 + toupper - 2622 + trim - 2623 + trimleft - 2624 + trimright - 2625 + wordend - 2626 + wordstart { return [DisplayHints <string>] } 2627 + } 2628 + } 2629 + 3 { 2630 + switch -- $cmd { 2631 + compare - 2632 + equal { 2633 + if {"-length" == $prev} { 2634 + return [DisplayHints <int>] 2635 + } 2636 + return [CompleteFromList ${text} \ 2637 + [RemoveUsedOptions $line {-nocase -length <string>}]] 2638 + } 2639 + 2640 + first - 2641 + last { return [DisplayHints <string2>] } 2642 + 2643 + map { 2644 + if {"-nocase" == $prev} { 2645 + return [DisplayHints <charMap>] 2646 + } else { 2647 + return [DisplayHints <string>] 2648 + } 2649 + } 2650 + match { 2651 + if {"-nocase" == $prev} { 2652 + return [DisplayHints <pattern>] 2653 + } else { 2654 + return [DisplayHints <string>] 2655 + } 2656 + } 2657 + 2658 + is { 2659 + return [CompleteFromList ${text} \ 2660 + [RemoveUsedOptions $line {-strict -failindex <string>}]] 2661 + } 2662 + 2663 + bytelength {} 2664 + index - 2665 + wordend - 2666 + wordstart { return [DisplayHints <charIndex>] } 2667 + range - 2668 + replace { return [DisplayHints <first>] } 2669 + repeat { return [DisplayHints <count>] } 2670 + tolower - 2671 + totitle - 2672 + toupper { return [DisplayHints ?first?] } 2673 + trim - 2674 + trimleft - 2675 + trimright { return [DisplayHints ?chars?] } 2676 + } 2677 + } 2678 + 4 { 2679 + switch -- $cmd { 2680 + compare - 2681 + equal { 2682 + if {"-length" == $prev} { 2683 + return [DisplayHints <int>] 2684 + } 2685 + return [CompleteFromList ${text} \ 2686 + [RemoveUsedOptions $line {-nocase -length <string>}]] 2687 + } 2688 + 2689 + first - 2690 + last { return [DisplayHints ?startIndex?] } 2691 + 2692 + map - 2693 + match { return [DisplayHints <string>] } 2694 + 2695 + is { 2696 + if {"-failindex" == $prev} { 2697 + return [VarCompletion ${text}] 2698 + } 2699 + return [CompleteFromList ${text} \ 2700 + [RemoveUsedOptions $line {-strict -failindex <string>}]] 2701 + } 2702 + 2703 + bytelength {} 2704 + index {} 2705 + length {} 2706 + range - 2707 + replace { return [DisplayHints <last>] } 2708 + repeat {} 2709 + tolower - 2710 + totitle - 2711 + toupper { return [DisplayHints ?last?] } 2712 + trim - 2713 + trimleft - 2714 + trimright {} 2715 + wordend - 2716 + wordstart {} 2717 + } 2718 + } 2719 + default { 2720 + switch -- $cmd { 2721 + compare - 2722 + equal { 2723 + if {"-length" == $prev} { 2724 + return [DisplayHints <int>] 2725 + } 2726 + return [CompleteFromList ${text} \ 2727 + [RemoveUsedOptions $line {-nocase -length <string>}]] 2728 + } 2729 + 2730 + is { 2731 + if {"-failindex" == $prev} { 2732 + return [VarCompletion ${text}] 2733 + } 2734 + return [CompleteFromList ${text} \ 2735 + [RemoveUsedOptions $line {-strict -failindex <string>}]] 2736 + } 2737 + 2738 + replace { return [DisplayHints ?newString?] } 2739 + } 1841 2740 } 1842 2741 } 1843 2742 return "" 1844 2743 } 1845 2744 1846 2745 proc complete(subst) {text start end line pos mod} { 1847 - set opts {-nobackslashes -nocommands -novariables} 1848 - set opts [RemoveUsedOptions ${line} ${opts}] 1849 - return [TryFromList ${mod} [concat ${opts} <string>]] 1850 - return "" 2746 + return [CompleteFromList ${text} [RemoveUsedOptions $line { 2747 + -nobackslashes -nocommands -novariables <string>}]] 1851 2748 } 1852 2749 1853 2750 proc complete(switch) {text start end line pos mod} { 1854 - set opts {-exact -glob -regexp --} 1855 - set opts [RemoveUsedOptions ${line} ${opts} {--}] 1856 - return [TryFromList ${mod} [concat ${opts} <string>]] 2751 + set prev [PreviousWord ${start} ${line}] 2752 + if {[llength ${prev}] && "--" != $prev && \ 2753 + ("-" == [string index ${prev} 0] || 1 == $pos)} { 2754 + set cmds [RemoveUsedOptions ${line} { 2755 + -exact -glob -regexp --} {--}] 2756 + if {[llength ${cmds}]} { 2757 + return [string trim [CompleteFromList $text $cmds]] 2758 + } 2759 + } else { 2760 + set virtual_pos [expr ${pos} - [FirstNonOption ${line}]] 2761 + switch -- ${virtual_pos} { 2762 + 0 { return [DisplayHints <string>] } 2763 + 1 { return [DisplayHints <pattern>] } 2764 + 2 { return [DisplayHints <body>] } 2765 + default { 2766 + switch [expr $virtual_pos % 2] { 2767 + 0 { return [DisplayHints ?body?] } 2768 + 1 { return [DisplayHints ?pattern?] } 2769 + } 2770 + } 2771 + } 2772 + } 1857 2773 return "" 1858 2774 } 1859 2775 1860 2776 proc complete(tell) {text start end line pos mod} { 1861 - if {1 == $pos} { 1862 - return [ChannelId ${mod}] 2777 + switch -- $pos { 2778 + 1 { return [ChannelId ${mod}] } 2779 + } 2780 + return "" 2781 +} 2782 + 2783 +proc complete(time) {text start end line pos mod} { 2784 + switch -- $pos { 2785 + 1 { return [DisplayHints <script>] } 2786 + 2 { return [DisplayHints ?count?] } 1863 2787 } 1864 2788 return "" 1865 2789 } 1866 2790 1867 2791 proc complete(trace) {text start end line pos mod} { 1868 - set cmd [lindex ${line} 1] 1869 - if {1 == $pos} { 1870 - return [TryFromList ${mod} {variable vdelete vinfo}] 1871 - } elseif {2 == $pos} { 1872 - return [Format [uplevel 2 info vars "${mod}*"] ${mod}] 1873 - } elseif {3 == $pos && "variable" == ${cmd}} { 1874 - return [TryFromList ${mod} {r w u}] 2792 + set cmd [Lindex ${line} 1] 2793 + switch -- $pos { 2794 + 1 { 2795 + return [CompleteFromList ${mod} {variable vdelete vinfo}] 2796 + } 2797 + 2 { 2798 + return [CompleteFromList ${text} \ 2799 + [uplevel [info level] info vars "${mod}*"]] 2800 + } 2801 + 3 { 2802 + switch -- $cmd { 2803 + variable - 2804 + vdelete { return [CompleteFromList ${text} {r w u}] } 2805 + } 2806 + } 2807 + 4 { 2808 + switch -- $cmd { 2809 + variable - 2810 + vdelete { 2811 + return [CompleteFromList $text [CommandCompletion $text]] 2812 + } 2813 + } 2814 + } 2815 + } 2816 + return "" 2817 +} 2818 + 2819 +proc complete(unknown) {text start end line pos mod} { 2820 + switch -- $pos { 2821 + 1 { 2822 + return [CompleteFromList $text [CommandCompletion $text]] 2823 + } 2824 + default { return [DisplayHints ?arg?] } 1875 2825 } 1876 2826 return "" 1877 2827 } 2828 + 2829 +proc complete(unset) {text start end line pos mod} { 2830 + return [VarCompletion ${text}] 2831 +} 1878 2832 1879 2833 proc complete(update) {text start end line pos mod} { 1880 - if {1 == $pos && ![llength ${mod}]} { 1881 - return idletasks 2834 + switch -- $pos { 2835 + 1 { return idletasks } 1882 2836 } 1883 2837 return "" 1884 2838 } 1885 2839 1886 2840 proc complete(uplevel) {text start end line pos mod} { 1887 - if {![llength ${mod}]} { 1888 - if {1 == $pos} { 1889 - return ?level? 1890 - } elseif {2 == $pos} { 1891 - return <command> 1892 - } elseif {3 == $pos} { 1893 - return ?arg? 1894 - } elseif {4 == $pos} { 1895 - return ?...? 2841 + set one [Lindex ${line} 1] 2842 + switch -- $pos { 2843 + 1 { 2844 + return [CompleteFromList $text "?level? [CommandCompletion $text]"] 1896 2845 } 2846 + 2 { 2847 + if {"#" == [string index $one 0] || [regexp {^[0-9]*$} $one]} { 2848 + return [CompleteFromList $text [CommandCompletion $text]] 2849 + } else { 2850 + return [DisplayHints ?arg?] 2851 + } 2852 + } 2853 + default { return [DisplayHints ?arg?] } 1897 2854 } 1898 2855 return "" 1899 2856 } 1900 2857 1901 2858 proc complete(upvar) {text start end line pos mod} { 1902 - if {![llength ${mod}]} { 1903 - if {1 == $pos} { 1904 - return ?level? 1905 - } elseif {2 == $pos} { 1906 - return <otherVar> 1907 - } elseif {3 == $pos} { 1908 - return <myVar> 1909 - } elseif {4 == $pos} { 1910 - return ?...? 2859 + set one [Lindex ${line} 1] 2860 + switch -- $pos { 2861 + 1 { 2862 + return [DisplayHints {?level? <otherVar>}] 2863 + } 2864 + 2 { 2865 + if {"#" == [string index $one 0] || [regexp {^[0-9]*$} $one]} { 2866 + return [DisplayHints <otherVar>] 2867 + } else { 2868 + return [DisplayHints <myVar>] 2869 + } 2870 + } 2871 + 3 { 2872 + if {"#" == [string index $one 0] || [regexp {^[0-9]*$} $one]} { 2873 + return [DisplayHints <myVar>] 2874 + } else { 2875 + return [DisplayHints ?otherVar?] 2876 + } 2877 + } 2878 + default { 2879 + set virtual_pos $pos 2880 + if {"#" == [string index $one 0] || [regexp {^[0-9]*$} $one]} { 2881 + incr virtual_pos 2882 + } 2883 + switch [expr $virtual_pos % 2] { 2884 + 0 { return [DisplayHints ?myVar?] } 2885 + 1 { return [DisplayHints ?otherVar?] } 2886 + } 1911 2887 } 1912 2888 } 1913 2889 return "" 1914 2890 } 1915 2891 1916 2892 proc complete(variable) {text start end line pos mod} { 1917 2893 set modulo [expr $pos % 2] 1918 - if {1 == ${modulo}} { 1919 - return [VarCompletion ${mod}] 1920 - } elseif {0 == ${modulo} && \ 1921 - ($text == "" || $text == "\"" || $text == "\{")} { 1922 - set line [QuoteQuotes $line] 1923 - incr pos -1 1924 - if {[catch \ 1925 - "set value [list [uplevel [info level] set [lindex $line ${pos}]]]"\ 1926 - msg]} { 1927 - return "" 1928 - } else { 1929 - return [Quote $value ${mod}] 2894 + switch -- $modulo { 2895 + 1 { return [VarCompletion ${text}] } 2896 + 0 { 2897 + if {$text == "" || $text == "\"" || $text == "\{"} { 2898 + set line [QuoteQuotes $line] 2899 + if {[catch [list set value [list [uplevel [info level] \ 2900 + set [PreviousWord $start $line]]]] msg] 2901 + } { 2902 + return "" 2903 + } else { 2904 + return [Quote $value ${text}] 2905 + } 2906 + } 1930 2907 } 1931 2908 } 1932 2909 return "" 1933 2910 } 1934 2911 1935 2912 proc complete(vwait) {text start end line pos mod} { 1936 - if {1 == ${pos}} { 1937 - return [VarCompletion ${mod}] 2913 + switch -- $pos { 2914 + 1 { return [VarCompletion ${mod}] } 1938 2915 } 2916 + return "" 1939 2917 } 1940 2918 1941 -proc complete(unset) {text start end line pos mod} { 1942 - return [VarCompletion ${text}] 2919 +proc complete(while) {text start end line pos mod} { 2920 + switch -- $pos { 2921 + 1 - 2922 + 2 { 2923 + return [BraceOrControlStatement $text $start $end $line $pos $mod] 2924 + } 2925 + } 2926 + return "" 1943 2927 } 1944 2928 1945 2929 # ------------------------------------- 1946 2930 # TK 1947 2931 # ------------------------------------- 1948 2932 1949 2933 # generic widget configuration