1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
|
<html>
<head>
<title>Writing an addin for MonoDevelop</title>
</head>
<body>
<h3>Introduction</h3>
<p>MonoDevelop (and SharpDevelop) have been written so that they
can be easily extended by others. This can be accomplished by doing
two simple things. First, by creating an assembly (dll) containing
the code for your addin. Second, providing an .addin XML file that
maps your code into MonoDevelop. There is a detailed pdf available
at SharpDevelop's website <a href="http://www.icsharpcode.net/TechNotes/ProgramArchitecture.pdf">here</a> that you will want to read for a
full understanding of the entire system and possiblities. The
SharpDevelop book has information on this as well. This is
intended as a simple and quick overview.</p>
<h3>Terms</h3>
<p><b>AddIn</b> - what many other systems refer to as a plugin. In this case the whole application is also a plugin<br />
<b>Pad</b> - content area like the project browser or output pad. <br />
<b>View</b> - main content area, like the SourceEditor.<br />
<b>Language binding</b> - compilation, execution, and project management for a programming language<br />
<b>Service</b> - reponsible for one part of the program, for example the MessageService is delegated the reponsiblity of displaying messages to the user.
</p>
<h3>AddIn assembly</h3>
<p>In your code you can extend the IDE at pretty much any point.
Some common things would be to extend the menus, pads, views,
services, commands, etc. I recommend looking at src/AddIns/ for a
few examples. In most cases you will simply inherit from an
abstract class or implement an interface for the various parts you
are extending. For example, a new service could be defined as:</p>
<code>
<pre>
using System;
using MonoDevelop.Core.Services;
namespace MonoDevelop.Services;
{
public class ExampleService : AbstractService
{
// Do stuff here
}
}
</pre>
</code>
<p>Here is a list of some of the common classes to extend for an AddIn:
<pre>
./Core/src/MonoDevelop.Base/Gui/Dialogs/AbstractOptionPanel.cs
./Core/src/MonoDevelop.Base/Gui/Dialogs/Wizard/AbstractWizardPanel.cs
./Core/src/MonoDevelop.Base/Gui/Pads/ClassScout/BrowserNode/AbstractClassScoutNode.cs
./Core/src/MonoDevelop.Base/Gui/Pads/ProjectBrowser/BrowserNode/AbstractBrowserNode.cs
./Core/src/MonoDevelop.Base/Gui/AbstractBaseViewContent.cs
./Core/src/MonoDevelop.Base/Gui/AbstractPadContent.cs
./Core/src/MonoDevelop.Base/Gui/AbstractViewContent.cs
./Core/src/MonoDevelop.Base/Gui/AbstractSecondaryViewContent.cs
</pre>
</p>
<h3>.addin.xml file</h3>
<p><b>Note:</b> MonoDevelop had to change to .addin.xml extension for
using gettext in translations. SharpDevelop uses .addin</p>
<p>The addin file basically maps the "entry" points of your code
into the various parts of the IDE. You specify services to load,
append menus in a certain place, and virtually everything else.
Since the entire application is an AddIn there is no limit.
It supports conditional directives and other advanced constructs.
In the following sample MonoDevelopNunit.addin.xml file, you can see
it specifies the name of the assembly to load, specifies a service
to load into the /Workspace/Services node, two views and some menus.
Last, it is important to note the class attribute that is used to
specify the type to instantiate for that part of the AddIn.</p>
<xmp>
<AddIn name = "MonoDevelop Nunit"
author = "John Luke"
copyright = "GPL"
url = "http://monodevelop.com"
description = "NUnit testing tool"
version = "0.2">
<Runtime>
<Import assembly="MonoDevelop.Nunit.dll"/>
</Runtime>
<Extension path="/Workspace/Services">
<Class id = "NunitService"
class = "MonoDevelop.Services.NunitService"/>
</Extension>
<Extension path="/SharpDevelop/Workbench/Views">
<Class id = "NunitTestTree"
class = "MonoDevelop.Nunit.Gui.TestTree"/>
<Class id = "NunitResultTree"
class = "MonoDevelop.Nunit.Gui.ResultTree"/>
</Extension>
<Extension path="/SharpDevelop/Workbench/MainMenu/Tools">
<MenuItem id = "NunitMenu" label = "NUnit" insertafter = "ExternalTools" insertbefore = "Options">
<MenuItem id = "LoadTestAssembly"
_label = "Load Assembly"
shortcut = ""
class = "MonoDevelop.Commands.NunitLoadAssembly" />
<MenuItem id = "NunitRunTests"
_label = "Run Tests"
shortcut = ""
class = "MonoDevelop.Commands.NunitRunTests" />
</MenuItem>
</Extension>
</AddIn>
</xmp>
<h3>AddIn tree</h3>
<p>The various addins are loaded and merge into an AddInTree, which
is how the IDE knows what and where to load. Look at
<code>build/AddIns/SharpDevelopCore.addin.xml</code> to see the
various places to attach your addin, such as the menu items.
</p>
<h3>Building and installing</h3>
<p>We currently support both running in a self-contained <code>build/</code>
directory as well as installing to <code>$(prefix)/lib/monodevelop</code> so you
will want to make sure both your .addin.xml file and .dll are placed
into the AddIn directory in both places. <b>Note:</b> this this may change
at some point in the future.</p>
<p>For those not familiar with autoconf/automake here is a brief
description of what you need to do, if you are wanting to add your
addin to the current build process. This will not be required when
we are self-hosting. Have a Makefile.am that compiles and installs
your dll and addin.xml files. I highly recommend you copy one of
the existing ones as a reference. Add
<code>path/to/your/addin/Makefile</code> to the
<code>AC_OUTPUT</code> section of configure.in.
This creates the Makefile from Makefile.am. In the parent
directory of your addin add your directory to the SUBDIRS variable.
If you are especially prudent you can make sure
<code>make distcheck</code> from the top directory still works.
</p>
<h3>Existing Examples</h3>
<ul>
<li>SourceEditor</li>
<li>CSharpBinding</li>
<li>VBNetBinding</li>
<li>JavaBinding</li>
<li>NemerleBinding</li>
<li>DebuggerAddin</li>
<li>Monodoc</li>
<li>NUnit (incomplete)</li>
</ul>
<h3>Caveats</h3>
<p>Although SharpDevelop and MonoDevelop currently use the same
format this may not always be the case. Also, while non-gui addins
could possibly be reused, MonoDevelop and SharpDevelop use different
GUI toolkits that will likely prevent sharing many things. Any
suggestions on making sharing things as easy as possible would be
appreciated.</p>
<h3>Internationalization</h3>
<p>Since we are using Gettext and not resources, you will want to
read the translation guide as that is handled in a
different way than SharpDevelop, and deserves its own explanation.
</p>
<h3>AddIn ideas</h3>
<p>There are various things that would be nice to have implemented
as addins. Here is a brief list of the top of my head.
<ul>
<li>A viewer for the mono profiler (mono --profile) and mono coverage tools.</li>
<li>Extra languages/compilers support.</li>
<li>NUnit and NAnt integration tools.</li>
<li>Glade (although a new GUI designer is planned).</li>
<li>Integration with Subversion, CVS, and other version control tools.</li>
<li>UML/CASE tools.</li>
<li>An advanced XML editor.</li>
<li>Also, there are some additional things that SharpDevelop already has that could be ported to MonoDevelop.</li>
</ul></p>
<h3>Credits, License, Errata</h3>
<p>Send comments to <a href="mailto:john.luke@gmail.com">john.luke@gmail.com</a> or the <a href="mailto:monodevelop-list@lists.ximian.com">monodevelop mailing list</a>.</p>
<p>Licensed under the <a href="http://opensource.org/licenses/mit-license.php">MIT License</a></p>
<p>Last updated March 18, 2005</p>
</body>
</html>
|