Make Kaleidoscope ignore trailing whitespace and differing line endings when comparing from Coda

Make Kaleidoscope ignore trailing whitespace and differing line endings when comparing from Coda

Are you a developer who uses Coda, with SVN or GIT, and Kaleidoscope?  Kaleidoscope is one of the best tools for comparing files, something that developers need to do often, especially when used with a versioning server like Subversion or GIT.  However, one glaring problem with Kaleidoscope is it’s inability (and the developer’s refusal to add the ability) to ignore whitespace when doing comparisons!

Why is ignoring whitespace important?

  • When using open source products, updates will often either strip or add whitespace to files, making it impossible to use Kaleidoscope to track down what changed when you make a comparison
  • Working in teams – if a team member strips all whitespace from a file, but also makes other changes, and then commits to the repo… well, again, you can’t use Kaleidoscope to track down those changes easily.  I encountered this recently when working on a site in which multiple freelancers are working as a team.  One of the other developers used an editor which strips whitespace by default when saving every file, which meant that every single file compare involving any of his commits was a problem with Kaleidoscope…. I actually switched to using another file compare tool because of it.
  • Whitespace means nothing to the interpreter.  The functionality of the program doesn’t depend on spacing, it doesn’t affect the outcome, so it isn’t considered a true “change” of the code like other changes.

 

To understand the hassle that we developers face when using Kaleidoscope in regards to whitespace, look at the following image.  The CSS file in this example had one number changed, a margin – changing from 1em to 2em – but it also had whitespace added at the end of each line.  Notice that the whole file is basically “lit up” with changes, which means that you would still have to go line by line comparing changes to find what was “actually” changed:

kal-before

Kaleidoscope app, when comparing from Coda, showing the problem with whitespace

 

So, what can be done?

Well, the first thing to do is to head over to Twitter at @kaleidoscopeapp and gripe about it.  It’s ridiculous that a file comparison tool, in 2013, can’t ignore whitespace… simply ridiculous.  Secondly, we have created a short script that may help you in your endeavors.  Its not perfect, we know that.  But, it will help you when using Coda and comparing files from the repo using Kaleidoscope.  It will allow you to ignore trailing whitespace and ignore differences in line endings!  Yep, you heard me right, it will allow you to use Kaleidoscope and ignore the whitespace.  Yippeee!

Here is how it works.  First, Kaleidoscope integrates with Coda via a command line script.  Inside of Kaleidoscope, you go to the “Kaleidoscope” menu at the top, then click on Integration., from there you install the “command line tool” which is a app called ksdiff – which goes into the /usr/local/bin directory.  Coda calls upon opendiff in order to compare files, so to make Kaleidoscope work you have to rename the opendiff app in /usr/bin (let’s say to opendiff.apple) and then create a symbolic link from opendiff to ksdiff, like this: ln -s /usr/local/bin/ksdiff /usr/bin/opendiff.  This causes Kaleidoscope to be called whenever opendiff is requested, and therefore work with Coda.

So, in order to fix our whitespace issue we are going to replace the opendiff script with one that works some “magic” on the files before they are compared.  Unfortunately we can’t make it use the original files, because that would actually change the source of your code, so we create some temporary files to accomplish this.  In order to be able to easily tell which file is from the repo and which is local, we name our temp files with a prefix of either repo-local:: or local-file::, that way you can easily tell which file is which.

In order to install the script, you must run terminal and then do the following (note that the dollar sign is the command line prompt, you don’t type that in):

$ sudo sh                 note: it will ask for your password on this step
$ cd /usr/bin
$ mv opendiff opendiff.old
$ nano opendiff

The above basically moved the old opendiff app to opendiff.old, for backup purposes, that way you can put it back in the future if you desire.  Nano is a text editor, if nano doesn’t work you can use vi.  At this point you want to COPY the script below and PASTE it into your terminal window into the nano editor.

Here is script:

#!/bin/sh

# Make sure our tmp directory exists
mkdir /tmp/kal 2>1 > /dev/null

