Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Make sure Dir Diff can pick one out of many plugins. Dir Diff no longer shortcuts for files with same size&mtime. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
689940e052576b5df67b1528441bcd89 |
User & Date: | peter 2017-12-16 01:11:38.969 |
Context
2017-12-22
| ||
00:22 | Added -excludedir and -excludefile options for dir diff. check-in: e37b52eb4e user: peter tags: trunk | |
2017-12-16
| ||
01:11 | Make sure Dir Diff can pick one out of many plugins. Dir Diff no longer shortcuts for files with same size&mtime. check-in: 689940e052 user: peter tags: trunk | |
01:00 | Make sure plugins are applied in the right order. check-in: 4ed588b9ab user: peter tags: trunk | |
Changes
Changes to Changes.
1 2 3 4 5 6 7 | 2017-12-07 Support -nocase in dirdiff. Repaired plugins for dirdiff (broken by multi plugin). 2017-12-07 Handle GIT revisions better for directory diff. | > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 2017-12-16 Make sure plugins are applied in the right order. Make sure Dir Diff can pick one out of many plugins. Dir Diff no longer shortcuts for files with same size&mtime. 2017-12-13 Use same font in commit window as in diff window. Upgraded tablelist to 6.0 2017-12-07 Support -nocase in dirdiff. Repaired plugins for dirdiff (broken by multi plugin). 2017-12-07 Handle GIT revisions better for directory diff. |
︙ | ︙ |
Changes to doc/plugins.txt.
︙ | ︙ | |||
38 39 40 41 42 43 44 | If the plugin procedure returns 1, the processed data is used also for displaying. When searching for a plugin "x", files "x" and "x.tcl" will match. The search path is current directory, "plugins" directory, the directory where Eskil is installed, "plugins" directory where Eskil is installed, and also the internal "plugins" wrapped into Eskil. | > > > | 38 39 40 41 42 43 44 45 46 47 | If the plugin procedure returns 1, the processed data is used also for displaying. When searching for a plugin "x", files "x" and "x.tcl" will match. The search path is current directory, "plugins" directory, the directory where Eskil is installed, "plugins" directory where Eskil is installed, and also the internal "plugins" wrapped into Eskil. Directory Diff only supports one plugin. The first plugin with FileCompare defined will be used. |
Changes to htdocs/plugins.wiki.
︙ | ︙ | |||
22 23 24 25 26 27 28 29 30 31 32 33 34 35 | * -plugindump plugin : Dump plugin source to stdout * -pluginlist : List known plugins * -pluginallow : Allow full access privilege for a plugin. A plugin may further define command line options that it accepts. A way to see the plugin's options is to do: <pre>eskil -plugin <plg> -help</pre> <h1>General Format</h1> A plugin is a Tcl script file that must start with the verbatim sequence "##Eskil Plugin :". A plugin is sourced and used in its own safe interpreter and thus have free access to its own global space. Hookup points are defined by declaring specifically named procedures as specified | > > > > | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | * -plugindump plugin : Dump plugin source to stdout * -pluginlist : List known plugins * -pluginallow : Allow full access privilege for a plugin. A plugin may further define command line options that it accepts. A way to see the plugin's options is to do: <pre>eskil -plugin <plg> -help</pre> Multiple -plugin may be given and they will be applied in the given order. Any -plugininfo and -pluginallow belongs to the last -plugin before them. <h1>General Format</h1> A plugin is a Tcl script file that must start with the verbatim sequence "##Eskil Plugin :". A plugin is sourced and used in its own safe interpreter and thus have free access to its own global space. Hookup points are defined by declaring specifically named procedures as specified |
︙ | ︙ | |||
106 107 108 109 110 111 112 | The FileCompare procedure can give the following return values: * 0 : Files are not equal * 1 : Files are equal * 2 : Files are equal as far as the channels have been read. Let the normal comparison finish the job. | > > > | 110 111 112 113 114 115 116 117 118 119 | The FileCompare procedure can give the following return values: * 0 : Files are not equal * 1 : Files are equal * 2 : Files are equal as far as the channels have been read. Let the normal comparison finish the job. Directory diff only supports one plugin. The first plugin with FileCompare defined will be used. |
Changes to src/dirdiff.tcl.
︙ | ︙ | |||
34 35 36 37 38 39 40 | # Accept case insensitive equality on windows if {$::tcl_platform(platform) eq "windows"} { if {[string equal -nocase $s1 $s2]} { return 0 } } # FIXA: What's the case on Mac? | | | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | # Accept case insensitive equality on windows if {$::tcl_platform(platform) eq "windows"} { if {[string equal -nocase $s1 $s2]} { return 0 } } # FIXA: What's the case on Mac? if {[lindex [lsort -dictionary [list $s1 $s2]] 0] eq $s1} { return -1 } return 1 } # Sort file names |
︙ | ︙ | |||
60 61 62 63 64 65 66 | return 0 } # Same type? set isdir1 [FileIsDirectory $file1] set isdir2 [FileIsDirectory $file2] if {$isdir1 != $isdir2} { | | | | < < < < | | | > | | | | | | | | | 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | return 0 } # Same type? set isdir1 [FileIsDirectory $file1] set isdir2 [FileIsDirectory $file2] if {$isdir1 != $isdir2} { return 0 } # Handle links if {$stat1(type) eq "link" && $stat2(type) eq "link"} { set l1 [file link $file1] set l2 [file link $file2] # Equal links are considered equal, otherwise check contents if {$l1 eq $l2} { return 1 } file stat $file1 stat1 file stat $file2 stat2 } # If contents is not checked, same size is enough to be equal if {$stat1(size) == $stat2(size) && $::Pref(dir,comparelevel) == 0} { return 1 } set anyPlugin $::eskil(.dirdiff,dirPlugin) set ignorekey $::Pref(dir,ignorekey) set nocase $::Pref(nocase) # Different size is enough when doing binary compare if {$stat1(size) != $stat2(size) && $::Pref(dir,comparelevel) == 2 \ && !$ignorekey && !$anyPlugin} { return 0 } # Don't check further if contents should not be checked if {$::Pref(dir,comparelevel) == 0} { return 0 } # Don't check further if any is a directory if {$isdir1 || $isdir2} { # Consider dirs equal until we implement something recursive return 1 } switch $::Pref(dir,comparelevel) { 2 - 1 { # Check contents internally set bufsz 65536 set eq 2 ;# 2 = equal this far, 1 = equal, 0 = not equal set ch1 [open $file1 r] set ch2 [open $file2 r] if {$::Pref(dir,comparelevel) == 2} { fconfigure $ch1 -translation binary fconfigure $ch2 -translation binary } # Allow a plugin to do its thing if {$anyPlugin} { #puts "PLUGIN!" $::eskil(.dirdiff,plugin,$anyPlugin) eval \ [list array set ::Pref [array get ::Pref]] $::eskil(.dirdiff,plugin,$anyPlugin) eval \ [list set ::argv $::eskil(argv)] interp share {} $ch1 $::eskil(.dirdiff,plugin,$anyPlugin) interp share {} $ch2 $::eskil(.dirdiff,plugin,$anyPlugin) set info1 [dict create name $file1 size $stat1(size)] set info2 [dict create name $file2 size $stat2(size)] set eq [$::eskil(.dirdiff,plugin,$anyPlugin) eval \ [list FileCompare $ch1 $ch2 $info1 $info2]] set allow [dict get $::eskil(.dirdiff,pluginpinfo,$anyPlugin) allow] if {$allow} { $::eskil(.dirdiff,plugin,$anyPlugin) eval close $ch1 $::eskil(.dirdiff,plugin,$anyPlugin) eval close $ch2 } else { $::eskil(.dirdiff,plugin,$anyPlugin) invokehidden close $ch1 $::eskil(.dirdiff,plugin,$anyPlugin) invokehidden close $ch2 } } if {$ignorekey} { # Assume that all keywords are in the first block set f1 [read $ch1 $bufsz] set f2 [read $ch2 $bufsz] |
︙ | ︙ | |||
409 410 411 412 413 414 415 | set right $newRight set rightDir $right } if {!$ScheduledRestart} { set ScheduledRestart 1 after idle [mymethod ReStart] } | | | | > > > > > > > > > > > > | | | 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 | set right $newRight set rightDir $right } if {!$ScheduledRestart} { set ScheduledRestart 1 after idle [mymethod ReStart] } } method nice {ms} { # Sanity check if {$ms < 1} { set ms 1 } if {$ms > 1000} {set ms 1000 } set AfterTime $ms } method ReStart {} { # Delete all idle processing if {$AfterId ne ""} { after cancel $AfterId } set AfterId "" set IdleQueue {} set ScheduledRestart 0 array unset IdleQueueArr set protect {left 0 right 0} # Directory Diff only supports one plugin. # Find if any configured plugin supports dir diff and choose it. set ::eskil(.dirdiff,dirPlugin) 0 foreach item [lsort -dictionary [array names ::eskil .dirdiff,pluginname,*]] { set n [lindex [split $item ","] end] if {$::eskil(.dirdiff,plugin,$n) ne "" && \ [dict get $::eskil(.dirdiff,pluginpinfo,$n) dir]} { set ::eskil(.dirdiff,dirPlugin) $n break } } # Fill in clean root data $tree delete 0 end set topIndex [$tree insertchild root end {}] set d1 [file tail $leftDir] set d2 [file tail $rightDir] if {$d1 eq $d2} { $tree cellconfigure $topIndex,structure -text $d1 } else { $tree cellconfigure $topIndex,structure -text "$d1 vs $d2" } $tree cellconfigure $topIndex,structure -image $::img(open) $tree rowattrib $topIndex type directory $self SetNodeStatus $topIndex empty $tree rowattrib $topIndex leftfull $leftDir $tree rowattrib $topIndex rightfull $rightDir $self UpdateDirNode $topIndex } method expandCmd {tbl row} { if {[$tree childcount $row] != 0} { $tree cellconfigure $row,0 -image $::img(open) |
︙ | ︙ | |||
659 660 661 662 663 664 665 | set rf [$tree rowattrib $node rightfull] set type [$tree rowattrib $node type] set oneside [expr {($lf ne "") ^ ($rf ne "")}] set m $win.popup destroy $m menu $m | | | 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 | set rf [$tree rowattrib $node rightfull] set type [$tree rowattrib $node type] set oneside [expr {($lf ne "") ^ ($rf ne "")}] set m $win.popup destroy $m menu $m if {$colname eq "structure"} { $m add command -label "Prune equal" -command [mymethod PruneEqual] $m add command -label "Expand all" -command [mymethod OpenAll] $m add command -label "Collapse all" -command [mymethod OpenAll 0] } if {$type eq "file" && $lf ne "" && $rf ne ""} { |
︙ | ︙ | |||
965 966 967 968 969 970 971 | ## Make it so that this node is openable $tree collapse $id #$tree insertchild $id end dummy ;# a dummy $tree cellconfigure $id,structure -text $name/ $self SetNodeStatus $id empty $self AddNodeToIdle $id $tree cellconfigure $id,structure -image $::img(clsd) | < < < | 974 975 976 977 978 979 980 981 982 983 984 985 986 987 | ## Make it so that this node is openable $tree collapse $id #$tree insertchild $id end dummy ;# a dummy $tree cellconfigure $id,structure -text $name/ $self SetNodeStatus $id empty $self AddNodeToIdle $id $tree cellconfigure $id,structure -image $::img(clsd) } elseif {$size1 == ""} { $self SetNodeStatus $id new } elseif {$size2 == ""} { $self SetNodeStatus $id old } else { $self SetNodeStatus $id unknown $self AddNodeToIdle $id |
︙ | ︙ | |||
1173 1174 1175 1176 1177 1178 1179 | if {$::tcl_platform(platform) eq "windows"} { if {![catch {package require registry}]} { $win.m.mt add separator $win.m.mt add command -label "Setup Registry" -underline 6 \ -command makeRegistryWin } } | | | | | | 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 | if {$::tcl_platform(platform) eq "windows"} { if {![catch {package require registry}]} { $win.m.mt add separator $win.m.mt add command -label "Setup Registry" -underline 6 \ -command makeRegistryWin } } $win.m add cascade -label "Help" -underline 0 -menu $win.m.help menu $win.m.help $win.m.help add command -label "Tutorial" -command makeTutorialWin \ -underline 0 $win.m.help add command -label "About" -command makeAboutWin -underline 0 if {$::eskil(debug)} { $win.m add cascade -label "Debug" -menu $win.m.md -underline 0 menu $win.m.md if {$::tcl_platform(platform) eq "windows"} { $win.m.md add checkbutton -label "Console" -variable consolestate \ -onvalue show -offvalue hide -command {console $consolestate} $win.m.md add separator } $win.m.md add command -label "Reread Source" -underline 0 \ -command {EskilRereadSource} $win.m.md add separator $win.m.md add command -label "Redraw Window" -command {makeDirDiffWin} } ttk::button $win.bu -image $::img(upup) -command [mymethod UpDir] \ -underline 0 addBalloon $win.bu "Up in both." bind $win <Alt-u> "$win.bu invoke" #catch {font delete myfont} #font create myfont -family $::Pref(fontfamily) -size $::Pref(fontsize) ttk::entryX $win.e1 -textvariable dirdiff(leftDir) -width 30 ttk::button $win.bu1 -image $::img(up) -command [mymethod UpDir 1] addBalloon $win.bu1 "Up in left." ttk::button $win.bb1 -image $::img(browse) \ |
︙ | ︙ | |||
1222 1223 1224 1225 1226 1227 1228 | [mymethod DoDirCompare]" addBalloon $win.bb2 "Browse right." after 50 [list after idle [list $win.e2 xview end]] bind $win.e1 <Return> [mymethod DoDirCompare] bind $win.e2 <Return> [mymethod DoDirCompare] ttk::label $win.sl -anchor w -textvariable [myvar statusVar] | | | | 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 | [mymethod DoDirCompare]" addBalloon $win.bb2 "Browse right." after 50 [list after idle [list $win.e2 xview end]] bind $win.e1 <Return> [mymethod DoDirCompare] bind $win.e2 <Return> [mymethod DoDirCompare] ttk::label $win.sl -anchor w -textvariable [myvar statusVar] pack $win.bb1 $win.bu1 -in $win.fe1 -side left -pady 1 -ipadx 10 pack $win.bu1 -padx 6 pack $win.e1 -in $win.fe1 -side left -fill x -expand 1 pack $win.bb2 $win.bu2 -in $win.fe2 -side right -pady 1 -ipadx 10 pack $win.bu2 -padx 6 pack $win.e2 -in $win.fe2 -side left -fill x -expand 1 grid $win.fe1 $win.bu $win.fe2 -sticky we grid $tree - - -sticky news grid $win.sl - - -sticky we grid $win.bu -padx 6 -ipadx 15 grid rowconfigure $win 1 -weight 1 grid columnconfigure $win {0 2} -weight 1 |
︙ | ︙ | |||
1337 1338 1339 1340 1341 1342 1343 | grid $check.rb2 -sticky w -padx 3 -pady 3 grid $check.rb3 -sticky w -padx 3 -pady 3 grid columnconfigure $check {0 1 2} -uniform a -weight 1 set opts [ttk::labelframe $top.opts -text "Options" -padding 3] ttk::checkbutton $opts.cb1 -variable ::TmpPref(dir,ignorekey) \ -text "Ignore \$Keyword:\$" | | | 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 | grid $check.rb2 -sticky w -padx 3 -pady 3 grid $check.rb3 -sticky w -padx 3 -pady 3 grid columnconfigure $check {0 1 2} -uniform a -weight 1 set opts [ttk::labelframe $top.opts -text "Options" -padding 3] ttk::checkbutton $opts.cb1 -variable ::TmpPref(dir,ignorekey) \ -text "Ignore \$Keyword:\$" pack {*}[winfo children $opts] -side top -anchor w set filter [ttk::labelframe $top.filter -text "Filter" -padding 3] ttk::label $filter.l1 -text "Include Files" -anchor w ttk::entryX $filter.e1 -width 20 -textvariable ::TmpPref(dir,incfiles) ttk::label $filter.l2 -text "Exclude Files" -anchor w ttk::entryX $filter.e2 -width 20 -textvariable ::TmpPref(dir,exfiles) ttk::label $filter.l3 -text "Include Dirs" -anchor w |
︙ | ︙ | |||
1390 1391 1392 1393 1394 1395 1396 | wm title $top "Eskil Dir Preprocess" ttk::entryX $top.e1 -textvariable ::dirdiff(pattern) -width 15 ttk::entryX $top.e2 -textvariable ::dirdiff(replace) -width 15 ttk::label $top.l1 -text "Pattern" -anchor w ttk::label $top.l2 -text "Subst" -anchor w | | | | 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 | wm title $top "Eskil Dir Preprocess" ttk::entryX $top.e1 -textvariable ::dirdiff(pattern) -width 15 ttk::entryX $top.e2 -textvariable ::dirdiff(replace) -width 15 ttk::label $top.l1 -text "Pattern" -anchor w ttk::label $top.l2 -text "Subst" -anchor w grid $top.l1 $top.e1 -sticky we grid $top.l2 $top.e2 -sticky we grid columnconfigure $top 1 -weight 1 grid rowconfigure $top 2 -weight 1 } proc makeDirDiffWin {} { if {![info exists ::dirdiff(leftDir)]} { set ::dirdiff(leftDir) "" } if {![info exists ::dirdiff(rightDir)]} { |
︙ | ︙ |