Anonymous avatar Anonymous committed 88e2dd1

Showing refactoring progress

Comments (0)

Files changed (3)

 * adding a menu
 * including pymacs in ropemacs?
 * change pymacs to accept unicode strings
-* previewing changes
-* showing refactoring progress
 
 > Public Release 0.2
 
 * new file/directory/module/package; C-x p n [fdmp]
 * showing proposal type in code-assist
+* previewing changes
+* showing refactoring progress

ropemacs/__init__.py

+import threading
+
 from Pymacs import lisp
-from rope.base import project, libutils
+from rope.base import project, libutils, taskhandle
 from rope.contrib import codeassist
 
 from ropemacs import refactor
     else:
         return _ask(data.prompt, default=data.default, starting=data.starting)
 
-def _message(self, message):
+def _message(message):
     lisp.message(message)
 
 
+class _RunTask(object):
+
+    def __init__(self, task, name, interrupts=True):
+        self.task = task
+        self.name = name
+        self.interrupts = interrupts
+
+    def __call__(self):
+        handle = taskhandle.TaskHandle(name=self.name)
+        _message('')
+        progress = lisp.make_progress_reporter(
+            '%s ... ' % self.name, 0, 100)
+        def update_progress():
+            jobset = handle.current_jobset()
+            if jobset:
+                percent = jobset.get_percent_done()
+                if percent is not None:
+                    lisp.progress_reporter_update(progress, percent)
+        handle.add_observer(update_progress)
+        class Calculate(object):
+
+            def __init__(self, task):
+                self.task = task
+                self.result = None
+                self.exception = None
+
+            def __call__(self):
+                try:
+                    self.result = self.task(handle)
+                except Exception, e:
+                    self.exception = e
+
+        calculate = Calculate(self.task)
+        thread = threading.Thread(target=calculate)
+        try:
+            thread.start()
+            thread.join()
+            lisp.progress_reporter_done(progress)
+            if calculate.exception is not None:
+                description = type(calculate.exception).__name__ + ': ' + \
+                                   str(calculate.exception)
+                _message('Task <%s> was interrupted.\nReason: <%s>' %
+                         (self.name, description))
+        except:
+            handle.stop()
+            _message('%s interrupted!' % self.name)
+            raise
+        return calculate.result
+
+
+
+
 DEFVARS = """\
 (defvar rope-confirm-saving t
   "If non-nil, you have to confirm saving all modified

ropemacs/refactor.py

+import rope.base.taskhandle
 import rope.contrib.generate
 import rope.refactor.extract
 import rope.refactor.inline
         self.interface._save_buffers(only_current=not self.saveall)
         self._create_refactoring()
         action, result = config.show_dialog(
-            ropemacs._lisp_askdata, ['perform', 'cancel'],
+            ropemacs._lisp_askdata, ['perform', 'preview', 'cancel'],
             self._get_confs(), self._get_optionals())
-        if action != 'perform':
+        if action == 'cancel':
             ropemacs._message('Cancelled!')
             return
-        changes = self._calculate_changes(result)
-        self._perform(changes)
-        self._done()
+        def calculate(handle):
+            return self._calculate_changes(result, handle)
+        name = 'Performing %s' % self.name
+        changes = ropemacs._RunTask(calculate, name=name)()
+        if action == 'perform':
+            self._perform(changes)
+        if action == 'preview':
+            ropemacs._message('We\'ll preview it!')
 
     @property
     def project(self):
     def region(self):
         return self.interface._get_region()
 
-    def _calculate_changes(self, option_values):
+    def _calculate_changes(self, option_values, task_handle):
         pass
 
     def _create_refactoring(self):
     def _perform(self, changes):
         if changes is None:
             return
-        self.project.do(changes)
-        self.interface._reload_buffers(changes.get_changed_resources())
+        def perform(handle, self=self, changes=changes):
+            self.project.do(changes, task_handle=handle)
+            self.interface._reload_buffers(changes.get_changed_resources())
+            self._done()
+        ropemacs._RunTask(perform, 'Making %s changes' % self.name,
+                          interrupts=False)()
         ropemacs._message(str(changes.description) + ' finished')
 
     def _get_confs(self):
         self.renamer = rope.refactor.rename.Rename(
             self.project, self.resource, self.offset)
 
-    def _calculate_changes(self, values):
+    def _calculate_changes(self, values, task_handle):
         newname = values['newname']
         unsure = values.get('unsure', 'no') == 'yes'
         kwds = {
             'unsure': (lambda occurrence: unsure)}
         if self.renamer.is_method():
             kwds['in_hierarchy'] = values.get('in_hierarchy', 'no') == 'yes'
-        return self.renamer.get_changes(newname, **kwds)
+        return self.renamer.get_changes(newname,
+                                        task_handle=task_handle, **kwds)
 
     def _get_confs(self):
         oldname = str(self.renamer.get_old_name())
     optionals = {'checks': config.Data('Checks: '),
                      'imports': config.Data('Imports: ')}
 
-    def _calculate_changes(self, values):
+    def _calculate_changes(self, values, task_handle):
         restructuring = rope.refactor.restructure.Restructure(
             self.project, values['pattern'], values['goal'])
         check_dict = {}
         checks = restructuring.make_checks(check_dict)
         imports = [line.strip()
                    for line in values.get('imports', '').split('\n')]
-        return restructuring.get_changes(checks=checks, imports=imports)
+        return restructuring.get_changes(checks=checks, imports=imports,
+                                         task_handle=task_handle)
 
 
 class Move(Refactoring):
                                                     self.resource,
                                                     self.offset)
 
-    def _calculate_changes(self, values):
+    def _calculate_changes(self, values, task_handle):
         destination = values['destination']
         if isinstance(self.mover, rope.refactor.move.MoveGlobal):
-            return self._move_global(destination)
+            return self._move_global(destination, task_handle)
         if isinstance(self.mover, rope.refactor.move.MoveModule):
-            return self._move_module(destination)
+            return self._move_module(destination, task_handle)
         if isinstance(self.mover, rope.refactor.move.MoveMethod):
-            return self._move_method(destination)
+            return self._move_method(destination, task_handle)
 
-    def _move_global(self, dest):
+    def _move_global(self, dest, handle):
         destination = self.project.pycore.find_module(dest)
-        return self.mover.get_changes(destination)
+        return self.mover.get_changes(destination, task_handle=handle)
 
-    def _move_method(self, dest):
-        return self.mover.get_changes(dest, self.mover.get_method_name())
+    def _move_method(self, dest, handle):
+        return self.mover.get_changes(
+            dest, self.mover.get_method_name(), task_handle=handle)
 
-    def _move_module(self, dest):
+    def _move_module(self, dest, handle):
         destination = self.project.pycore.find_module(dest)
-        return self.mover.get_changes(destination)
+        return self.mover.get_changes(destination, task_handle=handle)
 
     def _get_confs(self):
         if isinstance(self.mover, rope.refactor.move.MoveGlobal):
         self.packager = rope.refactor.ModuleToPackage(
             self.project, self.resource)
 
-    def _calculate_changes(self, values):
+    def _calculate_changes(self, values, task_handle):
         return self.packager.get_changes()
 
 
 
     name = 'inline'
     key = 'C-c r i'
-    saveall = False
     optionals = {'remove': config.Data('Remove the definition: ',
                                        values=['yes', 'no'])}
 
         self.inliner = rope.refactor.inline.create_inline(
             self.project, self.resource, self.offset)
 
-    def _calculate_changes(self, values):
+    def _calculate_changes(self, values, task_handle):
         remove = values.get('remove', 'yes') == 'yes'
-        return self.inliner.get_changes(remove=remove)
+        return self.inliner.get_changes(remove=remove,
+                                        task_handle=task_handle)
 
 
 class ExtractVariable(Refactoring):
         self.extractor = rope.refactor.extract.ExtractVariable(
             self.project, self.resource, start, end)
 
-    def _calculate_changes(self, values):
+    def _calculate_changes(self, values, task_handle):
         return self.extractor.get_changes(values['name'])
 
 
         self.extractor = rope.refactor.extract.ExtractMethod(
             self.project, self.resource, start, end)
 
-    def _calculate_changes(self, values):
+    def _calculate_changes(self, values, task_handle):
         return self.extractor.get_changes(values['name'])
 
 
     def _create_refactoring(self):
         self.organizer = rope.refactor.ImportOrganizer(self.project)
 
-    def _calculate_changes(self, values):
+    def _calculate_changes(self, values, task_handle):
         return self.organizer.organize_imports(self.resource)
 
 
         self.generator = rope.contrib.generate.create_generate(
             kind, self.project, self.resource, self.offset)
 
-    def _calculate_changes(self, values):
+    def _calculate_changes(self, values, task_handle):
         return self.generator.get_changes()
 
     def _done(self):
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.