# See which is the cached file and which is local - the following has
# weird quoting in order to overcome paths that have spaces in them
fileone=`echo |awk '{print match("'"$1"'","/Caches/Coda")}'`
filetwo=`echo |awk '{print match("'"$2"'","/Caches/Coda")}'`

if [ $fileone -gt 0 ];then
    fileonename=repo-cache::`basename "$1"`
    cp -f "$1" /tmp/kal/$fileonename
else
    fileonename=local-file::`basename "$1"`
    cp -f "$1" /tmp/kal/$fileonename
fi

if [ $filetwo -gt 0 ];then
    filetwoname=repo-cache::`basename "$2"`
    cp -f "$2" /tmp/kal/$filetwoname
else
    filetwoname=local-file::`basename "$2"`
    cp -f "$2" /tmp/kal/$filetwoname
fi

# Now strip trailing space from the files and blank out lines
# that contain only tabs
perl -lpi -e 's/\s*$//' "/tmp/kal/$fileonename"
perl -lpi -e 's/\s*$//' "/tmp/kal/$filetwoname"

# Now standardize our line endings
perl -pi -e 's/\r\n|\n|\r/\n/g' "/tmp/kal/$fileonename"
perl -pi -e 's/\r\n|\n|\r/\n/g' "/tmp/kal/$filetwoname"

# Call Kaleidoscope - add the wait option so that the script doesn't finish
# until Kaleidoscope is closed, that way we can delete/clean up our 
# temporary files automatically
/usr/local/bin/ksdiff --wait /tmp/kal/$fileonename /tmp/kal/$filetwoname

# Now remove our two temporary files
rm -f /tmp/kal/$fileonename /tmp/kal/$filetwoname

After you have pasted the above script into the editor, press Control+X on your keyboard to exit the nano editor.  It will ask if you want to save the changes, hit the Y key to save.  That should bring you back to the command line, you have a few more steps before we are finished.  We need to make sure the script is executable, and then we need to exit out of terminal:

$ chmod 755 opendiff
$ exit
$ exit

That’s it!  If all worked successfully, you should have created a new opendiff script, made it executable and then exited out of the terminal.  If the terminal didn’t fully close, just hit CMD+Q or choose “Quit Terminal” from the top menu.

Now, when you choose to compare your file from within Coda – I usually do this from the SCM sidebar – the comparison should work just like before, but now without any highlighted trailing space or different line endings.  The below image is of a file comparison of the same exact file as the first image above (compared, made the first image, installed the above script, compared and made the second image), but as you can see the only text highlighted is the actual change that was made:

Kaleidoscope app, when comparing from Coda - using the same file as the top image, but using our script. Notice that the whitespace highlighting is gone!

Kaleidoscope app, when comparing from Coda – using the same file as the top image,
but using our script. Notice that the whitespace highlighting is gone!

 

A Few Things

Some of you may be wondering why we have Kaleidoscope to wait before finishing our script, this is so that we can automatically clean up the temp files.  After you exit Kaleidoscope, the script continues executing and deletes the temporary files so that they aren’t hanging around out there.

Also, you may wondering why we don’t use wildcards on the perl commands that are run against the files.  We could use a wildcard against everything in our temp directory, because only our compares should be in there.  But, if you are making multiple comparisons (different files) and you keep those open on your screen, if you use a wildcard to do the conversion of the file, it will cause each of your comparison windows to refresh.  This would happen every time you do a comparison.  So by naming the files specifically, it keeps everything really “clean”.

Lastly, the first question we may be asked about is “can you ignore whitespace at the beginning of a line”.  Well, yes, we could.  However, because we are having to manipulate the files into temp files to accomplish our task – and the function isn’t built into Kaleidoscope – the only way to ignore whitespace at the beginning of a line is to remove all beginning whitespace.  Well, you can imagine what that will make your code look like.  That may be more confusing and troubling than the highlighted spacing differences.  That being said, if you want to do such a thing, let us know and we’ll send you the script.

 

Questions?

We hope it works as well for you as it has for us!  If you have questions, just ask.  If you spot a better technique to accomplish what we are trying to do here, share it!  Also, if you like what we have done here, click “Like” and/or let us know in the comments!