rope / ropemacs.py

The trunk branch has multiple heads

Ali Gholami Rudi 00521e9 






Ali Gholami Rudi b20f595 
Ali Gholami Rudi 00521e9 









































Ali Gholami Rudi c2f97cb 

Ali Gholami Rudi 00521e9 

































































































































































































Ali Gholami Rudi cef3c52 


Ali Gholami Rudi 00521e9 






















































from Pymacs import lisp

import rope.refactor.extract
import rope.refactor.inline
import rope.refactor.move
import rope.refactor.rename
from rope.base import project, libutils
from rope.contrib import codeassist


class interactive(object):

    def __init__(self, mode=''):
        self.mode = mode

    def __call__(self, func):
        func.interaction = self.mode
        return func


class RopeInterface(object):

    def __init__(self):
        self.project = None
        self.old_content = None

    def init(self):
        """Initialize rope mode"""
        lisp.add_hook(lisp.before_save_hook,
                      lisp.rope_before_save_actions)
        lisp.add_hook(lisp.after_save_hook,
                      lisp.rope_after_save_actions)
        lisp.add_hook(lisp.kill_emacs_hook,
                      lisp.rope_exiting_actions)

        actions = [
            ('C-x p o', lisp.rope_open_project),
            ('C-x p k', lisp.rope_close_project),
            ('C-x p u', lisp.rope_undo_refactoring),
            ('C-x p r', lisp.rope_redo_refactoring),

            ('C-c r r', lisp.rope_rename),
            ('C-c r l', lisp.rope_extract_variable),
            ('C-c r m', lisp.rope_extract_method),
            ('C-c r i', lisp.rope_inline),
            ('C-c r v', lisp.rope_move),
            ('C-c r 1 r', lisp.rope_rename_current_module),
            ('C-c r 1 v', lisp.rope_move_current_module),
            ('C-c r 1 p', lisp.rope_module_to_package),

            ('C-c g', lisp.rope_goto_definition),
            ('C-c C-d', lisp.rope_show_doc),
            ('C-c i o', lisp.rope_organize_imports)]
        for key, callback in actions:
            lisp.global_set_key(self._key_sequence(key), callback)

    def _key_sequence(self, sequence):
        result = []
        for key in sequence.split():
            if key.lower().startswith('c-'):
                number = ord(key[-1].upper()) - ord('A') + 1
                result.append(chr(number))
            else:
                result.append(key)
        return ''.join(result)

    def before_save_actions(self):
        if self.project is not None:
            resource = self._get_resource()
            if resource is not None and resource.exists():
                self.old_content = resource.read()
            else:
                self.old_content = ''

    def after_save_actions(self):
        if self.project is not None:
            libutils.report_change(self.project, lisp.buffer_file_name(),
                                   self.old_content)
            self.old_content = None

    def exiting_actions(self):
        if self.project is not None:
            self.close_project()

    @interactive('DRope Project Root Folder: ')
    def open_project(self, root):
        if self.project is not None:
            self.close_project()
        self.project = project.Project(root)

    @interactive()
    def close_project(self):
        if project is not None:
            self.project.close()
            self.project = None
            lisp.message('Project closed')

    @interactive('cUndo refactoring might change many files; proceed? (y)')
    def undo_refactoring(self, confirm):
        if chr(confirm) in ('\r', '\n', 'y'):
            self._check_project()
            for changes in self.project.history.undo():
                self._reload_buffers(changes.get_changed_resources())

    @interactive('cRedo refactoring might change many files; proceed? (y)')
    def redo_refactoring(self, confirm):
        if chr(confirm) in ('\r', '\n', 'y'):
            self._check_project()
            for changes in self.project.history.redo():
                self._reload_buffers(changes.get_changed_resources())

    def do_rename(self, newname, module=False):
        self._check_project()
        lisp.save_some_buffers()
        resource, offset = self._get_location()
        if module:
            offset = None
        renamer = rope.refactor.rename.Rename(self.project, resource, offset)
        changes = renamer.get_changes(newname, docs=True)
        self._perform(changes)

    @interactive('sNew Name: ')
    def rename(self, newname):
        self.do_rename(newname)

    @interactive('sNew Module Name: ')
    def rename_current_module(self, newname):
        self.do_rename(newname, module=True)

    @interactive()
    def move(self):
        mover = self._create_mover()
        if isinstance(mover, rope.refactor.move.MoveGlobal):
            lisp.call_interactively(lisp.rope_move_global)
        if isinstance(mover, rope.refactor.move.MoveModule):
            lisp.call_interactively(lisp.rope_move_module)
        if isinstance(mover, rope.refactor.move.MoveMethod):
            lisp.call_interactively(lisp.rope_move_method)

    def _create_mover(self, module=False):
        self._check_project()
        lisp.save_some_buffers()
        resource, offset = self._get_location()
        if module:
            offset = None
        return rope.refactor.move.create_move(self.project, resource, offset)

    @interactive('sDestination Module Name: ')
    def move_global(self, dest_module):
        mover = self._create_mover()
        destination = self.project.pycore.find_module(dest_module)
        self._perform(mover.get_changes(destination))

    @interactive('sDestination Attribute: ')
    def move_method(self, dest_attr):
        mover = self._create_mover()
        self._perform(mover.get_changes(dest_attr,
                                        mover.get_method_name()))

    @interactive('sDestination Package: ')
    def move_module(self, dest_package):
        mover = self._create_mover()
        destination = self.project.pycore.find_module(dest_package)
        self._perform(mover.get_changes(destination))

    @interactive('sDestination Package: ')
    def move_current_module(self, dest_package):
        mover = self._create_mover(module=True)
        destination = self.project.pycore.find_module(dest_package)
        self._perform(mover.get_changes(destination))

    @interactive()
    def module_to_package(self):
        self._check_project()
        lisp.save_buffer()
        packager = rope.refactor.ModuleToPackage(self.project,
                                                 self._get_resource())
        self._perform(packager.get_changes())

    def _do_extract(self, extractor, newname):
        self._check_project()
        lisp.save_buffer()
        resource = self._get_resource()
        start, end = self._get_region()
        extractor = extractor(self.project, resource, start, end)
        changes = extractor.get_changes(newname)
        self._perform(changes)

    @interactive('sNew Variable Name: ')
    def extract_variable(self, newname):
        self._do_extract(rope.refactor.extract.ExtractVariable, newname)

    @interactive('sNew Method Name: ')
    def extract_method(self, newname):
        self._do_extract(rope.refactor.extract.ExtractMethod, newname)

    @interactive()
    def inline(self):
        self._check_project()
        lisp.save_some_buffers()
        resource, offset = self._get_location()
        inliner = rope.refactor.inline.create_inline(
            self.project, resource, offset)
        self._perform(inliner.get_changes())

    @interactive()
    def organize_imports(self):
        self._check_project()
        lisp.save_buffer()
        organizer = rope.refactor.ImportOrganizer(self.project)
        self._perform(organizer.organize_imports(self._get_resource()))

    def _perform(self, changes):
        if changes is None:
            return
        self.project.do(changes)
        self._reload_buffers(changes.get_changed_resources())
        lisp.message(str(changes.description) + ' finished')

    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_offset(self):
        return lisp.point() - 1

    @interactive()
    def goto_definition(self):
        self._check_project()
        resource, offset = self._get_location()
        definition = codeassist.get_definition_location(
            self.project, lisp.buffer_string(), offset, resource)
        if definition[0]:
            lisp.find_file(definition[0].real_path)
        if definition[1]:
            lisp.goto_line(definition[1])

    @interactive()
    def show_doc(self):
        self._check_project()
        resource, offset = self._get_location()
        docs = codeassist.get_doc(
            self.project, lisp.buffer_string(), offset, resource)
        pydoc_buffer = lisp.get_buffer_create('*rope-pydoc*')
        lisp.set_buffer(pydoc_buffer)
        lisp.erase_buffer()
        if docs:
            lisp.insert(docs)
            lisp.display_buffer(pydoc_buffer)

    def _get_location(self):
        resource = self._get_resource()
        offset = self._get_offset()
        return resource, offset

    def _get_resource(self):
        filename = lisp.buffer_file_name()
        resource = libutils.path_to_resource(self.project, filename, 'file')
        return resource

    def _check_project(self):
        if self.project is None:
            lisp.call_interactively(lisp.rope_open_project)
        else:
            self.project.validate(self.project.root)

    def _reload_buffers(self, changed_resources):
        for resource in changed_resources:
            buffer = lisp.find_buffer_visiting(resource.real_path)
            if buffer and resource.exists():
                lisp.set_buffer(buffer)
                lisp.revert_buffer(None, 1)


interface = RopeInterface()

init = interface.init
open_project = interface.open_project
close_project = interface.close_project
undo_refactoring = interface.undo_refactoring
redo_refactoring = interface.redo_refactoring

rename = interface.rename
extract_variable = interface.extract_variable
extract_method = interface.extract_method
inline = interface.inline
rename_current_module = interface.rename_current_module
module_to_package = interface.module_to_package
move = interface.move
move_global = interface.move_global
move_module = interface.move_module
move_method = interface.move_method
move_current_module = interface.move_current_module

organize_imports = interface.organize_imports

before_save_actions = interface.before_save_actions
after_save_actions = interface.after_save_actions
exiting_actions = interface.exiting_actions

goto_definition = interface.goto_definition
show_doc = interface.show_doc
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.