📄 greppane.tcl
字号:
# Copyright (c) 2000, 2001, Red Hat, Inc.# # This file is part of Source-Navigator.# # Source-Navigator is free software; you can redistribute it and/or# modify it under the terms of the GNU General Public License as published# by the Free Software Foundation; either version 2, or (at your option)# any later version.# # Source-Navigator is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU# General Public License for more details.# # You should have received a copy of the GNU General Public License along# with Source-Navigator; see the file COPYING. If not, write to# the Free Software Foundation, 59 Temple Place - Suite 330, Boston,# MA 02111-1307, USA.# ############################################ Grep (Find in Files...)##########################################itcl::class sourcenav::GrepDriver { # Invoked to begin a grep operation public method start { pat files nocase max } # Invoked after a grep has completed normally public method finish {} # Invoked when user cancels the grep public method cancel {} # Return the name of a variable that will be # linked to a GUI scale display public method getScaleValueVariable {} # Tell driver where to insert results public method setTextWidget {} # Return 1 is a valid grep pattern, otherwise # return a string describing why it is not. public method isValidPattern { pat }}itcl::class Grep { inherit sourcenav::MultiChild constructor {args} { global sn_options # Check for grep, fallback to Tcl grep if it is not on the PATH if {![info exists ::env(SN_TCLGREP)] && [sourcenav::ExecGrepDriver::isAvailable]} { set driver [sourcenav::ExecGrepDriver \ $itk_component(hull).grepdriver] } else { set driver [sourcenav::TclGrepDriver \ $itk_component(hull).grepdriver] } # Load formats for pattern once, when the first instance is created if {! [info exists PatternFormats]} { set PatternFormats [list] set fil_file [sn_search_file grep.fil] sn_log "greppane loading pre-defined pattern formats file" if {[file isfile ${fil_file}]} { set fd [open ${fil_file}] fconfigure ${fd} -encoding $sn_options(def,system-encoding) -blocking 0 foreach l [split [read -nonewline ${fd}] "\n"] { set split_l [split ${l} \"] lappend PatternFormats [list \ [lindex $split_l 1] \ [lindex $split_l 3]] } close ${fd} } # Make entries for the combo box set PatternFormatsCombo [list] foreach l ${PatternFormats} { lappend PatternFormatsCombo [lindex ${l} 0] } } # Process arguements eval itk_initialize $args # Add menu entries if {$itk_option(-menu) != ""} { } # Add toolbar icons if {$itk_option(-toolbar) != ""} { # Toolbar grep frame itk_component add greptoolbar { frame $itk_option(-toolbar).grepframe } # Previous button itk_component add prev { button $itk_component(greptoolbar).prev \ -takefocus 0 \ -image del_image \ -command [itcl::code ${this} next_entry -1] \ -text [get_indep String Prev] } balloon_bind_info $itk_component(prev) [get_indep String PrevINFO] # Next button itk_component add next { button $itk_component(greptoolbar).next \ -takefocus 0 \ -image add_image \ -command [itcl::code ${this} next_entry +1] \ -text [get_indep String Next] } balloon_bind_info $itk_component(next) [get_indep String NextINFO] } # Frame for input itk_component add input { frame $itk_component(hull).input } # The label width needs to depend on the longest string that will # be displayed in the label and we need to set it at creation time. set longest_label 8 foreach str [list [get_indep String MultiGrepPattern] \ [get_indep String UtilFiles] \ [get_indep String MultiGrepFormat]] { set len [string length $str] if {$len > $longest_label} { set longest_label $len } } # Entries for pattern, file pattern, filter, and checkbuttons # Pattern itk_component add pattern { Combo& $itk_component(input).pattern \ -labelwidth $longest_label \ -anchor ne \ -entryvariable [itcl::scope pattern] \ -exportselection n \ -selectcommand \ [itcl::code ${this} history_combo_select_command] \ -label [get_indep String MultiGrepPattern] \ -underline [get_indep Pos MultiGrepPattern] } {} # File Pattern itk_component add filepattern { Combo& $itk_component(input).filepattern \ -labelwidth $longest_label \ -anchor ne \ -entryvariable [itcl::scope filepattern] \ -exportselection n \ -label [get_indep String UtilFiles] \ -underline [get_indep Pos UtilFiles] } {} # Filter itk_component add filtercombo { Combo& $itk_component(input).filtercombo \ -labelwidth $longest_label \ -anchor ne \ -entryvariable [itcl::scope GrepPatFilter] \ -contents ${PatternFormatsCombo} \ -selectcommand \ [itcl::code ${this} disp_filter $itk_component(input).filtercombo] \ -width 0 \ -label [get_indep String MultiGrepFormat] \ -underline [get_indep Pos MultiGrepFormat] } {} # Search button itk_component add buttons { frame $itk_component(input).buttonsframe } itk_component add search { button $itk_component(buttons).search \ -command [itcl::code ${this} StartGrep] \ -text [get_indep String UtilSearch] \ -underline [get_indep Pos UtilSearch] } balloon_bind_info $itk_component(search) [get_indep String GrepSearchINFO] # Cancel Button itk_component add cancel { button $itk_component(buttons).cancel \ -text [get_indep String Cancel] \ -underline [get_indep Pos Cancel] \ -command [itcl::code ${this} cancel_grep] \ -state disabled } balloon_bind_info $itk_component(cancel) [get_indep String GrepCancelINFO]# FIXME : This feature is not documented # Format button: Take the string that the user entered and format # it with the format pattern from the combobox itk_component add format { button $itk_component(buttons).format \ -text [get_indep String Format] \ -underline [get_indep Pos Format] \ -command "$this FormatPattern" } balloon_bind_info $itk_component(format) [get_indep String GrepFormatINFO] # Flags itk_component add case { checkbutton $itk_component(input).case \ -onvalue 1 \ -offvalue 0 \ -variable [itcl::scope GrepNocase] \ -text [get_indep String IgnoreCase] \ -underline [get_indep Pos IgnoreCase] } # Search limit itk_component add limit { Entry& $itk_component(input).limit \ -labelwidth 10 \ -width 4 \ -anchor ne \ -exportselection n \ -textvariable [itcl::scope maxmatches] \ -label [get_indep String MultiGrepMaxMatches] \ -filter natural } {} itk_component add lines-label { label $itk_component(input).lines \ -text [get_indep String MultiGrepLines] } # Slider for grep status/progress. itk_component add progressbar { ProgressBar $itk_option(-mesg_area).grep_status \ -variable [$driver getScaleValueVariable] } { } balloon_bind_info $itk_component(progressbar) \ [get_indep String GrepProcessing] # Grep Results itk_component add resultsframe { frame $itk_component(hull).resultsframe } itk_component add results { text $itk_component(resultsframe).results \ -wrap none \ -exportselection 0 } {} $driver setTextWidget $itk_component(results) itk_component add hscroll { scrollbar $itk_component(resultsframe).hscroll \ -orient horizontal \ -command "$itk_component(results) xview" } itk_component add vscroll { scrollbar $itk_component(resultsframe).vscroll \ -orient vertical \ -command "$itk_component(results) yview" } $itk_component(results) configure \ -xscrollcommand "$itk_component(hscroll) set" \ -yscrollcommand "$itk_component(vscroll) set" # Layout Management if {[info exists itk_component(greptoolbar)]} { pack $itk_component(greptoolbar) -side left pack $itk_component(prev) -side left -fill x -expand n pack $itk_component(next) -side left -fill x -expand n } grid $itk_component(pattern) -row 0 -column 0 -sticky ew -columnspan 5 grid $itk_component(filepattern) -row 1 -column 0 -sticky ew -columnspan 5 grid $itk_component(filtercombo) -row 2 -column 0 -sticky ew -columnspan 5 grid $itk_component(case) -row 3 -column 1 grid $itk_component(limit) -row 3 -column 2 grid $itk_component(lines-label) -row 3 -column 3 grid columnconfigure $itk_component(input) 1 -pad 50 grid columnconfigure $itk_component(input) 4 -weight 1 # FIXME: This is a rather nasty hack, but at least it is better # than the last hack with the empty label! update grid columnconfigure $itk_component(input) 0 \ -minsize [winfo width $itk_component(pattern).label] grid rowconfigure $itk_component(input) 0 -weight 1 grid rowconfigure $itk_component(input) 1 -weight 1 grid rowconfigure $itk_component(input) 2 -weight 1 grid rowconfigure $itk_component(input) 3 -weight 1 # Frame for the 3 command buttons grid $itk_component(buttons) -row 0 -column 5 -sticky ns -rowspan 4 pack $itk_component(search) -side top -padx 8 -pady 4 -fill x pack $itk_component(cancel) -side top -padx 8 -pady 4 -fill x pack $itk_component(format) -side top -padx 8 -pady 4 -fill x # Frame for the grep text and its scrollbars grid $itk_component(results) -row 0 -column 0 -sticky news grid $itk_component(hscroll) -row 1 -column 0 -sticky ew grid $itk_component(vscroll) -row 0 -column 1 -sticky ns# FIXME: scrollbars should always be minsized to the width or height of the scroll!# of course it would be better to just use an autoscroll widget! grid rowconfigure $itk_component(resultsframe) 0 -weight 1 grid columnconfigure $itk_component(resultsframe) 0 -weight 1 # Main frame for top section of the grep window. grid $itk_component(resultsframe) -row 1 -column 0 -sticky news grid $itk_component(input) -row 0 -column 0 -sticky ew -padx 5 grid rowconfigure $itk_component(hull) 1 -weight 1 grid columnconfigure $itk_component(hull) 0 -weight 1 # Bindings and other initializations [$itk_component(pattern) component entry] select to end # <Return> should start grepping independent of the widget in focus # Reorder bindings to deliver event to the hull first bind $itk_component(hull) <Return> [itcl::code ${this} StartGrep] foreach widget [list \ [$itk_component(limit) component entry] \ [$itk_component(pattern) component entry] \ [$itk_component(filepattern) component entry] \ [$itk_component(filtercombo) component entry]] { bindtags $widget [concat $itk_component(hull) [bindtags $widget]] } $itk_component(results) tag config sel -background $sn_options(def,select-bg) Editor&::set_tab $itk_component(results) 2 # Lock down bindings for this widget so we only use ours bindtags $itk_component(results) $itk_component(results) bind $itk_component(results) <ButtonPress-1> [itcl::code $this text_b1_down %W %x %y] bind $itk_component(results) <Double-1> [itcl::code $this text_b1_double %W %x %y] # Add history to the combo boxes refresh_combo_history Update_Layout# FIXME : are we breaking an external API by sending a text widget here? #call user defined function catch {sn_rc_grep $itk_component(hull) $itk_component(results)} err sn_log "trying to execute sn_rc_grep:${err}"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -