Menu

Commit [r144]  Maximize  Restore  History

* The NewDiff interactive Dialog is now the default when no args given

- it permits a simpler startup on graphical desktops via shortcuts
- yet still allows dynamic searching for SCM-based diff candidates, and
- its controls are now inter-related to assist making correct settings
* Users may now specify a preferred SCM system among those detectable
* Additionally, the SCM system may be manually selected during dialog use
* A new autoSrch preference allows immediate SCM startup from the cmdline
* It is now possible to COMBINE usage of two distinct SCMs, if desired;
- this also facilitates comparisons between distinct branches of an SCM
* It is now possible to request a "conflict" diff via the dialog
* Conflict parsing now accepts a diff3-like format (but only as a 2way)
* The (internal) setting of prefs is now managed to prevent lost settings
* Resolved a race condition causing instability in redrawing the DiffMap
* More uniformity of error messaging - particularly fatal errors
* New Help info on the role of the CWD during tool startup, plus the SCM
- features, and interpreting the interactive feedback from the dialog

vampm 2018-08-31

changed /trunk/tkdiff
/trunk/tkdiff Diff Switch to side-by-side view
--- a/trunk/tkdiff
+++ b/trunk/tkdiff
@@ -189,6 +189,8 @@
 }
 
 # general globals
+#   Note: 'scmS'  is the STATIC list of ALL known SCMs (rvrs alpha sorted).
+#   Note: 'scmSrch' is a STATIC list of SCMs capable of searches
 array set g {
     conflictset     0
     destroy         ""
@@ -203,12 +205,15 @@
     mergefile       ""
     mergefileset    0
     returnValue     0
+    scmDOsrch       0
+    scmPrefer       ""
+    scmS            {SVN SCCS RCS PVCS Perforce HG GIT CVS ClearCase BK Accurev}
+    scmSrch         {CVS GIT SVN}
     showmerge       0
     statusCurrent   "Standby...."
     statusInfo      ""
     tempfiles       ""
     thumbMinHeight  10
-    thumbHeight     10
     thumbDeltaY     0
 }
 
@@ -216,21 +221,27 @@
 #   Only those elements that are gauranteed to exist are initialized here.
 #
 #   The remainder of the FINFO entries are dynamically added and (occasionally
-#   removed) as the user interacts with the tool. There are 2 categories of
+#   removed) as the user interacts with the tool. There are 3 categories of
 #   information:
-#       1. entries that describe INPUT parameters:
+#      #1. entries that describe INPUT parameters:
 #           f,*       filespec that describe files/dirs/URLs to be acted upon
 #           rev,*     revision value (for a to-be-detected SCM system)
+#           scm*      SCM list (DERIVED from 'f,*'), that detected as valid
 #           ulbl,*    user-label: when provided, overrides "lbl" (see below)
 #
-#       2. entries ACTUALLY used AFTER input has been processed
+#      #2. entries ACTUALLY used AFTER input has been processed
 #           pth,*     the actual local (possibly temp) file to compare
 #           tmp,*     optional flag denotes "pth" AS a tempfile (& other uses)
 #           lbl,*     displayable label for "pth"
 #           pproc,*   special post processing needed for "pth" (rare)
 #
+#      #3. entries VERY similar to #2, but pertaining to ANCESTOR files
+#           apth,*    the actual local (possibly temp) file to compare
+#           atmp,*    optional flag denotes "apth" AS a tempfile (& other uses)
+#           albl,*    displayable label for "apth"
+#
 #       In each above case, '*' is a monotonic number beginning at 1. Zero
-#       is a special case used exclusively for an "Ancestor File" entry.
+#       is a special case used exclusively for a #1 "Ancestor File" entry.
 #       The SAME value, WITHIN its category, describes attributes of a SINGLE
 #       object --- However "ulbl" is an exception - its number is USED by
 #       category 2, despite being SET by category 1 (reasons are mostly
@@ -238,13 +249,18 @@
 #       "ulbl" is NOT expected to see usage beyond that still valid case,
 #       although it is NOT specifically prohibitted.
 #
-#   Items in category 1 represent data ENTERRED by the user; as such they
+#   Items in category #1 represent data ENTERRED by the user; as such they
 #   are tied somewhat to the GUI (thereby initialized here), and are
-#   (mostly) fixed at being at MOST two each (except MAYBE ulbl).
-#
-#   Items in category 2 (NOT set here) are grouped as adjacently numbered
+#   (mostly) fixed at being at MOST two each (except MAYBE ulbl). Note that
+#   scm,* (as an entry) is mostly for the inquiry/search modes as individually
+#   retrieved files will generate their OWN (NOT modifying this global value).
+#
+#   Items in category #2 (NOT set here) are grouped as adjacently numbered
 #   PAIRS, and are files intended, actually, or previously been compared,
-#   DERIVED from the items of category 1.
+#   DERIVED from the items of category #1.
+#
+#   Items in category #3 (NOT set here) use a DISJOINT monotonic numbering
+#   system from 1 to "fPairs" (explained next) AND a 'a'-prefix naming
 #
 #   "fCurpair" designates which monotonic PAIR is actively in use (1->fPairs)
 #   with "fPairs" itself being the COUNT of how many "fCurpair"s exist.
@@ -281,10 +297,12 @@
     f,1          ""
     ulbl,1       ""
     rev,1        ""
+    scm1         ""
 
     f,2          ""
     ulbl,2       ""
     rev,2        ""
+    scm2         ""
 }
 set uniq 0
 
@@ -292,6 +310,7 @@
 array set opts {
     autocenter        1
     autoselect        0
+    autoSrch          0
     colorcbs          0
     customCode        {}
     diffcmd           "diff"
@@ -304,6 +323,7 @@
     filetypes         {{{All Files} *} {{Text Files} .txt} {{TclFiles} .tcl}}
     geometry          "80x30"
     predomMrg         1
+    scmPrefer         {Auto Auto}
     showcbs           1
     showln            1
     showmap           1
@@ -476,13 +496,13 @@
 # created, otherwise put up a dialog and throw an exception.
 ###############################################################################
 proc fatal-error {msg} {
-    global g tcl_platform
+    global g
     debug-info "fatal-error ($msg)"
 
     if {$g(startPhase)} {
         do-error $msg "Aborting..."
     } else {
-        puts stderr $msg
+        puts stderr "Error: $msg\n$g(name) Aborted"
     }
     do-exit 2
 }
@@ -603,22 +623,27 @@
 proc scm-chkget {ndx} {
     global finfo
 
-    if {![info exists finfo(pth,$ndx)]} {
-        set finfo(pth,$ndx) "[tmpfile scm$ndx]"
-    }
-    debug-info "scm-chkget ($ndx) -> '$finfo(tmp,$ndx)': $finfo(pth,$ndx)"
-
-    set result [run-command "$finfo(tmp,$ndx)" "$finfo(pth,$ndx)"]
+    # 'ndx' is a number POSSIBLY prefixed by an 'a' (for ancestor)
+    #   adjust the NAMING for 'finfo(xxx)" elements accordingly
+    set A "a" ; if {[string index "$ndx" 0] == $A} {
+        set ndx [string range $ndx 1 end] } { set A "" }
+
+    if {![info exists finfo(${A}pth,$ndx)]} {
+        set finfo(${A}pth,$ndx) "[tmpfile scm$ndx]"
+    }
+    debug-info "scm-chkget ($ndx) -> '$finfo(${A}tmp,$ndx)': $finfo(${A}pth,$ndx)"
+
+    set result [run-command "$finfo(${A}tmp,$ndx)" "$finfo(${A}pth,$ndx)"]
     set stdout [lindex $result 0]
     set stderr [lindex $result 1]
 
     # Remember to postproccess (if needed) and ...
     if {![lindex $result 2]} {
-        if {[info exists finfo(pproc,$ndx)]} {
-            $finfo(pproc,$ndx) "$finfo(pth,$ndx)"
+        if {[info exists finfo(${A}pproc,$ndx)]} {
+            $finfo(${A}pproc,$ndx) "$finfo(${A}pth,$ndx)"
         }
         # ... return the erased cmd (DO NOT UNSET) to indicate Success
-        return [set finfo(tmp,$ndx) ""]
+        return [set finfo(${A}tmp,$ndx) ""]
     }
 
     # Send messages back to caller only on failure
@@ -1121,10 +1146,12 @@
 }
 
 ###############################################################################
-# Split a file containing CVS conflict markers into two temporary files
+# Split a file containing CVS (or other) conflict markers into two temp files
 #    name        Name of file containing conflict markers
-# Returns the names of the two temporary files and the names of the
-# files that were merged
+# Returns the names of the two tempfiles and the original names they represent
+# N.B> its POSSIBLE a third file (an ancestor) may be seen in the input format
+#      Although key pieces of code to implement have been provided, the SUPPORT
+#      at this time is to silently IGNORE any such data pending other changes
 ###############################################################################
 proc split-conflictfile {name} {
     global g opts
@@ -1133,32 +1160,34 @@
     if {[catch {set input [open $name r]}]} {
         fatal-error "Couldn't open file '$name'"
     }
-    set temp1 [tmpfile cf1]
-    set temp2 [tmpfile cf2]
-
-    set first [open $temp1 w]
-    set second [open $temp2 w]
-
-    set firstname ""
-    set secondname ""
-    set output 3
-
-    set firstMatch ""
-    set secondMatch ""
-    set thirdMatch ""
-
+
+    set first  [open [set temp1 [tmpfile cf1]] w]
+    set second [open [set temp2 [tmpfile cf2]] w]
+#   set third  [open [set temp3 [tmpfile cfa]] w]    ancestor file??
+
+    set firstname  [set secondname                  [set thirdname   ""]]
+    set firstMatch [set secondMatch [set thirdMatch [set fourthMatch ""]]]
+
+    set output 7
     while {[gets $input line] >= 0} {
+        # First marker tells us whose marking FORMAT to follow
         if {$firstMatch == ""} {
             if {[regexp {^<<<<<<<* +(.*)} $line]} {
-                set firstMatch {^<<<<<<<* +(.*)}
+                # This maps 'diff3-like' markers
+                set firstMatch  {^<<<<<<<* +(.*)}
                 set secondMatch {^=======*}
-                set thirdMatch {^>>>>>>>* +(.*)}
+                set thirdMatch  {^>>>>>>>* +(.*)}
+                set fourthMatch {^|||||||* +(.*)}
+
             } elseif {[regexp {^>>>>>>>* +(.*)} $line]} {
-                set firstMatch {^>>>>>>>* +(.*)}
+                # This maps '??whose??' markers (why do they have their OWN?)
+                set firstMatch  {^>>>>>>>* +(.*)}
                 set secondMatch {^<<<<<<<* +(.*)}
-                set thirdMatch {^=======*}
-            }
-        }
+                set thirdMatch  {^=======*}
+                set fourthMatch {^|||||||* +(.*)} ;# is this even possible?
+            }
+        }
+        # Dont bother with matching until we find the first marker
         if {$firstMatch != ""} {
             if {[regexp $firstMatch $line]} {
                 set output 2
@@ -1171,41 +1200,43 @@
                     regexp $secondMatch $line all firstname
                 }
             } elseif {[regexp $thirdMatch $line]} {
-                set output 3
+                set output 7
                 if {$firstname == ""} {
                     regexp $thirdMatch $line all firstname
                 }
+            } elseif {[regexp $fourthMatch $line]} {
+                set output 4
+                if {$thirdname == ""} {
+                    regexp $fourthMatch $line all thirdname
+                }
             } else {
-                if {$output & 1} {
-                    puts $first $line
-                }
-                if {$output & 2} {
-                    puts $second $line
-                }
+                if {$output & 1} { puts $first  $line }
+                if {$output & 2} { puts $second $line }
+#               if {$output & 4} { puts $third  $line }
             }
         } else {
-            puts $first $line
+            puts $first  $line
             puts $second $line
+#           puts $third  $line
         }
     }
     close $input
     close $first
     close $second
-
-    if {$firstname == ""} {
-        set firstname "old"
-    }
-    if {$secondname == ""} {
-        set secondname "new"
-    }
-
+#   close $third
+
+    if {$firstname == ""}  { set firstname  "old" }
+    if {$secondname == ""} { set secondname "new" }
+#   if {$thirdname == ""}  { set thirdname  "anc" }
+
+    # Cant return a 'third' file until caller knows how to HANDLE it
     return "{$temp1} {$temp2} {$firstname} {$secondname}"
 }
 
 ###############################################################################
