tkcon.tcl

来自「算断裂的」· TCL 代码 · 共 2,077 行 · 第 1/5 页

TCL
2,077
字号
    } else {	foreach i $names {	    if {[string match :: $i]} {		$m add radio -label "Main" -variable TKCON(namesp) -value $i \			-command "tkConAttachNamespace [list $i]; $cmd"	    } else {		$m add radio -label $i -variable TKCON(namesp) -value $i \			-command "tkConAttachNamespace [list $i]; $cmd"	    }	}    }}## Namepaces List ##;proc tkConNamespacesList {names} {    global TKCON        set f $TKCON(base).tkConNamespaces    catch {destroy $f}    toplevel $f    listbox $f.names -width 30 -height 15 -selectmode single \	    -yscrollcommand [list $f.scrollv set] \	    -xscrollcommand [list $f.scrollh set]    scrollbar $f.scrollv -command [list $f.names yview]    scrollbar $f.scrollh -command [list $f.names xview] -orient horizontal    frame $f.buttons    button $f.cancel -text "Cancel" -command [list destroy $f]    grid $f.names $f.scrollv -sticky nesw    grid $f.scrollh -sticky ew    grid $f.buttons -sticky nesw    grid $f.cancel -in $f.buttons -pady 6    grid columnconfigure $f 0 -weight 1    grid rowconfigure $f  0 -weight 1    #fill the listbox    foreach i $names {	if {[string match :: $i]} {	    $f.names insert 0 Main	} else {	    $f.names insert end $i	}    }    #Bindings    bind $f.names <Double-1> {	## Catch in case the namespace disappeared on us	catch { tkConAttachNamespace [%W get [%W nearest %y]] }	tkConPrompt "\n" [tkConCmdGet $TKCON(console)]	destroy [winfo toplevel %W]    }}# tkConXauthSecure --##   This removes all the names in the xhost list, and secures#   the display for Tk send commands.  Of course, this prevents#   what might have been otherwise allowable X connections## Arguments:#   none# Results:#   Returns nothing#proc tkConXauthSecure {} {    global tcl_platform    if {[string compare unix $tcl_platform(platform)]} {	# This makes no sense outside of Unix	return    }    set hosts [exec xhost]    # the first line is info only    foreach host [lrange [split $hosts \n] 1 end] {	exec xhost -$host    }    exec xhost -    tk_messageBox -title "Xhost secured" -message "Xhost secured" -icon info}## tkConFindBox - creates minimal dialog interface to tkConFind# ARGS:	w	- text widget#	str	- optional seed string for TKCON(find)##;proc tkConFindBox {w {str {}}} {    global TKCON    set base $TKCON(base).find    if {![winfo exists $base]} {	toplevel $base	wm withdraw $base	wm title $base "TkCon Find"	pack [frame $base.f] -fill x -expand 1	label $base.f.l -text "Find:"	entry $base.f.e -textvar TKCON(find)	pack [frame $base.opt] -fill x	checkbutton $base.opt.c -text "Case Sensitive" \		-variable TKCON(find,case)	checkbutton $base.opt.r -text "Use Regexp" -variable TKCON(find,reg)	pack $base.f.l -side left	pack $base.f.e $base.opt.c $base.opt.r -side left -fill both -expand 1	pack [frame $base.sep -bd 2 -relief sunken -height 4] -fill x	pack [frame $base.btn] -fill both	button $base.btn.fnd -text "Find" -width 6	button $base.btn.clr -text "Clear" -width 6	button $base.btn.dis -text "Dismiss" -width 6	eval pack [winfo children $base.btn] -padx 4 -pady 2 \		-side left -fill both	focus $base.f.e	bind $base.f.e <Return> [list $base.btn.fnd invoke]	bind $base.f.e <Escape> [list $base.btn.dis invoke]    }    $base.btn.fnd config -command "tkConFind [list $w] \$TKCON(find) \	    -case \$TKCON(find,case) -reg \$TKCON(find,reg)"    $base.btn.clr config -command "    [list $w] tag remove find 1.0 end    set TKCON(find) {}    "    $base.btn.dis config -command "    [list $w] tag remove find 1.0 end    wm withdraw [list $base]    "    if {[string compare {} $str]} {	set TKCON(find) $str	$base.btn.fnd invoke    }    if {[string compare normal [wm state $base]]} {	wm deiconify $base    } else { raise $base }    $base.f.e select range 0 end}## tkConFind - searches in text widget $w for $str and highlights it## If $str is empty, it just deletes any highlighting# ARGS: w	- text widget#	str	- string to search for#	-case	TCL_BOOLEAN	whether to be case sensitive	DEFAULT: 0#	-regexp	TCL_BOOLEAN	whether to use $str as pattern	DEFAULT: 0##;proc tkConFind {w str args} {    $w tag remove find 1.0 end    set truth {^(1|yes|true|on)$}    set opts  {}    foreach {key val} $args {	switch -glob -- $key {	    -c* { if {[regexp -nocase $truth $val]} { set case 1 } }	    -r* { if {[regexp -nocase $truth $val]} { lappend opts -regexp } }	    default { return -code error "Unknown option $key" }	}    }    if {![info exists case]} { lappend opts -nocase }    if {[string match {} $str]} return    $w mark set findmark 1.0    while {[string compare {} [set ix [eval $w search $opts -count numc -- \	    [list $str] findmark end]]]} {	$w tag add find $ix ${ix}+${numc}c	$w mark set findmark ${ix}+1c    }    global TKCON    $w tag configure find -background $TKCON(color,blink)    catch {$w see find.first}    return [expr {[llength [$w tag ranges find]]/2}]}## tkConAttach - called to attach tkCon to an interpreter# ARGS:	name	- application name to which tkCon sends commands#		  This is either a slave interperter name or tk appname.#	type	- (slave|interp) type of interpreter we're attaching to#		  slave means it's a TkCon interpreter#		  interp means we'll need to 'send' to it.# Results:	tkConEvalAttached is recreated to evaluate in the#		appropriate interpreter##;proc tkConAttach {{name <NONE>} {type slave}} {    global TKCON    if {[string match <NONE> $name]} {	if {[string match {} $TKCON(appname)]} {	    return [list [concat $TKCON(name) $TKCON(exec)] $TKCON(apptype)]	} else {	    return [list $TKCON(appname) $TKCON(apptype)]	}    }    set path [concat $TKCON(name) $TKCON(exec)]    if {[string match namespace $type]} {	return [uplevel tkConAttachNamespace $name]    } elseif {[string compare {} $name]} {	array set interps [tkConInterps]	if {[string match {[Mm]ain} [lindex $name 0]]} {	    set name [lrange $name 1 end]	}	if {[string match $path $name]} {	    set name {}	    set app $path	    set type slave	} elseif {[info exists interps($name)]} {	    if {[string match {} $name]} { set name Main; set app Main }	    set type slave	} elseif {[interp exists $name]} {	    set name [concat $TKCON(name) $name]	    set type slave	} elseif {[interp exists [concat $TKCON(exec) $name]]} {	    set name [concat $path $name]	    set type slave	} elseif {[lsearch -exact [winfo interps] $name] > -1} {	    if {[tkConEvalSlave info exists tk_library] \		    && [string match $name [tkConEvalSlave tk appname]]} {		set name {}		set app $path		set type slave	    } elseif {[set i [lsearch -exact \		    [tkConMain set TKCON(interps)] $name]] != -1} {		set name [lindex [tkConMain set TKCON(slaves)] $i]		if {[string match {[Mm]ain} $name]} { set app Main }		set type slave	    } else {		set type interp	    }	} else {	    return -code error "No known interpreter \"$name\""	}    } else {	set app $path    }    if {![info exists app]} { set app $name }    array set TKCON [list app $app appname $name apptype $type deadapp 0]    ## tkConEvalAttached - evaluates the args in the attached interp    ## args should be passed to this procedure as if they were being    ## passed to the 'eval' procedure.  This procedure is dynamic to    ## ensure evaluation occurs in the right interp.    # ARGS:	args	- the command and args to evaluate    ##    switch $type {	slave {	    if {[string match {} $name]} {		interp alias {} tkConEvalAttached {} tkConEvalSlave uplevel \#0	    } elseif {[string match Main $TKCON(app)]} {		interp alias {} tkConEvalAttached {} tkConMain	    } elseif {[string match $TKCON(name) $TKCON(app)]} {		interp alias {} tkConEvalAttached {} uplevel \#0	    } else {		interp alias {} tkConEvalAttached {} tkConSlave $TKCON(app)	    }	}	interp {	    if {$TKCON(nontcl)} {		interp alias {} tkConEvalAttached {} tkConEvalSlave		array set TKCON {A:version 0 A:namespace 0 A:itcl2 0 namesp ::}	    } else {		interp alias {} tkConEvalAttached {} tkConEvalSend	    }	}	default {	    return -code error "[lindex [info level 0] 0] did not specify\		    a valid type: must be slave or interp"	}    }    if {[string match slave $type] || \	    (!$TKCON(nontcl) && [string match interp $type])} {	set TKCON(A:version)   [tkConEvalAttached {info tclversion}]	set TKCON(A:namespace) [llength \		[tkConEvalAttached {info commands namespace}]]	# Itcl3.0 for Tcl8.0 should have Tcl8 namespace semantics	# and not effect the patchlevel	set TKCON(A:itcl2) [string match *i* \		[tkConEvalAttached {info patchlevel}]]	set TKCON(namesp) ::    }    return}## tkConAttachNamespace - called to attach tkCon to a namespace# ARGS:	name	- namespace name in which tkCon should eval commands# Results:	tkConEvalAttached will be modified##;proc tkConAttachNamespace { name } {    global TKCON    if {($TKCON(nontcl) && [string match interp $TKCON(apptype)]) \	    || $TKCON(deadapp)} {	return -code error "can't attach to namespace in bad environment"    }    if {[string match Main $name]} {set name ::}    if {[string compare {} $name] && \	    [lsearch [tkConNamespaces ::] $name] == -1} {	return -code error "No known namespace \"$name\""    }    if {[regexp {^(|::)$} $name]} {	## If name=={} || ::, we want the primary namespace	set alias [interp alias {} tkConEvalAttached]	if {[string match tkConEvalNamespace* $alias]} {	    eval [list interp alias {} tkConEvalAttached {}] [lindex $alias 1]	}	set name ::    } else {	interp alias {} tkConEvalAttached {} tkConEvalNamespace \		[interp alias {} tkConEvalAttached] [list $name]    }    set TKCON(namesp) $name}## tkConLoad - sources a file into the console## The file is actually sourced in the currently attached's interp# ARGS:	fn	- (optional) filename to source in# Returns:	selected filename ({} if nothing was selected)## ;proc tkConLoad { {fn ""} } {    global TKCON    set types {	{{Tcl Files}	{.tcl .tk}}	{{Text Files}	{.txt}}	{{All Files}	*}    }    if {	[string match {} $fn] &&	([catch {tk_getOpenFile -filetypes $types \	    -title "Source File"} fn] || [string match {} $fn])    } { return }    tkConEvalAttached [list source $fn]}## tkConSave - saves the console or other widget buffer to a file## This does not eval in a slave because it's not necessary# ARGS:	w	- console text widget# 	fn	- (optional) filename to save to## ;proc tkConSave { {fn ""} {type ""} {widget ""} {mode w} } {    global TKCON    if {![regexp -nocase {^(all|history|stdin|stdout|stderr|widget)$} $type]} {	array set s { 0 All 1 History 2 Stdin 3 Stdout 4 Stderr 5 Cancel }	## Allow user to specify what kind of stuff to save	set type [tk_dialog $TKCON(base).savetype "Save Type" \		"What part of the text do you want to save?" \		questhead 0 $s(0) $s(1) $s(2) $s(3) $s(4) $s(5)]	if {$type == 5 || $type == -1} return	set type $s($type)    }    if {[string match {} $fn]} {	set types {	    {{Tcl Files}	{.tcl .tk}}	    {{Text Files}	{.txt}}	    {{All Files}	*}	}	if {[catch {tk_getSaveFile -defaultextension .tcl -filetypes $types \		-title "Save $type"} fn] || [string match {} $fn]} return    }    set type [string tolower $type]    switch $type {	stdin -	stdout - stderr {	    set data {}	    foreach {first last} [$TKCON(console) tag ranges $type] {		lappend data [$TKCON(console) get $first $last]	    }	    set data [join $data \n]	}	history		{ set data [tkcon history] }	all - default	{ set data [$TKCON(console) get 1.0 end-1c] }	widget		{	    set data [$widget get 1.0 end-1c]	}    }    if {[catch {open $fn $mode} fid]} {	return -code error "Save Error: Unable to open '$fn' for writing\n$fid"    }    puts $fid $data    close $fid}## tkConMainInit## This is only called for the main interpreter to include certain procs## that we don't want to include (or rather, just alias) in slave interps.##;proc tkConMainInit {} {    global TKCON    if {![info exists TKCON(slaves)]} {	array set TKCON [list slave 0 slaves Main name {} \		interps [list [tk appname]]]    }    interp alias {} tkConMain {} tkConInterpEval Main    interp alias {} tkConSlave {} tkConInterpEval    ;proc tkConGetSlaveNum {} {	global TKCON	set i -1	while {[interp exists Slave[incr i]]} {	    # oh my god, an empty loop!	}	return $i    }    ## tkConNew - create new console window    ## Creates a slave interpreter and sources in this script.    ## All other interpreters also get a command to eval function in the    ## new interpreter.    ##     ;proc tkConNew {} {	global argv0 argc argv TKCON	set tmp [interp create Slave[tkConGetSlaveNum]]	lappend TKCON(slaves) $tmp	load {} Tk $tmp	lappend TKCON(interps) [$tmp eval [list tk appname \		"[tk appname] $tmp"]]	if {[info exist argv0]} {$tmp eval [list set argv0 $argv0]}	$tmp eval set argc $argc \; set argv [list $argv] \; \		set TKCON(name) $tmp \; set TKCON(SCRIPT) [list $TKCON(SCRIPT)]	$tmp alias exit			tkConExit $tmp	$tmp alias tkConDestroy		tkConDestroy $tmp	$tmp alias tkConNew		tkConNew	$tmp alias tkConMain		tkConInterpEval Main	$tmp alias tkConSlave		tkConInterpEval	$tmp alias tkConInterps		tkConInterps	$tmp alias tkConStateCheckpoint	tkConStateCheckpoint

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?