Anonymous avatar Anonymous committed 858afe1

ropemacs: added LispUtils.local_command(), global_command() and add_hook()

Comments (0)

Files changed (3)

ropecommon/decorators.py

     return newfunc
 
 
-def interactive(func):
-    func.interaction = ''
-    return func
-
-
 def lispfunction(func):
     func.lisp = None
     return func
     return decorator
 
 
-def local_command(key=None, interaction='', shortcut=None, name=None):
+def local_command(key=None, prefix=False, 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.prefix = prefix
         func.local_key = key
         func.shortcut_key = shortcut
         if name is None:
     return decorator
 
 
-def global_command(key=None, interaction=''):
+def global_command(key=None, prefix=False):
     def decorator(func):
         func = _exception_handler(func)
         func.kind = 'global'
-        if interaction is not None:
-            func.interaction = interaction
+        func.prefix = prefix
         func.global_key = key
         func.name = func.__name__
         return func

ropecommon/interface.py

 from ropecommon import refactor, decorators, dialog
 
 
-class Ropemacs(object):
+class RopeCommon(object):
 
     def __init__(self, env):
         self.project = None
         """Initialize rope mode"""
 
     def _init_ropemacs(self):
-        global_prefix = self.env.get('ropemacs-global-prefix')
-        local_prefix = self.env.get('ropemacs-local-prefix')
-        enable_shortcuts = self.env.get('ropemacs-enable-shortcuts')
         for attrname in dir(self):
             attr = getattr(self, attrname)
             if not callable(attr):
                 continue
             kind = getattr(attr, 'kind', None)
-            name = attr.__name__
             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.name,
-                                         local_prefix + ' ' + local_key)
-                if enable_shortcuts and shortcut_key:
-                    self._bind_local_key(attr.name, shortcut_key)
+                key = getattr(attr, 'local_key', None)
+                prefix = getattr(attr, 'prefix', None)
+                self.env.local_command(attrname, attr, key, prefix)
             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[_lisp_name(attr.name)])
+                key = getattr(attr, 'global_key', None)
+                prefix = getattr(attr, 'prefix', None)
+                self.env.global_command(attrname, attr, key, prefix)
             if kind == 'hook':
                 hook = getattr(attr, 'hook', None)
-                lisp.add_hook(lisp[hook], lisp[_lisp_name(attr.name)])
+                self.env.add_hook(attrname, attr, hook)
 
     def _prepare_refactorings(self):
         for name in dir(refactor):
     def _refactoring_name(self, refactoring):
         return refactor.refactoring_name(refactoring)
 
-    def _key_sequence(self, sequence):
-        result = []
-        for key in sequence.split():
-            if key.startswith('C-'):
-                number = ord(key[-1].upper()) - ord('A') + 1
-                result.append(chr(number))
-            elif key.startswith('M-'):
-                number = ord(key[-1].upper()) + 0x80
-                result.append(chr(number))
-            else:
-                result.append(key)
-        return ''.join(result)
-
     @decorators.rope_hook('before-save-hook')
     def before_save_actions(self):
         if self.project is not None:
                                    self.old_content)
             self.old_content = None
 
-    def _bind_local_key(self, callback, key):
-        lisp('(define-key ropemacs-local-keymap "%s" \'%s)' %
-             (self._key_sequence(key), _lisp_name(callback)))
-
     @decorators.rope_hook('kill-emacs-hook')
     def exiting_actions(self):
         if self.project is not None:
             self.close_project()
 
-    @decorators.lispfunction
-    def unload_hook(self):
-        """Unload registered hooks"""
-        for hook, function in hooks:
-            lisp.remove_hook(lisp[hook], lisp[function])
-
     @decorators.global_command('o')
     def open_project(self, root=None):
         if not root:
                 self.project.pycore.is_python_file(resource))
 
 
-def _lisp_name(name):
-    return 'rope-' + name.replace('_', '-')
-
 
 class _CodeAssist(object):
 
 """ropemacs, an emacs mode for using rope refactoring library"""
 from Pymacs import lisp
-from rope.base import taskhandle
+from rope.base import taskhandle, utils
 
 import ropecommon.dialog
 import ropecommon.interface
 
 class LispUtils(object):
 