-# Detect which Src Code Managment system is expected to obtain this filename
-###############################################################################
-proc scm-detect {fn} {
+# Derive the Src Code Managment systems that appear VALID for given dir or file
+###############################################################################
+proc scm-detect {fn {extra {}}} {
 
     regsub -all {\$} $fn {\$} fn   ;# (Backslash any '$' ciphers as literal)
     # Use dirname OF argument if it is not a directory already
@@ -1221,25 +1252,47 @@
     ### *My* gut feeling is the precedence described above should be followed
     ### (which is NOT completely the case as it exists here) however, as some
     ### cases are combo/subsets of others there is plenty of room for debate.
-    if {[file isdirectory [file join $dnam CVS]]}          { return CVS
-    } elseif {[is-repo-dir ".svn" $dnam]}                  { return SVN
-    } elseif {[is-git-repository]}                         { return GIT
-    } elseif {[regexp {://} $fn]}                          { return SVN
-    } elseif {[sccs-is-bk]}                                { return BK
-    } elseif {[file isdirectory [file join $dnam SCCS]]}   { return SCCS
-    } elseif {[file isdirectory [file join $dnam RCS]]}    { return RCS
-    } elseif {[file isfile $fn,v]}                         { return RCS
-    } elseif {[file exists [file join $dnam vcs.cfg]] || \
-              [info exists ::env(VCSCFG)]}                 { return PVCS
-    } elseif {[info exists ::env(P4CLIENT)] || \
-              [info exists ::env(P4CONFIG)]}               { return Perforce
-    } elseif {[info exists ::env(ACCUREV_BIN)]}            { return Accurev
-    } elseif {[info exists ::env(CLEARCASE_ROOT)]}         { return ClearCase
-    } elseif {[is-repo-dir ".hg" $dnam]}                   { return HG
-    }
-
-    return "" ;# Unrecognized
-}
+    #
+    # In any event, this is now a voting process (former if-else chain) where
+    # the user gets to pre-state their choice PROVIDED its an allowed one.
+    lappend scms
+    if {[file isdirectory [file join $dnam CVS]]}    { lappend scms CVS }
+    if {[is-repo-dir ".svn" $dnam]}                  { lappend scms SVN }
+    if {[is-git-repository]}                         { lappend scms GIT }
+    if {[regexp {://} $fn]}                          { lappend scms SVN }
+    if {[sccs-is-bk]}                                { lappend scms BK }
+    if {[file isdirectory [file join $dnam SCCS]]}   { lappend scms SCCS }
+    if {[file isdirectory [file join $dnam RCS]]}    { lappend scms RCS }
+    if {[file isfile $fn,v]}                         { lappend scms RCS }
+    if {[file exists [file join $dnam vcs.cfg]] || \
+        [info exists ::env(VCSCFG)]}                 { lappend scms PVCS }
+    if {[info exists ::env(P4CLIENT)] || \
+        [info exists ::env(P4CONFIG)]}               { lappend scms Perforce }
+    if {[info exists ::env(ACCUREV_BIN)]}            { lappend scms Accurev }
+    if {[info exists ::env(CLEARCASE_ROOT)]}         { lappend scms ClearCase }
+    if {[is-repo-dir ".hg" $dnam]}                   { lappend scms HG }
+
+    # We occasionally need to ADD a 'pseudo SCM' to the end of a NONEMPTY list
+    if {$extra != "" && [llength $scms]} {lappend scms $extra}
+    return $scms
+}
+
+###############################################################################
+# Decide which Src Code Managment system is expected to obtain the current file
+###############################################################################
+proc scm-elect {scms vote} {
+    #debug-info "Elect Candidates($scms) Vote($vote) for [info level -1]"
+
+    # Simply apply the users vote
+    #   N.B> This makes it APPEAR that either SCM meta-value (Auto or None)
+    #   always results in just TAKING the top entry - the trick is that when
+    #   'scms' was setup by 'newDiffDialog' it likely CONTAINS 'None' as a
+    #   candidate value, making it electable here, based on the 'vote'
+    # This allows the caller to recognize that access was BLOCKed not MISSING
+    if {$vote in $scms} {return $vote ;# new democratic way ...user choice
+    } else              {return [lindex $scms 0]} ;#ye olde way...1st found
+}
+
 ###############################################################################
 # Obtain a revision of a file:
 #   fn      requested file name
@@ -1283,11 +1336,20 @@
     set cmdsfx ""       ;# Prevent 'exec'-spoofing on Windows platform(?)
     if {$tcl_platform(platform) == "windows"} { set cmdsfx ".exe" }
 
+    # Ancestor files are stored into a slightly adjusted array element name 
+    if {$ndx < 0} {set A "a"; set ndx [expr {-1 * $ndx}]} {set A ""}
+
     # Presume eventual success ... then
     set msg {}
 
-    # DETECT and then FORMULATE an appropriate SCM command to request the file
-    if {"" == $Scm} {set Scm [scm-detect $fn]}
+    # DETECT and then FORMULATE the appropriate SCM command to request the file
+    #   N.B> The 'None' choice is PRESEVED when it was originally present
+    if {"" == $Scm} {
+        set Scm [expr {!($ndx & 1)}]               ;# Get from the correct side
+        set ScmVote [lindex $g(scmPrefer) $Scm]    ;# obtain CURRENT preference
+        set Scm [expr {"None" in $finfo(scm[incr Scm])? "None" : ""}]  ;# None?
+        set Scm [scm-elect [scm-detect $fn $Scm] $ScmVote] ;# & resolve the Scm
+    }
     switch -- $Scm {
     CVS {
         append cmd "cvs" $cmdsfx
@@ -1295,8 +1357,8 @@
         # directory.  It will however have a ,v suffix just like rcs.
         #   (There is not necessarily a RCS directory for RCS, either...)
         #   (however, if not, then the file will ALWAYS have a ,v suffix.)
-        set finfo(lbl,$ndx) "$fn (CVS $rev)"
-        set finfo(tmp,$ndx) "$cmd update -p $cvsopt \"$fn\""
+        set finfo(${A}lbl,$ndx) "$fn (CVS $rev)"
+        set finfo(${A}tmp,$ndx) "$cmd update -p $cvsopt \"$fn\""
 
         }
     SVN {
@@ -1307,19 +1369,19 @@
             if {![regsub {^.*@} $fn {} rev]} { set rev "HEAD" }
             regsub {@\d+$} $fn {} path
             if {"$rev" == ""} {
-                set finfo(tmp,$ndx) "$cmd cat $path"
-                set finfo(lbl,$ndx) "$fn (SVN)"
+                set finfo(${A}tmp,$ndx) "$cmd cat $path"
+                set finfo(${A}lbl,$ndx) "$fn (SVN)"
             } else {
-                set finfo(tmp,$ndx) "$cmd cat -r $rev $path"
-                set finfo(lbl,$ndx) "$fn (SVN $rev)"
+                set finfo(${A}tmp,$ndx) "$cmd cat -r $rev $path"
+                set finfo(${A}lbl,$ndx) "$fn (SVN $rev)"
             }
         } else {
             if {"$r" == "" || "$rev" == "rBASE"} {
-                set finfo(lbl,$ndx) "$fn (SVN BASE)"
+                set finfo(${A}lbl,$ndx) "$fn (SVN BASE)"
             } else {
-                set finfo(lbl,$ndx) "$fn (SVN $rev)"
-            }
-            set finfo(tmp,$ndx) "$cmd cat $svnopt \"$fn\""
+                set finfo(${A}lbl,$ndx) "$fn (SVN $rev)"
+            }
+            set finfo(${A}tmp,$ndx) "$cmd cat $svnopt \"$fn\""
         }
 
         }
@@ -1330,50 +1392,50 @@
             debug-info "exec $cmd rev-parse --show-prefix"
             set prefix [exec $cmd rev-parse --show-prefix]
             if {"$r" == "" || " " == [string index "$r" 0]} {
-                set finfo(lbl,$ndx) "$fn (GIT--staged)" ;# STAGEd vrsn
-                set finfo(tmp,$ndx) "$cmd show \":$prefix$fn\""
+                set finfo(${A}lbl,$ndx) "$fn (GIT--staged)" ;# STAGEd vrsn
+                set finfo(${A}tmp,$ndx) "$cmd show \":$prefix$fn\""
             } else {
-                set finfo(lbl,$ndx) "$fn (GIT $rev)" ;# REQSTd vrsn
-                set finfo(tmp,$ndx) "$cmd show \"$gitopt$prefix$fn\""
+                set finfo(${A}lbl,$ndx) "$fn (GIT $rev)" ;# REQSTd vrsn
+                set finfo(${A}tmp,$ndx) "$cmd show \"$gitopt$prefix$fn\""
             }
         } {set msg "Please re-start from within a Git work tree."}
         }
     BK {
         append cmd "bk" $cmdsfx
-        set finfo(lbl,$ndx) "$fn (Bitkeeper $rev)"
-        set finfo(tmp,$ndx) "$cmd get -p $bkopt \"$fn\""
+        set finfo(${A}lbl,$ndx) "$fn (Bitkeeper $rev)"
+        set finfo(${A}tmp,$ndx) "$cmd get -p $bkopt \"$fn\""
 
         }
     SCCS {
         append cmd "sccs" $cmdsfx
-        set finfo(lbl,$ndx) "$fn (SCCS $rev)"
-        set finfo(tmp,$ndx) "$cmd get -p $sccsopt \"$fn\""
+        set finfo(${A}lbl,$ndx) "$fn (SCCS $rev)"
+        set finfo(${A}tmp,$ndx) "$cmd get -p $sccsopt \"$fn\""
         }
     RCS {
         append cmd "co" $cmdsfx
-        set finfo(lbl,$ndx) "$fn (RCS $rev)"
-        set finfo(tmp,$ndx) "$cmd -p$rcsopt \"$fn\""
+        set finfo(${A}lbl,$ndx) "$fn (RCS $rev)"
+        set finfo(${A}tmp,$ndx) "$cmd -p$rcsopt \"$fn\""
         }
     PVCS {
         append cmd "get" $cmdsfx
-        set finfo(lbl,$ndx) "$fn (PVCS $rev)"
-        set finfo(tmp,$ndx) "$cmd -p $pvcsopt \"$fn\""
-        set finfo(pproc,$ndx) "filterCRCRLF"
+        set finfo(${A}lbl,$ndx) "$fn (PVCS $rev)"
+        set finfo(${A}tmp,$ndx) "$cmd -p $pvcsopt \"$fn\""
+        set finfo(${A}pproc,$ndx) "filterCRCRLF"
         }
     Perforce {
         append cmd "p4" $cmdsfx
-        set finfo(lbl,$ndx) "$fn (Perforce $rev)"
-        set finfo(tmp,$ndx) "$cmd print -q \"$p4file\""
+        set finfo(${A}lbl,$ndx) "$fn (Perforce $rev)"
+        set finfo(${A}tmp,$ndx) "$cmd print -q \"$p4file\""
         }
     Accurev {
         append cmd "accurev" $cmdsfx
-        set finfo(lbl,$ndx) "$fn (Accurev $rev)"
-        set finfo(tmp,$ndx) "$cmd cat $acopt \"$fn\""
+        set finfo(${A}lbl,$ndx) "$fn (Accurev $rev)"
+        set finfo(${A}tmp,$ndx) "$cmd cat $acopt \"$fn\""
         }
     ClearCase {
         # is this NOT a Windows tool (why no append of .exe?)
         set cmd "cleartool"
-        set finfo(lbl,$ndx) "$fn (ClearCase $rev)"
+        set finfo(${A}lbl,$ndx) "$fn (ClearCase $rev)"
 
         # list given file
         debug-info "exec $cmd ls -s $fn"
@@ -1406,8 +1468,8 @@
                 # Point DIRECTLY at the requested file
                 # However, make it APPEAR like it IS a tmpfile
                 #   (so we can deny invoking an editor later)
-                set finfo(pth,$ndx) $predecessor
-                set finfo(tmp,$ndx) ""
+                set finfo(${A}pth,$ndx) $predecessor
+                set finfo(${A}tmp,$ndx) ""
                 break
             }
         }
@@ -1420,22 +1482,27 @@
         if {"$r" == "" || "$rev" == "PARENT"} {
             # in hg, the revision for cat defaults to the parent revision
             # of the working directory
-            set finfo(lbl,$ndx) "$fn (HG PARENT)"
-            set finfo(tmp,$ndx) "$cmd cat $fn"
+            set finfo(${A}lbl,$ndx) "$fn (HG PARENT)"
+            set finfo(${A}tmp,$ndx) "$cmd cat $fn"
         } else {
-            set finfo(lbl,$ndx) "$fn (HG $rev)"
-            set finfo(tmp,$ndx) "$cmd cat $hgopt $fn"
-        }
-
-        }
-    default { set msg "File '$fn' is not part of a revision control system" }
+            set finfo(${A}lbl,$ndx) "$fn (HG $rev)"
+            set finfo(${A}tmp,$ndx) "$cmd cat $hgopt $fn"
+        }
+
+        }
+    None {
+        set msg "Did your preferred SCM system ($Scm) block file:\n"
+        append msg "    $fn\nfrom its intended SCM repository?"
+        }
+    default {set msg "File '$fn' is not part of a revision control system"}
     }
 
     # If NO errs (and in 1st pairing) NOW is the time to actually GET the file
+    # (even an ancestorfile if its required)
     if {$msg == ""} {
-        if {$ndx <= 2 && [string length $finfo(tmp,$ndx)]} {
-            watch-cursor "Accessing $finfo(lbl,$ndx)"
-            set msg [scm-chkget $ndx]
+        if {[string length $finfo(${A}tmp,$ndx)] && $ndx <("$A" == "" ? 3:2)} {
+            watch-cursor "Accessing $finfo(${A}lbl,$ndx)"
+            set msg [scm-chkget ${A}$ndx]
             restore-cursor
         }
     }
@@ -1494,9 +1561,12 @@
     global g finfo
     debug-info "get-file ($fn $ndx)"
 
+    # Ancestor files are stored into a slightly adjusted array element name 
+    if {$ndx < 0} {set A "a"; set ndx [expr {-1 * $ndx}]} {set A ""}
+
     set msg ""
     if {[file isfile $fn]} {
-        set finfo(lbl,$ndx) [set finfo(pth,$ndx) "$fn"]
+        set finfo(${A}lbl,$ndx) [set finfo(${A}pth,$ndx) "$fn"]
     } elseif {![file exist $fn]} {
              set msg "File '$fn' does not exist"
     } else { set msg "'$fn' exists, but is not a file" }
@@ -1628,21 +1698,39 @@
         exit 1
     }
 
-    # Underflow is trickier - ZERO *may* be legal given certain SCM abilities
-    if {$revs + $pths == 0} {
-        # Basically this is a simple hack to AVOID invoking "newDiffDialog"
-        #   Just prepend each SCM name here that knows how to GENERATE its
-        # own list of difference candidates when NO ARGS have been provided
-        # Generally this results in HEAD .vs. 'sandbox' (aka 'working copy')
-        switch -- [scm-detect "."] {
-            CVS -
-            SVN -
-            GIT { incr revs }
-        }
-    }
-    # NB: it MIGHT be a Good Thing to place the choice of the specific SCM
-    # into the preferences dialog (would need some thought to do properly;
-    # with maybe a DEFAULT of "auto-detect" which is what we do NOW...)
+    # Underflow is trickier - ZERO Fspecs *may* be legal given an appropriate
+    # CWD and compliant SCM. Even ZERO revs can be OK if the user permits it.
+    #
+    #   Basically this is all about AVOIDING "newDiffDialog" (if requested)
+    # when ZERO args (Revs or Fspecs) are provided
+    set g(scmDOsrch) 0
+    set g(scmPrefer) "$opts(scmPrefer)" ;# <-- Make the default 'active'
+    if {!$pths} {
+        # The automatic way out is a SINGLE, preferred, searchable SCM, with
+        # either given Revs, -OR- the users REQUEST that searching is desired.
+        # Otherwise it all gets load into the Dialog and the user can handle it
+        # N.B> do not simplify logic: 'scmDOsrch' is NEEDED by 'assemble-args'
+
+        # First, resolve which SIDE may have a viable SCM (if any)
+        set scms [scm-detect "."] ;# (need only 'detect' once w/CWD for both)
+        if {[set finfo(scm1) [scm-elect "$scms" [lindex $g(scmPrefer) 0]]] \
+                             in $g(scmSrch)} {incr g(scmDOsrch) 1}
+        if {[set finfo(scm2) [scm-elect "$scms" [lindex $g(scmPrefer) 1]]] \
+                             in $g(scmSrch)} {incr g(scmDOsrch) 2}
+
+        # Finally - check if we now have a DEFINITIVE choice ...
+        #   (if both SCMs are the same, it counts as just one)
+        if {$g(scmDOsrch) != 3 \
+        || ("$finfo(scm1)" == "$finfo(scm2)" && [incr g(scmDOsrch) -1])} {
+
+            # ... (and the Revs -OR- users OK to just go DO it)
+            if {$g(scmDOsrch) && $opts(autoSrch) && !$revs} {
+                incr revs ;# go STRAIGHT to processing (no dialog)
+            }
+        }
+        # If revs is ZERO as of now, the dialog will be presented next
+        #debug-info "DOsrch($g(scmDOsrch)) skipDialog($revs)"
+    }
 
     # Imply certain settings:
     #   - indicate the merge file is SUPPOSEDLY known (but may not survive)
