gitk: Only write changed configuration variables

When gitk contains some changed parameter, and there is an existing instance of gitk where the parameter is still old, it is reverted to that old value when that instance exits. Instead, store a parameter in config only if it has been modified in the exiting instance. Otherwise, preserve the value which currently is in file. This allows editing the configuration when several instances are running, without rollback of the modification if some other instance where the configuration was not edited is closed last. For scalar variables, use trace(3tcl) to detect their change. Since `trace` can send bogus events, doublecheck if the value has really been changed, but once it is marked as changed, do not reset it back to unchanged ever, because if user has restored the original value, it's the decision which should be stored as well as modified value. Treat view list especially: instead of rewriting the whole list, merge individual views. Place old and updated views in their old places, add new ones to the end of list. Collect modified views explicitly, in newviewok{} and delview{}. Do not merge geometry values. They are almost always changing because user moves and resises windows, and there is no way to find which one of the geometries is most desired. Just overwrite them unconditionally, like earlier. Signed-off-by: Max Kirillov <max@max630.net> Signed-off-by: Paul Mackerras <paulus@samba.org>

Max Kirillov committed Mar 4, 2015 at 05:58 UTC 995f792b992affdcea9489f063392557de2b3753
1 file changed +76 -10
gitk
+76 -10
@@ -2783,12 +2783,38 @@ proc doprogupdate {} {
2783 }
2784 }
2785
2786 +proc config_init_trace {name} {
2787 + global config_variable_changed config_variable_original
2788 +
2789 + upvar #0 $name var
2790 + set config_variable_changed($name) 0
2791 + set config_variable_original($name) $var
2792 +}
2793 +
2794 +proc config_variable_change_cb {name name2 op} {
2795 + global config_variable_changed config_variable_original
2796 +
2797 + upvar #0 $name var
2798 + if {$op eq "write" &&
2799 + (![info exists config_variable_original($name)] ||
2800 + $config_variable_original($name) ne $var)} {
2801 + set config_variable_changed($name) 1
2802 + }
2803 +}
2804 +
2805 proc savestuff {w} {
2787 - global viewname viewfiles viewargs viewargscmd viewperm nextviewnum
2788 - global use_ttk
2806 global stuffsaved
2807 global config_file config_file_tmp
2791 - global config_variables
2808 + global config_variables config_variable_changed
2809 + global viewchanged
2810 +
2811 + upvar #0 viewname current_viewname
2812 + upvar #0 viewfiles current_viewfiles
2813 + upvar #0 viewargs current_viewargs
2814 + upvar #0 viewargscmd current_viewargscmd
2815 + upvar #0 viewperm current_viewperm
2816 + upvar #0 nextviewnum current_nextviewnum
2817 + upvar #0 use_ttk current_use_ttk
2818
2819 if {$stuffsaved} return
2820 if {![winfo viewable .]} return
@@ -2800,16 +2826,24 @@ proc savestuff {w} {
2826 if {$::tcl_platform(platform) eq {windows}} {
2827 file attributes $config_file_tmp -hidden true
2828 }
2829 + if {[file exists $config_file]} {
2830 + source $config_file
2831 + }
2832 foreach var_name $config_variables {
2833 upvar #0 $var_name var
2805 - puts $f [list set $var_name $var]
2834 + upvar 0 $var_name old_var
2835 + if {!$config_variable_changed($var_name) && [info exists old_var]} {
2836 + puts $f [list set $var_name $old_var]
2837 + } else {
2838 + puts $f [list set $var_name $var]
2839 + }
2840 }
2841
2842 puts $f "set geometry(main) [wm geometry .]"
2843 puts $f "set geometry(state) [wm state .]"
2844 puts $f "set geometry(topwidth) [winfo width .tf]"
2845 puts $f "set geometry(topheight) [winfo height .tf]"
2812 - if {$use_ttk} {
2846 + if {$current_use_ttk} {
2847 puts $f "set geometry(pwsash0) \"[.tf.histframe.pwclist sashpos 0] 1\""
2848 puts $f "set geometry(pwsash1) \"[.tf.histframe.pwclist sashpos 1] 1\""
2849 } else {
@@ -2819,11 +2853,33 @@ proc savestuff {w} {
2853 puts $f "set geometry(botwidth) [winfo width .bleft]"
2854 puts $f "set geometry(botheight) [winfo height .bleft]"
2855
2856 + array set view_save {}
2857 + array set views {}
2858 + if {![info exists permviews]} { set permviews {} }
2859 + foreach view $permviews {
2860 + set view_save([lindex $view 0]) 1
2861 + set views([lindex $view 0]) $view
2862 + }
2863 puts -nonewline $f "set permviews {"
2823 - for {set v 0} {$v < $nextviewnum} {incr v} {
2824 - if {$viewperm($v)} {
2825 - puts $f "{[list $viewname($v) $viewfiles($v) $viewargs($v) $viewargscmd($v)]}"
2864 + for {set v 1} {$v < $current_nextviewnum} {incr v} {
2865 + if {$viewchanged($v)} {
2866 + if {$current_viewperm($v)} {
2867 + set views($current_viewname($v)) [list $current_viewname($v) $current_viewfiles($v) $current_viewargs($v) $current_viewargscmd($v)]
2868 + } else {
2869 + set view_save($current_viewname($v)) 0
2870 + }
2871 + }
2872 + }
2873 + # write old and updated view to their places and append remaining to the end
2874 + foreach view $permviews {
2875 + set view_name [lindex $view 0]
2876 + if {$view_save($view_name)} {
2877 + puts $f "{$views($view_name)}"
2878 }
2879 + unset views($view_name)
2880 + }
2881 + foreach view_name [array names views] {
2882 + puts $f "{$views($view_name)}"
2883 }
2884 puts $f "}"
2885 close $f
@@ -4245,7 +4301,7 @@ proc allviewmenus {n op args} {
4301
4302 proc newviewok {top n {apply 0}} {
4303 global nextviewnum newviewperm newviewname newishighlight
4248 - global viewname viewfiles viewperm selectedview curview
4304 + global viewname viewfiles viewperm viewchanged selectedview curview
4305 global viewargs viewargscmd newviewopts viewhlmenu
4306
4307 if {[catch {
@@ -4266,6 +4322,7 @@ proc newviewok {top n {apply 0}} {
4322 incr nextviewnum
4323 set viewname($n) $newviewname($n)
4324 set viewperm($n) $newviewopts($n,perm)
4325 + set viewchanged($n) 1
4326 set viewfiles($n) $files
4327 set viewargs($n) $newargs
4328 set viewargscmd($n) $newviewopts($n,cmd)
@@ -4278,6 +4335,7 @@ proc newviewok {top n {apply 0}} {
4335 } else {
4336 # editing an existing view
4337 set viewperm($n) $newviewopts($n,perm)
4338 + set viewchanged($n) 1
4339 if {$newviewname($n) ne $viewname($n)} {
4340 set viewname($n) $newviewname($n)
4341 doviewmenu .bar.view 5 [list showview $n] \
@@ -4300,7 +4358,7 @@ proc newviewok {top n {apply 0}} {
4358 }
4359
4360 proc delview {} {
4303 - global curview viewperm hlview selectedhlview
4361 + global curview viewperm hlview selectedhlview viewchanged
4362
4363 if {$curview == 0} return
4364 if {[info exists hlview] && $hlview == $curview} {
@@ -4309,6 +4367,7 @@ proc delview {} {
4367 }
4368 allviewmenus $curview delete
4369 set viewperm($curview) 0
4370 + set viewchanged($curview) 1
4371 showview 0
4372 }
4373
@@ -12129,6 +12188,10 @@ set config_variables {
12188 linehoveroutlinecolor mainheadcirclecolor workingfilescirclecolor
12189 indexcirclecolor circlecolors linkfgcolor circleoutlinecolor
12190 }
12191 +foreach var $config_variables {
12192 + config_init_trace $var
12193 + trace add variable $var write config_variable_change_cb
12194 +}
12195
12196 parsefont mainfont $mainfont
12197 eval font create mainfont [fontflags mainfont]
@@ -12256,6 +12319,7 @@ set highlight_related [mc "None"]
12319 set highlight_files {}
12320 set viewfiles(0) {}
12321 set viewperm(0) 0
12322 +set viewchanged(0) 0
12323 set viewargs(0) {}
12324 set viewargscmd(0) {}
12325
@@ -12314,6 +12378,7 @@ if {$cmdline_files ne {} || $revtreeargs ne {} || $revtreeargscmd ne {}} {
12378 set viewargs(1) $revtreeargs
12379 set viewargscmd(1) $revtreeargscmd
12380 set viewperm(1) 0
12381 + set viewchanged(1) 0
12382 set vdatemode(1) 0
12383 addviewmenu 1
12384 .bar.view entryconf [mca "Edit view..."] -state normal
@@ -12329,6 +12394,7 @@ if {[info exists permviews]} {
12394 set viewargs($n) [lindex $v 2]
12395 set viewargscmd($n) [lindex $v 3]
12396 set viewperm($n) 1
12397 + set viewchanged($n) 0
12398 addviewmenu $n
12399 }
12400 }