-    def get(self, name):
-        return lisp[name].value()
+    def askdata(self, data, starting=None):
+        """`data` is a `ropecommon.dialog.Data` object"""
+        ask_func = self.ask
+        ask_args = {'prompt': data.prompt, 'starting': starting,
+                    'default': data.default}
+        if data.values:
+            ask_func = self.ask_values
+            ask_args['values'] = data.values
+        elif data.kind == 'directory':
+            ask_func = self.ask_directory
+        return ask_func(**ask_args)
+
+    def ask_values(self, prompt, values, default=None, starting=None, exact=True):
+        if self._emacs_version() < 22:
+            values = [[value, value] for value in values]
+        if exact and default is not None:
+            prompt = prompt + ('[%s] ' % default)
+        reader = lisp['ropemacs-completing-read-function'].value()
+        result = reader(prompt, values, None, exact, starting)
+        if result == '' and exact:
+            return default
+        return result
+
+
+    def ask(self, prompt, default=None, starting=None):
+        if default is not None:
+            prompt = prompt + ('[%s] ' % default)
+        result = lisp.read_from_minibuffer(prompt, starting, None, None,
+                                           None, default, None)
+        if result == '' and default is not None:
+            return default
+        return result
+
+    def ask_directory(self, prompt, default=None, starting=None):
+        if default is not None:
+            prompt = prompt + ('[%s] ' % default)
+        if lisp.fboundp(lisp['read-directory-name']):
+            result = lisp.read_directory_name(prompt, starting, default)
+        else:
+            result = lisp.read_file_name(prompt, starting, default)
+        if result == '' and default is not None:
+            return default
+        return result
+
+    def message(self, message):
+        lisp.message(message)
 
     def yes_or_no(self, prompt):
         return lisp.yes_or_no_p(prompt)
     def y_or_n(self, prompt):
         return lisp.y_or_n_p(prompt)
 
-    def get_region(self):
-        offset1 = self.get_offset()
-        lisp.exchange_point_and_mark()
-        offset2 = self.get_offset()
-        lisp.exchange_point_and_mark()
-        return min(offset1, offset2), max(offset1, offset2)
+    def get(self, name):
+        return lisp[name].value()
 
     def get_offset(self):
         return lisp.point() - 1
             if narrowed:
                 lisp.narrow_to_region(old_min, old_max)
 
+    def get_region(self):
+        offset1 = self.get_offset()
+        lisp.exchange_point_and_mark()
+        offset2 = self.get_offset()
+        lisp.exchange_point_and_mark()
+        return min(offset1, offset2), max(offset1, offset2)
+
     def filename(self):
         return lisp.buffer_file_name()
 
                     lisp.bury_buffer(new_buffer)
         return new_buffer
 
-
     def hide_buffer(self, name, delete=True):
         buffer = lisp.get_buffer(name)
         if buffer is not None:
                     if lisp.buffer_name(lisp.current_buffer()) == name:
                         lisp.switch_to_buffer(None)
 
-
-    def message(self, message):
-        lisp.message(message)
-
-
-    def askdata(self, data, starting=None):
-        """`data` is a `ropecommon.dialog.Data` object"""
-        ask_func = self.ask
-        ask_args = {'prompt': data.prompt, 'starting': starting,
-                    'default': data.default}
-        if data.values:
-            ask_func = self.ask_values
-            ask_args['values'] = data.values
-        elif data.kind == 'directory':
-            ask_func = self.ask_directory
-        return ask_func(**ask_args)
-
-
-    def ask_values(self, prompt, values, default=None, starting=None, exact=True):
-        if self._emacs_version() < 22:
-            values = [[value, value] for value in values]
-        if exact and default is not None:
-            prompt = prompt + ('[%s] ' % default)
-        reader = lisp['ropemacs-completing-read-function'].value()
-        result = reader(prompt, values, None, exact, starting)
-        if result == '' and exact:
-            return default
-        return result
-
-
-    def ask(self, prompt, default=None, starting=None):
-        if default is not None:
-            prompt = prompt + ('[%s] ' % default)
-        result = lisp.read_from_minibuffer(prompt, starting, None, None,
-                                           None, default, None)
-        if result == '' and default is not None:
-            return default
-        return result
-
-    def ask_directory(self, prompt, default=None, starting=None):
-        if default is not None:
-            prompt = prompt + ('[%s] ' % default)
-        if lisp.fboundp(lisp['read-directory-name']):
-            result = lisp.read_directory_name(prompt, starting, default)
-        else:
-            result = lisp.read_file_name(prompt, starting, default)
-        if result == '' and default is not None:
-            return default
-        return result
-
     def _emacs_version(self):
         return int(lisp['emacs-version'].value().split('.')[0])
 
             progress = _OldProgress(name)
         return progress
 
