📄 console.tcl
字号:
# console.tcl --## This code constructs the console window for an application. It# can be used by non-unix systems that do not have built-in support# for shells.## RCS: @(#) $Id: console.tcl,v 1.3 1998/09/14 18:23:22 stanton Exp $## Copyright (c) 1995-1997 Sun Microsystems, Inc.## See the file "license.terms" for information on usage and redistribution# of this file, and for a DISCLAIMER OF ALL WARRANTIES.## TODO: history - remember partially written command# tkConsoleInit --# This procedure constructs and configures the console windows.## Arguments:# None.proc tkConsoleInit {} { global tcl_platform if {! [consoleinterp eval {set tcl_interactive}]} { wm withdraw . } if {"$tcl_platform(platform)" == "macintosh"} { set mod "Cmd" } else { set mod "Ctrl" } menu .menubar .menubar add cascade -label File -menu .menubar.file -underline 0 .menubar add cascade -label Edit -menu .menubar.edit -underline 0 menu .menubar.file -tearoff 0 .menubar.file add command -label "Source..." -underline 0 \ -command tkConsoleSource .menubar.file add command -label "Hide Console" -underline 0 \ -command {wm withdraw .} if {"$tcl_platform(platform)" == "macintosh"} { .menubar.file add command -label "Quit" -command exit -accel Cmd-Q } else { .menubar.file add command -label "Exit" -underline 1 -command exit } menu .menubar.edit -tearoff 0 .menubar.edit add command -label "Cut" -underline 2 \ -command { event generate .console <<Cut>> } -accel "$mod+X" .menubar.edit add command -label "Copy" -underline 0 \ -command { event generate .console <<Copy>> } -accel "$mod+C" .menubar.edit add command -label "Paste" -underline 1 \ -command { event generate .console <<Paste>> } -accel "$mod+V" if {"$tcl_platform(platform)" == "windows"} { .menubar.edit add command -label "Delete" -underline 0 \ -command { event generate .console <<Clear>> } -accel "Del" .menubar add cascade -label Help -menu .menubar.help -underline 0 menu .menubar.help -tearoff 0 .menubar.help add command -label "About..." -underline 0 \ -command tkConsoleAbout } else { .menubar.edit add command -label "Clear" -underline 2 \ -command { event generate .console <<Clear>> } } . conf -menu .menubar text .console -yscrollcommand ".sb set" -setgrid true scrollbar .sb -command ".console yview" pack .sb -side right -fill both pack .console -fill both -expand 1 -side left if {$tcl_platform(platform) == "macintosh"} { .console configure -font {Monaco 9 normal} -highlightthickness 0 } tkConsoleBind .console .console tag configure stderr -foreground red .console tag configure stdin -foreground blue focus .console wm protocol . WM_DELETE_WINDOW { wm withdraw . } wm title . "Console" flush stdout .console mark set output [.console index "end - 1 char"] tkTextSetCursor .console end .console mark set promptEnd insert .console mark gravity promptEnd left}# tkConsoleSource --## Prompts the user for a file to source in the main interpreter.## Arguments:# None.proc tkConsoleSource {} { set filename [tk_getOpenFile -defaultextension .tcl -parent . \ -title "Select a file to source" \ -filetypes {{"Tcl Scripts" .tcl} {"All Files" *}}] if {"$filename" != ""} { set cmd [list source $filename] if {[catch {consoleinterp eval $cmd} result]} { tkConsoleOutput stderr "$result\n" } }}# tkConsoleInvoke --# Processes the command line input. If the command is complete it# is evaled in the main interpreter. Otherwise, the continuation# prompt is added and more input may be added.## Arguments:# None.proc tkConsoleInvoke {args} { set ranges [.console tag ranges input] set cmd "" if {$ranges != ""} { set pos 0 while {[lindex $ranges $pos] != ""} { set start [lindex $ranges $pos] set end [lindex $ranges [incr pos]] append cmd [.console get $start $end] incr pos } } if {$cmd == ""} { tkConsolePrompt } elseif {[info complete $cmd]} { .console mark set output end .console tag delete input set result [consoleinterp record $cmd] if {$result != ""} { .console insert insert "$result\n" } tkConsoleHistory reset tkConsolePrompt } else { tkConsolePrompt partial } .console yview -pickplace insert}# tkConsoleHistory --# This procedure implements command line history for the# console. In general is evals the history command in the# main interpreter to obtain the history. The global variable# histNum is used to store the current location in the history.## Arguments:# cmd - Which action to take: prev, next, reset.set histNum 1proc tkConsoleHistory {cmd} { global histNum switch $cmd { prev { incr histNum -1 if {$histNum == 0} { set cmd {history event [expr {[history nextid] -1}]} } else { set cmd "history event $histNum" } if {[catch {consoleinterp eval $cmd} cmd]} { incr histNum return } .console delete promptEnd end .console insert promptEnd $cmd {input stdin} } next { incr histNum if {$histNum == 0} { set cmd {history event [expr {[history nextid] -1}]} } elseif {$histNum > 0} { set cmd "" set histNum 1 } else { set cmd "history event $histNum" } if {$cmd != ""} { catch {consoleinterp eval $cmd} cmd } .console delete promptEnd end .console insert promptEnd $cmd {input stdin} } reset { set histNum 1 } }}# tkConsolePrompt --# This procedure draws the prompt. If tcl_prompt1 or tcl_prompt2# exists in the main interpreter it will be called to generate the # prompt. Otherwise, a hard coded default prompt is printed.## Arguments:# partial - Flag to specify which prompt to print.proc tkConsolePrompt {{partial normal}} { if {$partial == "normal"} { set temp [.console index "end - 1 char"] .console mark set output end if {[consoleinterp eval "info exists tcl_prompt1"]} { consoleinterp eval "eval \[set tcl_prompt1\]" } else { puts -nonewline "% " } } else { set temp [.console index output] .console mark set output end if {[consoleinterp eval "info exists tcl_prompt2"]} { consoleinterp eval "eval \[set tcl_prompt2\]" } else { puts -nonewline "> " } } flush stdout .console mark set output $temp tkTextSetCursor .console end .console mark set promptEnd insert .console mark gravity promptEnd left}# tkConsoleBind --# This procedure first ensures that the default bindings for the Text# class have been defined. Then certain bindings are overridden for# the class.## Arguments:# None.proc tkConsoleBind {win} { bindtags $win "$win Text . all" # Ignore all Alt, Meta, and Control keypresses unless explicitly bound. # Otherwise, if a widget binding for one of these is defined, the # <KeyPress> class binding will also fire and insert the character, # which is wrong. Ditto for <Escape>. bind $win <Alt-KeyPress> {# nothing } bind $win <Meta-KeyPress> {# nothing} bind $win <Control-KeyPress> {# nothing} bind $win <Escape> {# nothing} bind $win <KP_Enter> {# nothing} bind $win <Tab> { tkConsoleInsert %W \t focus %W break } bind $win <Return> { %W mark set insert {end - 1c} tkConsoleInsert %W "\n" tkConsoleInvoke break } bind $win <Delete> { if {[%W tag nextrange sel 1.0 end] != ""} { %W tag remove sel sel.first promptEnd } else { if {[%W compare insert < promptEnd]} { break } } } bind $win <BackSpace> { if {[%W tag nextrange sel 1.0 end] != ""} { %W tag remove sel sel.first promptEnd } else { if {[%W compare insert <= promptEnd]} { break } } } foreach left {Control-a Home} { bind $win <$left> { if {[%W compare insert < promptEnd]} { tkTextSetCursor %W {insert linestart} } else { tkTextSetCursor %W promptEnd } break } } foreach right {Control-e End} { bind $win <$right> { tkTextSetCursor %W {insert lineend} break } } bind $win <Control-d> { if {[%W compare insert < promptEnd]} { break } } bind $win <Control-k> { if {[%W compare insert < promptEnd]} { %W mark set insert promptEnd } } bind $win <Control-t> { if {[%W compare insert < promptEnd]} { break } } bind $win <Meta-d> { if {[%W compare insert < promptEnd]} { break } } bind $win <Meta-BackSpace> { if {[%W compare insert <= promptEnd]} { break } } bind $win <Control-h> { if {[%W compare insert <= promptEnd]} { break } } foreach prev {Control-p Up} { bind $win <$prev> { tkConsoleHistory prev break } } foreach prev {Control-n Down} { bind $win <$prev> { tkConsoleHistory next break } } bind $win <Insert> { catch {tkConsoleInsert %W [selection get -displayof %W]} break } bind $win <KeyPress> { tkConsoleInsert %W %A break } foreach left {Control-b Left} { bind $win <$left> { if {[%W compare insert == promptEnd]} { break } tkTextSetCursor %W insert-1c break } } foreach right {Control-f Right} { bind $win <$right> { tkTextSetCursor %W insert+1c break } } bind $win <F9> { eval destroy [winfo child .] if {$tcl_platform(platform) == "macintosh"} { source -rsrc Console } else { source [file join $tk_library console.tcl] } } bind $win <<Cut>> { # Same as the copy event if {![catch {set data [%W get sel.first sel.last]}]} { clipboard clear -displayof %W clipboard append -displayof %W $data } break } bind $win <<Copy>> { if {![catch {set data [%W get sel.first sel.last]}]} { clipboard clear -displayof %W clipboard append -displayof %W $data } break } bind $win <<Paste>> { catch { set clip [selection get -displayof %W -selection CLIPBOARD] set list [split $clip \n\r] tkConsoleInsert %W [lindex $list 0] foreach x [lrange $list 1 end] { %W mark set insert {end - 1c} tkConsoleInsert %W "\n" tkConsoleInvoke tkConsoleInsert %W $x } } break }}# tkConsoleInsert --# Insert a string into a text at the point of the insertion cursor.# If there is a selection in the text, and it covers the point of the# insertion cursor, then delete the selection before inserting. Insertion# is restricted to the prompt area.## Arguments:# w - The text window in which to insert the string# s - The string to insert (usually just a single character)proc tkConsoleInsert {w s} { if {$s == ""} { return } catch { if {[$w compare sel.first <= insert] && [$w compare sel.last >= insert]} { $w tag remove sel sel.first promptEnd $w delete sel.first sel.last } } if {[$w compare insert < promptEnd]} { $w mark set insert end } $w insert insert $s {input stdin} $w see insert}# tkConsoleOutput --## This routine is called directly by ConsolePutsCmd to cause a string# to be displayed in the console.## Arguments:# dest - The output tag to be used: either "stderr" or "stdout".# string - The string to be displayed.proc tkConsoleOutput {dest string} { .console insert output $string $dest .console see insert}# tkConsoleExit --## This routine is called by ConsoleEventProc when the main window of# the application is destroyed. Don't call exit - that probably already# happened. Just delete our window.## Arguments:# None.proc tkConsoleExit {} { destroy .}# tkConsoleAbout --## This routine displays an About box to show Tcl/Tk version info.## Arguments:# None.proc tkConsoleAbout {} { global tk_patchLevel tk_messageBox -type ok -message "Tcl for WindowsCopyright \251 1996 Sun Microsystems, Inc.Tcl [info patchlevel]Tk $tk_patchLevel"}# now initialize the consoletkConsoleInit
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -