代码改变世界

NINJA-IDE插件编写(Draft)

2012-01-11 19:25  ubunoon  阅读(2521)  评论(1编辑  收藏  举报

 NINJA是新出的Python的IDE工具,全称是NINJA is not just anther IDE,主要由Python语言用PyQt作为底层核心进行开发的,非常容易做扩展。目前放出的版本,功能相对很简单,但启动速度还是蛮快的。

 

NINJA-IDE目前只是2.0的beta版本,plugin方式可能会被修改。

 

总结:

NINJA-IDE功能可以很容易通过插件扩展,可以通过下面的方式添加:

1、插件描述,因此NINJA-IDE可以被应用集成

2、插件源码

3、ServiceLocator对象,插件通过这个与IDE进行交互。

 

注意:最好的方式是通过理解内部的源码。

 

最新的NINJA-IDE构架允许插件通过下面两种方式与NINJA-IDE核心交互

  • 直接方式:插件启动交互
  • 间接方式:核心NINJA-IDE启动插件交互监听然后与之交互

 

插件描述:

一个文件后缀为".plugin"的json描述文件。下面的信息必须在插件描述中:

{
"module": "my_plugin",
"class": "MyPluginExample",
"authors": "Martin Alderete <malderete@gmail.com>",
"version": "0.1",
"url": "http://code.google.com/p/ninja-ide",
"description": "Este plugin es de prueba"
}

 

module:模块名称,插件代码放置位置,被NINJA-IDE初始化实例

class : 提示实现插件的类名称

authors:作者数组

version:插件版本

url : 插件url可能的doc文档位置

description:插件描述

 

注意,插件是一个文件夹,必须创建__init__.py文件,在__init__.py文件必须导入主要实现类,如下:

from my_plugin import MyPluginExample

(译注:其实就是python的package,在原文中为init.py,与从网上下载的__init__.py有差别) 

 

需要NINJA-IDE插件基础

因为是通过PyQt小件,如QMenu,QAction,QEvent等构建插件

 

插件

ninja_ide.core.plugin.Plugin: 每个插件的基类,提供两个函数用来覆盖,initialize, finish。

Instance attributes Description
locator ServiceLocator类的实例
metadata 插件描述,会被NINJA-IDE自动设置

 

 

Instance methods Description
initialize(self) 插件被载入时调用
finish(self) 插件被卸载时调用
get_preferences_widget(self) 当配置打开时调用,必须反悔一个QWidget的子类实例,使用IPluginPreferences接口

 

ServiceLocator

ninja_ide.core.plugin_manager.ServiceLocator 对象给插件提供服务

 

Instance attributes Description
get_availables_services(self) 所有可用服务的名字列表
get_service(self, service_name) 返回服务


Plugin Interfaces

ninja_ide.core.plugin_interfaces:  文件包含了USEFUL接口,不需要一些行为,例如添加一个“新的工程类型"

IProjectTypeHandler: 创建工程类型处理句柄

ISmbolsHandler创建符号句柄

IPluginPreferences配置小件插件

 

NINJA-IDE Services

通过PLUGINS和NINJA-IDE交互的服务。

可以使用的服务有:

  • editor
  • toolbar
  • menuApp
  • misc
  • explorer

editor: 允许与Editor交互

 

Events(事件) Description(描述)
editorKeyPressEvent(QEvent) 键按下时发送
fileSaved(fileName) 文件保存时发送
currentTabChanged(fileName) 当前tab更改时发送
executeFile(fileName) 文件被执行时发送
executeProject(projectName) 工程被执行时发送

 

Instance methods(实例方法) Description(描述) Returns(返回值)
add_menu(self, menu, lang="py") 在上下文上添加菜单  
get_editor(self) 获取获得焦点的编辑器 Editor or None
get_editor_path(self) 获取当前文件路径 String
add_editor(self, fileName="") 添加一个editor到IDE中  
get_text(self) 获取编辑器中的纯文本 String or None
insert_text(self, text) 插入文本到当前位置  
jump_to_line(self, lineno) 跳到某一行  
get_lines_count(self) 获取当前编辑器的行数 Integer or None


toolbar:允许与工具条交互

 

Instance methods(实例方法) Description(描述)
add_action(self, action) 在工具条中添加action


menuApp: 允许与菜单插件交互

 

Instance methods(实例方法) Description(描述)
add_menu(self, menu) NINJA-IDE中添加一个菜单
add_action(self, action) NINJA-IDE中添加一个菜单行为


misc:与MiscContainer交互(ninja底部panel,console所在的panel)

 

Instance methods(实例方法) Description(描述)
add_widget(self, widget, icon_path, description) 用给定的icon和提示在容器中添加一个widget


explorer:允许与Explorer交互

 

Instance methods(实例方法) Description(描述) Returns(返回值)
get_tree_projects(self) 获取树工程对象(如果数可视) gui.explorer.tree_projects_widget.TreeProjectsWidget or None
get_current_project_item(self) 从树工程中获取当前节点 gui.explorer.tree_projects_widget.ProjectTree or gui.explorer.tree_projects_widget.ProjectItem
get_tree_symbols(self) 获取树符号(如果可视) gui.explorer.tree_symbols_widget.TreeSymbolsWidget or None
set_symbols_handler(self, file_extension, symbols_handler) 为给定文件添加一个新的符号句柄,符号句柄必须有一个特殊的接口ninja_ide.core.plugin_interfaces None
set_project_type_handler(self, project_type, project_type_handler) 给新的工程累i系那个添加一个句柄,project_type_handler必须有一个特殊的接口,见 ninja_ide.core.plugin_interfaces None
add_tab(self, tab, title) 用给定名称添加一个tab None
get_actual_project(self) 返回打开工程的路径 String
add_project_menu(self, menu, lang='all') 为给定文件后缀,添加额外的菜单当到工程explorer中, None


ok,熟悉完所有的接口信息后,可以编写插件了

首先创建一个josn插件文件描述符。my_plugin.plugin

 

{
"module": "my_plugin",
"class": "ExamplePlugin",
"authors": "Martin Alderete <malderete@gmail.com>",
"version": "0.1",
"description": "Example of NINJA-IDE plugin"
}


注意:与Python不一样,此处的json用的是Python的json包进行解析,因此最后的一个描述后面,一定不要添加 , 否则会出现NINJA-IDE启动不了。


最小的插件代码

from ninja_ide.core import plugin


class ExamplePlugin(plugin.Plugin):

def initialize(self):
print "This message go to the console when the plugins is loaded"


是的,我们创建自己的插件,这个插件不能够做任何事情。


更高级的插件

首先,我们给NINJA-IDE添加一个插件菜单行为,然后连接单击事件

 

from ninja_ide.core import plugin

from PyQt4.QtGui import QAction
from PyQt4.QtGui import QDialog


class ExamplePlugin(plugin.Plugin):

def initialize(self):
self.menuapp_s = self.locator.get_service('menuApp')
self.action = QAction("Example plugin menu action", self)
self.connect(self.action, SIGNAL("triggered()"), self.action_click)
self.menuapp_s.add_action(self.action)

def action_click(self):
d = Dialog()
d.exec_()


class Dialog(QDialog):
def __init_(self):
QDialog.__init__(self)

接下来,我们可以处理Editor的keyPressEvent事件

from ninja_ide.core import plugin
from PyQt4.QtCore import Qt


class ExamplePlugin(plugin.Plugin):

def initialize(self):
self.editor_s = self.locator.get_service('editor')
self.editor_s.editorKeyPressEvent.connect(self.handle_keyPress)

def handle_keyPress(self, event):
if event.key() in (Qt.Key_Enter, Qt.Key_Return):
print "Someone has pressed the return key"


至此,一个完整的NINJA-IDE工程插件结束