+    def current_word(self):
+        return lisp.current_word()
+
+    def push_mark(self):
+        lisp.push_mark()
+
+    def prefix_value(self, prefix):
+        return lisp.prefix_numeric_value(prefix)
+
     def show_occurrences(self, locations):
         text = []
         for filename, offset, note in locations:
                                   empty_goto=False, fit_lines=fit_lines)
         lisp.local_set_key('q', lisp.bury_buffer)
 
-    def current_word(self):
-        return lisp.current_word()
 
-    def push_mark(self):
-        lisp.push_mark()
+    def local_command(self, name, callback, key=None, prefix=False):
+        globals()[name] = callback
+        self._set_interaction(callback, prefix)
+        if self.local_prefix and key:
+            key = self._key_sequence(self.local_prefix + ' ' + key)
+            lisp('(define-key ropemacs-local-keymap "%s" \'%s)' %
+                 (self._key_sequence(key), _lisp_name(name)))
 
-    def prefix_value(self, prefix):
-        return lisp.prefix_numeric_value(prefix)
+    def global_command(self, name, callback, key=None, prefix=False):
+        globals()[name] = callback
+        self._set_interaction(callback, prefix)
+        if self.global_prefix and key:
+            key = self._key_sequence(self.global_prefix + ' ' + key)
+            lisp.global_set_key(key, lisp[_lisp_name(name)])
 
+    def _key_sequence(self, sequence):
+        result = []
+        for key in sequence.split():
+            if key.startswith('C-'):
+                number = ord(key[-1].upper()) - ord('A') + 1
+                result.append(chr(number))
+            elif key.startswith('M-'):
+                number = ord(key[-1].upper()) + 0x80
+                result.append(chr(number))
+            else:
+                result.append(key)
+        return ''.join(result)
+
+    def _set_interaction(self, callback, prefix):
+        if hasattr(callback, 'im_func'):
+            callback = callback.im_func
+        if prefix:
+            callback.interaction = 'P'
+        else:
+            callback.interaction = ''
+
+    def add_hook(self, name, callback, hook):
+        globals()[name] = callback
+        lisp.add_hook(lisp[hook], lisp[_lisp_name(name)])
+
+    @property
+    @utils.cacheit
+    def global_prefix(self):
+        return self.get('ropemacs-global-prefix')
+
+    @property
+    @utils.cacheit
+    def local_prefix(self):
+        return self.get('ropemacs-local-prefix')
+
+
+def _lisp_name(name):
+    return 'rope-' + name.replace('_', '-')
 
 class _LispProgress(object):
 
 occurrences_goto_occurrence.interaction = ''
 
 
-def _register_functions(interface):
-    for attrname in dir(interface):
-        attr = getattr(interface, attrname)
-        if hasattr(attr, 'interaction') or hasattr(attr, 'lisp'):
-            globals()[attrname] = attr
-
-
 DEFVARS = """\
 (defgroup ropemacs nil
   "ropemacs, an emacs plugin for rope."
 
 ropecommon.decorators.logger.message = lisp.message
 lisp(DEFVARS)
-_interface = ropecommon.interface.Ropemacs(env=LispUtils())
-_register_functions(_interface)
+_interface = ropecommon.interface.RopeCommon(env=LispUtils())
 _interface.init()
 lisp(MINOR_MODE)
 lisp.add_hook(lisp['python-mode-hook'], lisp['ropemacs-mode'])
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.