Files

410 lines
38 KiB
HTML
Raw Permalink Normal View History

<!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 &mdash; 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 APIs 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">&quot;python.linting.enabled&quot;</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
<span class="nt">&quot;python.linting.mypyEnabled&quot;</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
<span class="nt">&quot;python.linting.flake8Enabled&quot;</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">&quot;editor.formatOnSave&quot;</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
<span class="nt">&quot;editor.formatOnPaste&quot;</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
<span class="nt">&quot;python.formatting.provider&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;black&quot;</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 &quot;My Plugin&quot;
</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">&quot;version&quot;</span><span class="o">:</span><span class="w"> </span><span class="s2">&quot;2.0.0&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;tasks&quot;</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">&quot;label&quot;</span><span class="o">:</span><span class="w"> </span><span class="s2">&quot;reload plugin&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;type&quot;</span><span class="o">:</span><span class="w"> </span><span class="s2">&quot;shell&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;command&quot;</span><span class="o">:</span><span class="w"> </span><span class="s2">&quot;$MO2DIR/ModOrganizer.exe&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="s2">&quot;args&quot;</span><span class="o">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="s2">&quot;reload-plugin&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;My Plugin&quot;</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">&quot;triggerTaskOnSave.on&quot;</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">&quot;triggerTaskOnSave.tasks&quot;</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s2">&quot;reload plugin&quot;</span><span class="o">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="s2">&quot;*.py&quot;</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">-&gt;</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">-&gt;</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">-&gt;</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 APIs 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>&#169; 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>