Eskil

Check-in [9b0b8b820c]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Include a file selector when committing multiple files.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 9b0b8b820ca6f2768c03b59243ffb336223ed483c48970429f3bc38f2c696259
User & Date: peter 2019-02-04 15:55:53.773
Context
2019-02-04
15:56
Document default print settings. check-in: c07ac8613c user: peter tags: trunk
15:55
Include a file selector when committing multiple files. check-in: 9b0b8b820c user: peter tags: trunk
15:52
Handle a dir name with -review. check-in: 8ecbca03a0 user: peter tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to Changes.




1
2
3
4
5
6
7
8
9




2018-10-03
Handle deleted files in GIT vcsvfs

2018-09-23
 Upgraded tablelist to 6.3

2018-06-20
 Added save-reload option in edit mode.
 Upgraded tablelist to 6.2
>
>
>
>

|







1
2
3
4
5
6
7
8
9
10
11
12
13
2019-02-04
 Include a file selector when committing multiple files.
 Allow directory with -review.

2018-10-03
 Handle deleted files in GIT vcsvfs

2018-09-23
 Upgraded tablelist to 6.3

2018-06-20
 Added save-reload option in edit mode.
 Upgraded tablelist to 6.2
Changes to src/dirdiff.tcl.
45
46
47
48
49
50
51

























52
53
54
55
56
57
58
    return 1
}

# Sort file names
proc Fsort {l} {
    lsort -dictionary $l
}


























# Compare two files or dirs
# Return true if equal
proc CompareFiles {file1 file2} {
    if {[catch {file lstat $file1 stat1}]} {
        return 0
    }







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
    return 1
}

# Sort file names
proc Fsort {l} {
    lsort -dictionary $l
}

set ::profList [list CompareFiles eskil::rev::SVN::mount]
proc InitProf {} {
    foreach n $::profList {
        trace add execution $n {enter} [list DoProfEnter $n]
        trace add execution $n {leave} [list DoProfLeave $n]
    }
    set ::prof(start) [clock milliseconds]
}
proc DoProfEnter {point args} {
    set ::prof($point,enter) [clock milliseconds]
}
proc DoProfLeave {point args} {
    set dur [expr { [clock milliseconds] - $::prof($point,enter)}]
    incr ::prof($point,dur) $dur
}
proc EndProf {} {
    set ::prof(end) [clock milliseconds]
    set ::prof(dur) [expr {$::prof(end) - $::prof(start)}]
    foreach n $::profList {
        trace remove execution $n {enter} [list DoProfEnter $n]
        trace remove execution $n {leave} [list DoProfLeave $n]
    }
    parray ::prof
}

# Compare two files or dirs
# Return true if equal
proc CompareFiles {file1 file2} {
    if {[catch {file lstat $file1 stat1}]} {
        return 0
    }
101
102
103
104
105
106
107

108


109

110
111
112
113
114
115
116
    }

    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!"







>

>
>

>







126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
    }

    switch $::Pref(dir,comparelevel) {
        2 -
        1 { # Check contents internally
            set bufsz 65536
            set eq 2 ;# 2 = equal this far, 1 = equal, 0 = not equal
            DoProfEnter OpenFile1
            set ch1 [open $file1 r]
            DoProfLeave OpenFile1
            DoProfEnter OpenFile2
            set ch2 [open $file2 r]
            DoProfLeave OpenFile2
            if {$::Pref(dir,comparelevel) == 2} {
                fconfigure $ch1 -translation binary
                fconfigure $ch2 -translation binary
            }
            # Allow a plugin to do its thing
            if {$anyPlugin} {
                #puts "PLUGIN!"
154
155
156
157
158
159
160

161
162

163
164
165
166
167
168
169
170
171
172
173
174
175
176

177
178

179
180
181
182
183
184
185
                } else {
                    if {![string equal $f1 $f2]} {
                        set eq 0
                    }
                }
            }
            while {$eq == 2 && ![eof $ch1] && ![eof $ch2]} {

                set f1 [read $ch1 $bufsz]
                set f2 [read $ch2 $bufsz]

                if {$nocase} {
                    if {![string equal -nocase $f1 $f2]} {
                        set eq 0
                    }
                } else {
                    if {![string equal $f1 $f2]} {
                        set eq 0
                    }
                }
            }
            if {$eq == 2 && (![eof $ch1] || ![eof $ch2])} {
                set eq 0
            }
            # Errors during close are not interesting

            catch {close $ch1}
            catch {close $ch2}

        }
    }
    return [expr {$eq != 0}]
}

