Compare Files



  • I find that I often need to compare the contents of two files. If the two files are open in Notepad++, I have to save them both, then compare them using BeyondCompare. This is a bit time consuming and tedious. Is it possible to compare them within Notepad++? Ideal would be a feature to compare the contents of two windows, and also to compare the contents of one window with the contents of the original file on disk, i.e. to see all the changes one has made since opening the file.

    It would need good facilities for highlighting the lines that differ between the two files, the characters that are different between the two lines, ignoring whitespace changes and/or changes within comments. Beyond Compare is pretty good in most of these respects.

    Is anything like this currently possible?

    If not, please can it be put on the wish list?

    Thanks - Rowan



  • See compare plugin https://github.com/pnedev/compare-plugin, available also via PluginManager.



  • There’s a compare plugin that you can install. The easiest way to install it is with the plugin manager, which unfortunately doesn’t come with a new NPP installation anymore. I’ve pointed out a couple of places where you can find instructions to install the plugin manger here. The search capabilities on this site can be a bit flaky so if you want to search the board you might want to use google. In the google search box you can type “plugin manager site:notepad-plus-plus.org” and that will get you started.

    Once you get the plugin manager going, you can find the “compare” plugin and install it. Use the same google method to find some threads on the compare plugin if you need some pointers on that plugin.

    Here’s an alternative to the compare plugin. I find I often don’t want to compare a whole file, just sections of code. So I wrote a python script that automates the whole “saving to a file and opening in your compare tool” business. You have to have two views open and something selected in each view. When you fire the script it will grab both selections and write them to pre-defined file names and paths. Then it will fire off your chosen compare tool and feed the tool the two file names. This code suffers from the same malady as all my personal scripts in that as soon as it worked well enough the first time, I closed it and never cleaned it up, so YMMV and zero guarantees. :) You’ll need the python script plugin and this needs to be placed in the python script directory and run from the plugin menu.

    # coding: iso-8859-1
    #import difflib
    #help(difflib)
    def writefile(fn, txt):
    	fh = open(fn, 'wb')
    	fh.write(txt)
    	fh.close()
    
    tmpDir = "C:/temp/mycompare/"
    winmerge = "C:/Program Files/TortoiseSVN/bin/TortoiseMerge.exe, c:/temp/mycompare/topView.txt, c:/temp/mycompare/bottomView.txt"
    viewA =  notepad.getCurrentView()
    #console.write(str(viewA))
    selectedA = editor.getSelText()
    filenameA = notepad.getCurrentFilename()
    #console.write(selectedA)
    viewIndexA = notepad.getCurrentDocIndex(viewA)
    #console.write("\r\n"+str(viewIndexA))
    
    
    
    viewB = 1 - viewA
    #console.write(str(viewB))
    
    viewIndexB = notepad.getCurrentDocIndex(viewB)
    #console.write("\r\nviewIndexB"+str(viewIndexB))
    
    if viewIndexB > 100:
    	notepad.messageBox('Open two views and select some text', 'Notepad++', 0)
    else:
    	notepad.activateIndex(viewB,viewIndexB) 
    	selectedB = editor.getSelText()
    	#console.write(selectedB)
    	filenameB = notepad.getCurrentFilename()
    
    	if len(selectedA) > 0 and len(selectedB) > 0:
    		#console.write('\r\n'+filenameA)
    		if viewA == 0:
    			fullNameA = tmpDir+'topView.txt'
    			fullNameB = tmpDir+'bottomView.txt'
    		else:
    			fullNameB = tmpDir+'topView.txt'
    			fullNameA = tmpDir+'bottomView.txt'
    		writefile(fullNameA, selectedA)
    		writefile(fullNameB, selectedB)
    		console.run("C:/Program Files/TortoiseSVN/bin/TortoiseMerge.exe c:/temp/mycompare/topView.txt c:/temp/mycompare/bottomView.txt")
    
    	else:
    		notepad.messageBox('select something from each view', 'Notepad++', 0)
    

    Hope this helps, good luck.



  • @Rowan-Sylvester-Bradley and others:

    I see that someone else has offered up some Pythonscript for doing external compares (i.e., without the Notepad++ Compare plugin). It’s a good idea and I have a similar script. Since mine directly uses Beyond Compare and the original-poster also seems to be a user of that, I’ll offer up my script as well, as something that could be used by the OP without the need for modification. Hopefully I don’t get picked-on for answering a question that has already been answered–and yes, Claudia, this means you. :^D

    With this script it is best to save 2 files intended for compare first and to have no selection active when you set the files for compare. This way you can use the compare program to actually make edits that affect the original files (and then reload them when prompted when returning to N++; assumes File Status Auto-Detection enabled). Otherwise you can do compares of selections but it will act on temporary files only–still valuable.

    So here’s the workflow:

    • Be in the editor tab for the file you want to be the “left side” of the compare
    • Either have a selection active, or not, as you intend; remember, an active selection will cause only that selection’s text to be used in the compare
    • Run the script
    • Activate the second file or make a text selection in the desired file
    • Run the script again
    • It will prompt you to do the compare (by answering “Yes” to this prompt) or set a new “left side” of the current file/selection (by answering “No”)

    You can compare a file that has been modified to its saved-on-disk version as follows:

    • Be in the editor tab for the file
    • Have no selection active
    • Run the script (which will set “left side” as the on-disk file)
    • Press ctrl+a to select the entire document (we want the “right side of the compare” to be the modified contents of the file)
    • Run the script again and answer “Yes” to the prompt (the compare runs with the saved changes on the left and the unsaved changes on the right)

    I call the script BeyondCompareFilesOrSelections.py and here it is; fairly short:

    import os
    import tempfile
    import subprocess
    import time
    
    try:
        BCFOS__left_side
    except NameError:
        BCFOS__left_side = None
    
    def BCFOS__main():
    
        global BCFOS__left_side
    
        compare_prog_path = r'C:\Program Files\Beyond Compare 4\BCompare.exe'
    
        if BCFOS__left_side != None:
    
            file_or_sel = 'FILE' if editor.getSelectionEmpty() else 'SELECTION'
    
            if notepad.messageBox('A "LEFT side" is already buffered; use the current {} as the "RIGHT side" of the compare?'.format(file_or_sel) +
                    '\r\n' * 4 +
                    'Answering YES will compare current {} with the buffered "left side"'.format(file_or_sel) +
                    '\r\n' * 2 +
                    'Answering NO will make the current {} the new "left side"'.format(file_or_sel), '', MESSAGEBOXFLAGS.YESNO) == MESSAGEBOXFLAGS.RESULTNO:
                BCFOS__left_side = None
    
        side = 'Left' if BCFOS__left_side == None else 'Right'
    
        cfn = original_cfn = notepad.getCurrentFilename()
    
        if cfn.startswith('new ') or not editor.getSelectionEmpty():
    
            ext = 'txt'  # default; get real extension from file if we have one:
            if os.sep in cfn:
                _ = cfn.rsplit(os.sep, 1)
                if '.' in _[1]: ext = _[1].rsplit('.', 1)[1]
    
            # put current time in temporary filename so can have multiple compare windows open (without filename collision possibility)
            ymd_hms = time.strftime("%Y%m%d-%H%M%S", time.localtime())
            cfn = tempfile.gettempdir() + os.sep + 'Compare{left_or_right}Side_{time}.{e}'.format(left_or_right=side, time=ymd_hms, e=ext)
            with open(cfn, 'w') as f:
                f.write('originating file: ' + original_cfn.rsplit(os.sep, 1)[-1] + '\n')
                f.write('originating path: ' + original_cfn + '\n\n')
                f.write(editor.getText() if editor.getSelectionEmpty() else editor.getSelText())
    
        if side == 'Left':
    
            BCFOS__left_side = cfn
    
            notepad.messageBox('"LEFT side" set for later compare...', '')
    
        else:
    
            # spawn BeyondCompare to do the compare:
            subprocess.Popen([compare_prog_path, BCFOS__left_side, cfn])
    
            BCFOS__left_side = None
    
    BCFOS__main()
    


  • @Scott-Sumner

    :-D

    Cheers
    Claudia


Log in to reply