@@ -1667,7 +1755,7 @@
     #debug-info " mergefile set: $g(mergefileset) $g(mergefile)"
     #debug-info " diff command: $opts(diffcmd) "
 
-    # Recount how many files and revs we got from the GUI or commandline
+    # RE-establish how many files and revs we got from the GUI or commandline
     #   (An AncestorFile - slot ZERO - is never part of the count)
     set pths 0
     foreach p [array names finfo f,*] {
@@ -1681,10 +1769,10 @@
             incr revs
         }
     }
-    # Save the CURRENT derived values (in case NEWLY derived values fail)
+    # Save the CURRENT derived values (in case NEWLY provided ones fail)
     # and establish a catchall failure msg (should NEVER actually see it)
-    set priorVals [array get finfo {[ptl]*[0-9]}]
-    array unset finfo {[ptl]*[0-9]}
+    set priorVals [array get finfo {[aptl]*[0-9]}]
+    array unset finfo {[aptl]*[0-9]}
     set msg "Unexpected failure (internal error)"
 
     debug-info " Recovered $pths filespecs, $revs revisions"
@@ -1726,7 +1814,7 @@
         set msg "you specified $pths filespec(s) and $revs revision(s)"
         if {$revs <= 2 && $pths == 0} {
             #################################################################
-            #  tkdiff                                 (simply NO input given)
+            #  tkdiff       (inquiry or interactive)  (simply NO input given)
             #                        -OR-
             #  tkdiff -rREV                            ($CWD is)  SCM sandbox
             #  tkdiff -rREV1 -rREV2                   (with 1 or 2 revisions)
@@ -1736,30 +1824,45 @@
             # different; POSSIBLY with no input whatsoever. So detect the SCM
             # first, THEN (if it is one) let *it* try. All other cases lead
             # to error msgs (if revs were given).
-            # Note that DETECTING the SCM is based on the current PROCESS dir
-            switch -- [set Scm [scm-detect "."]] {
+            # Note that DETECTING the SCM was based on the current PROCESS dir
+            # and that 'scmPrefer' used here is DERIVED from the preference
+            if {$g(scmDOsrch)} {
+                set Scm [lindex $g(scmPrefer) $g(scmDOsrch)-1]    ;# VOTE first
+                set Scm [scm-elect $finfo(scm$g(scmDOsrch)) $Scm] ;# then ELECT
+            } else {set Scm "$g(scmPrefer)" } ;# <-- basically, not searchable
+            switch -glob -- "$Scm" {
             GIT {
                 # N.B: An input syntax of '-r ' (or '-r " "') is the Git Index
                 # If (cnt < 2), "msg" will be overwritten with reason why
-                set cnt [inquire-git $revs msg]
+                if {$opts(autoSrch) || $g(scmDOsrch)} {
+                    set cnt [inquire-git $revs msg]
+                } {set msg "You denied access for $Scm to search for files"}
             }
 
             SVN {
-                set cnt [inquire-svn $revs msg]
+                if {$opts(autoSrch) || $g(scmDOsrch)} {
+                    set cnt [inquire-svn $revs msg]
+                } {set msg "You denied access for $Scm to search for files"}
             }
 
             CVS {
-                set cnt [inquire-cvs $revs msg]
+                if {$opts(autoSrch) || $g(scmDOsrch)} {
+                    set cnt [inquire-cvs $revs msg]
+                } {set msg "You denied access for $Scm to search for files"}
+            }
+
+            "* *" {
+                set msg "no searchable SCM was detected/designated\n"
+                if {([lindex $Scm 0] != ""     && [lindex $Scm 1] != "") \
+                &&  ([lindex $Scm 0] != "Auto" || [lindex $Scm 1] != "Auto")} {
+                    append msg "      were your SCM settings '$Scm' at fault ?"
+                }
             }
 
             default {
-              if {$revs} {
                 if {"$Scm" != "" } {
-                  set msg "the $Scm SCM system needs at least 1 filespec given"
-                } else {
-                  set msg "no SCM could be detected for the current directory"
-                }
-              }
+                    set msg "the $Scm SCM system needs at least 1 Fspec given"
+                } { set msg "no SCM was detected for the current directory" }
             }
             }
         } elseif {$revs < 2 && $pths == 1} {
@@ -1783,7 +1886,7 @@
                 if {[get-file-rev "$f" [incr cnt] "$r1"]} {
                     array unset finfo "\[ptl]*,1" ; incr cnt -1
                 } elseif {[get-file "$f" [incr cnt]]} {
-                    array unset finfo "\[ptl]*,[12]"
+                    array unset finfo "\[ptl]*,\[12]"
                 }
             }
 
@@ -1808,7 +1911,7 @@
                 if {[get-file-rev "$f" [incr cnt] "$r1"]} {
                     array unset finfo "\[ptl]*,1" ; incr cnt -1
                 } elseif {[get-file-rev "$f" [incr cnt] "$r2"]} {
-                    array unset finfo "\[ptl]*,[12]"
+                    array unset finfo "\[ptl]*,\[12]"
                 }
             }
 
@@ -1816,7 +1919,7 @@
             #################################################################
             #  tkdiff -rREV1 FILESPEC1          (file in, dir at) SCM sandbox
             #   (+)   -rREV2 FILESPEC2         (same or distinct) SCM sandbox
-            #      (permits comparisons that CROSS a branch/WC boundary)
+            # (permits comparisons that CROSS a branch/WC boundary or SCMs)
             #################################################################
             set f1 $finfo(f,1) ; set r1 "$finfo(rev,1)"
             set f2 $finfo(f,2) ; set r2 "$finfo(rev,2)"
@@ -1858,13 +1961,13 @@
                 if {[get-file-rev "$f1" [incr cnt] "$r1"]} {
                     array unset finfo "\[ptl]*,1" ; incr cnt -1
                 } elseif {[get-file-rev "$f2" [incr cnt] "$r2"]} {
-                    array unset finfo "\[ptl]*,[12]"
+                    array unset finfo "\[ptl]*,\[12]"
                 }
             }
 
         } elseif {$revs == 0 && $pths == 2} {
             ############################################################
-            #  tkdiff FILESPEC1 FILESPEC2     (files, dirs, or BOTH url)
+            #  tkdiff FILESPEC1 FILESPEC2    (dirs, or files and/or url)
             ############################################################
             set f1 $finfo(f,1)
             set f2 $finfo(f,2)
@@ -1894,7 +1997,7 @@
                     set msg "Searched file $f1 non-existant in: $f2"
                 }
             } else {
-                # Otherwise they MIGHT be Subversion URL paths, or local files
+                # Otherwise they MIGHT be Subversion URL paths, or just files
                 if {[regexp {://} $f1]} {
                     if {![get-file-rev "$f1" 1]} {incr cnt}
                 } else {
@@ -1920,27 +2023,29 @@
             do-usage cline
         }
         # Restore PRIOR values to finfo 
-        array unset finfo {[ptl]*[0-9]}
+        array unset finfo {[aptl]*[0-9]}
         array set finfo $priorVals
     } else {
         set finfo(fCurpair) 1
         set finfo(fPairs) [expr {$cnt / 2}]
 
-        # Unlike other files, an Ancestor file can ONLY come from an SCM when
-        # a revision has been given (because DEFAULTING it to the most recent
-        # check-in defeats its purpose)
         if {[set f $finfo(f,0)] != {}} {
-            if {[set r0 $finfo(rev,0)] != ""} {
-                if {[get-file-rev "$f" 0 "$r0"]} {
-                    array unset finfo "\[ptl]*,0"
+            # The USER may only specify a 3way when its a SINGLE comparison
+            # Otherwise we silently erase their attempt
+            if {$cnt == 2} {
+                # Unlike other files, Ancestors can ONLY come from an SCM when
+                # a rev is given (because DEFAULTING it to the most recent
+                # check-in defeats its purpose) (?? but what about 'BASE' ??)
+                if {[set r0 $finfo(rev,0)] != ""} {
+                    if {[get-file-rev "$f" -$finfo(fCurpair) "$r0"]} {
+                        array unset finfo "a\[ptl]*,1"
+                    }
+                } elseif {[get-file "$f" -$finfo(fCurpair)]} {
+                    array unset finfo "a\[ptl]*,1"
                 }
-            } elseif {[get-file "$f" 0]} {
-                array unset finfo "\[ptl]*,0"
-            }
-        }
-    }
-    # Establish if 3way mode is NOW active or not
-    set g(is3way) [info exists finfo(lbl,0)]
+            } else { set finfo(f,0) [set finfo(rev,0) ""] }
+        }
+    }
     return $finfo(fPairs)
 }
 
