"Smart" front end for Beyond Compare

I freely confess to having made almost no attempt to make this code highly portable. It is really intended as an example for others to modify to suit and hopefully improve. In particular, the way I decide what to compare under what circumstances may well be different to the logic others would instinctively choose.

In some of my other test scripts I use a global variable to switch debugging on/off but I overlooked that when I knocked this script up and was too idle to go back and change it afterwards.

Regards, AB

Its a good example, I used it as a start to some stuff I did.
In this script you use this to get the debug value objCmd.IsSet("$glob:debug");.

So if you wanted to enable debugging do you have a button to change the value in the global variable?
This seems like a good pattern.

Yes. I use a button to toggle the global variable.

Regards, AB

Did you manage to get the button to highlight when debug is enabled/disabled?
Could you post the button?

I use a lister scoped variable rather than a global variable. The button..

@ifset:$lst:dbg
@set lst:dbg
Set UTILITY=Off
@ifset:else
@set lst:dbg=true
Set UTILITY=OtherLog,On

In my VBScript, I test the variable like this..

dbg = cdf.Command.IsSet("$lst:dbg")

I don't have to worry about changing the button icon because I switch the UTILITY panel on or off in synch with the setting of dgb.

Regards, AB

Thanks mate, good thought to add the utility.
Cheers

Thanks for pointing this out. I have modified my VBScript version to deal with libraries.

@language vbscript

option explicit

' "Smart" front end to Beyond Compare
' (Re)Written by AussieBoykie in VBScript because it is more familiar to the author! 8-)
' Handles very long paths as best possible
' Logic for what is actually compared is articulated in comments in the code. See below..

