emacs.py :  » IDE » PIDA » pida-0.6beta3 » pida » editors » emacs » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » IDE » PIDA 
PIDA » pida 0.6beta3 » pida » editors » emacs » emacs.py
# -*- coding: utf-8 -*- 

"""
    The Emacs editor core classes for Pida
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    This module and other Pida Emacs related classes
    are based on preliminary worksby Ali Afshar
    (see Emacs module in Pida 0.2.2).

    The Emacs editor for Pida is also,
    heavily based on the Vim editor.

    :copyright: 2007-2008 by The PIDA Project
    :license: GPL 2 or later (see README/COPYING/LICENSE)
 
""" 


import logging
import os

# PIDA Imports
import pida.core.environment as env

from pida.ui.views import PidaView

from pida.core.log import get_logger
from pida.core.editors import EditorService

# Emacs specific
from .emacsembed import EmacsEmbedWidget
from .emacscom import EmacsClient

from pida.core.pdbus import DbusConfig,EXPORT

EEXPORT = EXPORT(suffix='emacs')

class EmacsView(PidaView):
    """
    UI class for emacs editor 
    uses EmacsEmbedWidget to integrate into a PidaView widget
    """
    def create_ui(self):
        self._emacs = EmacsEmbedWidget(
            'emacs',
            self.svc.initscript,
             ['-eval', '(pida-connect 1001)']
        )
        self.add_main_widget(self._emacs)

    def run(self):
        self._emacs.run()

    def grab_input_focus(self):
        self._emacs.grab_input_focus()


class EmacsCallback(object):
    """Emacs editor callback behaviours.

    Communication is done over dbus 
    """

    def __init__(self, svc):
        """Constructor."""
        self._log = get_logger('emacs')
        self._svc = svc

    def em_BufferOpen(self, filename):
        """File opened event."""
        if filename:
            self._log.debug('emacs buffer opened "%s"' % filename)
            self._svc.boss.cmd('buffer', 'open_file', file_name=filename)
        return True

    def em_BufferChange(self, filename):
        """Buffer changed event.
        Actually, this hook is called whenever the window containing the
        buffer changes. So notification can occur only when window is resized
        or split for example.
        """
        self._svc.top_buffer = filename
        current = self._svc.current_document
        try:
            if filename and (not current or current.filename != filename):
                self._log.debug('emacs buffer changed "%s"' % filename)
                if os.path.isdir(filename):
                    self._svc.boss.cmd('filemanager', 'browse', 
                                       new_path=filename)
                    self._svc.boss.cmd('filemanager', 'present_view')
                else:
                    self._svc.boss.cmd('buffer', 'open_file', 
                                       file_name=filename)
        except IOError:
            pass
        return True


    def em_BufferClose(self, filename):
        """Buffer closed event."""
        if filename:
            self._log.debug('emacs buffer killed "%s"' % filename)
            self._svc.remove_file(filename)
            self._svc.boss.cmd('buffer', 'close_file', file_name=filename)
        return True

    def em_BufferSave(self, filename):
        """Buffer saved event."""
        self._log.debug('emacs buffer saved "%s"' % filename)
        self._svc.boss.cmd('buffer', 'current_file_saved')
        return True

    def em_EmacsKill(self):
        """Emacs killed event."""
        self._log.debug('emacs killed')
        self._svc.inactivate_client()
        self._svc.boss.stop(force=True)
        return False

class EmacsDbusConfig(DbusConfig):
    

    @EEXPORT(out_signature = '', in_signature = '')
    def EmacsEnter(self):
        """
        This method is called by emacs to notify emacs is started.
        """
        self.svc.emit_editor_started()