# Returns the contents of a directory as a sorted list of full file paths.
proc DirContents {dir} {







>


>














>


>







183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
                } else {
                    if {![string equal $f1 $f2]} {
                        set eq 0
                    }
                }
            }
            while {$eq == 2 && ![eof $ch1] && ![eof $ch2]} {
                DoProfEnter ReadIt
                set f1 [read $ch1 $bufsz]
                set f2 [read $ch2 $bufsz]
                DoProfLeave ReadIt
                if {$nocase} {
                    if {![string equal -nocase $f1 $f2]} {
                        set eq 0
                    }
                } else {
                    if {![string equal $f1 $f2]} {
                        set eq 0
                    }
                }
            }
            if {$eq == 2 && (![eof $ch1] || ![eof $ch2])} {
                set eq 0
            }
            # Errors during close are not interesting
            DoProfEnter Close
            catch {close $ch1}
            catch {close $ch2}
            DoProfLeave Close
        }
    }
    return [expr {$eq != 0}]
}

# Returns the contents of a directory as a sorted list of full file paths.
proc DirContents {dir} {
434
435
436
437
438
439
440

441
442
443
444
445
446
447
            set DebugCh ""
            set DebugTime {}
        }
        # Uncomment to activate debug logging
        #set DebugCh [open ~/dirdiff.log a]
        #$self DlogTablelist
        $self Dlog RESTART

        set AfterId ""
        set IdleQueue {}
        set ScheduledRestart 0
        array unset IdleQueueArr
        set protect {left 0 right 0}

        # Directory Diff only supports one plugin.







>







467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
            set DebugCh ""
            set DebugTime {}
        }
        # Uncomment to activate debug logging
        #set DebugCh [open ~/dirdiff.log a]
        #$self DlogTablelist
        $self Dlog RESTART
        InitProf
        set AfterId ""
        set IdleQueue {}
        set ScheduledRestart 0
        array unset IdleQueueArr
        set protect {left 0 right 0}

        # Directory Diff only supports one plugin.
904
905
906
907
908
909
910

911
912
913
914
915
916
917
            } else {
                set statusvar "$rightfull  ($count)"
            }

            $self Dlog Reschedule
            set AfterId [after $AfterTime [mymethod UpdateIdle]]
        } else {

            $self Dlog DONE
            set statusvar ""
            set AfterId ""
        }
    }

    method SetNodeStatus {node status} {







>







938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
            } else {
                set statusvar "$rightfull  ($count)"
            }

            $self Dlog Reschedule
            set AfterId [after $AfterTime [mymethod UpdateIdle]]
        } else {
            EndProf
            $self Dlog DONE
            set statusvar ""
            set AfterId ""
        }
    }

    method SetNodeStatus {node status} {
Changes to src/eskil.tcl.
1066
1067
1068
1069
1070
1071
1072

1073
1074
1075
1076
1077
1078
1079
    mapNoChange $top 0
}