Function OnClick(ByRef ClickData)

   Dim dbg
   Dim cdf
   Dim fsu
   Dim sPath
   Dim sPathIsLib
   Dim dPath
   Dim dPathIsLib
   Dim nodest
   Dim src
   Dim tgt
   Dim l
   Dim r
   Dim n
   Dim pair
   Dim cd
   Dim BCBeta
   Dim BCVer
   Dim BCCmd
   Dim BCArgs
   Dim cmdstring

   Const lib = "lib://"
   Const vbQuote = """"
   'Const dbg = TRUE ' Switch to FALSE to disable or TRUE to enable debug output
   
   Set cdf = ClickData.func
   dbg = cdf.Command.IsSet("$lst:dbg")
   Set fsu = DOpus.FSUtil

   ' Test the global variable BCBeta to decide whether to use Beyond Compare 3 (stable) or 4 (beta)
   ' Edit the BCCmd = statement below to reflect the correct path to the BC executable on your system   
   BCBeta = cdf.Command.IsSet("$glob:BCBeta")
   if BCBeta then BCVer = 4 else BCVer = 3
   BCCmd = "/homeroot\utilities\bc" & BCVer & "\bcompare.exe"
   if dbg then DOpus.Output "BCCmd: " & BCCmd

   Set src = cdf.sourcetab
   sPath = src.path
   sPathIsLib = lcase(Left(sPath,6)) = lib
   if sPathIsLib then sPath = fsu.Resolve(sPath)
   nodest = cdf.desttab = 0
   if dbg then DOpus.Output "nodest: " & nodest
   if nodest then
      Set tgt = src
      dPath = sPath
   else
      Set tgt = cdf.desttab
      dPath = tgt.path
      dPathIsLib = lcase(Left(dPath,6)) = lib
      if dPathIsLib then dPath = fsu.Resolve(dPath)
   end if
   n = 1
   if len(dPath) > len(sPath) and not dPathIsLib then
      cd = dPath
      if not right(dPath,1)="\" then n = 2
   elseif not sPathIsLib then
      cd = sPath
      if not right(sPath,1)="\" then n = 2
   else
      cd = ""
      n=0
   end if

   if dbg then DOpus.Output "Sourcetab: " & sPathIsLib & " - " & sPath
   if dbg then DOpus.Output "Desttab: " & dPathIsLib & " - " & dPath

   ' The final BC command string is of the form <some path>\bcompare.exe <spec1> <spec2>
   ' The combined length of <spec1> and <spec2> can cause problems if one or other or both is very long
   ' In an attempt to avoid problems we will change directory before executing the BC command
   ' The target directory will be either <spec1> or <spec2>, whichever is longest
   ' The target name can then be specified without its path - e.g. some.txt instead of C:\SomeLongPath\some.txt
   pair = false
   if src.selected_files.count = 2 then
      if sPathIsLib then
         l = fsu.Resolve(src.selected_files(0))
         r = fsu.Resolve(src.selected_files(1))
      else
         l = mid(src.selected_files(0),len(sPath)+n)
         r = mid(src.selected_files(1),len(sPath)+n)
      end if
      pair = true
      if dbg then DOpus.Output "Left File: " & l
      if dbg then DOpus.Output "Right File: " & r
   elseif src.selected_dirs.count = 2 then
      if sPathIsLib then
         l = fsu.Resolve(src.selected_dirs(0))
         r = fsu.Resolve(src.selected_dirs(1))
      else
         l = mid(src.selected_dirs(0),len(sPath)+n)
         r = mid(src.selected_dirs(1),len(sPath)+n)
      end if
      pair = true
      if dbg then DOpus.Output "Left Folder: " & l
      if dbg then DOpus.Output "Right Folder: " & r
   end if

   ' If SOURCE and DEST are the same then...
   ' If exactly two files are selected (whether or not folders are also selected)
   ' or exactly two folders are selected (whether or not files are also selected)
   ' then execute a compare, otherwise just bring up the Beyond Compare main menu
   if sPath = dPath then ' Source only
      if pair then
         BCArgs = vbQuote & l & vbQuote & " " & vbQuote & r & vbQuote
      else
         BCArgs = ""
      end if
      
   ' If SOURCE and DEST are different then...
   ' If exactly one SOURCE file and one DEST file are selected (whether or not folders are also selected)
   ' or exactly one SOURCE folder and one DEST folder are selected (whether or not files are also selected)
   ' then execute a compare, otherwise...
   ' if a pair of files or a pair of folders is selected in SOURCE then execute a compare, otherwise
   ' compare SOURCE and DEST folders
   else
      if src.selected_files.count = 1 and tgt.selected_files.count = 1 then
         if cd = sPath then
            l = mid(src.selected_files(0),len(sPath)+n)
            r = fsu.Resolve(tgt.selected_files(0))
	 elseif cd = dPath then
            l = fsu.Resolve(src.selected_files(0))
            r = mid(tgt.selected_files(0),len(dPath)+n)
	 else
            l = fsu.Resolve(src.selected_files(0))
            r = fsu.Resolve(tgt.selected_files(0))
	 end if
	 BCArgs = vbQuote & l & vbQuote & " " & vbQuote & r & vbQuote
      elseif src.selected_dirs.count = 1 and tgt.selected_dirs.count = 1 then
         if cd = sPath then
            l = mid(src.selected_dirs(0),len(sPath)+n)
            r = fsu.Resolve(tgt.selected_dirs(0))
	 elseif cd = dPath then
            l = fsu.Resolve(src.selected_dirs(0))
            r = mid(tgt.selected_dirs(0),len(dPath)+n)
	 else
            l = fsu.Resolve(src.selected_dirs(0))
            r = fsu.Resolve(tgt.selected_dirs(0))
	 end if
         BCArgs = vbQuote & l & vbQuote & " " & vbQuote & r & vbQuote
      elseif pair then
         BCArgs = vbQuote & l & vbQuote & " " & vbQuote & r & vbQuote
      else
         l = sPath
	 r = dPath
         BCArgs = vbQuote & l & vbQuote & " " & vbQuote & r & vbQuote
      end if
   end if

   if lcase(l) = lib then
      if dbg then DOpus.Output "l = " & l & " : r = " & StripPath(r)
      eMsg "Unable to compare " & l & " with " & StripPath(r)
   elseif lcase(r) = lib then
      if dbg then DOpus.Output "r = " & r & " : l = " & StripPath(l)
      eMsg "Unable to compare " & StripPath(l) & " with " & r
   else
      cmdstring = vbQuote & BCCmd & vbQuote & " " & BCArgs
      if dbg then DOpus.Output cmdstring
      With cdf.Command
         .deselect = FALSE
         if not cd = "" then .addline "cd " & spath
         .addline cmdstring
         .run
      End With
   end if

End Function

Sub eMsg(msg)
   
   ' Display a supplied error message
   
   Dim objDlg
   Dim result
   
   Set objDlg = Dopus.Dlg
   With objDlg
      .title = "Fatal Error"
      .buttons = "Quit"
      .message = msg
      result = .show
   End With
   
End Sub

Function StripPath(filespec)
   Dim s
   Dim n
   s = StrReverse(filespec)
   n = InStr(1,s,"\")
   if n > 0 then
      StripPath = StrReverse(Left(s,n-1))
   else
      StripPath = filespec
   end if
End Function

Regards, AB

I have the executable of my Beyond Compare 3 in E:\BACKUP\New backup\Program\Beyond Compare 3\BCompare.exe. How should I edit the BCCmd according to my mentioned path?

Just change it to...

BCCmd = "E:\BACKUP\New backup\Program\Beyond Compare 3\BCompare.exe"

Regards, AB

Ya, I have already changed the BCCmd = statement below the "if BCBeta then BCVer = 4 else BCVer = 3" to "BCCmd = "E:\BACKUP\New backup\Program\Beyond Compare 3\BCompare" but I can only compare two items in a same pane. I thought this script can be used to compare items in different pane as well but if I do that, it will only open the Beyond Compare's Home. That is why I am asking. Could you confirm if this is a normal behavior or there is a missing step that I did?

As I recall it should work in a DUAL pane as follows:

If 2 files are selected in SOURCE pane, compare them.
If 2 folders are selected in SOURCE pane, compare them.
If 1 file is selected in SOURCE and 1 file in DEST then compare them.
If 1 folder is selected in SOURCE and 1 folder in DEST then compare them.
Otherwise compare SOURCE and DEST folders.

And if there is no DUAL pane:

If 2 files are selected in SOURCE pane, compare them.
If 2 folders are selected in SOURCE pane, compare them.
Otherwise open Beyond Compare main menu

I am in the process of testing a simpler and more efficient V2 which I expect to post later today.

Regards, AB

Version 2 is attached as a ZIP. To install, extract Beyond Compare.vbs from the zip and copy this file into the /dopusdata\Script AddIns folder. You should then edit the script (via Preferences may be easiest) to point to the correct location of BCompare.exe on your system.




Once the VBS is installed, use the $BC command to execute Beyond Compare. The "smart" compare logic is as described in the previous post above.

Regards, AB
Beyond Compare.zip (1.6 KB)

Hi AB, as you have converted this in to a script package, you could leverage the script configuration, this would mean that users don't need to edit the script to set the path.
In the init you would add something like this

  initData.config.BCPath= "C:\\Utilities\\BC3\\BCompare.exe";

Also, I think its worth updating your first post so people will find the latest version easily.

Thanks wowbagger. Until you pointed it out I had not picked up on the ability to manage user supplied configuration variables. This is a neat way of doing things. I will post updated code and instructions shortly and link from the original post.

Regards, AB

Yep it is very handy indeed. As the user wont need to edit the script you can rename the zip to ops, then they wont need to extract the vb file after downloading. Also if you use an ops file you can include icons with the script. This is nice because it means that you can provide a sample button with an icon without pulling that icon from the bcompare exe.

I have done up a sample, adding the bcompare icons to the zip you provided.
Beyond Compare.osp (6.92 KB)

Version 2.1 is attached as an Opus Script Package. To install, copy the OSP file into the /dopusdata\Script AddIns folder. You should then configure the script via Preferences to point to the correct location of BCompare.exe on your system. Once installed you simply execute the $BC command to execute Beyond Compare. The "smart" compare logic is as described in an earlier post in this thread.

Note that the OSP includes Beyond Compare icons (once again, thanks to wowbagger) which can be used on any button you create to execute $BC.


Change log..

' v2 = simpler, cleaner rewrite
' v2.1 add user configurable path to BCompare.exe via Preferences dialog
' (thanks to wowbagger for the suggestion)
' use fsu.resolve consistently to fully resolve paths

Regards, AB

BeyondCompareV21.osp (7.02 KB)

Hi mate thanks for the update, its working well :slight_smile:.

Couple of comments, you can set the default icon for you method using this

cmd.icon = "BeyondCompare:BeyondCompare";

You can specify a proper script version this way.

initData.name = "Smart Beyond Compare" initData.version= "2.1";

Thanks for two more good suggestions wowbagger. Both are implemented in v2.2 (attached).


To install, copy the OSP file into the /dopusdata\Script AddIns folder (and delete any earlier versions). You should configure the script via Preferences to point to the correct location of BCompare.exe on your system. Once installed you simply run the $BC command to execute Beyond Compare. The "smart" compare logic is as described in an earlier post in this thread.

Regards, AB

Beyond Compare.osp (6.33 KB)

Very awesome mate :slight_smile:

Did you mean to change the small icon to 16x16? The default buttons use 22x22 for small and 32x32 for large.