diff --git a/CHANGELOG b/CHANGELOG index b2c7ed8..35489e6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -73,3 +73,12 @@ - Added config options filesPanelPlace (left/right) - Fixed ViewFilesTree procedure with rigth variable filesPanelShow (true/false) +22/08/2022 + - Fixed clicking on proc or func names into tree if file was closed + +23/08/2022 + - Added procedure and function navigation window by Ctrl+j pressed on editor + - Fixed correctly focused on editor text widget + +24/08/2022 + - Fixed ReadStructure procedure (added lexer) diff --git a/lib/editor.tcl b/lib/editor.tcl index f04e4b0..bdfa122 100644 --- a/lib/editor.tcl +++ b/lib/editor.tcl @@ -411,8 +411,8 @@ namespace eval Editor { #bind $txt "auto_completition $txt" #bind $txt "auto_completition $txt" - bind $txt "auto_completition_proc $txt" - bind $txt "auto_completition_proc $txt" + # bind $txt "" + # bind $txt "" bind $txt "ImageBase64Encode $txt" bind $txt "Editor::InsertTabular $txt" @@ -436,6 +436,8 @@ namespace eval Editor { bind $txt <> "Editor::SelectionGet $txt" bind $txt ImageBase64Encode bind $txt "Editor::SearchBrackets %W" + bind $txt "Editor::GoToFunction $w" + bind $txt "Editor::GoToFunction $w" } proc SearchBrackets {txt} { @@ -509,16 +511,21 @@ namespace eval Editor { } proc ReadStructure {txt treeItemName} { - global tree nbEditor + global tree nbEditor editors lexers + set fileType [dict get $editors $txt fileType] + set l "" + if {[dict exists $lexers $fileType] == 0} {return} for {set lineNumber 0} {$lineNumber <= [$txt count -lines 0.0 end]} {incr lineNumber} { set line [$txt get $lineNumber.0 $lineNumber.end] # TCL procedure - if {[regexp -nocase -all -- {^\s*?(proc) (::|_|)(\w+)(::|:|_|)(\w+)\s*?(\{|\()(.*)(\}|\)) \{} $line match v1 v2 v3 v4 v5 v6 params v8]} { + # puts "[dict get $lexers $fileType procRegexpCommand]" + if {[eval [dict get $lexers $fileType procRegexpCommand]]} { set procName "$v2$v3$v4$v5" # lappend procList($activeProject) [list $procName [string trim $params]] # puts "$treeItemName proc $procName $params" # tree parent item type text puts [Tree::InsertItem $tree $treeItemName $procName "procedure" "$procName ($params)"] + lappend l [list $procName $params] } # GO function if {[regexp -nocase -all -- {^\s*?func\s*?\((\w+\s*?\*\w+)\)\s*?(\w+)\((.*?)\)\s*?([a-zA-Z0-9\{\}\[\]\(\)-_.]*?|)\s*?\{} $line match v1 funcName params returns]} { @@ -531,17 +538,20 @@ namespace eval Editor { # puts "$treeItemName func $funcName $params" # tree parent item type text puts [Tree::InsertItem $tree $treeItemName $funcName "func" "$functionName ($params)"] + lappend l [list $functionName $params] } if {[regexp -nocase -all -- {^\s*?func\s*?(\w+)\((.*?)\)\s+?([a-zA-Z0-9\{\}\[\]\(\)-_.]*?|)\s*?\{} $line match funcName params returns]} { # puts "$treeItemName func $funcName $params" # tree parent item type text puts [Tree::InsertItem $tree $treeItemName $funcName "func" "$funcName ($params)"] + lappend l [list $funcName $params] } - } + dict set editors $txt procedureList $l + } - proc FindFunction {findString} { +proc FindFunction {findString} { global nbEditor puts $findString set pos "0.0" @@ -562,7 +572,7 @@ namespace eval Editor { $txt tag add sel $pos $line.end # #$text tag configure sel -background $editor(selectbg) -foreground $editor(fg) $txt tag raise sel - focus -force $txt + focus -force $txt.t # Position return 1 } @@ -604,17 +614,126 @@ namespace eval Editor { # tk_messageBox -title $pattern -message "char: $char; $pos; o_count=$o_count; c_count=$c_count" if {[string equal $char $o_bracket]} {incr o_count ; set found 1} if {[string equal $char $c_bracket]} {incr c_count ; set found 1} - if {($found == 1) && ($o_count == $c_count) } { return [$widget index "$pos + 1 chars"] } + if {($found == 1) && ($o_count == $c_count) } { return [$widget index "$pos + 1 chars"]} set found 0 set start_pos "$pos - 0 chars" set pos [$widget search -backward -regexp -- $pattern $start_pos $end_pos] } ;# while search return -1 - } ;# proc _searchOpenBracket - + } + # ---------------------------------------------------------------------- + # Вызов диалога со списком процедур или функций присутствующих в тексте + + proc GoToFunction { w } { + global tree editors + set txt $w.frmText.t + # set start_word [$txt get "insert - 1 chars wordstart" insert] + set box [$txt bbox insert] + set box_x [expr [lindex $box 0] + [winfo rootx $txt] ] + set box_y [expr [lindex $box 1] + [winfo rooty $txt] + [lindex $box 3] ] + set l "" + bindtags $txt [list GoToFunctionBind [winfo toplevel $txt] $txt Text sysAfter all] + bind GoToFunctionBind "bindtags $txt {[list [winfo toplevel $txt] $txt Text sysAfter all]}; catch { destroy .gotofunction; break}" + bind GoToFunctionBind { Editor::GoToFunctionKey %W %K %A ; break} + # puts [array names editors] + + foreach item [dict get $editors $txt procedureList] { + # puts $item + lappend l [lindex $item 0] + } + if {$l ne ""} { + eval GotoFunctionDialog $w $box_x $box_y [lsort $l] + focus .gotofunction.lBox + } + } + + # proc GoToFunctionKey { txt K A } { + # set win .gotofunction + # set ind [$win.lBox curselection] + # puts "$txt $K $A" + # switch -- $K { + # Prior { + # set up [expr [$win.lBox index active] - [$win.lBox cget -height]] + # if { $up < 0 } { set up 0 } + # $win.lBox activate $up + # $win.lBox selection clear 0 end + # $win.lBox selection set $up $up + # } + # Next { + # set down [expr [$win.lBox index active] + [$win.lBox cget -height]] + # if { $down >= [$win.lBox index end] } { set down end } + # $win.lBox activate $down + # $win.lBox selection clear 0 end + # $win.lBox selection set $down $down + # } + # Up { + # set up [expr [$win.lBox index active] - 1] + # if { $up < 0 } { set up 0 } + # $win.lBox activate $up + # $win.lBox selection clear 0 end + # $win.lBox selection set $up $up + # } + # Down { + # set down [expr [$win.lBox index active] + 1] + # if { $down >= [$win.lBox index end] } { set down end } + # $win.lBox activate $down + # $win.lBox selection clear 0 end + # $win.lBox selection set $down $down + # } + # Return { + # Editor::FindFunction "proc $values" + # eval [bind GoToFunctionBind ] + # } + # default { + # $txt insert "insert" $A + # eval [bind GoToFunctionBind ] + # } + # } + # } + + # ------------------------------------------------------------------------ + # Диалоговое окно со списком процедур или функций в редактируемом тексте + proc GotoFunctionDialog {w x y args} { + global editors lexers + variable txt + set txt $w.frmText.t + set win .gotofunction + + if { [winfo exists $win] } { destroy $win } + toplevel $win + wm transient $win . + wm overrideredirect $win 1 + + listbox $win.lBox -width 30 -border 2 -yscrollcommand "$win.yscroll set" -border 1 + scrollbar $win.yscroll -orient vertical -command "$win.lBox yview" -width 13 -border 1 + pack $win.lBox -expand true -fill y -side left + pack $win.yscroll -side left -expand false -fill y + + foreach { word } $args { + $win.lBox insert end $word + } + + catch { $win.lBox activate 0 ; $win.lBox selection set 0 0 } + + if { [set height [llength $args]] > 10 } { set height 10 } + $win.lBox configure -height $height + + bind $win " destroy $win; focus $w.frmText.t; break " + bind $win.lBox " destroy $win; focus $w.frmText.t; break" + bind $win.lBox { + Editor::FindFunction "[dict get $lexers [dict get $editors $Editor::txt fileType] procFindString][.gotofunction.lBox get [.gotofunction.lBox curselection]]" + destroy .gotofunction + $Editor::txt tag remove sel 1.0 end + # focus $Editor::txt.t + break + } + + wm geom $win +$x+$y + } + proc Editor {fileFullPath nb itemName} { - global cfgVariables + global cfgVariables editors set fr $itemName if ![string match "*untitled*" $itemName] { set lblText $fileFullPath @@ -632,7 +751,8 @@ namespace eval Editor { pack $frmText -side top -expand true -fill both pack [ttk::scrollbar $frmText.s -command "$frmText.t yview"] -side right -fill y - ctext $txt -yscrollcommand "$frmText.s set" -font $cfgVariables(font) -linemapfg $cfgVariables(lineNumberFG) \ + ctext $txt -yscrollcommand "$frmText.s set" -font $cfgVariables(font) \ + -linemapfg $cfgVariables(lineNumberFG) -linemapbg $cfgVariables(lineNumberBG) \ -tabs "[expr {4 * [font measure $cfgVariables(font) 0]}] left" -tabstyle tabular -undo true \ -relief flat @@ -646,9 +766,16 @@ namespace eval Editor { set fileType [string toupper [string trimleft [file extension $fileFullPath] "."]] if {$fileType eq ""} {set fileType "Unknown"} - + # puts ">$fileType<" # puts [info procs Highlight::GO] + dict set editors $txt fileType $fileType + dict set editors $txt procedureList [list] + + # puts ">>[dict get $editors $txt fileType]" + # puts ">>[dict get $editors $txt procedureList]" + # puts ">>>>> $editors" + if {[info procs ::Highlight::$fileType] ne ""} { Highlight::$fileType $txt } else { diff --git a/lib/files.tcl b/lib/files.tcl index 12e5545..99d0c89 100644 --- a/lib/files.tcl +++ b/lib/files.tcl @@ -62,7 +62,8 @@ namespace eval FileOper { proc Close {} { global nbEditor modified tree set nbItem [$nbEditor select] - puts "close tab $nbItem" + puts "close tab $nbItem" + if {$nbItem == ""} {return} if {$modified($nbItem) eq "true"} { set answer [tk_messageBox -message [::msgcat::mc "File was modifyed"] \ @@ -78,6 +79,13 @@ namespace eval FileOper { destroy $nbItem set treeItem "file::[string range $nbItem [expr [string last "." $nbItem] +1] end ]" if [$tree exists $treeItem] { + # delete all functions from tree item + set children [$tree children $treeItem] + if {$children ne ""} { + foreach i $children { + $tree delete $i + } + } if {[$tree parent $treeItem] eq ""} { $tree delete $treeItem } @@ -176,7 +184,7 @@ namespace eval FileOper { set txt $itemName.frmText.t if ![string match "*untitled*" $itemName] { set file [open "$fileFullPath" r] - $txt insert end [chan read -nonewline $file] + $txt insert end [chan read -nonewline $file] close $file } # Delete emty last line @@ -184,6 +192,7 @@ namespace eval FileOper { $txt delete {end-1 line} end puts ">[$txt get {end-1 line} end]<" } + $txt see 1.0 } proc Edit {fileFullPath} { @@ -199,10 +208,12 @@ namespace eval FileOper { ReadFile $fileFullPath $itemName $itemName.frmText.t highlight 1.0 end ResetModifiedFlag $itemName + $itemName.frmText.t see 1.1 } $nbEditor select $itemName Editor::ReadStructure $itemName.frmText.t $treeItemName - focus -force $itemName.frmText.t + + focus -force $itemName.frmText.t.t return $itemName } diff --git a/lib/gui.tcl b/lib/gui.tcl index 3be4f53..323198c 100644 --- a/lib/gui.tcl +++ b/lib/gui.tcl @@ -68,7 +68,7 @@ if [info exists cfgVariables(theme)] { ttk::frame .frmMenu -border 0 -relief raised ttk::frame .frmBody -border 1 -relief raised -ttk::frame .frmStatus -border 0 -relief sunken +ttk::frame .frmStatus -border 0 -relief raised pack .frmMenu -side top -padx 1 -fill x pack .frmBody -side top -padx 1 -fill both -expand true pack .frmStatus -side top -padx 1 -fill x @@ -113,14 +113,16 @@ set frmTree [ttk::frame .frmBody.frmTree] set tree [ttk::treeview $frmTree.tree -show tree \ -xscrollcommand [list .frmBody.frmTree.h set] -yscrollcommand [list .frmBody.frmTree.v set]] - +# $tree heading #0 -text "Files tree" +# $tree column #0 -anchor e + ttk::scrollbar $frmTree.h -orient horizontal -command [list $frmTree.tree xview] ttk::scrollbar $frmTree.v -orient vertical -command [list $frmTree.tree yview] bind $tree {Tree::DoublePressItem $tree} -bind $tree {Tree::PressItem $tree} +bind $tree {Tree::PressItem $tree; break} grid $tree -row 0 -column 0 -sticky nsew grid $frmTree.v -row 0 -column 1 -sticky nsew @@ -175,7 +177,7 @@ if {$cfgVariables(filesPanelShow) eq "true"} { } } else { .frmBody.panel add $frmWork -weight 1 -} +} ttk::style configure . \ -foreground $::cfgVariables(guiFG) \ diff --git a/lib/highlight.tcl b/lib/highlight.tcl index 49115bc..abb1a4e 100644 --- a/lib/highlight.tcl +++ b/lib/highlight.tcl @@ -44,7 +44,7 @@ namespace eval Highlight {} { proc GO {txt} { ctext::addHighlightClassForRegexp $txt flags orange {-+[a-zA-Z\-_]+} - ctext::addHighlightClass $txt stackControl #19a2a6 {if else for while case switch func import return interface map make} + ctext::addHighlightClass $txt stackControl #19a2a6 {if else for while case switch func import return interface map make break chan fallthrough defer continue go select package} ctext::addHighlightClass $txt types #7187d5 {string int int16 int32 int64 float bool byte} ctext::addHighlightClassWithOnlyCharStart $txt vars #4471ca "\&" ctext::addHighlightClassWithOnlyCharStart $txt vars #4471ca "\*" diff --git a/lib/lexers.tcl b/lib/lexers.tcl new file mode 100644 index 0000000..d45e0dc --- /dev/null +++ b/lib/lexers.tcl @@ -0,0 +1,8 @@ +#--------------------------------------------------- +# TCL/TK +dict set lexers TCL procFindString {proc } +dict set lexers TCL procRegexpCommand {regexp -nocase -all -- {^\s*?(proc) (::|_|)(\w+)(::|:|_|)(\w+)\s*?(\{|\()(.*)(\}|\)) \{} $line match v1 v2 v3 v4 v5 v6 params v8} + +#-------------------------------------------------- +# Go lang +dict set lexers GO procFindString {func.*?} diff --git a/lib/tree.tcl b/lib/tree.tcl index 83ff326..9a3eb59 100644 --- a/lib/tree.tcl +++ b/lib/tree.tcl @@ -74,7 +74,7 @@ namespace eval Tree { } proc PressItem {tree} { - global nbEditor + global nbEditor lexers editors set id [$tree selection] $tree tag remove selected $tree item $id -tags selected @@ -92,16 +92,13 @@ namespace eval Tree { file { FileOper::Edit $values } - func { + default { set parentItem [$tree parent $id] - puts $values - $nbEditor select $nbEditor.[string range $parentItem [expr [string last "::" $parentItem] + 2] end] - Editor::FindFunction "func.*?$values" - } - procedure { - set parentItem [$tree parent $id] - $nbEditor select $nbEditor.[string range $parentItem [expr [string last "::" $parentItem] + 2] end] - Editor::FindFunction "proc $values" + # puts $values + set nbItem "$nbEditor.[string range $parentItem [expr [string last "::" $parentItem] + 2] end]" + $nbEditor select $nbItem + set txt $nbItem.frmText.t + Editor::FindFunction "[dict get $lexers [dict get $editors $txt fileType] procFindString]$values" } } } diff --git a/projman.tcl b/projman.tcl index b33ec0f..f9a1ccb 100755 --- a/projman.tcl +++ b/projman.tcl @@ -10,7 +10,7 @@ exec wish "$0" -- "$@" ###################################################### # Version: 2.0.0 # Release: alpha -# Build: 17082022162534 +# Build: 24082022134211 ###################################################### # определим текущую версию, релиз и т.д. diff --git a/theme/ttk_theme_dark.tcl b/theme/ttk_theme_dark.tcl index 20b79a1..03aae2c 100644 --- a/theme/ttk_theme_dark.tcl +++ b/theme/ttk_theme_dark.tcl @@ -29,6 +29,9 @@ namespace eval ttk::theme::dark { -selectbg "#4a6984" -selectfg "#ffffff" -foreground "#cecbc9" + -linemapbg "#121212" + -linemapfg "#2c2c2c" + -treebg "#2c2c2c" } ttk::style theme create dark -parent clam -settings { @@ -90,16 +93,16 @@ namespace eval ttk::theme::dark { -foreground [list disabled $colors(-disabledfg)] ttk::style configure Treeview \ - -background $colors(-lightframe) -itembackground {gray60 gray50} \ + -background $colors(-treebg) -itembackground {gray60 gray50} \ -itemfill #ffffff -itemaccentfill yellow \ - -fieldbackground $colors(-lightframe) + -fieldbackground $colors(-treebg) # -indicatormargins 0 \ # -indicatorsize -1 \ # -padding 0 ttk::style configure Text \ - -linemapbg [list active $colors(-lightframe)]\ - -linemapbg [list active $colors(-disabledfg)]\ + -linemapbg [list active $colors(-linemapbg)]\ + -linemapfg [list active $colors(-linemapfg)]\ -background [list active $colors(-lighter)] \ -foreground [list disabled $colors(-disabledfg)]