# Read a patch file and display it
proc displayPatch {top} {
    set ::eskil($top,leftLabel) "Patch $::eskil($top,patchFile): old"
    set ::eskil($top,rightLabel) "Patch $::eskil($top,patchFile): new"

    update idletasks

    if {$::eskil($top,patchFile) eq ""} {
        if {$::eskil($top,patchData) eq ""} {
            set data [getFullPatch $top]
        } else {
            set data $::eskil($top,patchData)







>







1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
    mapNoChange $top 0
}

# Read a patch file and display it
proc displayPatch {top} {
    set ::eskil($top,leftLabel) "Patch $::eskil($top,patchFile): old"
    set ::eskil($top,rightLabel) "Patch $::eskil($top,patchFile): new"
    set ::eskil($top,patchFilelist) {}
    update idletasks

    if {$::eskil($top,patchFile) eq ""} {
        if {$::eskil($top,patchData) eq ""} {
            set data [getFullPatch $top]
        } else {
            set data $::eskil($top,patchData)
1118
1119
1120
1121
1122
1123
1124




1125
1126
1127
1128
1129
1130
1131
                    insertLine $top $side "" $divider patch
                    insertLine $top $side "" $fname   patch
                    insertLine $top $side "" $divider patch
                }
                addChange $top 4 change 0 0 0 0
            }
            set fname [string range $line 7 end]




        }
        # Detect the first line in a -c style diff
        if {[regexp {^\*\*\* } $line]} {
            if {$state eq "right"} {
                displayOnePatch $top $leftLines $rightLines $leftLine $rightLine
                set leftLines {}
                set rightLines {}







>
>
>
>







1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
                    insertLine $top $side "" $divider patch
                    insertLine $top $side "" $fname   patch
                    insertLine $top $side "" $divider patch
                }
                addChange $top 4 change 0 0 0 0
            }
            set fname [string range $line 7 end]
            # Collect the files seen. Used by revision control for commit.
            if {[file isfile $fname]} {
                lappend ::eskil($top,patchFilelist) $fname
            }
        }
        # Detect the first line in a -c style diff
        if {[regexp {^\*\*\* } $line]} {
            if {$state eq "right"} {
                displayOnePatch $top $leftLines $rightLines $leftLine $rightLine
                set leftLines {}
                set rightLines {}
1271
1272
1273
1274
1275
1276
1277




1278
1279
1280
1281
1282
1283
1284
            emptyLine $top $side
            insertLine $top $side "" $divider patch
            insertLine $top $side "" $fname   patch
            insertLine $top $side "" $divider patch
        }
        addChange $top 4 change 0 0 0 0
    }




}

#####################################
# Main diff
#####################################

# Prepare for a diff by creating needed temporary files







>
>
>
>







1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
            emptyLine $top $side
            insertLine $top $side "" $divider patch
            insertLine $top $side "" $fname   patch
            insertLine $top $side "" $divider patch
        }
        addChange $top 4 change 0 0 0 0
    }

    # Cleanup detected files
    set ::eskil($top,patchFilelist) [lsort -dictionary -unique \
                                             $::eskil($top,patchFilelist)]
}

#####################################
# Main diff
#####################################

# Prepare for a diff by creating needed temporary files
Changes to src/rev.tcl.
1608
1609
1610
1611
1612
1613
1614





1615

1616
1617
1618
1619
1620
1621
1622
    set ::eskil($top,leftFile) $::eskil($top,RevFile)
}

proc revCommit {top} {
    if {[$::widgets($top,commit) cget -state] eq "disabled"} return
    set type $::eskil($top,modetype)
    if {$::eskil($top,mode) eq "patch"} {





        set files $::eskil($top,reviewFiles)

    } else {
        set files [list $::eskil($top,RevFile)]
    }
    eskil::rev::${type}::commitFile $top {*}$files
}

proc revRevert {top} {







>
>
>
>
>
|
>







1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
    set ::eskil($top,leftFile) $::eskil($top,RevFile)
}

proc revCommit {top} {
    if {[$::widgets($top,commit) cget -state] eq "disabled"} return
    set type $::eskil($top,modetype)
    if {$::eskil($top,mode) eq "patch"} {
        if {[llength $::eskil($top,patchFilelist)] != 0} {
            # Use the list extracted from patch
            set files $::eskil($top,patchFilelist)
        } else {
            # Use the list given by user
            set files $::eskil($top,reviewFiles)
        }
    } else {
        set files [list $::eskil($top,RevFile)]
    }
    eskil::rev::${type}::commitFile $top {*}$files
}

