Index: vc/patch.py
===================================================================
--- vc/patch.py	(revision 0)
+++ vc/patch.py	(revision 0)
@@ -0,0 +1,74 @@
+### Copyright (C) 2009 Vincent Legoll <vincent.legoll@gmail.com>
+
+### Redistribution and use in source and binary forms, with or without
+### modification, are permitted provided that the following conditions
+### are met:
+### 
+### 1. Redistributions of source code must retain the above copyright
+###    notice, this list of conditions and the following disclaimer.
+### 2. Redistributions in binary form must reproduce the above copyright
+###    notice, this list of conditions and the following disclaimer in the
+###    documentation and/or other materials provided with the distribution.
+
+### THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+### IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+### OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+### IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+### INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+### NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+### DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+### THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+### (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+### THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import os
+import _vc
+
+# TODO: add support for showing diff without having original files (c.f. kompare)
+
+class Vc(_vc.Vc):
+
+    CMD = "patch"
+    NAME = "Patch Viewer"
+    PATCH_INDEX_RE = "^---[ \t]+(\S+)[ \t]+.*$"
+    VC_ROOT_WALK = False
+
+    def is_repo_root(self, location):
+        # This plugin is only for patch files
+        if os.path.isdir(location) or not self._is_patch(location):
+            raise ValueError()
+        root = os.path.dirname(location)
+        if not self._is_applicable(location, root):
+            # TODO: here implement GUI source dir chooser
+            raise ValueError()
+        self.location = location
+        return root
+
+    def get_working_directory(self, workdir):
+        return self.root
+
+    def diff_command(self):
+        return ["cat", os.path.join(self.root, self.location)]
+
+    # Check that all files listed in patch are available
+    def _is_applicable(self, location, directory):
+        for f in self._patch_files(location):
+            if not os.path.isfile(f):
+                return False
+        return True
+
+    # Is the given patch parseable ?
+    def _is_patch(self, location):
+        if len(self._patch_files(location)) > 0:
+            return True
+        return False
+
+    def _patch_files(self, location):
+        #TODO: memoize
+        return self.get_patch_files(open(location).read())
+
+    def lookup_files(self, dirs, files):
+        retfiles = []
+        for f in self._patch_files(self.location):
+            retfiles.append(_vc.File(os.path.join(self.root, f), os.path.basename(f), _vc.STATE_MODIFIED, "", "", ""))
+        return [], retfiles
Index: meldapp.py
===================================================================
--- meldapp.py	(revision 1347)
+++ meldapp.py	(working copy)
@@ -946,7 +946,14 @@
         if len(paths) == 1:
             a = paths[0]
             if os.path.isfile(a):
-                self._single_file_open(a)
+                import vc.patch
+                try:
+                    vc.patch.Vc(a)
+                    tab = self.append_vcview([a], auto_compare)
+                except ValueError:
+                    if a.endswith('.patch') or a.endswith('.diff'):
+                        self.usage(_("Patch format is not recognized."))
+                    self._single_file_open(a)
             else:
                 tab = self.append_vcview([a], auto_compare)
                     
