Anonymous avatar Anonymous committed 4bee544

added decorators module

Comments (0)

Files changed (3)

ropemacs/decorators.py

+import traceback
+
+from rope.base import exceptions
+
+from ropemacs import lisputils
+from ropemacs.lisputils import message
+
+
+def lisphook(func):
+    def newfunc(*args, **kwds):
+        try:
+            func(*args, **kwds)
+        except Exception, e:
+            trace = str(traceback.format_exc())
+            message('%s\nIgnored an exception in ropemacs hook: %s: %s' %
+                    (trace, type(e).__name__, str(e)))
+    newfunc.lisp = None
+    newfunc.__name__ = func.__name__
+    newfunc.__doc__ = func.__doc__
+    return newfunc
+
+
+def interactive(func):
+    func.interaction = ''
+    return func
+
+
+def lispfunction(func):
+    func.lisp = None
+    return func
+
+
+input_exceptions = (exceptions.RefactoringError,)
+
+def _lisp_name(func):
+    return 'rope-' + func.__name__.replace('_', '-')
+
+def _exception_handler(func):
+    def newfunc(*args, **kwds):
+        try:
+            func(*args, **kwds)
+        except exceptions.RopeError, e:
+            if isinstance(e, input_exceptions):
+                lisputils.message('%s: %s' % (e.__class__.__name__, str(e)))
+            else:
+                raise e
+    newfunc.__name__ = func.__name__
+    newfunc.__doc__ = func.__doc__
+    return newfunc
+
+def rope_hook(hook):
+    def decorator(func):
+        func = lisphook(func)
+        func.lisp_name = _lisp_name(func)
+        func.kind = 'hook'
+        func.hook = hook
+        return func
+    return decorator
+
+
+def local_command(key=None, interaction='', shortcut=None, name=None):
+    def decorator(func, name=name):
+        func = _exception_handler(func)
+        func.kind = 'local'
+        if interaction is not None:
+            func.interaction = interaction
+        func.local_key = key
+        func.shortcut_key = shortcut
+        if name is None:
+            name = _lisp_name(func)
+        func.lisp_name = name
+        return func
+    return decorator
+
+
+def global_command(key=None, interaction=''):
+    def decorator(func):
+        func = _exception_handler(func)
+        func.kind = 'global'
+        if interaction is not None:
+            func.interaction = interaction
+        func.global_key = key
+        func.lisp_name = _lisp_name(func)
+        return func
+    return decorator

ropemacs/interface.py

 from rope.base import libutils
 from rope.contrib import codeassist, generate, autoimport
 
-import ropemacs
-from ropemacs import refactor, lisputils
+from ropemacs import refactor, lisputils, decorators, dialog
 
 
-def _lisp_name(func):
-    return 'rope-' + func.__name__.replace('_', '-')
-
-def global_command(key=None, interaction=''):
-    def decorator(func):
-        if interaction is not None:
-            func.interaction = interaction
-        if key:
-            global_keys.append((key, _lisp_name(func)))
-        return func
-    return decorator
-
-def local_command(key=None, interaction='', shortcut=None, name=None):
-    def decorator(func, name=name):
-        if name is None:
-            name = _lisp_name(func)
-        if interaction is not None:
-            func.interaction = interaction
-        if key:
-            local_keys.append((key, name))
-        if shortcut:
-            shortcuts.append((shortcut, name))
-        return func
-    return decorator
-
-def rope_hook(hook):
-    def decorator(func):
-        name = _lisp_name(func)
-        func = lisputils.lisphook(func)
-        hooks.append((hook, name))
-        return func
-    return decorator
-
-global_keys = []
-local_keys = []
-shortcuts = []
-hooks = [('python-mode-hook', 'ropemacs-mode')]
-
 class Ropemacs(object):
 
     def __init__(self):
 
     def init(self):
         """Initialize rope mode"""
-        for hook, function in hooks:
-            lisp.add_hook(lisp[hook], lisp[function])
+        global_prefix = lisp.ropemacs_global_prefix.value()
+        for attrname in dir(self):
+            attr = getattr(self, attrname)
+            if not callable(attr):
+                continue
+            kind = getattr(attr, 'kind', None)
+            if kind == 'global':
+                global_key = getattr(attr, 'global_key', None)
+                if global_key:
+                    key = self._key_sequence(global_prefix + ' ' + global_key)
+                    lisp.global_set_key(key, lisp[attr.lisp_name])
+            if kind == 'hook':
+                hook = getattr(attr, 'hook', None)
+                lisp.add_hook(lisp[hook], lisp[attr.lisp_name])
+        lisp.add_hook(lisp['python-mode-hook'], lisp['ropemacs-mode'])
 