@@ -1950,6 +2055,9 @@
 proc alignDecor {pairnum} {
     global g w finfo
 
+    # Establish if 3way mode is NOW active and what file ndxs will be used
+    set g(is3way) [info exists finfo(albl,$pairnum)]
+    debug-info "is3way($g(is3way))"
     set  ndx(1) [set ndx(2) [expr {$pairnum * 2}]]
     incr ndx(1) -1
 
@@ -1972,10 +2080,10 @@
     # Add/Remove the Ancestor indicator (and its tooltip) as needed
     if {$g(is3way)} {
         grid $w(AncfLabel) -row 0 -column 1
-        if {![info exists finfo(tmp,0)]} {
-            set    tipdata "{$finfo(pth,0)\n"
-            append tipdata "[clock format [file mtime $finfo(pth,0)]]}"
-        } { set    tipdata "{$finfo(lbl,0)}"}
+        if {![info exists finfo(atmp,$pairnum)]} {
+            set    tipdata "{$finfo(apth,$pairnum)\n"
+            append tipdata "[clock format [file mtime $finfo(apth,$pairnum)]]}"
+        } { set    tipdata "{$finfo(albl,$pairnum)}"}
         set_tooltips $w(AncfLabel) "$tipdata"
     } else {
         set_tooltips $w(AncfLabel) {}
@@ -2158,24 +2266,22 @@
     }
 
     # Expected output form should look like lines of:
-    #           "flgs     filename"
-    # (indices)  0-------78--------->
+    #           "flgs      filename"
+    # (indices)  0-------7 8--------->
     #
     #  where flgs can be:
     #      D    -deleted
     #      A    -added
     #      M    -modified
     #      xM   -(2nd M) properties modified
-    # Do we need to pass an EMPTY file if the flag shows up as 'D' or 'A' ??
-    #   - I think we should ignore them, just as git diff does. They'll cause an
-    #     error otherwise  - dr
-    # Note, svn diff --summarize doesn't report a conflicted file differently, so
-    # we may end up doing a plain diff when we should do a conflict diff
+    # Note, "svn diff --summarize" unfortunately reports a CONFLICTED file
+    # as 'M' as well, so we need to analyze a bit further
+    # (because diffing of the embedded 'markers' would not be very usefull)
 
     set ndx 0
     foreach ln [split $svnOUT "\n"] {
         if {[lindex $ln 0] eq "M"} {
-            string trim [set file [string range $ln 8 end]]
+            set file [string range $ln 8 end]
             foreach i {1 2} {
                 incr ndx
                 if {"" != $rev($i)} {
@@ -2183,7 +2289,7 @@
                         if {$i == 1} {incr ndx -1; break} {incr ndx -2}
                     }
                 } else {
-                    # Just point at the REAL 'working copy' file (allows editting)
+                    # Just point at REAL 'working copy' files (allows editting)
                     set finfo(lbl,$ndx) "$file (SVN--WC)"
                     set finfo(pth,$ndx) $file
                 }
@@ -2229,15 +2335,19 @@
     set cvsOUT [lindex $result 0]
     set cvsERR [lindex $result 1]
     set cvsRC [lindex $result 2]
-    # Slurp up the output file. We need to catch it in case it's empty to undo
-    # run-command writing an error message over it.
+    # cvsRC can be non-zero in many cases,
+    #   for example: if a file doesn't have one of the revs
+    #   Thus it isn't very meaningful or helpfull here; however,
+    #   cvsERR should at least contain "cvs diff: Diffing ." regardless.
+    #   Yet in the empty case, cvsRC is then zero (rather confusing).
+    # Due in part to these issues (and what TCL presumes about errors) we were
+    #   thus forced to place the cmd output into a file, to AVOID Tcl replacing
+    #   it (in cvsOUT) with its OWN error msgs.
+    # SO - rewrite cvsOUT FROM that file so we SEE the case when it's empty,
+    # and we will deduce Success (or not) out of the messaging provided
     set fp [open $outfile r]
     set cvsOUT [read $fp]
     close $fp
-    # cvsRC can be non-zero in many cases, for example if a file doesn't have
-    # one of the revs, so it isn't very meaningful here
-    # cvsERR will at least contain "cvs diff: Diffing ." but in the empty case,
-    # cvsRC is zero
     if {[string match {*Diffing*} $cvsERR] } {
         if {$cvsOUT == ""} {
             set MSG "CVS diff shows NO output using -r $cmit(1)$cmit(2)"
@@ -2260,7 +2370,7 @@
     # retrieving revision 1.5
     # diff --brief -r1.5 Ftrunk.txt
     # Files /var/tmp/cvs3Wrp6F and Ftrunk.txt differ
-    #
+
     # Note, cvs diff --brief doesn't report a conflicted file differently, and
     # cvs update -p will throw an error, unlike svn cat -p
 
@@ -2275,7 +2385,7 @@
                         if {$i == 1} {incr ndx -1; break} {incr ndx -2}
                     }
                 } else {
-                    # Just point at the REAL 'working copy' file (allows editing)
+                    # Just point at REAL 'working copy' files (allows editing)
                     set finfo(lbl,$ndx) "$file (CVS--WC)"
                     set finfo(pth,$ndx) $file
                 }
@@ -2647,8 +2757,10 @@
 
     # Might need this for a 3way diff (see 'alignDecor' for details)
     button $w(AncfLabel) -bd 0 -image ancfImg -command {
-      simpleEd open $finfo(pth,0) title "$finfo(lbl,0) - Ancestor" \
-        ro fg [$w(mergeText) cget -fg] bg [$w(mergeText) cget -bg] }
+        simpleEd open $finfo(apth,$finfo(fCurpair)) ro \
+                           fg [$w(mergeText) cget -fg] \
+                           bg [$w(mergeText) cget -bg] \
+                   title "$finfo(albl,$finfo(fCurpair)) - Ancestor" }
 
     # These hold the text widgets and the scrollbars. The reason
     # for the frame is purely for aesthetics. It just looks
@@ -3985,41 +4097,38 @@
 proc map-move-thumb {y1 y2} {
     global g w
 
-    set thumbheight [expr {($y2 - $y1) * $g(mapheight)}]
-    if {$thumbheight < $g(thumbMinHeight)} {
-        set thumbheight $g(thumbMinHeight)
-    }
-
-    if {![info exists g(mapwidth)]} {
-        set g(mapwidth) 0
-    }
+    # Scale the thumb height (subject to a minumum size big enough to 'grab')
+    set thumbheight [max [expr {($y2-$y1) * $g(mapheight)}] $g(thumbMinHeight)]
+
+    # L/R edge positions (-3 so right edge remains INSIDE our border)
     set x1 1
-    set x2 [expr {$g(mapwidth) - 3}]
-
-    # why -2? it's the thickness of our border...
-    set y1 [expr {int(($y1 * $g(mapheight)) - 2)}]
-    if {$y1 < 0} {
-        set y1 0
-    }
-
+    if {[info exists g(mapwidth)]} {
+        set x2 [expr {$g(mapwidth) - 3}]
+    } {set x2 0}
+
+    # B/T edge positions (-2 so bottom edge remains INSIDE our border)
+    #   but ensure top edge wont exceed the top of the map itself
+    set y1 [max [expr {int(($y1 * $g(mapheight)) - 2)}] 0]
     set y2 [expr {$y1 + $thumbheight}]
     if {$y2 > $g(mapheight)} {
         set y2 $g(mapheight)
         set y1 [expr {$y2 - $thumbheight}]
     }
 
+    # extra offset values for upcomming drawing trick
     set dx1 [expr {$x1 + 1}]
     set dx2 [expr {$x2 - 1}]
     set dy1 [expr {$y1 + 1}]
     set dy2 [expr {$y2 - 1}]
 
+    # Draw two L-shapes (1 light, 1 dark) aligned for a 3d appearance
     $w(mapCanvas) coords thumbUL $x1 $y2 $x1 $y1 $x2 $y1 $dx2 $dy1 $dx1 $dy1 \
       $dx1 $dy2
     $w(mapCanvas) coords thumbLR $dx1 $y2 $x2 $y2 $x2 $dy1 $dx2 $dy1 $dx2 \
       $dy2 $dx1 $dy2
 
+    # Record bounding box (for use in event handler, eg., dragging, etc)
     set g(thumbBbox) [list $x1 $y1 $x2 $y2]
-    set g(thumbHeight) $thumbheight
 }
 
 ###############################################################################
@@ -4246,7 +4355,7 @@
     pack $w(preferences).buttons.save -side right -padx 1 -pady 5
     pack $w(preferences).buttons.apply -side right -padx 1 -pady 5
 
-    # a series of checkbuttons to act as a poor mans notebook tab
+    # a series of radiobuttons to act as a poor mans notebook tab
     frame $w(preferences).notebook -bd 0
     pack $w(preferences).notebook -side top -fill x -pady 4
     set pagelist {}
@@ -4259,7 +4368,7 @@
     } else {
         set indicatoron false
     }
-    foreach page [list General Display Appearance] {
+    foreach page {General Display Appearance} {
         set frame $w(preferences).f$page
         lappend pagelist $frame
         set rb $w(preferences).notebook.f$page
@@ -4286,7 +4395,7 @@
     # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
     set frame $w(preferences).fGeneral
     set row 0
-    foreach key {diffcmd ignoreblanksopt tmpdir editor ignoreRegexLnopt \
+    foreach key {diffcmd ignoreblanksopt tmpdir editor ignoreRegexLnopt
                                                          filetypes geometry } {
         label $frame.l$row -text "$pref($key): " -anchor w
         set tmpopts($key) $opts($key)
@@ -4317,8 +4426,8 @@
     #       an 'x' means an empty column; a '-' means an empty row
     # (Note: each row must be fully filled - even if that means a trailing 'x')
     set col 0
-    foreach key [list ignoreblanks toolbarIcons - ignoreEmptyLn autocenter - \
-            ignoreRegexLn autoselect - syncscroll fancyButtons - predomMrg x] {
+    foreach key { ignoreblanks autocenter - ignoreEmptyLn autoselect -
+            ignoreRegexLn autoSrch syncscroll scmPrefer - predomMrg x} {
 
         if {$key != "x"} {
             if {$key == "-"} {
@@ -4328,7 +4437,23 @@
                 set col 1 ;# forces NEXT column to zero and increments row
             } else {
                 set tmpopts($key) $opts($key)
-                if {"$key" == "predomMrg"} {
+                if {"$key" == "scmPrefer"} {
+                    set f [frame $frame.c${row}$col -bd 0]
+                    pack [label $f.l -text "$pref($key): " -anchor w] -side left
+                    # Hmm, annoying - we need two of these, but want to pretend
+                    # the value is the list of BOTH - this'll take some work
+                    foreach {val} {0 1} {
+                         # Command it to reassemble values when EITHER changes
+                         spinbox $f.s$val -width 7 -repeatinterval 400 \
+                                 -values [list None {*}$g(scmS) Auto] \
+                                 -command "apply {{ndx v} {
+                                  global tmpopts
+                                  lset tmpopts($key) \$ndx \$v
+                                 }} $val %s" -state readonly
+                         eval $f.s$val set [lindex $tmpopts($key) $val]
+                         pack $f.s$val -side top
+                    }
+                } elseif {"$key" == "predomMrg"} {
                     set f [frame $frame.c${row}$col -bd 0]
                     pack [label $f.l -text "$pref($key): " -anchor w] -side left
                     foreach {nam val} {Left 1 Right 2} {
@@ -4376,7 +4501,7 @@
     # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
     set frame $w(preferences).fAppearance
     set row 0
-    foreach key {textopt difftag deltag instag chgtag currtag bytetag \
+    foreach key {textopt difftag deltag instag chgtag currtag bytetag
                                                         inlinetag overlaptag} {
         set tmpopts($key) $opts($key)
         label $frame.l$row -text "$pref($key): " -anchor w
@@ -4461,8 +4586,9 @@
     # (Note: each row must be fully filled - even if that means a trailing 'x')
     set row 0
     set col 0
-    foreach key [list showln tagln - showcbs tagcbs - showmap colorcbs - \
-      tagtext showinline1 x showinline2 - showlineview x ] {
+    foreach key { toolbarIcons fancyButtons - showln tagln - showcbs tagcbs -
+                  showmap colorcbs - tagtext showinline1 x showinline2 -
+                  showlineview x } {
 
         if {$key != "x"} {
             if {$key == "-"} {
@@ -4474,7 +4600,9 @@
                 set tmpopts($key) $opts($key)
                 checkbutton $frame.c${row}${col} -indicatoron true -onvalue 1 \
                         -offvalue 0 -text "$pref($key)" -variable tmpopts($key)
-                grid $frame.c${row}$col -row $row -column $col -sticky w -padx 5
+                if {$key != "fancyButtons" || $g(windowingSystem) != "aqua"} {
+                grid $frame.c${row}$col -sticky w -padx 5 -row $row -column $col
+                }
             }
         }
         if {![set col [expr {$col ? 0 : 1}]]} { incr row }
@@ -4654,6 +4782,7 @@
     set pref(adjcdr)           {CDR region color during adjustment }      ;# A
     set pref(autocenter)      {Automatically center current diff region } ;#G
     set pref(autoselect) {Auto-select nearest diff region when scrolling} ;#G
+    set pref(autoSrch)         {Auto-search detected SCM when capable}    ;#G
     set pref(bytetag)          {Tag options for characters in line view}  ;#  A
     set pref(chgtag)           {Tag options for changed diff region}      ;#  A
     set pref(colorcbs)         {Color change bars to match the diff map}  ;# D
@@ -4662,7 +4791,7 @@
     set pref(diffcmd)          {diff command}                             ;#G
     set pref(difftag)          {Tag options for diff regions}             ;#  A
     set pref(editor)           {Program for editing files}                ;#G
-    set pref(fancyButtons)     {Windows-style toolbar buttons}            ;#G
+    set pref(fancyButtons)     {Windows-style toolbar buttons}            ;# D
     set pref(filetypes)        {Choice of file suffixes for file dialogs} ;#G
     set pref(geometry)         {Text window size}                         ;#G
     set pref(ignoreblanks)     {Ignore blanks when diffing}               ;#G
@@ -4678,6 +4807,7 @@
     set pref(mapolp)           {Map color for collisions}                 ;#  A
     set pref(overlaptag)       {Tag options for overlap diff region}      ;#  A
     set pref(predomMrg)        {Predominate merge choice}                 ;#G
+    set pref(scmPrefer)        {Prefer given SCM when detected}           ;#G
     set pref(showcbs)          {Show change bars}                         ;# D
     set pref(showinline1)      {Show inline diffs (byte comparisons)}     ;# D
     set pref(showinline2) {Show inline diffs (recursive match algorithm)} ;# D
@@ -4690,8 +4820,8 @@
     set pref(tagln)            {Highlight line numbers}                   ;# D
     set pref(tagtext)          {Highlight file contents}                  ;# D
     set pref(textopt)          {Text widget options}                      ;#  A
-    set pref(toolbarIcons) {Use icons instead of labels in the toolbar}   ;#G
     set pref(tmpdir)           {Directory for scratch files}              ;#G
+    set pref(toolbarIcons) {Use icons instead of labels in the toolbar}   ;# D
 }
 
 ###############################################################################
@@ -4836,26 +4966,27 @@
     set OTHER(showinline1) showinline2
     set OTHER(showinline2) showinline1
 
-    # ... next, preloading of the keys needing their OWN precedence order ...
-    #   (content of an '...opt' field that IS [and WILL] remain in use)
-    lappend keys ignoreRegexLnopt ignoreRegexLn ignoreblanksopt ignoreblanks
-    #   (switching among inline algorithms, including to ON or OFF)
+    # ... next, preload any keys needing their OWN precedence order ...
+    #   (Reason: chgd content of an '...opt' field that IS [and WILL] remain
+    #            in use, OR turning the entire category ON/OFF )
+    lappend keys ignoreEmptyLn ignoreRegexLnopt ignoreRegexLn \
+                 ignoreblanksopt ignoreblanks
+
+    #   (Reason: switching among inline algorithms, including to ON or OFF)
     lappend keys showinline1 showinline2
 
-    #   (then everything ELSE - alphabetically [a code reading convenience])
-    lappend  keys adjcdr autocenter autoselect bytetag chgtag \
-                  colorcbs currtag deltag diffcmd difftag editor \
-                  fancyButtons filetypes geometry ignoreEmptyLn \
-                  inlinetag instag mapchg mapdel mapins mapolp \
-                  overlaptag predomMrg showcbs showlineview showln \
-                  showmap syncscroll tabstops tagcbs tagln tagtext  \
-                  textopt tmpdir toolbarIcons
+    #   (followed by EVERY PREF defined - but we only process each ONCE)
+    #   N.B> makes certain we dont MISS any (as has happened before... )
+    lappend keys {*}[array names pref]
+    set ONCE {}
 
     # ... finally, init the flags we need to derive - and then GET TO IT!!
-    set remark 0                   ;# started as: 'remark' will not be run,
+    set remap [set remark 0]       ;# defaulted as: do NOT remap or remark
     set inlActn [set redoDiff {}]  ;#  nor will Diff or 'compute-inlines'
     foreach key $keys {
-        if {"$tmpopts($key)" ne "$opts($key)"} {
+        if {$key in $ONCE} {
+            continue ;# (prevent early items from processing twice - but DO all)
+        } elseif {"$tmpopts($key)" ne "$opts($key)"} {
             # What is transitioning ?
             switch $key {
                 "ignoreEmptyLn" {
@@ -4917,7 +5048,7 @@
                 "mapchg" -
                 "mapdel" -
                 "mapins" - 
-                "mapolp" {if {$g(mapheight) > 0} {set g(mapheight) -1}}
+                "mapolp" {if {$g(mapheight) > 0} {set remap 1}}
 
                 "chgtag"     -
                 "currtag"    -
@@ -4931,6 +5062,7 @@
             }
         }
         set opts($key) $tmpopts($key)
+        lappend ONCE $key
     }
 
     # interpret this binary toggle into its true value
@@ -4957,12 +5089,13 @@
         } elseif {"$inlActn" != ""} {
             eval $inlActn 1 ;# recompute the inlines, but tag ONLY them
         }
+        # chgd map colors (in a map that IS or COULD go visible) ?
+        if {$remap > 0} {map-draw map $g(mapwidth) $g(mapheight)}
     }
 
     # Align, (show or hide) various data (Lnums, Cbars, etc.), and we are done
     reconfigure-toolbar
     do-show-Info
-    if {$g(mapheight) < 0} {map-resize} ;# in case colors changed
     do-show-map
     do-show-lineview
     update idletasks  ;# update all this BEFORE propagate is shut off !!
@@ -5128,9 +5261,9 @@
 }
 
 ###############################################################################
-# Make a miniature map of the diff regions
-###############################################################################
-proc create-map {name mapwidth mapheight} {
+# Draw a miniature map of the diff regions
+###############################################################################
+proc map-draw {name mapwidth mapheight} {
     global g w opts map
 
     set map $name
@@ -5182,29 +5315,36 @@
 ###############################################################################
 proc map-resize {args} {
     global g w opts
-
-    set mapwidth [winfo width $w(map)]
-    set g(mapborder) [expr {[$w(map) cget -borderwidth] + [$w(map) cget \
-      -highlightthickness]}]
-    set mapheight [expr {[winfo height $w(map)] - $g(mapborder) * 2}]
-
-    # We'll get a couple of "resize" events, so DON'T draw a map ...
-    # - unless the map size has changed -OR- 
-    # - we don't have a map and don't want one (so don't make one)
-    if {$mapheight == $g(mapheight) \
-    || ($g(mapheight) == 0 && $opts(showmap) == 0)} {
-        return
-    }
-
-    # This seems to happen on Windows!? _After_ the map is drawn the first time
-    # another event triggers and [winfo height $w(map)] is then 0...
-    if {$mapheight < 1} {
-        return
-    }
-
+    debug-info "map-resize $args"
+
+    # if we don't already have a map and don't want one (don't make one)
+    if {!$g(mapheight) && !$opts(showmap)} {return}
+
+    # Otherwise we need to keep it up-to-date, starting with its height
+    # First account for spacing items surrounding the map
+    set  g(mapborder) [$w(map) cget -borderwidth]
+    incr g(mapborder) [$w(map) cget -highlightthickness]
+
+    # This can be touchy - we are racing against the TK bkgnd task that
+    #   is cfg'ing the vertical scrolling (which calls us - at least twice
+    #   - because of each of the Left/Right scrollbars, which is why we bail
+    #   LATER if the size remains the same). HOWEVER -- that FIRST call
+    #   might not have updated our canvas size yet, causing w(map) to still
+    #   be AT its 1x1 initial size which will FAIL as we try to compute the
+    #   INTERIOR size we can plot within - so bail and wait for the NEXT call
+    #
+    # Normally, just reduce that height by the border elements (top AND bottom)
+    if {[set mapheight [winfo height $w(map)]] < 2} {return}
+    set mapheight [expr {$mapheight - $g(mapborder) * 2}]
+
+    # Finally, if the PRESENT height DID NOT change, then just skip the redraw
+    if {$mapheight == $g(mapheight)} {return}
+
+    # Record values and DRAW it
+    set g(mapwidth) [winfo width $w(map)]
     set g(mapheight) $mapheight
-    set g(mapwidth) $mapwidth
-    create-map map $mapwidth $mapheight
+
+    map-draw map $g(mapwidth) $g(mapheight)
 }
 
 ###############################################################################
@@ -5713,8 +5853,8 @@
                 -message "Did this choice RESOLVE the collision ?" ]}   \
                      { unset g(overlap$hID)
                        set-tag $hID currtag overlaptag
-                       if {$opts(showmap) || $g(mapheight)} \
-                           {set g(mapheight) -1 ; map-resize}
+                       if {$g(mapheight) > 0} \
+                           {map-draw map $g(mapwidth) $g(mapheight)}
                      }
         }]
     }
@@ -5745,7 +5885,7 @@
 
         return [list $s1 $e1 $s2 $e2 $op]
     } else {
-        fatal-error "Cannot parse output from diff:\n$line"
+        fatal-error "Could not parse following output line from diff:\n$line"
     }
 
 }
@@ -6259,6 +6399,7 @@
     # N.B: It is critical that hID-related datums, particularly those that use
     # their EXISTANCE as the basis for internal decision making, be REMOVED
     # when attempting to "start over" to avoid seemingly random errors.
+    # NOTE: finfo is handled specifically by 'assemble-args'
     array unset g {scrInf,[0-9]*}
     array unset g {overlap[0-9]*}
     array unset g {merge[0-9]*}
@@ -6674,7 +6815,7 @@
     if {$g(count)} {merge-add-marks $rmvrpl}
 
     # Lastly, ensure the MAP reflects the CURRENT diffs and go (re-)TAG it all
-    map-resize
+    if {$g(mapheight) > 0} {map-draw map $g(mapwidth) $g(mapheight)}
     remark-diffs
     return $g(count)
 }
@@ -6877,7 +7018,7 @@
     # Read the files into their respective widgets
     # and derive the overall line number magnitude.
     set g(lnumDigits) 0
-    set  i [set j [expr $finfo(fCurpair) * 2]]
+    set  i [set j [expr [set pairnum $finfo(fCurpair)] * 2]]
     incr i -1
     set msg {} ;# Assume this is gonna work ....
     foreach {LR ndx} [list Left $i Right $j] {
@@ -6910,11 +7051,12 @@
         set g(lnumDigits) [max [string length "$lines"] $g(lnumDigits)]
     }
     # Provide feedback on this filepair being successfully accessed (or not)...
-    # then push g(lnumDigits) to reconfig width of Info canvas widgets
+    # decorate all the visuals per this set of files...and then finally push
+    # g(lnumDigits OR is3way) to reconfig width of Info widgets (do-show-Info)
     $w(multiFileMenu) entryconf "$finfo(lbl,$i)" \
         -activebackg [expr {"$msg" != {}  ? {Tomato} : {PaleGreen}}]
-    alignDecor $finfo(fCurpair)
-    cfg-line-info
+    alignDecor $pairnum
+    do-show-Info
 
     # Diff the two files and store the summary lines into 'g(diff)'
     if {$opts(ignoreblanks) == 1} {
@@ -7017,6 +7159,12 @@
     debug-info "DIFF([llength $g(DIFF)]) .vs. diff([llength $g(diff)])"
 
     if {$g(is3way)} {
+        # Make sure we HAVE the ancestorfile (go get it if not)
+        if {![info exists finfo(apth,$pairnum)]} {
+            # if it fails: finfo(apth,$pairnum) will LIKELY be an empty tmpfile
+            if {"" != [set msg [scm-chkget "a$pairnum"]]} {do-error "$msg"}
+        }
+
         foreach {LR NDX} [list Left $i Right $j] {
 
             # 3-way merge - compare file  with ancestor
@@ -7026,7 +7174,7 @@
             if {$opts(ignoreblanks) == 1} {
                  lappend diffcmd $opts(ignoreblanksopt)
             } 
-            append diffcmd " {$finfo(pth,$NDX)} {$finfo(pth,0)}"
+            append diffcmd " {$finfo(pth,$NDX)} {$finfo(apth,$pairnum)}"
 
             show-status "Executing \"$diffcmd\""
             set result [run-command "$diffcmd"]
@@ -7208,18 +7356,8 @@
     wipe-window
     watch-cursor    ;# in case of delay from diff OR a maybe-slow SCM
     update idletasks
-    set result [catch {
-        if {$g(mapheight)} {
-            ## ?? Not sure why THIS needs to be caught ...
-            #   (when 'g(mapheight)' is non-zero, 'map' should exist)
-            catch {$map blank}
-            set g(mapheight) -1 ;# once its ON, keep it updated because
-            # toggling it to show only (un)maps the widget itself
-        }
-
-        rediff
-
-    } output]
+
+    set result [catch { rediff } output]
 
     #debug-info "  rediff result: $result   outptut: $output"
     check-error $result $output
@@ -7324,7 +7462,7 @@
 #   Insufficient pairings results in an "Abort".
 
     if {[commandline] > 0 || [newDiffDialog]} {
-        if {![assemble-args]} {fatal-error "$g(name): Aborted"}
+        if {![assemble-args]} {fatal-error "Insufficeint usable input"}
     } elseif {![info exists ::waitvar] || !$::waitvar} {do-exit}
 
     # The ONLY WAY this exists is if 'assemble-args' was forced
@@ -7424,6 +7562,12 @@
 
     button $w.done -text Dismiss -command "destroy $w"
     pack $w.done -side right -fill none -pady 5 -padx 5
+    # Silly idea - writing the help text out for printing ... maybe TROFF ?
+    #button $w.write -text {} -relief flat -command \
+    "set pth \[tk_getSaveFile -parent $w.f.text -initialdir {.}]
+    #if {\$pth != {}} {puts \[set pth \[open \$pth w]] {<ttl>$title</ttl>\n$text}
+    #close \$pth}"
+    #pack $w.write -side right -fill none
 
     put-text $w.f.title "<ttl>$title</ttl>"
     put-text $w.f.text $text
@@ -7504,21 +7648,26 @@
 
         set simple [frame $w(newDiffPopup).simple -borderwidth 2 -relief groove]
 
-        # N.B> The entry widget naming is constrained by the 'newDiffBrowse'
-        #      callback in regard to the LAST letter of their pathname to
+        # N.B> Widget naming here is constrained by various callbacks...
+        #      eg. 'newDiffBrowse' uses the LAST letter of their pathname to
         #      implement a 'shared directory path' protocol among the TWO main
-        #      entry widgets 'e1' and 'e2'. A trailing NON-digit will AVOID it.
-        # Each revision label must also reflect when its ENTRY is non-null
-        label $simple.l1 -text "FSpec 1:"
-        set w(newDiffPopup,refocus) [entry $simple.e1 -textvariable finfo(f,1)]
+        #      entry widgets 'e1' and 'e2'. Using a NON-digit AVOIDS it.
+        #      Revision labels reflect when their ENTRY is non-null; and SCM
+        #      lists dynamically derive from Entry values, SETs searchability,
+        #      and 'scm-updat' knows WAY to much about almost everything.
+        #      Be Carefull!!
+        label $simple.l1  -text "FSpec 1:"
+        set w(newDiffPopup,FSpec1) \
+        [entry $simple.e1 -textvariable finfo(f,1) -vcmd {scm-updat scm1 %W %P}]
         entry $simple.er1 -textvariable finfo(rev,1) -validate key \
                       -vcmd [list occupancy [label $simple.lr1 -text "-r"] %P]
-        $simple.er1 validate
-
-        label $simple.l2 -text "FSpec 2:"
-        entry $simple.e2 -textvariable finfo(f,2)
+
+        label $simple.l2  -text "FSpec 2:"
+        set w(newDiffPopup,FSpec2) \
+        [entry $simple.e2 -textvariable finfo(f,2) -vcmd {scm-updat scm2 %W %P}]
         entry $simple.er2 -textvariable finfo(rev,2) -validate key \
                       -vcmd [list occupancy [label $simple.lr2 -text "-r"] %P] 
+        $simple.er1 validate
         $simple.er2 validate
 
         label $simple.lA -text "Ancestor:"
@@ -7533,6 +7682,17 @@
           radiobutton $mrgopt.r2 -variable opts(predomMrg) -text Right -value 2
           pack $mrgopt.l4 $mrgopt.r1 $mrgopt.r2 -side left
 
+        # Now create the SCM comboboxes + 'labels' (tying them to the entry box)
+        ::combobox::combobox $simple.scm1 -editable 0 -listvar finfo(scm1) \
+                                            -width 10 -command "scm-updat srch"
+        ::combobox::combobox $simple.scm2 -editable 0 -listvar finfo(scm2) \
+                                            -width 10 -command "scm-updat srch"
+        checkbutton $simple.scm1lbl -offrelief flat -onvalue 1 \
+                                     -command "scm-updat set $simple.scm1lbl 1"
+        checkbutton $simple.scm2lbl -offrelief flat -onvalue 2 \
+                                     -command "scm-updat set $simple.scm2lbl 2"
+        $simple.e1 configure -validate key
+        $simple.e2 configure -validate key
 
         # We need the Browser buttons to fit the COMBINED height of BOTH the
         # filename entry and revision fields, so pre-pack it into a subframe
@@ -7564,38 +7724,43 @@
             set_tooltips $Brws2.bf {"to a file"}
 
         # we'll use the grid geometry manager to get things lined up right...
-        grid $simple.l1 -row 0 -column 0 -sticky e
-        grid $simple.e1 -row 0 -column 1 -columnspan 4 -sticky nsew -pady 4
-        grid $simple.lr1 -row 1 -column 2
-        grid $simple.er1 -row 1 -column 3
-        grid $Brws1 -row 0 -column 5 -rowspan 2 -sticky nsew -padx 4 -pady 4
-
-        grid $simple.l2 -row 2 -column 0 -sticky e
-        grid $simple.e2 -row 2 -column 1 -columnspan 4 -sticky nsew -pady 4
-        grid $simple.lr2 -row 3 -column 2
-        grid $simple.er2 -row 3 -column 3
-        grid $Brws2 -row 2 -column 5 -rowspan 2 -sticky nsew -padx 4 -pady 4
-
-        grid $simple.lA -row 4 -column 0 -sticky e
-        grid $simple.eA -row 4 -column 1 -columnspan 4 -sticky nsew -pady 4
-        grid $simple.lrA -row 5 -column 2
-        grid $simple.erA -row 5 -column 3
-        grid $Brws3 -row 4 -column 5 -rowspan 2 -sticky nsew -padx 4 -pady 4
-
-        grid $simple.f4 -row 6 -column 0 -columnspan 4 -sticky w -pady 4
+        grid $simple.l1                           -sticky e    -row 0 -column 0
+        grid $simple.e1 -columnspan 4 -pady 4     -sticky nsew -row 0 -column 1
+        grid $simple.scm1lbl                      -sticky e    -row 1 -column 0
+        grid $simple.scm1                         -sticky e    -row 1 -column 1
+        grid $simple.lr1       -padx {5 0}                     -row 1 -column 2
+        grid $simple.er1                                       -row 1 -column 3
+        grid $Brws1 -rowspan 2 -padx 4 -pady 4    -sticky nsew -row 0 -column 5
+
+        grid $simple.l2                           -sticky e    -row 2 -column 0
+        grid $simple.e2 -columnspan 4 -pady {8 4} -sticky nsew -row 2 -column 1
+        grid $simple.scm2lbl                      -sticky e    -row 3 -column 0
+        grid $simple.scm2                         -sticky e    -row 3 -column 1
+        grid $simple.lr2       -padx {5 0}                     -row 3 -column 2
+        grid $simple.er2                                       -row 3 -column 3
+        grid $Brws2 -rowspan 2 -padx 4 -pady 4    -sticky nsew -row 2 -column 5
+
+        # N.B> Padding Ancestor label reserves spacing for scm(N)lbl checkboxes
+        grid $simple.lA -padx {12 0}              -sticky e    -row 4 -column 0
+        grid $simple.eA -columnspan 4 -pady {8 4} -sticky nsew -row 4 -column 1
+        grid $simple.lrA                                       -row 5 -column 2
+        grid $simple.erA                                       -row 5 -column 3
+        grid $Brws3 -rowspan 2 -padx 4 -pady 4    -sticky nsew -row 4 -column 5
+
+        grid $simple.f4 -columnspan 4  -pady 4    -sticky w    -row 6 -column 0
 
         grid columnconfigure $simple 1 -weight 1
-        grid columnconfigure $simple 4 -weight 2
+        grid columnconfigure $simple 4 -weight 4
 
         set options [frame $w(newDiffPopup).options -borderwidth 2 \
           -relief groove]
 
         button $options.more -text "More" -command open-more-options
 
+        checkbutton $options.cflct -var g(conflictset) \
+                                             -text "input is Conflict format"
         label $options.ml -text "Merge Output"
         entry $options.me -textvariable g(mergefile)
-        label $options.al -text "Ancestor"
-        entry $options.ae -textvariable finfo(f,0)
         label $options.l1l -text "Label for File 1"
         entry $options.l1e -textvariable finfo(ulbl,1)
         label $options.l2l -text "Label for File 2"
@@ -7607,14 +7772,14 @@
         # here are the buttons for this dialog...
         set commands [frame $w(newDiffPopup).buttons]
 
-        button $commands.ok -text "Ok" -width 5 -default active -command {
-            set waitvar 1
-        }
+        button $commands.ok -text "Ok" -width 5 -default active \
+            -command { if {! [file isfile $finfo(f,1)] && $g(conflictset)} {
+                           set g(conflictset) 0 } ;  set waitvar 1
+                     }
         button $commands.cancel -text "Cancel" -width 5 -default normal \
-          -command {
-            if {! [winfo exists .client]} {do-exit}
-            wm withdraw $w(newDiffPopup); set waitvar 0
-        }
+            -command { if {! [winfo exists .client]} {do-exit}
+                       wm withdraw $w(newDiffPopup); set waitvar 0
+                     }
         pack $commands.ok $commands.cancel -side left -fill none -expand y \
           -pady 4
 
@@ -7642,7 +7807,11 @@
     }
     wm deiconify $w(newDiffPopup)
     raise $w(newDiffPopup)
-    focus $w(newDiffPopup,refocus)
+    set g(scmDOsrch) 0                  ;# Begin from a non-search SCM state
+    set g(scmPrefer) "$opts(scmPrefer)" ;# and w/default SCM preferences
+    focus $w(newDiffPopup,FSpec1)       ;# Focus, then bring it all up-to-date
+    $w(newDiffPopup,FSpec1) validate
+    $w(newDiffPopup,FSpec2) validate
     set detectMrgFilChg $g(mergefile)
     ######
     tkwait variable waitvar        ;# MODAL: wait for user to interact
@@ -7655,34 +7824,143 @@
     return $waitvar
 }
 
+###############################################################################
+# Specialized handler for dynamic SCM state/choice transitions within NewDiff
+#   N.B> (it knows ALOT about the NAMING of the widgets it manipulates)
+###############################################################################
+proc scm-updat {subcmd wdg val {recurs 0}} {
+    global g w opts finfo
+
+    # Create some useful meta-pgming conversions
+    set Other([set Other(2) 1]) 2   ;#  (a simple meta-pgm identity value)
+    if {[string is digit [set ndx [string index $wdg end]]]} {
+        # grab the instance number of widget (if any); then use it
+        # to create meta-addressable names for PAIRED widgets
+        set W($ndx) $wdg              
+        set W($Other($ndx)) [string replace $wdg end end $Other($ndx)]
+    }
+
+    # Overall this implements a 'ripple effect' starting from an 'entrybox'
+    # validation to load a 'combobox' list of detected SCMs (whose value MAY
+    # then be "searchable") to a checkbutton that ASKs for such searching.
+    # Also each widget along the way can initiate its OWN ripple independently
+    switch -glob $subcmd {
+        "scm\[12]" {
+            set finfo($subcmd) [scm-detect $val None]
+            set scmbox [file rootname $wdg].$subcmd ;# matching SCM widget
+            # We WANT the command to fire (to update its srch state)
+            # but only AFTER this callback completes (so we can see result)
+            set vote [lindex $opts(scmPrefer) $ndx-1] ; after idle \
+            $scmbox configure -value "{[scm-elect $finfo($subcmd) $vote]}"
+
+            # We also need to alert the user about USING the 2nd slot widget
+            # when the 1st is still empty -> highlight 2nd widget bkgnd.
+            if {($ndx==2 && "$val" != "" && ![$W(1) index end]) \
+            ||  ($ndx==1 && "$val" == "" &&  [$W(2) index end])} {
+                $W(2) configure -bg Tomato
+            } else {
+                $W(2) configure -bg [$W(1) cget -bg]
+            }
+            return true ;# validation is ALWAYS true - we are monitoring only
+        }
+        "srch" {
+            lset g(scmPrefer) $ndx-1 "$val" ;# Keep working global up-to-date
+            # Cant search when ANY Fspec exists or a non-detected SCM
+            if {[$w(newDiffPopup,FSpec1) index end] \
+            ||  [$w(newDiffPopup,FSpec2) index end]} {
+                set wdg [string range $wdg 0 end-1]
+                foreach lbl "1lbl 2lbl" {
+                    $wdg$lbl configure -text "   SCM :" -indicatoron 0
+                    $wdg$lbl deselect
+                }
+            # Otherwise srch is determined PER CHOSEN SCM for each Fspec
+            } else {
+                if {$val in $g(scmSrch)} {
+                    ${wdg}lbl configure -text  "Search?" -indicatoron 1
+                } else {
+                    # Chosen SCM cant handle searching - remove option
+                    ${wdg}lbl configure -text "   SCM :" -indicatoron 0
+                    ${wdg}lbl deselect
+                }
+                # MAY need to reactivate OTHER side (if Fspecs JUST went empty)
+                #   (N.B> recurs flag prevents nasty endless ping-pong loop)
+                if {!$recurs} { scm-updat srch $W($Other($ndx)) \
+                                              [$W($Other($ndx)) cget -value] 1
+                }
+            }
+        }
+        "set" {
+            # If allowed, USER chooses whether to SEARCH the SCM for candidates
+            if {[$wdg cget -indicatoron]} {
+                # 'val' here is which SIDE was toggled - merge its NEW VALUE
+                # adjusting the other side to establish the radio-like value
+                if {($val & $g(scmDOsrch))} {
+                    incr     g(scmDOsrch) -$val ;# Turn choice OFF
+                } else { set g(scmDOsrch)  $val ;# Turn choice ON ... but
+                    [file rootname $wdg].scm$Other($val)lbl deselect;
+                    # N.B>  Only ONE choice can be ON (but BOTH can be OFF)
+                }
+            # Un-toggle (ie. ignore THIS invocation) if indicator was NOT shown
+            #   (means they clicked on it when it wasn't "armed" to accept)
+            } else  {$wdg deselect}
+        }
+    }
+}
+
+
+###############################################################################
+# Disables the LABEL (wdg) when the ENTRY value (newV) is empty ...
+#   (primarily a GUI feedback trick to discern an EMPTY field from BLANKS)
+#
+# BUT also used to monitor the main PAIR of Rev entry-widgets to warn the user
+# about using #2 w/o using #1 (because 'assemble-args' will IGNORE #2)
+###############################################################################
 proc occupancy {wdg newV} {
-    # Disables the LABEL (wdg) when the ENTRY value (newV) is empty ...
-    #   (simply a GUI feedback trick to discern an EMPTY field from BLANKS)
+
+    # (grab the instance number of widget - doesn't apply when there ISNT one)
+    if {[string is digit [set ndx [string index $wdg end]]]} {
+        set Other([set Other(2) 1]) 2   ;#  (a simple meta-pgm identity value)
+
+        # And then derive meta-addressable names for BOTH entry widgets
+        set W($ndx) [file rootname $wdg][string map {l e} [file ext $wdg]]
+        set W($Other($ndx)) [string replace $W($ndx) end end $Other($ndx)]
+
+        # finally adjusting the bkgnd of #2 if it is USED when #1 is empty
+        if {($ndx==2 && "$newV" != "" && ![$W(1) index end]) \
+        ||  ($ndx==1 && "$newV" == "" &&  [$W(2) index end])} {
+            $W(2) configure -bg Tomato
+        } else {
+            $W(2) configure -bg [$W(1) cget -bg]
+        }
+    }
+
+    # Simple check of the entry value determines STATE of its (provided) label
     if {[string length $newV]} {
         $wdg configure -state normal
     } else {
         $wdg configure -state disabled
     }
-    return true
+    return true ;# validation is ALWAYS true - we are monitoring only
 }
 
 proc open-more-options {} {
     global w
 
-    grid $w(newDiffPopup).options.ml -row 0 -column 1 -sticky e
-    grid $w(newDiffPopup).options.me -row 0 -column 2 -sticky nsew -pady 4
-    grid $w(newDiffPopup).options.l1l -row 1 -column 1 -sticky e
-    grid $w(newDiffPopup).options.l1e -row 1 -column 2 -sticky nsew -pady 4
-    grid $w(newDiffPopup).options.l2l -row 2 -column 1 -sticky e
-    grid $w(newDiffPopup).options.l2e -row 2 -column 2 -sticky nsew -pady 4
-
-    grid columnconfigure $w(newDiffPopup).options 2 -weight 1
-
-    $w(newDiffPopup).options.more configure -text "Less" \
-      -command close-more-options
+    set Woptions $w(newDiffPopup).options
+    grid $Woptions.cflct -row 0 -column 2 -sticky w
+    grid $Woptions.ml    -row 1 -column 1 -sticky e
+    grid $Woptions.me    -row 1 -column 2 -sticky nsew -pady 4 -padx {0 4}
+    grid $Woptions.l1l   -row 2 -column 1 -sticky e
+    grid $Woptions.l1e   -row 2 -column 2 -sticky nsew -pady 4 -padx {0 4}
+    grid $Woptions.l2l   -row 3 -column 1 -sticky e
+    grid $Woptions.l2e   -row 3 -column 2 -sticky nsew -pady 4 -padx {0 4}
+
+    grid columnconfigure $Woptions 2 -weight 1
+
+    $Woptions.more configure -text "Less" -command close-more-options
     set x [winfo width $w(newDiffPopup)]
     set y [winfo height $w(newDiffPopup)]
-    set yi [winfo reqheight $w(newDiffPopup).options]
+    set yi [winfo reqheight $Woptions]
     set newy [expr $y + $yi]
     if {[winfo exists .client]} {
        centerWindow $w(newDiffPopup)
@@ -7694,6 +7972,7 @@
 proc close-more-options {} {
     global g w finfo
 
+    grid remove $w(newDiffPopup).options.cflct
     grid remove $w(newDiffPopup).options.ml
     grid remove $w(newDiffPopup).options.me
     grid remove $w(newDiffPopup).options.l1l
@@ -8090,8 +8369,6 @@
     set g(pos) [min $minpos $g(pos)]
 
     # Remove and Replace the designated HIDs
-    #   (but ensure the MAP is adjusted to the new regions)
-    if {$opts(showmap) || $g(mapheight)} {set g(mapheight) -1}
     mark-diffs $rnge
     update-display
 }
@@ -8739,8 +9016,10 @@
 # Throw up a "command line usage" window.
 ###############################################################################
 proc do-usage {mode} {
-    global g
+    global g pref
     debug-info "do-usage ($mode)"
+
+    customize-initLabels ;# Needed for access to global 'pref' array
 
     set usage {
     $g(name) may be started in any of the following ways:
@@ -8759,7 +9038,7 @@
     Source control (AccuRev, BitKeeper, ClearCase, CVS, Git, Mercurial,\
       Perforce, PVCS, RCS, SCCS, Subversion)
         tkdiff  -rREV1 [-rREV2]  FILESPEC1 [FILESPEC2]
-        tkdiff [-rREV1 [-rREV2]]              (Git or Subversion)
+        tkdiff [-rREV1 [-rREV2]]            (Search: CVS, Git or Subversion)
         tkdiff OLD-URL[@OLDREV] NEW-URL[@NEWREV]  (Subversion)
 
     Additional optional parameters:
@@ -8777,7 +9056,7 @@
 
     set text {
 <hdr>Description</hdr>
-Generally speaking, a diff is a <itl>directed</itl> comparison of two text\
+Classically speaking, a diff is a <itl>directed</itl> comparison of two text\
       files that describes what would need to be changed to convert the first\
       such file content into the second. $g(name) thus groups its parameters\
       as specified into a "Left" and "Right" pairing based on their\
@@ -8786,30 +9065,46 @@
       next would be the "Right". Revision specifications work similarly.
       However, $g(name) occasionally <itl>infers</itl> an argument (be it\
       'filespec' or 'revision') to satisfy the need for two items to compare.\
-      When this occurs, $g(name) will attempt to access a Source Code\
-      Management (SCM: see below) system to provide the missing item, but it\
-      will <itl>ALSO</itl> force that item to be the "Left", or first, element\
-      of the comparison. Beyond that convention, each parameter is indepedent\
-      of others on the commandline. Ultimately, all "Left" args are\
-      collectively used to specify the item(s) to compare to item(s)\
-      collectively formed by "Right" args.
-
-In the first form, $g(name) will generally present a dialog to allow you to\
-      choose the files to diff interactively (providing a detected SCM does\
-      NOT produce a default comparison list). At present this dialog only\
-      supports a diff between files or directories that already exist or can\
-      be obtained by a recognized SCM (see below). Specifically it does not\
-      permit the third form (described shortly), nor "Browsing" to a URL for\
-      either <cmp>FILESPEC</cmp>. However, you may always <itl>type</itl>\
-      anything that makes sense, be it URL, file path, or directory path or\
-      simply "Browse" to <itl>either</itl> files or directories.
-      Please note that <itl>most</itl> of the "Additional Optional parameters"\
+      When this occurs, $g(name) will attempt to access a <bld>S</bld>ource\
+      <bld>C</bld>ode <bld>M</bld>anagement (SCM: see below) system to provide\
+      the missing item, but it will <itl>ALSO</itl> force that item to be the\
+      "Left", or first, element of the comparison. Beyond that convention,\
+      each parameter is indepedent of others on the commandline. Ultimately,\
+      all "Left" args are collectively used to specify the item(s) to compare\
+      to item(s) collectively formed by "Right" args.
+
+In the first form, $g(name) will <itl>almost always</itl> present a dialog to\
+      allow you to choose the files to diff (subject only to a preference\
+      setting '<itl>$pref(autoSrch)</itl>' described on the "Preferences" Help\
+      page).
+      This dialog, known as the <btn>new Diff</btn> dialog, provides an\
+      interactive means of specifying the majority of command line parameters.\
+      However, note that while the command line uses repetition to distinguish\
+      "Left" and "Right" parameter instances, the dialog expects such values\
+      to be <itl>filled</itl> in a similar "Left first" order; as a reminder,\
+      entering a value (such as a <cmp>FILESPEC</cmp> or <cmp>REV</cmp>) into\
+      the "second position" while the "first" remains <itl>empty</itl> will\
+      result in a red warning highlight of the mis-positioned value.
+      Another distinction of the dialog is its presentation and adjustability\
+      of the SCM that will be used <itl>if and when</itl> the command syntax\
+      requires one. Where the command line operates purely by preference\
+      settings, the dialog allows you to adjust the final interpretation\
+      within the bounds of all <itl>presently entered</itl> parameters, which\
+      is to say the dialog will continually readjust as values are enterred\
+      or removed. One of the clear advantages of the dialog is the ability\
+      to "Browse" to files or directories, although typing is still valid.
+      In contrast to the preference-controlled 'automatic' search mode of the
+      command line, requesting that mode via the dialog is handled via a\
+      checkbox, that will present when conditions indicate it is possible.
+      Please note that <itl>most</itl> of the "Additional optional parameters"\
       <itl>are available</itl> from the dialog, but are initially hidden from\
       view, as they are often not applicable except in special cases. If you\
       need to set them, <bld>do not</bld> re-"hide" them before clicking the\
       <btn>OK</btn> button on the dialog as hiding them <itl>ALSO</itl> causes\
-      them ALL to become completely <bld>unset</bld>. Any items not provided\
-      on that dialog ('Ignore...' settings) are presented elsewhere in $g(name).
+      them ALL to become completely <bld>unset</bld>. Lastly, those items not\
+      provided for within the dialog ('Ignore...' settings, etc.), or really\
+      <itl>ANY</itl> of the "Additional optional parameters" listed may still\
+      be provided on the command line without forfeit of invoking the dialog.
 
 In the second form, either or both <cmp>FILESPEC</cmp>s may be to a local file\
       or directory, or symbolic links to such. When a directory is involved,\
@@ -8821,17 +9116,21 @@
 In the third form, a single <cmp>FILE</cmp> containing "conflict markers" will\
       be split into two temporary files and used as ordinary input by $g(name).\
       Such files can be generated by external tools such as "<cmp>merge</cmp>",\
-      "<cmp>cvs</cmp>", or "<cmp>vmrg</cmp>" and perhaps others.
+      "<cmp>cvs</cmp>", or "<cmp>vmrg</cmp>" and perhaps others. Note that the\
+      '<bld>-conflict</bld>' flag is also available on the dialog (via the\
+      hidden grouping), but the corresponding <cmp>FILESPEC1</cmp>\
+      <itl>must</itl> then also <bld>be</bld> an actual <cmp>FILE</cmp>, or\
+      the setting will be ignored.
 
 The fourth form is conditional on $g(name) being able to detect a viable SCM\
       system (see below). However, make note that if it <itl>DOES</itl>, it\
-      <bld>may</bld> effectively override the first form described earlier\
-      (i.e. interactive startup). Presently only the "Git" or "Subversion" SCM\
-      systems will behave this way, when invoked with no arguments as is\
-      suggested here as syntactically possible.
+      <bld>may</bld> effectively override the first form as described earlier\
+      (i.e. interactive startup). Presently only "CVS", "Git" or "Subversion"\
+      SCM systems will behave this way, when invoked with no arguments as is\
+      suggested here in this form as syntactically possible.
 
 <hdr>Source Code Control</hdr>
-In all the SCM forms, $g(name) will detect which SCM system to utilize. This\
+In all the SCM forms, $g(name) will detect which SCM system are possible. This\
       detection supports RCS, CVS and SCCS by looking for a directory\
       with the same name, although RCS can also be detected via its ",v" file\
       naming suffix convention. It detects and supports PVCS by looking for a\
@@ -8841,15 +9140,18 @@
       directory, but will only work when started from within a Git work-tree.\
       Similarly, Subversion looks for a .svn directory, except when using\
       URLs, expecting any <cmp>FILESPEC</cmp> to reside within a recognized\
-      "Working Copy" (WC). Mercurial is supported by looking for a directory\
-      named ".hg" in the <cmp>FILESPEC</cmp> directory or any of its ancestor\
-      directories, which is also how .git and .svn are searched.
+      "<bld>W</bld>orking <bld>C</bld>opy" (WC). Mercurial is supported by\
+      looking for a directory named ".hg" in the <cmp>FILESPEC</cmp> directory\
+      or any of its ancestor directories, which is also how .git and .svn\
+      are searched.
       It is important to recognize that several detections are based on the\
-      provided FILESPEC(s), or alternately the "current working directory"\
-      where $g(name) was invoked, and at times, BOTH. Often this can\
-      necessitate invoking $g(name) from <itl>within</itl> the "Sandbox" (a\
-      synonym for "WC") which are the actual files and directories that the\
-      specific SCM is actively tracking.
+      provided FILESPEC(s), or alternately the "<bld>C</bld>urrent\
+      <bld>W</bld>orking <bld>D</bld>irectory" (CWD) where $g(name) was\
+      invoked, and at times, BOTH. Often this can necessitate invoking\
+      $g(name) from <itl>within</itl> the "Sandbox" (a synonym for "WC")\
+      which are the actual files and directories that the specific SCM is\
+      actively tracking. This implicit use of the CWD is often instrumental in\
+      making a given SCM interaction not only detectable, but functional.
 
 <cmp>REV1</cmp> and <cmp>REV2</cmp>, when given, must be a valid revision value\
       for <cmp>FILESPEC</cmp>. When the SCM system (RCS, CVS, etc.) is detected\
@@ -8859,7 +9161,7 @@
       a directory; where each would then use the same revision.
 
 Revision values are generally peculiar to a specific SCM. For example, a Git <cmp>REV</cmp>\
-(see man git-rev-parse) offers several unusual variations:
+(see manpage for  git-rev-parse) offers several unusual variations:
      <cmp>FILE</cmp>                 [compare with <cmp>HEAD</cmp> by default]
   -r <cmp>HEAD</cmp> <cmp>FILE</cmp>        [compare with <cmp>HEAD</cmp>]
   -r <cmp>HEAD^</cmp> <cmp>FILE</cmp>      [compare with parent of <cmp>HEAD</cmp>]
@@ -8869,20 +9171,36 @@
   -r v1.2.3 <cmp>FILE</cmp>      [compare with tag (UNTESTED)]
 $g(name) does not, itself, do anything with the value other than pass it along.
 
-Lastly, some SCM systems provide utilities that can identify which of their\
-      files are <itl>different</itl> given <itl>only</itl> a pair of revisions.\
-      $g(name), using its capacity for accepting multiple pairings, will\
-      attempt to access the utilities it knows about to obtain such as an\
-      input source. SCM systems lacking this ability will simply reject the\
-      existing command arguments as inadequate with an error message.
+Because there are potentially two <cmp>FILESPEC</cmp>s there can also be two\
+      distinct SCM systems. Although most people will only ever need to\
+      deal with one SCM system for a given situation, there <itl>IS</itl>\
+      an unusual arrangement possible that has a distinct advantage.
+      For example, presume you use Subversion, or any other network-based\
+      repository, but will be unable to assure a viable network connection\
+      for some stretch of time. One solution would be to create a RCS\
+      subdirectory and post local modifications to it (avoiding the network)\
+      until such time as you can once again contact the server, at which point\
+      you can reinstate whichever RCS version you wish to send to Subversion\
+      using $g(name) to confirm exactly which changes you want current.
+      Even with just a single SCM system, you may have multiple WCs,\
+      representing perhaps different branches of the same code, and wish to\
+      fabricate a merged file as a hybrid of the two versions. $g(name) can\
+      address BOTH simultaneously, thus allowing the hybrid to be constructed.
+
+Additionally, some SCM systems provide abilities that can identify which of\
+      their files are <itl>different</itl> given <itl>only</itl> some set of\
+      desired revisions (including defaulted). $g(name), using its capacity\
+      for accepting multiple pairings, will attempt to access the utilities\
+      it knows about to obtain such as an input source. SCM systems lacking\
+      this ability will simply reject the existing command arguments as\
+      inadequate with an error message.
       Note that given the <bld>lack</bld> of a <cmp>FILESPEC</cmp> in this\
-      instance, such SCM utilities basically expect the\
-      "current working directory" (of, in this case, $g(name)) to <bld>be</bld>\
-      the same as where they place the "working copies" of the files they\
-      manage. Thus the directory where you invoke $g(name) plays a role, but\
+      instance, such SCM utilities basically expect the CWD (of, in this case,\
+      $g(name)) to <bld>be</bld> within the "WC" of the files they manage.\
+      Thus the directory where you invoke $g(name) again plays a role, but\
       was likely instrumental in getting that SCM to be detected in the first\
       place, so should not be an issue.
-      Accordingly, if only <itl>fewer</itl> than two revisions are given\
+      Accordingly, if <itl>fewer</itl> than two revisions are given\
       <bld>and</bld> the SCM can accomodate it, inferred revisions will be\
       supplied (generally the latest or HEAD, or similar). However, note that\
       the <bld>Git</bld> SCM has an unusual arrangement in that an intermediate\
@@ -8890,9 +9208,9 @@
       the working copy and the last commit; $g(name) will allow you to specify\
       this quasi-revision using a revision value of " " (blanks) either on the\
       commandline or in the GUI dialog. Remember that on the commandline this\
-      will require quoting (to be parsed correctly). For the GUI, the field\
-      label for the revision will be dimmed when it is EMPTY, as it would\
-      otherwise be difficult to actually SEE a legally enterred blank.
+      will require quoting (to be parsed correctly). For the dialog, the field\
+      <bld>label</bld> for the revision will be dimmed when it is EMPTY, as it\
+      would otherwise be difficult to actually SEE a legally enterred blank.
 
 <hdr>A quick word about quoting</hdr>
 Most command environments, a Unix/Linux Shell for example, offer multiple\
@@ -8902,7 +9220,7 @@
       prefixed to that value, or separated by "white space" (blanks, tabs,\
       etc.). However you must <itl>not</itl> try to <bld>pack</bld> multiple\
       $g(name) flags into a single parameter as they will not be recognized\
-      by $g(name), and would thus likely be passed directly to "diff" or\
+      by $g(name), and would thus likely be passed directly to "Diff" or\
       whatever other differencing engine has been configured, as is.\
       See the section "The Diff engine" below for further specific rules.
 
@@ -8946,7 +9264,7 @@
       indeterminate file pairing. Thus $g(name) then reverts to "suggesting"\
       its own name. Of course, you may <itl>at that point</itl> then choose\
       whatever filename you wish.
-      In a similar fashion, many of the "Additional Optional parameters"\
+      In a similar fashion, many of the "Additional optional parameters"\
       shown are intended for use when $g(name) is invoked to process a\
       <itl>SINGLE</itl> file pair, as was its original historical heritage. 
 
@@ -9007,7 +9325,8 @@
       its input/output and invocation requirements cannot be used. Because of\
       this, $g(name) can be configured to interoperate with other differencing\
       engines, some having perhaps more advanced (or desireable) detection\
-      methods.
+      methods. The primary requirement for such engines is it must produce what\
+      GNU Diff calls "<bld>normal</bld>" diff output format (NOT "Unified").
       Accordingly, any option flag having a leading dash that is <itl>not</itl>\
       recognized as a $g(name) option is passed <itl>almost untouched</itl>\
       to your Diff engine of choice. This permits you to temporarily alter the\
@@ -9032,29 +9351,31 @@
       can illustrate the issues involved. Thus if something similar\
       <itl>WERE</itl> to be passed to tell Diff (in this example) to not\
       consider any line that starts with a octathorp (#) followed by a space,\
-      you might specify this to $g(name) as <itl>either</itl> :
-      "--ignore-matching-lines=^#  "   (or even "-I^#  ")
+      you might think to specify this to $g(name) as <itl>either</itl> :
+      "--ignore-matching-lines=^#  "   (or better "-I^#  ")
 or
       <bld>"</bld>-I  <bld>\"</bld>^#  <bld>\" "</bld>    (or "-I  {^#  }")
 Note in each case, the quoting of BOTH the flag and its value\
       <itl>together</itl>. But particularly, in the second form, note the extra\
       quoting (done with escaped double quotes or "brace" characters as shown)\
-      surrounding the value as well; be aware that <itl>single quotes will NOT\
-      work</itl> here. A "brace" character is simply the lexical mechanism used\
-      by the internals of $g(name) to quote its contained content. Without this\
-      'extra' quoting as shown, $g(name) <itl>would pass</itl> the option, but\
-      the resulting Diff would <itl>MISS</itl> the trailing blank of the RE.
+      surrounding the value as well; this demonstrates how to pass an flag that
+      MUST be separated from the value it passes. Be aware that <itl>single\
+      quotes will NOT work</itl> here. The "brace" character is simply the\
+      lexical mechanism used by the internals of $g(name) to quote its content\
+      where potential "substitutions" are to be avoided. Without this 'extra'\
+      quoting as shown, $g(name) <itl>would pass</itl> the option, but the\
+      resulting Diff would <itl>MISS</itl> the trailing blank of the value.
       The reason is primarily that $g(name) <itl>has no understanding</itl> of\
       any flags being passed to the engine, nor if they might legitimately\
       require a value, or need said value to be separated from its flag while\
       still <itl>preserving</itl> any embedded blanks.
-      IMPORTANT NOTE - from a $g(name) perspective, this particular GNU Diff\
+      IMPORTANT NOTE - from a $g(name) perspective, this specific GNU Diff\
       option should <bld>never</bld> be passed to <bld>ANY</bld> diff engine\
       ... it was designed to make the <itl>direct output of Diff itself</itl>\
       more meaningful to a <itl>human</itl> by simply suppressing what is,\
-      in reality, actual differences. $g(name) <itl>will fail badly</itl> if\
-      you were to sneak the option to Diff (using its long-form flag name).\
-      You have been warned.
+      in reality, actual differences. $g(name) <bld>will fail badly</bld> if\
+      you were to perhaps <itl>sneak</itl> the option to Diff (using its\
+      long-form flag name). You have been warned.
     }
 
     if {$mode == "cline"} {
@@ -9087,7 +9408,7 @@
       and its modification time when hoverring over it with the mouse,\
       <itl>provided</itl> it is not a tempfile (such as extracted from an SCM).
       In addition, if an ANCESTORFILE was specified at startup, a third label\
-      (a graphic denoting a text file labelled  "A") will appear between the\
+      (a graphic denoting a text file labelled "A") will appear between the\
       other two labels. It also will display a tooltip indicating its name,\
       and <itl>possibly</itl> its modification time, the latter based on the\
       file <itl>not</itl> having been extracted from an SCM. But in reality\
@@ -9285,7 +9606,6 @@
       windows. You can also set <btn>Auto Center</btn> in\
       <btn>Preferences</btn> (or via the <btn>View</btn> menu) to do this\
       automatically for you as you navigate through the diff records.
-
 
 <hdr>Keyboard Navigation</hdr>
 
@@ -9614,9 +9934,10 @@
       <itl>first</itl> clicking on it (to remove the selection highlight) and\
       then using the keyboard to traverse about the entry (arrows, backspace,\
       retyping) until satisfied, whereupon pressing [Return] will\
-      <bld>add</bld> the new value. Note that shifting the current focus\
+      <bld>add</bld> it <itl>as a new value</itl> (<itl>not</itl> as an edit\
+      to the previous entry). Note that shifting the current focus\
       <itl>away</itl> via a mouse click elsewhere, or pressing [Tab], also\
-      counts as a [Return].
+      counts as a [Return], confirming your edit completion.
       If instead you simply start typing first, either AFTER a declined\
       deletion, or from the initial empty display state, you will simply\
       <bld>add</bld> whatever is typed.
@@ -9657,10 +9978,12 @@
       \"<btn>Recompute Diff</btn>\" which <bld>WILL DISCARD</bld> any\
       mergefile activity not yet completed.
 
-<bld>$pref(toolbarIcons)</bld>
-
-If <bld>set</bld>, the toolbar buttons will use icons instead of text labels.
-If <bld>unset</bld>, the toolbar buttons will use text labels instead of icons.
+<bld>$pref(autocenter)</bld>
+
+If <bld>set</bld>, whenever a new diff record becomes the current diff record (for\
+      example, when pressing the next or previous buttons), the diff record\
+      will be automatically centered on the screen.
+If <bld>unset</bld>, no automatic centering will occur.
 
 <bld>$pref(ignoreEmptyLn)</bld>
 
@@ -9675,13 +9998,16 @@
       <bld>set</bld> <itl>or</itl> <bld>unset</bld>), it will trigger an\
       immediate \"<btn>Recompute Diff</btn>\" which <bld>WILL DISCARD</bld>\
       any mergefile activity not yet completed.
-
-<bld>$pref(autocenter)</bld>
-
-If <bld>set</bld>, whenever a new diff record becomes the current diff record (for\
-      example, when pressing the next or previous buttons), the diff record\
-      will be automatically centered on the screen.
-If <bld>unset</bld>, no automatic centering will occur.
+Also note that when you choose to ignore empty lines, you are implicitly\
+      saying that those affected lines <itl>will be retained</itl> in any\
+      merged output <bld>exactly</bld> as they appear in the "Left" version.
+
+<bld>$pref(autoselect)</bld>
+
+If <bld>set</bld>, automatically select the nearest visible diff region when\
+      scrolling.
+If <bld>unset</bld>, the current diff region will not change during scrolling.
+This only takes effect if "<itl>$pref(syncscroll)</itl>" is <bld>set</bld>.
 
 <bld>$pref(ignoreRegexLn)</bld>
 
@@ -9698,13 +10024,26 @@
       mergefile activity not yet completed.
 Conversely, if you <bld>set</bld> this, but the list of REs is empty at the\
       time of the "Apply", this setting will simply revert to <bld>unset</bld>.
-
-<bld>$pref(autoselect)</bld>
-
-If <bld>set</bld>, automatically select the nearest visible diff region when\
-      scrolling.
-If <bld>unset</bld>, the current diff region will not change during scrolling.
-This only takes effect if "<itl>$pref(syncscroll)</itl>" is <bld>set</bld>.
+Again, note that when you choose to ignore matched lines, you are implicitly\
+      saying that those affected lines <itl>will be retained</itl> in any\
+      merged output <bld>exactly</bld> as they appear in the "Left" version.
+
+<bld>$pref(autoSrch)</bld>
+
+When <bld>set</bld>, $g(name) will automatically initiate, at any tool startup\
+     that does <itl>NOT</itl> provide a <cmp>FILESPEC</cmp>, an attempt to\
+     query a detected, preferred and capable SCM for files that it claims have\
+     differences. While this capability is always available at startup when at\
+     least <itl>one</itl> <cmp>REV</cmp> is provided, this setting\
+     <bld>overrides</bld> the normal behavior of $g(name) to produce the\
+     <btn>New Diff</btn> dialog, when <itl>zero</itl> arguments are provided.
+     Note that for most capable SCMs to be detected in this fashion, the\
+     <bld>C</bld>urrent <bld>W</bld>orking <bld>D</bld>irectory for $g(name)\
+     needs to be inside the actual "Working Copy" (WC) set of files the\
+     particular SCM controls.
+     When the choice is <bld>unset</bld>, normal dialog behavior is restored.\
+     This setting is mostly a convenience for users that find themselves\
+     actively persuing merge resolutions on a day-to-day basis.
 
 <bld>$pref(syncscroll)</bld>
 
@@ -9715,13 +10054,27 @@
       contents, in that changes of the CDR will "jump" scroll, but direct\
       interactive scrolling will not (explained in the "<bld>On GUI</bld>" help.
 
-<bld>$pref(fancyButtons)</bld>
-
-If <bld>set</bld>, toolbar buttons will mimic the visual behavior of typical\
-      Microsoft Windows applications. Buttons will initially be flat until the\
-      cursor moves over them, at which time they will be raised.
-If <bld>unset</bld>, toolbar buttons will always appear raised.
-This feature is not supported in MacOSX.
+<bld>$pref(scmPrefer)</bld>
+
+This setting is actually a pair of values, describing which SCM you prefer to\
+      utilize for EACH of the two possible sides of the comparison. Initially\
+      both values default to "Auto" which produces the classical $g(name)\
+      behavior of the "first-detected" SCM possible (based on an internal\
+      precedence list of known SCM systems). By choosing a <itl>specific</itl>\
+      SCM system, you are effectively <itl>overriding</itl> that internal list\
+      <bld>provided</bld> the chosen value is <itl>still detectable</itl>.\
+      If not, then the behavior reverts to the classical norm whenever that\
+      <itl>side</itl> requires the use of an SCM.
+      There is also a possible value of 'None', if you believe that\
+      <itl>NO</itl> SCM should be involved for that side, but be aware that\
+      such a setting may interfere with the ability to query an otherwise\
+      capable SCM from providing candidates to be compared. $g(name) will try\
+      to inform you should this seem to occur, although there are other\
+      reasons, besides this, for that possibility. Note however, that because\
+      of subtle differences between the two ways of starting the tool: the\
+      command line or the dialog; 'None' is generally <itl>ignored</itl> for\
+      command line uses, while it behaves as a preferred value on the dialog
+      <itl>until</itl> the dialog is actually accepted.
 
 <bld>$pref(predomMrg)</bld>
 
@@ -9741,9 +10094,22 @@
 
 <hdr>Display</hdr>
 
+<bld>$pref(toolbarIcons)</bld>
+
+If <bld>set</bld>, the toolbar buttons will use icons instead of text labels.
+If <bld>unset</bld>, the toolbar buttons will use text labels instead of icons.
+
+<bld>$pref(fancyButtons)</bld>
+
+If <bld>set</bld>, toolbar buttons will mimic the visual behavior of typical\
+      Microsoft Windows applications. Buttons will initially be flat until the\
+      cursor moves over them, at which time they will be raised.
+If <bld>unset</bld>, toolbar buttons will always appear raised.
+This feature is not supported in MacOSX.
+
 <bld>$pref(showln)</bld>
 
-If <bld>set</bld>, line numbers will be displayed alongside each line of each file.
+If <bld>set</bld>, line numbers are displayed alongside each line of each file.
 If <bld>unset</bld>, no line numbers will appear.
 
 <bld>$pref(tagln)</bld>
@@ -9754,49 +10120,55 @@
 
 <bld>$pref(showcbs)</bld>
 
-If <bld>set</bld>, change bars will be displayed alongside each line of each file.
+If <bld>set</bld>, change bars are displayed alongside each line of each file.
 If <bld>unset</bld>, no change bars will appear.
 
 <bld>$pref(tagcbs)</bld>
 
-If <bld>set</bld>, change indicators will be highlighted. If <itl>$pref(colorcbs)</itl>\
-      is set they will appear as solid colored bars that match the colors\
-      used in the diff map. If <itl>$pref(colorcbs)</itl>\
-      is <bld>unset</bld>, the change indicators will be highlighted according to the\
-      options defined in the Appearance section of the preferences.
+If <bld>set</bld>, change indicators will be highlighted. If \
+      <itl>$pref(colorcbs)</itl> is set they will appear as solid colored bars\
+      that match the colors used in the diff map. If <itl>$pref(colorcbs)</itl>\
+      is <bld>unset</bld>, the change indicators will be highlighted according\
+      to the options defined in the Appearance section of the preferences.
 
 <bld>$pref(showmap)</bld>
 
-If <bld>set</bld>, a colorized, graphical "diff map" will be displayed between the two\
-      files, showing regions that have changed. Red is used to show deleted\
-      lines, green for added lines, blue for changed\
+If <bld>set</bld>, a colorized, graphical "diff map" will be displayed between\
+      the two files, showing regions that have changed. Red is used to show\
+      deleted lines, green for added lines, blue for changed\
       lines, and yellow for overlapping lines during a 3-way merge.
 If <bld>unset</bld>, the diff map will not be shown.
 
-<bld>$pref(showlineview)</bld>
-
-If <bld>set</bld>, show a window at the bottom of the display that shows the current\
-      line from each file, one on top of the other. This window is most\
-      useful to do a byte-by-byte comparison of a line that has\
-      changed.
-If <bld>unset</bld>, the window will not be shown.
+<bld>$pref(colorcbs)</bld>
+
+If <bld>set</bld>, the change bars will display as solid bars of color that\
+      match the colors used by the diff map.
+If <bld>unset</bld>, the change bars will display a "+" for lines that exist\
+      in only one file, a "-" for lines that are missing from only one file,\
+      and "!" for lines that are different between the two files.
+
+<bld>$pref(tagtext)</bld>
+
+If <bld>set</bld>, the file contents will be highlighted with the options\
+       defined in the Appearance section of the preferences.
+If <bld>unset</bld>, the file contents won\'t be highlighted.
 
 <bld>$pref(showinline1)</bld>
 
-If <bld>set</bld>, show inline diffs in the main window. This is useful to see what the\
-      actual diffs are within a large diff region.\
-If <bld>unset</bld>, the inline diffs are neither computed nor shown.  This is the\
-      simpler approach, where byte-by-byte comparisons\
+If <bld>set</bld>, show inline diffs in the main window. This is useful to\
+      see what the actual diffs are within a large diff region.
+If <bld>unset</bld>, the inline diffs are neither computed nor shown. This\
+      is the simpler approach, where byte-by-byte comparisons\
       are used.  However, this inline diff <itl>never</itl> honors\
       any \"<itl>$pref(ignoreblanksopt)</itl>\" value, regardless of that\
       option being enabled.
 
 <bld>$pref(showinline2)</bld>
 
-If <bld>set</bld>, show inline diffs in the main window. This is useful to see what the\
-      actual diffs are within a large diff region.\
-If <bld>unset</bld>, the inline diffs are neither computed nor shown.  This approach\
-      is more complex, but should give more pleasing\
+If <bld>set</bld>, show inline diffs in the main window. This is useful to see\
+      what the actual diffs are within a large diff region.
+If <bld>unset</bld>, the inline diffs are neither computed nor shown. This\
+      approach is more complex, but should give more pleasing\
       results for source code and written text files.  This is the\
       Ratcliff/Obershelp pattern matching algorithm which recursively\
       finds the largest common substring, and recursively repeats on the left\
@@ -9804,19 +10176,17 @@
       any \"<itl>$pref(ignoreblanksopt)</itl>\" value, regardless of that\
       option being enabled.
 
-<bld>$pref(tagtext)</bld>
-
-If <bld>set</bld>, the file contents will be highlighted with the options defined in the\
-       Appearance section of the preferences.
-If <bld>unset</bld>, the file contents won\'t be highlighted.
-
-<bld>$pref(colorcbs)</bld>
-
-If <bld>set</bld>, the change bars will display as solid bars of color that match the\
-      colors used by the diff map.
-If <bld>unset</bld>, the change bars will display a "+" for lines that exist in only\
-      one file, a "-" for lines that are missing from only one file, and\
-      "!" for lines that are different between the two files.
+<bld>$pref(showlineview)</bld>
+
+If <bld>set</bld>, show a window at the bottom of the display that shows the\
+      current line from each file, one on top of the other. Clicking on any\
+      specific line in either text window selects which line will be displayed.\
+      This window is most useful to do a byte-by-byte comparison of a line that\
+      has changed; by default, mismatched bytes are marked with underlines,\
+      but other possibilities include configuring with a "constant width" font\
+      (via <itl>$pref(bytetag)</itl>) such as "Courier" to easily spot the\
+      differences.
+If <bld>unset</bld>, the window will not be shown.
 
 <hdr>Appearance</hdr>
 
@@ -9928,7 +10298,7 @@
      via a text editor. Still, occasionally there have been customizations of\
      the GUI that many users found helpful that are often difficult (if not\
      impossible) to specify correctly using other means. Although there are\
-     fewer at the moment (per the newer 'color' buttons described above), we
+     fewer at the moment (per the newer 'color' buttons described above), we\
      offer up the following (still valid) possibilit(y/ies) as suggestions:
 
     1. Highlighting the current Merge Choice (when in Icon mode) -
@@ -10146,7 +10516,7 @@
                   -underline 1 -command [list simpleEd save $filename $w]
                 $w.menubar.fileMenu add command -label "Save As..." \
                   -underline 1 -command [list simpleEd saveAs $filename $w]
-            $w.menubar.fileMenu add separator
+                $w.menubar.fileMenu add separator
             }
             $w.menubar.fileMenu add command -label "Exit" -underline 1 \
               -command [list simpleEd exit $w]
@@ -10158,10 +10528,10 @@
 
                 $w.menubar.editMenu add command -label "Cut" -command \
                   [list event  generate $w.text <<Cut>>]
-            $w.menubar.editMenu add command -label "Copy" -command \
-              [list event generate $w.text <<Copy>>]
-            $w.menubar.editMenu add command -label "Paste" -command \
-              [list event generate $w.text <<Paste>>]
+                $w.menubar.editMenu add command -label "Copy" -command \
+                  [list event generate $w.text <<Copy>>]
+                $w.menubar.editMenu add command -label "Paste" -command \
+                  [list event generate $w.text <<Paste>>]
             }
 
             text $w.text -wrap none -xscrollcommand [list $w.hsb set] \
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.