Добавлен диалог навигации по структуре (процедурам) по Ctrl+F. Исправлена ошибка при закрытии файлов (функции из дерева теперь удаляются).

master
svkalinin 2022-08-24 15:04:19 +03:00
parent 38e188e20b
commit eeb001a92a
9 changed files with 193 additions and 36 deletions

View File

@ -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)

View File

@ -411,8 +411,8 @@ namespace eval Editor {
#bind $txt <Control-adiaeresis> "auto_completition $txt"
#bind $txt <Control-l> "auto_completition $txt"
bind $txt <Control-icircumflex> "auto_completition_proc $txt"
bind $txt <Control-j> "auto_completition_proc $txt"
# bind $txt <Control-icircumflex> ""
# bind $txt <Control-j> ""
bind $txt <Control-i> "ImageBase64Encode $txt"
bind $txt <Control-bracketleft> "Editor::InsertTabular $txt"
@ -436,6 +436,8 @@ namespace eval Editor {
bind $txt <<Selection>> "Editor::SelectionGet $txt"
bind $txt <Control-i> ImageBase64Encode
bind $txt <Control-u> "Editor::SearchBrackets %W"
bind $txt <Control-F> "Editor::GoToFunction $w"
bind $txt <Control-f> "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 <Escape> "bindtags $txt {[list [winfo toplevel $txt] $txt Text sysAfter all]}; catch { destroy .gotofunction; break}"
bind GoToFunctionBind <Key> { 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 <Escape>]
# }
# default {
# $txt insert "insert" $A
# eval [bind GoToFunctionBind <Escape>]
# }
# }
# }
# ------------------------------------------------------------------------
# Диалоговое окно со списком процедур или функций в редактируемом тексте
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 <Escape> " destroy $win; focus $w.frmText.t; break "
bind $win.lBox <Escape> " destroy $win; focus $w.frmText.t; break"
bind $win.lBox <Return> {
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 {

View File

@ -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
}

View File

@ -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 <Double-ButtonPress-1> {Tree::DoublePressItem $tree}
bind $tree <ButtonRelease-1> {Tree::PressItem $tree}
bind $tree <ButtonRelease-1> {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) \

View File

@ -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 "\*"

8
lib/lexers.tcl 100644
View File

@ -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.*?}

View File

@ -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"
}
}
}

View File

@ -10,7 +10,7 @@ exec wish "$0" -- "$@"
######################################################
# Version: 2.0.0
# Release: alpha
# Build: 17082022162534
# Build: 24082022134211
######################################################
# определим текущую версию, релиз и т.д.

View File

@ -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)]