-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsetup-tools.html
More file actions
410 lines (383 loc) · 37.9 KB
/
setup-tools.html
File metadata and controls
410 lines (383 loc) · 37.9 KB
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
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
<!DOCTYPE html>
<html class="writer-html5" lang="en" data-content_root="./">
<head>
<meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Setting up the environment — MO2 Python Plugin API documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=b86133f3" />
<link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" />
<link rel="stylesheet" type="text/css" href="_static/graphviz.css?v=4ae1632d" />
<link rel="shortcut icon" href="_static/mo2.ico"/>
<script src="_static/jquery.js?v=5d32c60e"></script>
<script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
<script src="_static/documentation_options.js?v=5929fcd5"></script>
<script src="_static/doctools.js?v=9bcbadda"></script>
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
<script src="_static/js/theme.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Type of Plugins" href="plugin-types.html" />
<link rel="prev" title="Welcome to MO2 Python Plugin API’s documentation!" href="index.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="index.html" class="icon icon-home">
MO2 Python Plugin API
</a>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="search.html" method="get">
<input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
<ul class="current">
<li class="toctree-l1 current"><a class="current reference internal" href="#">Setting up the environment</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#required-tools">Required tools</a></li>
<li class="toctree-l2"><a class="reference internal" href="#preparation">Preparation</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#get-the-mobase-stubs">1. Get the <code class="docutils literal notranslate"><span class="pre">mobase</span></code> stubs</a></li>
<li class="toctree-l3"><a class="reference internal" href="#configure-visual-studio-code-for-mobase">2. Configure Visual Studio Code for <code class="docutils literal notranslate"><span class="pre">mobase</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="#optional-configure-black-to-auto-format-your-source-files">3. [Optional] Configure <code class="docutils literal notranslate"><span class="pre">black</span></code> to auto-format your source files</a></li>
<li class="toctree-l3"><a class="reference internal" href="#optional-automatically-reload-plugins-during-development">4. [Optional] Automatically reload plugins during development</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="#testing-the-setup">Testing the setup</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="plugin-types.html">Type of Plugins</a><ul>
<li class="toctree-l2"><a class="reference internal" href="plugin-types.html#installers">Installers</a></li>
<li class="toctree-l2"><a class="reference internal" href="plugin-types.html#previewers">Previewers</a></li>
<li class="toctree-l2"><a class="reference internal" href="plugin-types.html#mod-page">Mod Page</a></li>
<li class="toctree-l2"><a class="reference internal" href="plugin-types.html#game">Game</a></li>
<li class="toctree-l2"><a class="reference internal" href="plugin-types.html#tool">Tool</a></li>
<li class="toctree-l2"><a class="reference internal" href="plugin-types.html#proxies">Proxies</a></li>
<li class="toctree-l2"><a class="reference internal" href="plugin-types.html#free-plugins"><em>Free Plugins</em></a></li>
<li class="toctree-l2"><a class="reference internal" href="plugin-types.html#extension-interfaces">Extension Interfaces</a><ul>
<li class="toctree-l3"><a class="reference internal" href="plugin-types.html#diagnose">Diagnose</a></li>
<li class="toctree-l3"><a class="reference internal" href="plugin-types.html#file-mappings">File Mappings</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="writing-plugins.html">Writing Plugins</a><ul>
<li class="toctree-l2"><a class="reference internal" href="writing-plugins.html#getting-started">Getting started</a><ul>
<li class="toctree-l3"><a class="reference internal" href="writing-plugins.html#single-file-plugins">Single file plugins</a></li>
<li class="toctree-l3"><a class="reference internal" href="writing-plugins.html#module-plugins">Module Plugins</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="writing-plugins.html#writing-the-plugin">Writing the plugin</a><ul>
<li class="toctree-l3"><a class="reference internal" href="writing-plugins.html#iplugin-interface"><code class="docutils literal notranslate"><span class="pre">IPlugin</span></code> interface</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="writing-plugins.html#examples">Examples</a><ul>
<li class="toctree-l3"><a class="reference internal" href="writing-plugins.html#tutorial-plugins">Tutorial Plugins</a></li>
<li class="toctree-l3"><a class="reference internal" href="writing-plugins.html#official-plugins">Official Plugins</a></li>
<li class="toctree-l3"><a class="reference internal" href="writing-plugins.html#unofficial-plugins">Unofficial Plugins</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="writing-plugins.html#internationalization">Internationalization</a><ul>
<li class="toctree-l3"><a class="reference internal" href="writing-plugins.html#adding-translation-code">Adding translation code</a></li>
<li class="toctree-l3"><a class="reference internal" href="writing-plugins.html#generating-qt-translation-files">Generating Qt translation files</a></li>
<li class="toctree-l3"><a class="reference internal" href="writing-plugins.html#translating">Translating</a></li>
<li class="toctree-l3"><a class="reference internal" href="writing-plugins.html#distributing-translations">Distributing translations</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="faq.html">FAQ</a><ul>
<li class="toctree-l2"><a class="reference internal" href="faq.html#why-is-mo2-throwing-an-exception-when-i-try-to-create-a-type-inheriting-one-of-mo2-class">1. Why is MO2 throwing an exception when I try to create a type inheriting one of MO2 class?</a></li>
<li class="toctree-l2"><a class="reference internal" href="faq.html#how-can-i-be-sure-to-implement-all-the-required-methods-when-creating-a-plugin">2. How can I be sure to implement all the required methods when creating a plugin?</a></li>
<li class="toctree-l2"><a class="reference internal" href="faq.html#why-are-my-isinstance-x-qobject-and-isinstance-y-qwidget-not-working">3. Why are my <code class="docutils literal notranslate"><span class="pre">isinstance(x,</span> <span class="pre">QObject)</span></code> and <code class="docutils literal notranslate"><span class="pre">isinstance(y,</span> <span class="pre">QWidget)</span></code> not working?</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="autoapi/index.html">API Reference</a><ul>
<li class="toctree-l2"><a class="reference internal" href="autoapi/mobase/index.html">mobase</a><ul>
<li class="toctree-l3"><a class="reference internal" href="autoapi/mobase/index.html#submodules">Submodules</a><ul>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/widgets/index.html">mobase.widgets</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="autoapi/mobase/index.html#attributes">Attributes</a></li>
<li class="toctree-l3"><a class="reference internal" href="autoapi/mobase/index.html#classes">Classes</a></li>
<li class="toctree-l3"><a class="reference internal" href="autoapi/mobase/index.html#functions">Functions</a></li>
<li class="toctree-l3"><a class="reference internal" href="autoapi/mobase/index.html#package-contents">Package Contents</a><ul>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.BSAInvalidation"><code class="docutils literal notranslate"><span class="pre">BSAInvalidation</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.DataArchives"><code class="docutils literal notranslate"><span class="pre">DataArchives</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.EndorsedState"><code class="docutils literal notranslate"><span class="pre">EndorsedState</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.ExecutableForcedLoadSetting"><code class="docutils literal notranslate"><span class="pre">ExecutableForcedLoadSetting</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.ExecutableInfo"><code class="docutils literal notranslate"><span class="pre">ExecutableInfo</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.FileInfo"><code class="docutils literal notranslate"><span class="pre">FileInfo</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.FileTreeEntry"><code class="docutils literal notranslate"><span class="pre">FileTreeEntry</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.GameFeature"><code class="docutils literal notranslate"><span class="pre">GameFeature</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.GamePlugins"><code class="docutils literal notranslate"><span class="pre">GamePlugins</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.GuessQuality"><code class="docutils literal notranslate"><span class="pre">GuessQuality</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.GuessedString"><code class="docutils literal notranslate"><span class="pre">GuessedString</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.IDownloadManager"><code class="docutils literal notranslate"><span class="pre">IDownloadManager</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.IFileTree"><code class="docutils literal notranslate"><span class="pre">IFileTree</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.IGameFeatures"><code class="docutils literal notranslate"><span class="pre">IGameFeatures</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.IInstallationManager"><code class="docutils literal notranslate"><span class="pre">IInstallationManager</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.IModInterface"><code class="docutils literal notranslate"><span class="pre">IModInterface</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.IModList"><code class="docutils literal notranslate"><span class="pre">IModList</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.IModRepositoryBridge"><code class="docutils literal notranslate"><span class="pre">IModRepositoryBridge</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.IOrganizer"><code class="docutils literal notranslate"><span class="pre">IOrganizer</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.IPlugin"><code class="docutils literal notranslate"><span class="pre">IPlugin</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.IPluginDiagnose"><code class="docutils literal notranslate"><span class="pre">IPluginDiagnose</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.IPluginFileMapper"><code class="docutils literal notranslate"><span class="pre">IPluginFileMapper</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.IPluginGame"><code class="docutils literal notranslate"><span class="pre">IPluginGame</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.IPluginInstaller"><code class="docutils literal notranslate"><span class="pre">IPluginInstaller</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.IPluginInstallerCustom"><code class="docutils literal notranslate"><span class="pre">IPluginInstallerCustom</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.IPluginInstallerSimple"><code class="docutils literal notranslate"><span class="pre">IPluginInstallerSimple</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.IPluginList"><code class="docutils literal notranslate"><span class="pre">IPluginList</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.IPluginModPage"><code class="docutils literal notranslate"><span class="pre">IPluginModPage</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.IPluginPreview"><code class="docutils literal notranslate"><span class="pre">IPluginPreview</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.IPluginRequirement"><code class="docutils literal notranslate"><span class="pre">IPluginRequirement</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.IPluginTool"><code class="docutils literal notranslate"><span class="pre">IPluginTool</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.IProfile"><code class="docutils literal notranslate"><span class="pre">IProfile</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.ISaveGame"><code class="docutils literal notranslate"><span class="pre">ISaveGame</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.ISaveGameInfoWidget"><code class="docutils literal notranslate"><span class="pre">ISaveGameInfoWidget</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.InstallResult"><code class="docutils literal notranslate"><span class="pre">InstallResult</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.LoadOrderMechanism"><code class="docutils literal notranslate"><span class="pre">LoadOrderMechanism</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.LocalSavegames"><code class="docutils literal notranslate"><span class="pre">LocalSavegames</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.Mapping"><code class="docutils literal notranslate"><span class="pre">Mapping</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.ModDataChecker"><code class="docutils literal notranslate"><span class="pre">ModDataChecker</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.ModDataContent"><code class="docutils literal notranslate"><span class="pre">ModDataContent</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.ModRepositoryFileInfo"><code class="docutils literal notranslate"><span class="pre">ModRepositoryFileInfo</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.ModState"><code class="docutils literal notranslate"><span class="pre">ModState</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.PluginRequirementFactory"><code class="docutils literal notranslate"><span class="pre">PluginRequirementFactory</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.PluginSetting"><code class="docutils literal notranslate"><span class="pre">PluginSetting</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.PluginState"><code class="docutils literal notranslate"><span class="pre">PluginState</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.ProfileSetting"><code class="docutils literal notranslate"><span class="pre">ProfileSetting</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.ReleaseType"><code class="docutils literal notranslate"><span class="pre">ReleaseType</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.SaveGameInfo"><code class="docutils literal notranslate"><span class="pre">SaveGameInfo</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.ScriptExtender"><code class="docutils literal notranslate"><span class="pre">ScriptExtender</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.SortMechanism"><code class="docutils literal notranslate"><span class="pre">SortMechanism</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.TrackedState"><code class="docutils literal notranslate"><span class="pre">TrackedState</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.UnmanagedMods"><code class="docutils literal notranslate"><span class="pre">UnmanagedMods</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.VersionInfo"><code class="docutils literal notranslate"><span class="pre">VersionInfo</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.VersionScheme"><code class="docutils literal notranslate"><span class="pre">VersionScheme</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.getFileVersion"><code class="docutils literal notranslate"><span class="pre">getFileVersion()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.getIconForExecutable"><code class="docutils literal notranslate"><span class="pre">getIconForExecutable()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.getProductVersion"><code class="docutils literal notranslate"><span class="pre">getProductVersion()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.GameFeatureType"><code class="docutils literal notranslate"><span class="pre">GameFeatureType</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.INVALID_HANDLE_VALUE"><code class="docutils literal notranslate"><span class="pre">INVALID_HANDLE_VALUE</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.MoVariant"><code class="docutils literal notranslate"><span class="pre">MoVariant</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="autoapi/mobase/index.html#mobase.__version__"><code class="docutils literal notranslate"><span class="pre">__version__</span></code></a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="index.html">MO2 Python Plugin API</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="index.html" class="icon icon-home" aria-label="Home"></a></li>
<li class="breadcrumb-item active">Setting up the environment</li>
<li class="wy-breadcrumbs-aside">
<a href="_sources/setup-tools.rst.txt" rel="nofollow"> View page source</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<section id="setting-up-the-environment">
<h1>Setting up the environment<a class="headerlink" href="#setting-up-the-environment" title="Link to this heading"></a></h1>
<p>This page will get you started for creating a MO2 python plugin. If you have troubles getting
everything setup, feel free to come by our discord server at <a class="reference external" href="https://discord.gg/cYwdcxj">https://discord.gg/cYwdcxj</a>.</p>
<section id="required-tools">
<h2>Required tools<a class="headerlink" href="#required-tools" title="Link to this heading"></a></h2>
<p>It is possible to write a MO2 python plugin using any text editor, but this guide will focus on
<a class="reference external" href="https://code.visualstudio.com/">Visual Studio Code</a>.
This guide assumes that:</p>
<ul class="simple">
<li><p>You have <a class="reference external" href="https://code.visualstudio.com/">Visual Studio Code</a> installed with the
<a class="reference external" href="https://marketplace.visualstudio.com/items?itemName=ms-python.python">Python extension</a>.</p></li>
<li><p>You have Python installed: <a class="reference external" href="https://www.python.org/downloads/">https://www.python.org/downloads/</a>.</p>
<ul>
<li><p>You must use the Python version that used by MO2.
You can check the <code class="docutils literal notranslate"><span class="pre">pythonXX.dll</span></code> in the MO2 installation folder to find the Python version used by MO2 (<code class="docutils literal notranslate"><span class="pre">python38.dll</span></code> means Python 3.8).</p></li>
</ul>
</li>
<li><p>You obviously need a valid MO2 installation: <a class="reference external" href="https://github.com/modorganizer2/modorganizer/releases">https://github.com/modorganizer2/modorganizer/releases</a></p>
<ul>
<li><p>This guide is written for MO2 ≥ 2.3.0.</p></li>
</ul>
</li>
</ul>
<p><strong>Note:</strong> In the following, I will refer to the MO2 installation directory as <code class="docutils literal notranslate"><span class="pre">$MO2DIR</span></code>. So if you
installed MO2 at <code class="docutils literal notranslate"><span class="pre">C:\MO2</span></code> and you are asked to copy a file to <code class="docutils literal notranslate"><span class="pre">$MO2DIR/plugins</span></code>, it refers to <code class="docutils literal notranslate"><span class="pre">C:\MO2\plugins</span></code>.</p>
</section>
<section id="preparation">
<h2>Preparation<a class="headerlink" href="#preparation" title="Link to this heading"></a></h2>
<p><strong>Note:</strong> This part is optional but highly recommended if you want a proper environment to work with.
Everything here is written to be as simple as possible but you can of course adapt it to your preferences:
use a python virtual environment, use workspace settings instead of global ones, etc.</p>
<section id="get-the-mobase-stubs">
<h3>1. Get the <code class="docutils literal notranslate"><span class="pre">mobase</span></code> stubs<a class="headerlink" href="#get-the-mobase-stubs" title="Link to this heading"></a></h3>
<p><code class="docutils literal notranslate"><span class="pre">mobase</span></code> is the MO2 Python module. The module is written in C++ and thus cannot be read directly by tools such
as <code class="docutils literal notranslate"><span class="pre">flake8</span></code> or <code class="docutils literal notranslate"><span class="pre">mypy</span></code>.
Instead, we provide <a class="reference external" href="https://stackoverflow.com/questions/59051631/what-is-the-use-of-stub-files-pyi-in-python">stubs</a>
which can be used for auto-completion or type-checking.</p>
<p>You can install the stubs for <code class="docutils literal notranslate"><span class="pre">mobase</span></code> using <code class="docutils literal notranslate"><span class="pre">pip</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">pip</span> <span class="n">install</span> <span class="n">mobase</span><span class="o">-</span><span class="n">stubs</span>
</pre></div>
</div>
<p>This will install the stubs for <code class="docutils literal notranslate"><span class="pre">mobase</span></code> but also for PyQt5, which is heavily used by MO2.</p>
</section>
<section id="configure-visual-studio-code-for-mobase">
<h3>2. Configure Visual Studio Code for <code class="docutils literal notranslate"><span class="pre">mobase</span></code><a class="headerlink" href="#configure-visual-studio-code-for-mobase" title="Link to this heading"></a></h3>
<p>We are going to configure Visual Studio Code to have auto-completion and linting (error and type checking)
for the MO2 Python module.
Open <code class="docutils literal notranslate"><span class="pre">settings.json</span></code> (Ctrl+Shift+P, then “Open Settings (JSON)”), and add the following entries:</p>
<div class="highlight-json-object notranslate"><div class="highlight"><pre><span></span><span class="nt">"python.linting.enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
<span class="nt">"python.linting.mypyEnabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
<span class="nt">"python.linting.flake8Enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
</pre></div>
</div>
</section>
<section id="optional-configure-black-to-auto-format-your-source-files">
<h3>3. [Optional] Configure <code class="docutils literal notranslate"><span class="pre">black</span></code> to auto-format your source files<a class="headerlink" href="#optional-configure-black-to-auto-format-your-source-files" title="Link to this heading"></a></h3>
<p>This step is optional for your own plugin but recent MO2 plugins use <code class="docutils literal notranslate"><span class="pre">black</span></code>
to get consistent formatting.</p>
<p>You can install <code class="docutils literal notranslate"><span class="pre">black</span></code> with <code class="docutils literal notranslate"><span class="pre">pip</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">pip</span> <span class="n">install</span> <span class="n">black</span> <span class="n">flake8</span><span class="o">-</span><span class="n">black</span>
</pre></div>
</div>
<p>To configure Visual Studio Code to auto-format your code with <code class="docutils literal notranslate"><span class="pre">black</span></code> when saving, open <code class="docutils literal notranslate"><span class="pre">settings.json</span></code>
(Ctrl+Shift+P, then “Open Settings (JSON)”), and add the following entries:</p>
<div class="highlight-json-object notranslate"><div class="highlight"><pre><span></span><span class="nt">"editor.formatOnSave"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
<span class="nt">"editor.formatOnPaste"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
<span class="nt">"python.formatting.provider"</span><span class="p">:</span><span class="w"> </span><span class="s2">"black"</span><span class="p">,</span>
</pre></div>
</div>
</section>
<section id="optional-automatically-reload-plugins-during-development">
<h3>4. [Optional] Automatically reload plugins during development<a class="headerlink" href="#optional-automatically-reload-plugins-during-development" title="Link to this heading"></a></h3>
<p>This section is optional and requires you to already have written a “working”
plugin (a plugin that MO2 can load).</p>
<p>Since MO2 2.4 alpha 6, a new command has been added to <code class="docutils literal notranslate"><span class="pre">ModOrganizer.exe</span></code> to
reload plugins during execution.
If your plugin is named “My Plugin”, you can use the following command to reload
it while MO2 is running:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$MO2DIR\ModOrganizer.exe reload-plugin "My Plugin"
</pre></div>
</div>
<p>If you are using Visual Studio Code, you can send this command to MO2 automatically
after saving files from your project.</p>
<ol class="arabic simple">
<li><p>Create a “reload plugin” task in Visual Studio Code (Ctrl+Shift+P then
<code class="docutils literal notranslate"><span class="pre">Tasks:</span> <span class="pre">Configure</span> <span class="pre">task</span></code> or open <code class="docutils literal notranslate"><span class="pre">.vscode/tasks.json</span></code>) using the following
snippet (replace the name and directory as needed):</p></li>
</ol>
<div class="highlight-javascript notranslate"><div class="highlight"><pre><span></span><span class="c1">// .vscode/tasks.json</span>
<span class="p">{</span>
<span class="w"> </span><span class="c1">// See https://go.microsoft.com/fwlink/?LinkId=733558</span>
<span class="w"> </span><span class="c1">// for the documentation about the tasks.json format</span>
<span class="w"> </span><span class="s2">"version"</span><span class="o">:</span><span class="w"> </span><span class="s2">"2.0.0"</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"tasks"</span><span class="o">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"label"</span><span class="o">:</span><span class="w"> </span><span class="s2">"reload plugin"</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"type"</span><span class="o">:</span><span class="w"> </span><span class="s2">"shell"</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"command"</span><span class="o">:</span><span class="w"> </span><span class="s2">"$MO2DIR/ModOrganizer.exe"</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"args"</span><span class="o">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="s2">"reload-plugin"</span><span class="p">,</span><span class="w"> </span><span class="s2">"My Plugin"</span>
<span class="w"> </span><span class="p">]</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">]</span>
<span class="p">}</span>
</pre></div>
</div>
<ol class="arabic simple" start="2">
<li><p>Install the <a class="reference external" href="https://marketplace.visualstudio.com/items?itemName=Gruntfuggly.triggertaskonsave">Trigger Task on Save</a>
extension from Visual Studio Code marketplace.</p></li>
<li><p>Add the following to your Visual Studio Code settings (<code class="docutils literal notranslate"><span class="pre">.vscode/settings.json</span></code>)</p></li>
</ol>
<div class="highlight-javascript notranslate"><div class="highlight"><pre><span></span><span class="c1">// .vscode/settings.json</span>
<span class="p">{</span>
<span class="w"> </span><span class="s2">"triggerTaskOnSave.on"</span><span class="o">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
<span class="w"> </span><span class="s2">"triggerTaskOnSave.tasks"</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">"reload plugin"</span><span class="o">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="s2">"*.py"</span>
<span class="w"> </span><span class="p">]</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</section>
</section>
<section id="testing-the-setup">
<h2>Testing the setup<a class="headerlink" href="#testing-the-setup" title="Link to this heading"></a></h2>
<p>Create a new Python file in Visual Studio Code, and paste the following content (if you create
the file in <code class="docutils literal notranslate"><span class="pre">$MO2DIR\plugins</span></code>, do not forget to delete it after since it is not a valid
plugin):</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">mobase</span>
<span class="k">class</span><span class="w"> </span><span class="nc">MyPlugin</span><span class="p">(</span><span class="n">mobase</span><span class="o">.</span><span class="n">IPluginTool</span><span class="p">):</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">()</span>
<span class="k">def</span><span class="w"> </span><span class="nf">init</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">organizer</span><span class="p">:</span> <span class="n">mobase</span><span class="o">.</span><span class="n">IOrganizer</span><span class="p">)</span> <span class="o">-></span> <span class="nb">bool</span><span class="p">:</span>
<span class="n">organizer</span><span class="o">.</span><span class="n">dow</span> <span class="c1"># (1)</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">def</span><span class="w"> </span><span class="nf">name</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">int</span><span class="p">:</span>
<span class="k">return</span> <span class="mi">0</span>
<span class="k">def</span><span class="w"> </span><span class="nf">createPlugin</span><span class="p">()</span> <span class="o">-></span> <span class="n">mobase</span><span class="o">.</span><span class="n">IPlugin</span><span class="p">:</span>
<span class="k">return</span> <span class="n">MyPlugin</span><span class="p">()</span>
</pre></div>
</div>
<p>If your setup is valid, here is what you should have.</p>
<ul class="simple">
<li><p>You should see the following (with the errors underlined):</p></li>
</ul>
<img alt="_images/check-setup-1.png" src="_images/check-setup-1.png" />
<ul class="simple">
<li><p>If you press <code class="docutils literal notranslate"><span class="pre">Ctrl+Space</span></code> after <code class="docutils literal notranslate"><span class="pre">.down</span></code> (1), you should see the following
meaning that auto-complete is working:</p></li>
</ul>
<img alt="_images/check-setup-2.png" src="_images/check-setup-2.png" />
<ul class="simple">
<li><p>In the error window (click <img alt="error-window" src="_images/error-window.png" /> on the status bar), you should see
the 3 following errors:</p></li>
</ul>
<img alt="_images/check-setup-3.png" src="_images/check-setup-3.png" />
<p>If everything is as above, you can delete the test file and move on to writing
your own plugin!</p>
</section>
</section>
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="index.html" class="btn btn-neutral float-left" title="Welcome to MO2 Python Plugin API’s documentation!" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="plugin-types.html" class="btn btn-neutral float-right" title="Type of Plugins" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>
<div role="contentinfo">
<p>© Copyright 2023, Holt59.</p>
</div>
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>