{"action":"created","comment":{"url":"https://api.github.com/repos/geany/geany/pulls/comments/36866049","id":36866049,"diff_hunk":"@@ -186,59 +195,143 @@ Let's start with the very basic headers and add more later if necessary.\n @a geanyplugin.h includes all of the Geany API and also the necessary GTK header files,\n so there is no need to include @a gtk/gtk.h yourself.\n \n-@note\n-@a plugindata.h contains the biggest part of the plugin API and provides some basic macros.\n-\n-Then you should define two basic variables which will give access to data fields\n-provided by the plugin API.\n-@code\n-GeanyPlugin\t\t\t*geany_plugin;\n-GeanyData\t\t\t*geany_data;\n-@endcode\n+@note @a plugindata.h contains the biggest part of the plugin API and provides some basic macros.\n \n Now you can go on and write your first lines for your new plugin. As mentioned before,\n-you will need to implement and fill out a couple of functions/macros to make the plugin work.\n-So let's start with PLUGIN_VERSION_CHECK().\n-\n-PLUGIN_VERSION_CHECK() is a convenient way to tell Geany which version of Geany's plugin API\n-is needed at minimum to run your plugin. The value is defined in\n+you will need to implement and a couple of functions. Arguably the most important\n+one is @a geany_load_module(). This is the function that makes Geany see you plugin at all. When\n+Geany scans the pre-defined and user-configured plugin directories, it will take a look at each\n+shared library (or DLL on Windows) to see if it exports a @a geany_load_module() symbol. Files\n+lacking these will be outright ignored.\n+\n+@subsection register Registering a Plugin\n+\n+Geany will then invoke this function, always and regardless of whether the user activates your\n+plugin. In fact its purpose to probe if the plugin should even be presented to the user. Therefore\n+it important that you use this function to register your plugin, making it available to the user.\n+Geany will pass a pointer to a GeanyPlugin instance which acts as a unique handle to your plugin.\n+Use this pointer for registering and later API calls. Registering the plugin consists of a number\n+of steps:\n+\n+  1. Filling GeanyPlugin::info with metadata\n+    - @ref PluginInfo::name : The name of your plugin\n+    - @ref PluginInfo::description : A brief description.\n+    - @ref PluginInfo::version : The current version.\n+    - @ref PluginInfo::author : Your contanct information.\n+    .\n+    Filling all of them is recommended to provide the best user experience, but only the name is truly\n+    mandatory.\n+  2. Filling GeanyPlugin::funcs with function pointers\n+    - @ref GeanyPluginFuncs::init : an initialization function\n+    - @ref GeanyPluginFuncs::cleanup : a finalization function\n+    - @ref GeanyPluginFuncs::configure : a function that provides configuration (optional)\n+    - @ref GeanyPluginFuncs::help : a function that provides help (optional)\n+    - @ref GeanyPluginFuncs::callbacks : a pointer to an array of PluginCallback (optional).\n+    .\n+    @a init and @a cleanup are mandatory, the other ones depend on how advanced your plugin is.\n+    Furthermore, the @a init and @a cleanup\n+    pair is called when the user activates your plugin in the Plugin Manager. So use these to\n+    do advanced initialization and teardown as to not waste resources when the plugin is not even\n+    enabled.\n+  3. Registering for real by calling @a geany_plugin_register(). You must pass the GeanyPlugin\n+    pointer that your received and filled out as above. geany_plugin_register() also takes\n+    various version numbers which are detailed below. Please <b>use the macro @a\n+    GEANY_PLUGIN_REGISTER()</b> where you only specify the minimum API version. Please also\n+    <b>observer the return value</b> of geany_plugin_register(). Geany may refuse to load your\n+    plugin due to incompatibilities, you should then abort any extra setup.\n+  4. Optionally setting user data that is passed to GeanyPlugin::funcs with geany_plugin_set_data().\n+    Here you can set a data pointer that is passed back to your functions called by Geany. This\n+    allows to avoid global variables which may be useful. It also allows to set instance pointer\n+    to objects in case your plugin isn't written in pure C, enabling you to use member functions\n+    as plugin functions.\n+    You may also call this function later on, for example in your @ref GeanyPluginFuncs::init\n+    routine to defer costly allocations to when the plugin is actually activated by the user.\n+\n+\n+@subsection versions On API and ABI Versions\n+As previously mentioned @a geany_plugin_register() takes a number of versions as arguments:\n+  1. api_version\n+  2. min_api_version\n+  3. abi_version\n+\n+These refer to Geany's versioning scheme to manage plugin compatibility. It follows conrete rules:\n+  - Plugins are compiled against a specific Geany version on the build machine at the time of plugin\n+    compilation. This version of Geany has specific ABI and API versions, which will be compiled\n+    into the plugin.\n+  - The Geany version that loads the plugin may be different, possibly even have different API and\n+    ABI versions.\n+  - The ABI version is primary for plugin compatibility. The ABI version of the running Geany and\n+    the one that's compiled into the plugin must match exactly (==). In case of mismatch, the\n+    affected plugins generally need to be simply recompiled (without source code changes) against\n+    the running Geany.\n+  - The API version is secondary. It must not match exactly, however the plugin can report\n+    a minimum API version that it requires to run. Geany will check if its own API is larger than\n+    that (>=) and will otherwise refuse to load the plugin.\n+  - The API version the plugin is compiled against is still relevant for enabling compatibility\n+    code inside Geany (for cases where incrementing the ABI version could be avoided).\n+\n+Instead of @a geany_plugin_register() it is very highly recommended to use @a GEANY_PLUGIN_REGISTER().","path":"doc/plugins.dox","position":136,"original_position":136,"commit_id":"78ae829fb04db7500ccb1062e13dec113bd09e71","original_commit_id":"78ae829fb04db7500ccb1062e13dec113bd09e71","user":{"login":"b4n","id":793526,"avatar_url":"https://avatars.githubusercontent.com/u/793526?v=3","gravatar_id":"","url":"https://api.github.com/users/b4n","html_url":"https://github.com/b4n","followers_url":"https://api.github.com/users/b4n/followers","following_url":"https://api.github.com/users/b4n/following{/other_user}","gists_url":"https://api.github.com/users/b4n/gists{/gist_id}","starred_url":"https://api.github.com/users/b4n/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/b4n/subscriptions","organizations_url":"https://api.github.com/users/b4n/orgs","repos_url":"https://api.github.com/users/b4n/repos","events_url":"https://api.github.com/users/b4n/events{/privacy}","received_events_url":"https://api.github.com/users/b4n/received_events","type":"User","site_admin":false},"body":"`[Instead of] calling [@a geany_plugin_register()] directly, [it is highly recommended to use @a GEANY_PLUGIN_REGISTER()].`","created_at":"2015-08-12T14:30:36Z","updated_at":"2015-08-12T14:30:36Z","html_url":"https://github.com/geany/geany/pull/469#discussion_r36866049","pull_request_url":"https://api.github.com/repos/geany/geany/pulls/469","_links":{"self":{"href":"https://api.github.com/repos/geany/geany/pulls/comments/36866049"},"html":{"href":"https://github.com/geany/geany/pull/469#discussion_r36866049"},"pull_request":{"href":"https://api.github.com/repos/geany/geany/pulls/469"}}},"pull_request":{"url":"https://api.github.com/repos/geany/geany/pulls/469","id":33302675,"html_url":"https://github.com/geany/geany/pull/469","diff_url":"https://github.com/geany/geany/pull/469.diff","patch_url":"https://github.com/geany/geany/pull/469.patch","issue_url":"https://api.github.com/repos/geany/geany/issues/469","number":469,"state":"open","locked":false,"title":"New hooks","user":{"login":"kugel-","id":564520,"avatar_url":"https://avatars.githubusercontent.com/u/564520?v=3","gravatar_id":"","url":"https://api.github.com/users/kugel-","html_url":"https://github.com/kugel-","followers_url":"https://api.github.com/users/kugel-/followers","following_url":"https://api.github.com/users/kugel-/following{/other_user}","gists_url":"https://api.github.com/users/kugel-/gists{/gist_id}","starred_url":"https://api.github.com/users/kugel-/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kugel-/subscriptions","organizations_url":"https://api.github.com/users/kugel-/orgs","repos_url":"https://api.github.com/users/kugel-/repos","events_url":"https://api.github.com/users/kugel-/events{/privacy}","received_events_url":"https://api.github.com/users/kugel-/received_events","type":"User","site_admin":false},"body":"This is the new plugin loader mechanism we discussed on the mailing lists. Please review and comment. The initial commit explains a lot of details.","created_at":"2015-04-14T21:38:26Z","updated_at":"2015-08-12T14:30:36Z","closed_at":null,"merged_at":null,"merge_commit_sha":"31d8d792b551a37e00d45c2699a8615080f63c31","assignee":null,"milestone":{"url":"https://api.github.com/repos/geany/geany/milestones/3","html_url":"https://github.com/geany/geany/milestones/1.26","labels_url":"https://api.github.com/repos/geany/geany/milestones/3/labels","id":1173856,"number":3,"title":"1.26","description":"","creator":{"login":"codebrainz","id":181177,"avatar_url":"https://avatars.githubusercontent.com/u/181177?v=3","gravatar_id":"","url":"https://api.github.com/users/codebrainz","html_url":"https://github.com/codebrainz","followers_url":"https://api.github.com/users/codebrainz/followers","following_url":"https://api.github.com/users/codebrainz/following{/other_user}","gists_url":"https://api.github.com/users/codebrainz/gists{/gist_id}","starred_url":"https://api.github.com/users/codebrainz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codebrainz/subscriptions","organizations_url":"https://api.github.com/users/codebrainz/orgs","repos_url":"https://api.github.com/users/codebrainz/repos","events_url":"https://api.github.com/users/codebrainz/events{/privacy}","received_events_url":"https://api.github.com/users/codebrainz/received_events","type":"User","site_admin":false},"open_issues":11,"closed_issues":2,"state":"open","created_at":"2015-06-21T08:04:50Z","updated_at":"2015-08-04T00:06:24Z","due_on":"2015-11-15T08:00:00Z","closed_at":null},"commits_url":"https://api.github.com/repos/geany/geany/pulls/469/commits","review_comments_url":"https://api.github.com/repos/geany/geany/pulls/469/comments","review_comment_url":"https://api.github.com/repos/geany/geany/pulls/comments{/number}","comments_url":"https://api.github.com/repos/geany/geany/issues/469/comments","statuses_url":"https://api.github.com/repos/geany/geany/statuses/78ae829fb04db7500ccb1062e13dec113bd09e71","head":{"label":"kugel-:new_hooks","ref":"new_hooks","sha":"78ae829fb04db7500ccb1062e13dec113bd09e71","user":{"login":"kugel-","id":564520,"avatar_url":"https://avatars.githubusercontent.com/u/564520?v=3","gravatar_id":"","url":"https://api.github.com/users/kugel-","html_url":"https://github.com/kugel-","followers_url":"https://api.github.com/users/kugel-/followers","following_url":"https://api.github.com/users/kugel-/following{/other_user}","gists_url":"https://api.github.com/users/kugel-/gists{/gist_id}","starred_url":"https://api.github.com/users/kugel-/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kugel-/subscriptions","organizations_url":"https://api.github.com/users/kugel-/orgs","repos_url":"https://api.github.com/users/kugel-/repos","events_url":"https://api.github.com/users/kugel-/events{/privacy}","received_events_url":"https://api.github.com/users/kugel-/received_events","type":"User","site_admin":false},"repo":{"id":2544402,"name":"geany","full_name":"kugel-/geany","owner":{"login":"kugel-","id":564520,"avatar_url":"https://avatars.githubusercontent.com/u/564520?v=3","gravatar_id":"","url":"https://api.github.com/users/kugel-","html_url":"https://github.com/kugel-","followers_url":"https://api.github.com/users/kugel-/followers","following_url":"https://api.github.com/users/kugel-/following{/other_user}","gists_url":"https://api.github.com/users/kugel-/gists{/gist_id}","starred_url":"https://api.github.com/users/kugel-/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kugel-/subscriptions","organizations_url":"https://api.github.com/users/kugel-/orgs","repos_url":"https://api.github.com/users/kugel-/repos","events_url":"https://api.github.com/users/kugel-/events{/privacy}","received_events_url":"https://api.github.com/users/kugel-/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/kugel-/geany","description":"A fast and lightweight IDE","fork":true,"url":"https://api.github.com/repos/kugel-/geany","forks_url":"https://api.github.com/repos/kugel-/geany/forks","keys_url":"https://api.github.com/repos/kugel-/geany/keys{/key_id}","collaborators_url":"https://api.github.com/repos/kugel-/geany/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/kugel-/geany/teams","hooks_url":"https://api.github.com/repos/kugel-/geany/hooks","issue_events_url":"https://api.github.com/repos/kugel-/geany/issues/events{/number}","events_url":"https://api.github.com/repos/kugel-/geany/events","assignees_url":"https://api.github.com/repos/kugel-/geany/assignees{/user}","branches_url":"https://api.github.com/repos/kugel-/geany/branches{/branch}","tags_url":"https://api.github.com/repos/kugel-/geany/tags","blobs_url":"https://api.github.com/repos/kugel-/geany/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/kugel-/geany/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/kugel-/geany/git/refs{/sha}","trees_url":"https://api.github.com/repos/kugel-/geany/git/trees{/sha}","statuses_url":"https://api.github.com/repos/kugel-/geany/statuses/{sha}","languages_url":"https://api.github.com/repos/kugel-/geany/languages","stargazers_url":"https://api.github.com/repos/kugel-/geany/stargazers","contributors_url":"https://api.github.com/repos/kugel-/geany/contributors","subscribers_url":"https://api.github.com/repos/kugel-/geany/subscribers","subscription_url":"https://api.github.com/repos/kugel-/geany/subscription","commits_url":"https://api.github.com/repos/kugel-/geany/commits{/sha}","git_commits_url":"https://api.github.com/repos/kugel-/geany/git/commits{/sha}","comments_url":"https://api.github.com/repos/kugel-/geany/comments{/number}","issue_comment_url":"https://api.github.com/repos/kugel-/geany/issues/comments{/number}","contents_url":"https://api.github.com/repos/kugel-/geany/contents/{+path}","compare_url":"https://api.github.com/repos/kugel-/geany/compare/{base}...{head}","merges_url":"https://api.github.com/repos/kugel-/geany/merges","archive_url":"https://api.github.com/repos/kugel-/geany/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/kugel-/geany/downloads","issues_url":"https://api.github.com/repos/kugel-/geany/issues{/number}","pulls_url":"https://api.github.com/repos/kugel-/geany/pulls{/number}","milestones_url":"https://api.github.com/repos/kugel-/geany/milestones{/number}","notifications_url":"https://api.github.com/repos/kugel-/geany/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/kugel-/geany/labels{/name}","releases_url":"https://api.github.com/repos/kugel-/geany/releases{/id}","created_at":"2011-10-09T20:46:57Z","updated_at":"2015-07-28T08:28:33Z","pushed_at":"2015-08-05T06:19:56Z","git_url":"git://github.com/kugel-/geany.git","ssh_url":"git@github.com:kugel-/geany.git","clone_url":"https://github.com/kugel-/geany.git","svn_url":"https://github.com/kugel-/geany","homepage":"http://www.geany.org","size":41789,"stargazers_count":2,"watchers_count":2,"language":"C","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":2,"default_branch":"master"}},"base":{"label":"geany:master","ref":"master","sha":"c0898618f9a162913dfdddc74e2526019dcfb9ea","user":{"login":"geany","id":1108795,"avatar_url":"https://avatars.githubusercontent.com/u/1108795?v=3","gravatar_id":"","url":"https://api.github.com/users/geany","html_url":"https://github.com/geany","followers_url":"https://api.github.com/users/geany/followers","following_url":"https://api.github.com/users/geany/following{/other_user}","gists_url":"https://api.github.com/users/geany/gists{/gist_id}","starred_url":"https://api.github.com/users/geany/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/geany/subscriptions","organizations_url":"https://api.github.com/users/geany/orgs","repos_url":"https://api.github.com/users/geany/repos","events_url":"https://api.github.com/users/geany/events{/privacy}","received_events_url":"https://api.github.com/users/geany/received_events","type":"Organization","site_admin":false},"repo":{"id":2532922,"name":"geany","full_name":"geany/geany","owner":{"login":"geany","id":1108795,"avatar_url":"https://avatars.githubusercontent.com/u/1108795?v=3","gravatar_id":"","url":"https://api.github.com/users/geany","html_url":"https://github.com/geany","followers_url":"https://api.github.com/users/geany/followers","following_url":"https://api.github.com/users/geany/following{/other_user}","gists_url":"https://api.github.com/users/geany/gists{/gist_id}","starred_url":"https://api.github.com/users/geany/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/geany/subscriptions","organizations_url":"https://api.github.com/users/geany/orgs","repos_url":"https://api.github.com/users/geany/repos","events_url":"https://api.github.com/users/geany/events{/privacy}","received_events_url":"https://api.github.com/users/geany/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/geany/geany","description":"A fast and lightweight IDE","fork":false,"url":"https://api.github.com/repos/geany/geany","forks_url":"https://api.github.com/repos/geany/geany/forks","keys_url":"https://api.github.com/repos/geany/geany/keys{/key_id}","collaborators_url":"https://api.github.com/repos/geany/geany/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/geany/geany/teams","hooks_url":"https://api.github.com/repos/geany/geany/hooks","issue_events_url":"https://api.github.com/repos/geany/geany/issues/events{/number}","events_url":"https://api.github.com/repos/geany/geany/events","assignees_url":"https://api.github.com/repos/geany/geany/assignees{/user}","branches_url":"https://api.github.com/repos/geany/geany/branches{/branch}","tags_url":"https://api.github.com/repos/geany/geany/tags","blobs_url":"https://api.github.com/repos/geany/geany/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/geany/geany/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/geany/geany/git/refs{/sha}","trees_url":"https://api.github.com/repos/geany/geany/git/trees{/sha}","statuses_url":"https://api.github.com/repos/geany/geany/statuses/{sha}","languages_url":"https://api.github.com/repos/geany/geany/languages","stargazers_url":"https://api.github.com/repos/geany/geany/stargazers","contributors_url":"https://api.github.com/repos/geany/geany/contributors","subscribers_url":"https://api.github.com/repos/geany/geany/subscribers","subscription_url":"https://api.github.com/repos/geany/geany/subscription","commits_url":"https://api.github.com/repos/geany/geany/commits{/sha}","git_commits_url":"https://api.github.com/repos/geany/geany/git/commits{/sha}","comments_url":"https://api.github.com/repos/geany/geany/comments{/number}","issue_comment_url":"https://api.github.com/repos/geany/geany/issues/comments{/number}","contents_url":"https://api.github.com/repos/geany/geany/contents/{+path}","compare_url":"https://api.github.com/repos/geany/geany/compare/{base}...{head}","merges_url":"https://api.github.com/repos/geany/geany/merges","archive_url":"https://api.github.com/repos/geany/geany/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/geany/geany/downloads","issues_url":"https://api.github.com/repos/geany/geany/issues{/number}","pulls_url":"https://api.github.com/repos/geany/geany/pulls{/number}","milestones_url":"https://api.github.com/repos/geany/geany/milestones{/number}","notifications_url":"https://api.github.com/repos/geany/geany/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/geany/geany/labels{/name}","releases_url":"https://api.github.com/repos/geany/geany/releases{/id}","created_at":"2011-10-07T14:25:32Z","updated_at":"2015-08-10T13:24:48Z","pushed_at":"2015-08-11T18:56:47Z","git_url":"git://github.com/geany/geany.git","ssh_url":"git@github.com:geany/geany.git","clone_url":"https://github.com/geany/geany.git","svn_url":"https://github.com/geany/geany","homepage":"http://www.geany.org","size":50238,"stargazers_count":633,"watchers_count":633,"language":"C","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":233,"mirror_url":null,"open_issues_count":152,"forks":233,"open_issues":152,"watchers":633,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/geany/geany/pulls/469"},"html":{"href":"https://github.com/geany/geany/pull/469"},"issue":{"href":"https://api.github.com/repos/geany/geany/issues/469"},"comments":{"href":"https://api.github.com/repos/geany/geany/issues/469/comments"},"review_comments":{"href":"https://api.github.com/repos/geany/geany/pulls/469/comments"},"review_comment":{"href":"https://api.github.com/repos/geany/geany/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/geany/geany/pulls/469/commits"},"statuses":{"href":"https://api.github.com/repos/geany/geany/statuses/78ae829fb04db7500ccb1062e13dec113bd09e71"}}}}