proc revRevert {top} {
1726
1727
1728
1729
1730
1731
1732





1733
1734
1735
1736
1737
1738
1739
        return $last
    } else {
        return [file join $penultimate $last]
    }
}

# Dialog for commit, getting log message





proc CommitDialog {top target system precmd postcmd {useSts 0}} {
    set w $top.logmsg
    destroy  $w
    toplevel $w -padx 3 -pady 3
    wm title $w "Commit log message for $target"

    set ::eskil($top,logdialogok) 0







>
>
>
>
>







1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
        return $last
    } else {
        return [file join $penultimate $last]
    }
}

# Dialog for commit, getting log message
# target: String shown in dialog
# system: Rev System
# precmd: Command part before message
# postcmd: Command part after message. Assumed to be files.
# useSts: Use status from exec rather than message to recognise error.
proc CommitDialog {top target system precmd postcmd {useSts 0}} {
    set w $top.logmsg
    destroy  $w
    toplevel $w -padx 3 -pady 3
    wm title $w "Commit log message for $target"

    set ::eskil($top,logdialogok) 0
1759
1760
1761
1762
1763
1764
1765















1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
















1776
1777
1778
1779
1780
1781
1782
    bind $w <Alt-c> [list destroy $w]\;break
    bind $w <Key-Escape> [list destroy $w]\;break

    grid $w.t  - -sticky news -padx 3 -pady 3
    grid $w.ok $w.ca -padx 3 -pady 3
    grid columnconfigure $w $w.t -weight 1 -uniform a
    grid rowconfigure    $w $w.t -weight 1















    tkwait visibility $w
    focus -force $w.t
    tkwait window $w.dummy

    if {!$::eskil($top,logdialogok)} {
        return
    }

    set res [string trim $::eskil(logdialog)]
    set ::eskil(logdialog) $res

















    # Splash screen for visual feedback
    set now [clock clicks -milliseconds]
    ttk::label $w.splash -text "Committing" -anchor center -font myfont
    place $w.splash -x 0 -y 0 -relwidth 1.0 -relheight 1.0
    update
    # Commit







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>










>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
    bind $w <Alt-c> [list destroy $w]\;break
    bind $w <Key-Escape> [list destroy $w]\;break

    grid $w.t  - -sticky news -padx 3 -pady 3
    grid $w.ok $w.ca -padx 3 -pady 3
    grid columnconfigure $w $w.t -weight 1 -uniform a
    grid rowconfigure    $w $w.t -weight 1

    if {[llength $postcmd] > 1} {
        # TODO: Scrolled frame
        ttk::frame $w.f -padding 1
        set t 0
        foreach fileName $postcmd {
            set ::eskil($top,commit,fileselect$t) 1
            ttk::checkbutton $w.f.cb$t -text $fileName \
                    -variable ::eskil($top,commit,fileselect$t)
            grid $w.f.cb$t -sticky "w" -padx 1 -pady 1
            incr t
        }
        grid $w.f -sticky news -padx 3 -pady 3
    }

    tkwait visibility $w
    focus -force $w.t
    tkwait window $w.dummy

    if {!$::eskil($top,logdialogok)} {
        return
    }

    set res [string trim $::eskil(logdialog)]
    set ::eskil(logdialog) $res

    set todo $postcmd
    if {[llength $postcmd] > 1} {
        set todo {}
        set t 0
        foreach fileName $postcmd {
            if {$::eskil($top,commit,fileselect$t)} {
                lappend todo $fileName
            }
            incr t
        }
        # None left means skip.
        if {[llength $todo] == 0} {
            return
        }
    }

    # Splash screen for visual feedback
    set now [clock clicks -milliseconds]
    ttk::label $w.splash -text "Committing" -anchor center -font myfont
    place $w.splash -x 0 -y 0 -relwidth 1.0 -relheight 1.0
    update
    # Commit