-        prefix = lisp.ropemacs_global_prefix.value()
-        if prefix is not None:
-            for key, callback in global_keys:
-                lisp.global_set_key(self._key_sequence(prefix + ' ' + key),
-                                    lisp[callback])
+    def _init_ropemacs_keymap(self):
+        local_prefix = lisp.ropemacs_local_prefix.value()
+        enable_shortcuts = lisp['ropemacs-enable-shortcuts'].value()
+        for attrname in dir(self):
+            attr = getattr(self, attrname)
+            if not callable(attr):
+                continue
+            kind = getattr(attr, 'kind', None)
+            name = decorators._lisp_name(attr)
+            if kind == 'local':
+                local_key = getattr(attr, 'local_key', None)
+                shortcut_key = getattr(attr, 'shortcut_key', None)
+                if local_prefix is not None and local_key:
+                    self._bind_local_key(attr.lisp_name,
+                                         local_prefix + ' ' + local_key)
+                if enable_shortcuts and shortcut_key:
+                    self._bind_local_key(attr.lisp_name, shortcut_key)
 
     def _prepare_refactorings(self):
         for name in dir(refactor):
                    issubclass(attr, refactor.Refactoring):
                     ref_name = self._refactoring_name(attr)
                     lisp_name = 'rope-' + ref_name.replace('_', '-')
-                    @local_command(attr.key, 'P', None, lisp_name)
+                    @decorators.local_command(attr.key, 'P', None, lisp_name)
                     def do_refactor(prefix, self=self, refactoring=attr):
                         initial_asking = prefix is None
                         refactoring(self).show(initial_asking=initial_asking)
                 result.append(key)
         return ''.join(result)
 
-    @rope_hook('before-save-hook')
+    @decorators.rope_hook('before-save-hook')
     def before_save_actions(self):
         if self.project is not None:
             if not self._is_python_file(lisp.buffer_file_name()):
             else:
                 self.old_content = ''
 
-    @rope_hook('after-save-hook')
+    @decorators.rope_hook('after-save-hook')
     def after_save_actions(self):
         if self.project is not None and self.old_content is not None:
             libutils.report_change(self.project, lisp.buffer_file_name(),
                                    self.old_content)
             self.old_content = None
 
-    def _init_ropemacs_keymap(self):
-        prefix = lisp.ropemacs_local_prefix.value()
-        for key, callback in local_keys:
-            if prefix is not None:
-                self._bind_local_key(callback, prefix + ' ' + key)
-        if lisp['ropemacs-enable-shortcuts'].value():
-            for key, callback in shortcuts:
-                self._bind_local_key(callback, key)
-
     def _bind_local_key(self, callback, key):
         lisp('(define-key ropemacs-local-keymap "%s" \'%s)' %
              (self._key_sequence(key), callback))
 
-    @rope_hook('kill-emacs-hook')
+    @decorators.rope_hook('kill-emacs-hook')
     def exiting_actions(self):
         if self.project is not None:
             self.close_project()
 
-    @lisputils.lispfunction
+    @decorators.lispfunction
     def unload_hook(self):
         """Unload registered hooks"""
         for hook, function in hooks:
             lisp.remove_hook(lisp[hook], lisp[function])
 
-    @global_command('o')
+    @decorators.global_command('o')
     def open_project(self, root=None):
         if not root:
             root = lisputils.ask_directory('Rope project root folder: ')
             self.autoimport = autoimport.AutoImport(self.project)
         progress.done()
 