class Emacs(EditorService):
    """The Emacs service.
    This service is the Emacs editor driver. 
    """ 
    dbus_config = EmacsDbusConfig

    def _create_initscript(self):
        return env.get_data_path('pida_emacs_dbus.el')

    def emit_editor_started(self):
        """called when emacs started: Let notify the other services 
        and connect to dbus signals
        """
        self._cb = EmacsCallback(self)
        self._client = EmacsClient(self._cb, self)
        self._client.connect_signals()
        self.boss.get_service('editor').emit('started')
        
    def pre_start(self):
        """Start the editor"""
        self._documents = {}

        # The current document. Its value is set by Pida and used to drop
        # useless messages to emacs.
        self._current = None

        # The current buffer displayed. Its value is set by the EmacsCallback
        # instance and is used as well to prevent sending useless messages.
        self._top_buffer = ''

        self._current_line = 1

        # Prepare logger for emacs related stuff.
        format = logging.Formatter('%(levelname)s %(name)s: %(message)s')
        emacs_logger = get_logger('emacs')
        handler = logging.StreamHandler()
        handler.setFormatter(format)
        emacs_logger.addHandler(handler)
        if env.is_debug():
            emacs_logger.setLevel(logging.DEBUG)
        else:
            emacs_logger.setLevel(logging.INFO)

        #Start Emacs view
        self.initscript = self._create_initscript()
        self._view = EmacsView(self)
        self.boss.window.add_view(paned='Editor', view=self._view)
        self._view.run()


    def stop(self):
        self._client.quit()

    def _get_current_document(self):
        return self._current

    def _set_current_document(self, document):
        self._current = document

    current_document = property(fget=_get_current_document,
                                fset=_set_current_document,
                                fdel=None,
                                doc="The document currently edited")

    def _get_top_buffer(self):
        return self._top_buffer

    def _set_top_buffer(self, filename):
        self._top_buffer = filename

    top_buffer = property(fget=_get_top_buffer,
                          fset=_set_top_buffer,
                          fdel=None,
                          doc="Last buffer reported as being viewed by emacs")

    def inactivate_client(self):
        pass

    def open(self, document):
        """Open a document"""
        if document is not self._current:
            if self.top_buffer != document.filename:
                if document.unique_id in self._documents:
                    self._client.change_buffer(document.filename)
                else:
                    self._client.open_file(document.filename)
                    self._documents[document.unique_id] = document
            self.current_document = document

    def open_many(self, documents):
        """Open a few documents"""
        pass
    
    def close(self, document):
        if document.unique_id in self._documents:
            self._remove_document(document)
            self._client.close_buffer(document.filename)
        return True

    def remove_file(self, filename):
        document = self._get_document_for_filename(filename)
        if document is not None:
            self._remove_document(document)

    def _remove_document(self, document):
        del self._documents[document.unique_id]

    def _get_document_for_filename(self, filename):
        for uid, doc in self._documents.iteritems():
            if doc.filename == filename:
                return doc
            
    def close_all(self):
        """Close all the documents"""

    def save(self):
        """Save the current document"""
        self._client.save_buffer()

    def save_as(self, filename):
        """Save the current document as another filename"""
        pass # TODO

    def goto_line(self, line):
        """Goto a line"""
        self._client.goto_line(line)
        self.grab_focus()

    def cut(self):
        """Cut to the clipboard"""
        self._client.cut()

    def copy(self):
        """Copy to the clipboard"""
        self._client.copy()

    def paste(self):
        """Paste from the clipboard"""
        self._client.paste()

    def undo(self):
        self._client.undo()

    def redo(self):
        self._client.redo()

    def grab_focus(self):
        """Grab the focus"""
        self._view.grab_input_focus()

    def define_sign_type(self, name, icon, linehl, text, texthl):
        # TODO
        pass
    
    def undefine_sign_type(self, name):
        # TODO
        pass
    
    def show_sign(self, sign_type, filename, line):
        # TODO
        pass
    
    def hide_sign(self, sign_type, filename, line):
        # TODO
        pass
    
    def set_current_line(self, line_number):
        self._current_line = line_number

    def get_current_line(self):
        return self._current_line

    def set_path(self, path):
        return self._client.set_directory(path)


# Required Service attribute for service loading
Service = Emacs


# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.