Commits

Anonymous committed f815441

Better diff highlighting

Comments (0)

Files changed (6)

 ===========
 
 
+- Better diff highlighting : July 20, 2007
+
+
 - Handling imports when inlining : July 20, 2007
 
 

rope/base/change.py

         differ = difflib.Differ()
         result = list(differ.compare(self.old_contents.splitlines(True),
                                      self.new_contents.splitlines(True)))
+        result = difflib.unified_diff(
+            self.old_contents.splitlines(True),
+            self.new_contents.splitlines(True), 'a/' + self.resource.path,
+            'b/' + self.resource.path)
         return ''.join(result)
 
     def get_changed_resources(self):

rope/refactor/inline.py

     def get_changes(self, task_handle=taskhandle.NullTaskHandle()):
         return self.performer.get_changes(task_handle)
 
+    def get_kind(self):
+        if self._is_variable():
+            return 'variable'
+        else:
+            return 'method'
+
     def _is_variable(self):
         return isinstance(self.pyname, pynames.AssignedName)
 

rope/ui/fileactions.py

     frame = Tkinter.Frame(toplevel)
     list_frame = Tkinter.Frame(frame)
     enhanced_list = uihelpers.DescriptionList(
-        list_frame, title, lambda change: change.get_description())
+        list_frame, title, lambda change: change.get_description(),
+        callback=uihelpers.highlight_diffs)
     for change in reversed(undo_list):
         enhanced_list.add_entry(change)
     list_frame.grid(row=0, column=0, columnspan=2)
     cancel_button = Tkinter.Button(frame, text='Cancel',
                                    command=cancel, width=15)
     undo_button.grid(row=1, column=0)
-    toplevel.bind('<Return>', lambda event: undo())
     toplevel.bind('<Escape>', lambda event: cancel())
     toplevel.bind('<Control-g>', lambda event: cancel())
     toplevel.bind('<Alt-u>', lambda event: undo())
+    undo_button.bind('<Return>', lambda event: undo())
     cancel_button.grid(row=1, column=1)
     frame.grid()
     undo_button.focus_set()

rope/ui/refactor.py

         def description(change):
             return change.get_description()
         frame = Tkinter.Frame(toplevel)
-        description_list = DescriptionList(frame, 'Changes', description,
-                                           indexwidth=30)
+        description_list = DescriptionList(
+            frame, 'Changes', description, indexwidth=30,
+            callback=uihelpers.highlight_diffs)
         for change in self.changes.changes:
             description_list.add_entry(change)
 
         frame = Tkinter.Frame(self.toplevel)
         label = Tkinter.Label(frame, text='New %s Name :' % self.kind)
         label.grid(row=0, column=0)
-        self.new_name_entry = Tkinter.Entry(frame)
+        self.new_name_entry = Tkinter.Entry(frame, width=30)
         self.new_name_entry.grid(row=0, column=1)
         self.new_name_entry.insert(0, 'extracted')
         self.new_name_entry.select_range(0, Tkinter.END)
         similar = Tkinter.Checkbutton(
             frame, text='Extract similar expressions/statements',
             variable=self.similar)
-        similar.grid(row=1, column=0, columnspan=2)
+        similar.grid(row=1, column=0, columnspan=2, sticky=Tkinter.W)
 
         self.new_name_entry.bind('<Return>', lambda event: self._ok())
         self.new_name_entry.focus_set()
     _import_action(context, ImportOrganizer.handle_long_imports)
 
 
+class InlineDialog(RefactoringDialog):
+
+    def __init__(self, context):
+        self.inliner = rope.refactor.inline.Inline(
+            context.project, context.resource, context.offset)
+        super(InlineDialog, self).__init__(
+            context, 'Inline ' + self.inliner.get_kind().title())
+
+    def _calculate_changes(self, handle):
+        return self.inliner.get_changes(task_handle=handle)
+
+    def _get_dialog_frame(self):
+        frame = Tkinter.Frame(self.toplevel)
+        label = Tkinter.Label(
+            frame, text='Inlining occurrences of <%s> %s.' %
+            (self.inliner.name, self.inliner.get_kind()), width=50)
+        label.grid()
+        return frame
+
+
 def inline(context):
-    if context.get_active_editor():
-        fileeditor = context.get_active_editor()
-        resource = fileeditor.get_file()
-        editor = fileeditor.get_editor()
-        def calculate(handle):
-            return rope.refactor.inline.Inline(
-                context.project, resource,
-                editor.get_current_offset()).get_changes(task_handle=handle)
-        changes = StoppableTaskRunner(calculate, 'Inlining')()
-        context.project.do(changes)
+    InlineDialog(context).show()
 
 
 def encapsulate_field(context):

rope/ui/uihelpers.py

 
 class _DescriptionListHandle(EnhancedListHandle):
 
-    def __init__(self, text, description):
+    def __init__(self, text, description, callback):
         self.text = text
         self.description = description
+        self.callback = callback
 
     def entry_to_string(self, obj):
         return str(obj)
         self.text['state'] = Tkinter.NORMAL
         self.text.delete('0.0', Tkinter.END)
         self.text.insert('0.0', self._get_description(obj))
+        self.callback(self.text)
         self.text['state'] = Tkinter.DISABLED
 
     def _get_description(self, obj):
 
 class DescriptionList(object):
 
-    def __init__(self, parent, title, description, height=12, indexwidth=50):
+    def __init__(self, parent, title, description,
+                 height=12, indexwidth=50, callback=lambda text: None):
         frame = Tkinter.Frame(parent)
-
         description_text = ScrolledText.ScrolledText(frame, height=height,
                                                      width=80)
-        self.handle = _DescriptionListHandle(description_text, description)
+        self.handle = _DescriptionListHandle(
+            description_text, description, callback)
         self.list = EnhancedList(frame, self.handle, title,
                                  height=height, width=indexwidth)
         description_text.grid(row=0, column=1, sticky=N+E+W+S)
         if c1 != c2:
             return prefix[:index]
     return prefix[:min(len(prefix), len(word))]
+
+
+def highlight_diffs(text):
+    last = '0.0'
+    current = '1.0'
+    text.tag_config('red', foreground='#AA1111')
+    text.tag_config('green', foreground='#11AA11')
+    text.tag_config('blue', foreground='#1111AA')
+    text.tag_config('grey', foreground='#9999BB')
+    tag_map = {'+': 'green', '-': 'red', '?': 'grey', '@': 'blue'}
+    while current != last:
+        c = text.get(current)
+        if c in tag_map:
+            text.tag_add(tag_map[c], current, current + ' lineend')
+        last = current
+        current = text.index(current + ' +1l')