-    @global_command('k')
+    @decorators.global_command('k')
     def close_project(self):
         if self.project is not None:
             progress = lisputils.create_progress('Closing "%s" project' %
             self.project = None
             progress.done()
 
-    @global_command()
+    @decorators.global_command()
     def write_project(self):
         if self.project is not None:
             progress = lisputils.create_progress(
             self.project.sync()
             progress.done()
 
-    @global_command('u')
+    @decorators.global_command('u')
     def undo(self):
         self._check_project()
         change = self.project.history.tobe_undone
                     self._reload_buffers(changes, undo=True)
             lisputils.runtask(undo, 'Undo refactoring', interrupts=False)
 
-    @global_command('r')
+    @decorators.global_command('r')
     def redo(self):
         self._check_project()
         change = self.project.history.tobe_redone
             if narrowed:
                 lisp.narrow_to_region(old_min, old_max)
 
-    @local_command('a g', shortcut='C-c g')
+    @decorators.local_command('a g', shortcut='C-c g')
     def goto_definition(self):
         self._check_project()
         resource, offset = self._get_location()
         else:
             lisputils.message('Cannot find the definition!')
 
-    @local_command('a d', 'P', 'C-c d')
+    @decorators.local_command('a d', 'P', 'C-c d')
     def show_doc(self, prefix):
         self._check_project()
         self._base_show_doc(prefix)
 
-    @local_command('a c', 'P')
+    @decorators.local_command('a c', 'P')
     def show_call_doc(self, prefix):
         self._check_project()
         offset = self._get_offset()
         if docs is None:
             lisputils.message('No docs avilable!')
 
-    @local_command('a f', shortcut='C-c f')
+    @decorators.local_command('a f', shortcut='C-c f')
     def find_occurrences(self):
         self._check_project()
         self._save_buffers()
         resource, offset = self._get_location()
 
         optionals = {
-            'unsure': ropemacs.dialog.Data('Find uncertain occurrences: ',
+            'unsure': dialog.Data('Find uncertain occurrences: ',
                                            default='no', values=['yes', 'no']),
-            'resources': ropemacs.dialog.Data('Files to search: '),
-            'in_hierarchy': ropemacs.dialog.Data(
+            'resources': dialog.Data('Files to search: '),
+            'in_hierarchy': dialog.Data(
                     'Rename methods in class hierarchy: ',
                     default='no', values=['yes', 'no'])}
-        action, values = ropemacs.dialog.show_dialog(
+        action, values = dialog.show_dialog(
             lisputils.askdata, ['search', 'cancel'], optionals=optionals)
         if action == 'search':
             unsure = values.get('unsure') == 'yes'
             lisp.local_set_key('q', lisp.rope_occurrences_quit)
 
 
-    @lisputils.interactive
+    @decorators.interactive
     def occurrences_goto_occurrence(self):
         self._check_project()
         start = lisp.line_beginning_position()
             lisp.goto_char(offset + 1)
             lisp.switch_to_buffer_other_window('*rope-occurrences*')
 
-    @lisputils.interactive
+    @decorators.interactive
     def occurrences_quit(self):
         lisputils.hide_buffer('*rope-occurrences*')
 
-    @local_command('a /', 'P', 'M-/')
+    @decorators.local_command('a /', 'P', 'M-/')
     def code_assist(self, prefix):
         _CodeAssist(self).code_assist(prefix)
 
-    @local_command('a ?', 'P', 'M-?')
+    @decorators.local_command('a ?', 'P', 'M-?')
     def lucky_assist(self, prefix):
         _CodeAssist(self).lucky_assist(prefix)
 
-    @local_command()
+    @decorators.local_command()
     def auto_import(self):
         _CodeAssist(self).auto_import()
 
             return False
         return True
 
-    @global_command()
+    @decorators.global_command()
     def generate_autoimport_cache(self):
         if not self._check_autoimport():
             return
             self.autoimport.generate_modules_cache(modules, task_handle=handle)
         lisputils.runtask(generate, 'Generate autoimport cache')
 
-    @global_command('f', 'P')
+    @decorators.global_command('f', 'P')
     def find_file(self, prefix):
         file = self._base_find_file(prefix)
         if file is not None:
             lisp.find_file(file.real_path)
 
-    @global_command('4 f', 'P')
+    @decorators.global_command('4 f', 'P')
     def find_file_other_window(self, prefix):
         file = self._base_find_file(prefix)
         if file is not None:
             return file
         lisputils.message('No file selected')
 
-    @local_command('a j')
+    @decorators.local_command('a j')
     def jump_to_global(self):
         if not self._check_autoimport():
             return
         if resource:
             self._goto_location(resource, result[resource])
 
-    @global_command('c')
+    @decorators.global_command('c')
     def project_config(self):
         self._check_project()
         if self.project.ropefolder is not None:
         else:
             lisputils.message('No rope project folder found')
 
-    @global_command('n m')
+    @decorators.global_command('n m')
     def create_module(self):
         def callback(sourcefolder, name):
             return generate.create_module(self.project, name, sourcefolder)
         self._create('module', callback)
 
-    @global_command('n p')
+    @decorators.global_command('n p')
     def create_package(self):
         def callback(sourcefolder, name):
             folder = generate.create_package(self.project, name, sourcefolder)
             return folder.get_child('__init__.py')
         self._create('package', callback)
 
-    @global_command('n f')
+    @decorators.global_command('n f')
     def create_file(self):
         def callback(parent, name):
             return parent.create_file(name)
         self._create('file', callback, 'parent')
 
-    @global_command('n d')
+    @decorators.global_command('n d')
     def create_directory(self):
         def callback(parent, name):
             parent.create_folder(name)
         self._create('directory', callback, 'parent')
 
-    @global_command()
+    @decorators.global_command()
     def analyze_module(self):
         """Perform static object inference analysis on this module"""
         self._check_project()
 
     def _create(self, name, callback, parentname='source'):
         self._check_project()
-        confs = {'name': ropemacs.dialog.Data(name.title() + ' name: ')}
+        confs = {'name': dialog.Data(name.title() + ' name: ')}
         parentname = parentname + 'folder'
-        optionals = {parentname: ropemacs.dialog.Data(
+        optionals = {parentname: dialog.Data(
                 parentname.title() + ' Folder: ',
                 default=self.project.address, kind='directory')}
-        action, values = ropemacs.dialog.show_dialog(
+        action, values = dialog.show_dialog(
             lisputils.askdata, ['perform', 'cancel'], confs, optionals)
         if action == 'perform':
             parent = libutils.path_to_resource(

ropemacs/lisputils.py

 
 def _emacs_version():
     return int(lisp['emacs-version'].value().split('.')[0])
-
-
-def lispfunction(func):
-    func.lisp = None
-    return func
-
-def interactive(func):
-    func.interaction = ''
-    return func
-
-def lisphook(func):
-    def newfunc(*args, **kwds):
-        try:
-            func(*args, **kwds)
-        except Exception, e:
-            trace = str(traceback.format_exc())
-            message('%s\nIgnored an exception in ropemacs hook: %s: %s' %
-                    (trace, type(e).__name__, str(e)))
-    newfunc.lisp = None
-    return newfunc
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.