imenu.tcl
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 package require snit
00011 package require textutil::repeat
00012 package require textutil::tabify
00013 package require term::ansi::send
00014 package require term::receive::bind
00015 package require term::ansi::code::ctrl
00016
00017 namespace ::term::receive::menu {}
00018
00019
00020
00021 snit::type ::term::interact::menu {
00022
00023 option -in -default stdin
00024 option -out -default stdout
00025 option -column -default 0
00026 option -line -default 0
00027 option -height -default 25
00028 option -actions -default {}
00029 option -hilitleft -default 0
00030 option -hilitright -default end
00031 option -framed -default 0 -readonly 1
00032
00033
00034
00035
00036
00037 constructor {dict args} {
00038 $self configurelist $args
00039 Save $dict
00040
00041 install bind using ::term::receive::bind \
00042 ${selfns}::bind $options(-actions)
00043
00044 $bind map [cd::cu] [myret Up]
00045 $bind map [cd::cd] [mymethod Down]
00046 $bind map \n [mymethod Select]
00047 #$bind default [mymethod DEF]
00048
00049 return
00050 }
00051
00052 # ### ### ### ######### ######### #########
00053 ##
00054
00055 method interact () {
00056 Show
00057 $bind listen $options(-in)
00058 vwait [myvar done]
00059 $bind unlisten $options(-in)
00060 return $map($done)
00061 }
00062
00063 ret done () {set done $at ; return}
00064 ret clear () {Clear ; return}
00065
00066
00067
00068
00069
00070 component bind
00071
00072
00073
00074
00075
00076 variable map -array {}
00077 variable header
00078 variable labels
00079 variable footer
00080 variable empty
00081
00082 ret Save (type dict) {
00083 upvar 1 header header labels labels footer footer
00084 upvar 1 empty empty at at map map top top
00085 upvar 1 options(-height) height
00086
00087 set max 0
00088 foreach {l code} $dict {
00089 if {[set len [string length $l]] > $max} {set max $len}
00090 }
00091
00092 set header [cd::groptim [cd::tlc][textutil::repeat::strRepeat [cd::hl] $max][cd::trc]]
00093 set footer [cd::groptim [cd::blc][textutil::repeat::strRepeat [cd::hl] $max][cd::brc]]
00094
00095 set labels {}
00096 set at 0
00097 foreach {l code} $dict {
00098 set map($at) $code
00099 lappend labels ${l}[textutil::repeat::strRepeat " " [expr {$max-[string length $l]}]]
00100 incr at
00101 }
00102
00103 set h $height
00104 if {$h > [llength $labels]} {set h [llength $labels]}
00105
00106 set eline " [textutil::repeat::strRepeat { } $max]"
00107 set empty $eline
00108 for {set i 0} {$i <= $h} {incr i} {
00109 append empty \n$eline
00110 }
00111
00112 set at 0
00113 set top 0
00114 return
00115 }
00116
00117 variable top 0
00118 variable at 0
00119 variable done .
00120
00121 ret Show () {
00122 upvar 1 header header labels labels footer footer at at
00123 upvar 1 options(-in) in options(-column) col top top
00124 upvar 1 options(-out) out options(-line) row
00125 upvar 1 options(-height) height options(-framed) framed
00126 upvar 1 options(-hilitleft) left
00127 upvar 1 options(-hilitright) right
00128
00129 set bot [expr {$top + $height - 1}]
00130 set fr [expr {$framed ? [cd::vl] : { }}]
00131
00132 set text $header\n
00133 set i $top
00134 foreach l [lrange $labels $top $bot] {
00135 append text $fr
00136 if {$i != $at} {
00137 append text $l
00138 } else {
00139 append text [string replace $l $left $right \
00140 [cd::sda_revers][string range $l $left $right][cd::sda_reset]]
00141 }
00142 append text $fr \n
00143 incr i
00144 }
00145 append text $footer
00146
00147 vt::wrch $out [cd::showat $row $col $text]
00148 return
00149 }
00150
00151 ret Clear () {
00152 upvar 1 empty empty options(-column) col
00153 upvar 1 options(-out) out options(-line) row
00154
00155 vt::wrch $out [cd::showat $row $col $empty]
00156 return
00157 }
00158
00159
00160
00161
00162
00163 ret Up (type str) {
00164 if {$at == 0} return
00165 incr at -1
00166 if {$at < $top} {incr top -1}
00167 Show
00168 return
00169 }
00170
00171 ret Down (type str) {
00172 upvar 0 options(-height) height
00173 if {$at == ([llength $labels]-1)} return
00174 incr at
00175 set bot [expr {$top + $height - 1}]
00176 if {$at > $bot} {incr top}
00177 Show
00178 return
00179 }
00180
00181 ret Select (type str) {
00182 $self done
00183 return
00184 }
00185
00186 ret DEF (type str) {
00187 puts stderr "($str)"
00188 exit
00189 }
00190
00191
00192
00193
00194 }
00195
00196
00197
00198
00199 namespace ::term::interact::menu {
00200 term::ansi::code::ctrl::import cd
00201 term::ansi::send::import vt
00202 }
00203
00204 package provide term::interact::menu 0.1
00205
00206
00207
00208