[meld] Make VC commands, output and errors visually distinct (bgo#698496)



commit edffb0bd94c0ce5f2a1f45d63166508c086a4fb4
Author: Kai Willadsen <kai willadsen gmail com>
Date:   Sat Apr 27 13:47:54 2013 +1000

    Make VC commands, output and errors visually distinct (bgo#698496)

 meld/misc.py   |   30 +++++++++++++++++++++---------
 meld/vcview.py |   46 ++++++++++++++++++++++++++++++++++------------
 2 files changed, 55 insertions(+), 21 deletions(-)
---
diff --git a/meld/misc.py b/meld/misc.py
index c1b13ad..3049fd1 100644
--- a/meld/misc.py
+++ b/meld/misc.py
@@ -188,6 +188,7 @@ def shorten_names(*names):
     # no common path. empty names get changed to "[None]"
     return [name or _("[None]") for name in basenames]
 
+
 def read_pipe_iter(command, errorstream, yield_interval=0.1, workdir=None):
     """Read the output of a shell command iteratively.
 
@@ -199,13 +200,19 @@ def read_pipe_iter(command, errorstream, yield_interval=0.1, workdir=None):
     class sentinel(object):
         def __init__(self):
             self.proc = None
+
         def __del__(self):
             if self.proc:
-                errorstream.write("killing '%s'\n" % command[0])
+                errorstream.error("killing '%s'\n" % command[0])
                 self.proc.terminate()
-                errorstream.write("killed (status was '%i')\n" % self.proc.wait())
+                errorstream.error("killed (status was '%i')\n" %
+                                  self.proc.wait())
+
         def __call__(self):
-            self.proc = subprocess.Popen(command, cwd=workdir, stdin=subprocess.PIPE, 
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+            self.proc = subprocess.Popen(command, cwd=workdir,
+                                         stdin=subprocess.PIPE,
+                                         stdout=subprocess.PIPE,
+                                         stderr=subprocess.PIPE)
             self.proc.stdin.close()
             childout, childerr = self.proc.stdout, self.proc.stderr
             bits = []
@@ -219,24 +226,29 @@ def read_pipe_iter(command, errorstream, yield_interval=0.1, workdir=None):
                         raise Exception("Error reading pipe")
                 if childout in state[0]:
                     try:
-                        bits.append( childout.read(4096) ) # get buffer size
+                        # get buffer size
+                        bits.append(childout.read(4096))
                     except IOError:
-                        break # ick need to fix
+                        # FIXME: ick need to fix
+                        break
                 if childerr in state[0]:
                     try:
-                        errorstream.write( childerr.read(1) ) # how many chars?
+                        # how many chars?
+                        errorstream.error(childerr.read(1))
                     except IOError:
-                        break # ick need to fix
+                        # FIXME: ick need to fix
+                        break
             status = self.proc.wait()
-            errorstream.write( childerr.read() )
+            errorstream.error(childerr.read())
             self.proc = None
             if status:
-                errorstream.write("Exit code: %i\n" % status)
+                errorstream.error("Exit code: %i\n" % status)
             yield "".join(bits)
     if workdir == "":
         workdir = None
     return sentinel()()
 
+
 def write_pipe(command, text, error=None):
     """Write 'text' into a shell command and discard its stdout output.
     """
diff --git a/meld/vcview.py b/meld/vcview.py
index fce0484..83e4e99 100644
--- a/meld/vcview.py
+++ b/meld/vcview.py
@@ -127,6 +127,37 @@ class CommitDialog(gnomeglade.Component):
             buf.set_text(model[idx][1])
 
 
+class ConsoleStream(object):
+
+    def __init__(self, textview):
+        self.textview = textview
+        buf = textview.get_buffer()
+        self.command_tag = buf.create_tag("command")
+        self.command_tag.props.weight = pango.WEIGHT_BOLD
+        self.output_tag = buf.create_tag("output")
+        self.error_tag = buf.create_tag("error")
+        # FIXME: Need to add this to the gtkrc?
+        self.error_tag.props.foreground = "#cc0000"
+        self.end_mark = buf.create_mark(None, buf.get_end_iter(),
+                                        left_gravity=False)
+
+    def command(self, message):
+        self.write(message, self.command_tag)
+
+    def output(self, message):
+        self.write(message, self.output_tag)
+
+    def error(self, message):
+        self.write(message, self.error_tag)
+
+    def write(self, message, tag):
+        if not message:
+            return
+        buf = self.textview.get_buffer()
+        buf.insert_with_tags(buf.get_end_iter(), message, tag)
+        self.textview.scroll_mark_onscreen(self.end_mark)
+
+
 COL_LOCATION, COL_STATUS, COL_REVISION, COL_TAG, COL_OPTIONS, COL_END = \
     list(range(tree.COL_END, tree.COL_END+6))
 
@@ -284,16 +315,6 @@ class VcView(melddoc.MeldDoc, gnomeglade.Component):
                 self.state_filters.append(s)
                 self.actiongroup.get_action(action_name).set_active(True)
 
-        class ConsoleStream(object):
-            def __init__(self, textview):
-                self.textview = textview
-                b = textview.get_buffer()
-                self.mark = b.create_mark("END", b.get_end_iter(), 0)
-            def write(self, s):
-                if s:
-                    b = self.textview.get_buffer()
-                    b.insert(b.get_end_iter(), s)
-                    self.textview.scroll_mark_onscreen( self.mark )
         self.consolestream = ConsoleStream(self.consoleview)
         self.location = None
         self.treeview_column_location.set_visible(self.actiongroup.get_action("VcFlatten").get_active())
@@ -633,17 +654,18 @@ class VcView(melddoc.MeldDoc, gnomeglade.Component):
             workdir = self.vc.get_working_directory( _commonprefix(files) )
         files = [ relpath(workdir, f) for f in files ]
         r = None
-        self.consolestream.write( misc.shelljoin(command+files) + " (in %s)\n" % workdir)
+        self.consolestream.command(misc.shelljoin(command + files) + " (in %s)\n" % workdir)
         readiter = misc.read_pipe_iter(command + files, self.consolestream,
                                        workdir=workdir)
         try:
             while r is None:
                 r = next(readiter)
-                self.consolestream.write(r)
+                self.consolestream.output(r)
                 yield 1
         except IOError as e:
             misc.run_dialog("Error running command.\n'%s'\n\nThe error was:\n%s" % ( 
misc.shelljoin(command), e),
                 parent=self, messagetype=gtk.MESSAGE_ERROR)
+        self.consolestream.output("\n")
         if refresh:
             self.refresh_partial(workdir)
         yield workdir, r


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]