8077 Commits

Author SHA1 Message Date
Colomban Wendling
c6952c7599 Merge pull request #629 from kugel-/pluxy
Add support for plugins acting as proxies for foreign plugins,
promoting foreign plugins to first-class citizen.
2015-10-06 15:53:14 +02:00
Colomban Wendling
d0f94460ea Bump plugin API version for proxy plugins support 2015-10-06 15:43:40 +02:00
Thomas Martitz
6cb443e863 plugins: enforce geany_plugin_register_proxy() can be called once
In the future we might want to enable calling it again to set new supported
plugin types/extensions. This is not implemented yet, but in order to
allow this in the future we have to prevent it now, otherwise we'd
need to break the API.
2015-10-06 15:40:57 +02:00
Thomas Martitz
6dfe5ce942 plugins: use GQueue to restore GLib compatibility
g_ptr_array_insert() is too recent (2.40), but prepending is required. GQueue
is a fine replacement with better old-glib support, at the expense of working
with a doubly-linked list instead of plain array.
2015-10-06 15:40:57 +02:00
Thomas Martitz
7ac89deebd plugins: improve PM dialog for proxy and sub-plugins
Geany now remembers how many plugins depend on a pluxy. It uses this
information to disable the "Active" checkbox in the PM dialog.

Additionally, the PM dialog displays plugins in a hierarchical manner, so that
sub-plugins are shown next to pluxy. This is espcially handy since it makes
the sub-plugin <-> pluxy relationship really obvious, and it's easier to spot
which plugins need to be disabled before the pluxy can be disabled. This allows
to remove code to re-select the plugin because the row (respective to the
hierarchy level) does not change anymore.
2015-10-06 15:40:57 +02:00
Thomas Martitz
bbf8e882c2 demoproxy: add a demo proxy showcasing how to create a proxy plugin
This demo proxy does not actually do anything useful. It simply loads
pseudo-plugins from an ini-style file. The point is that there will be a plugin
in the PM dialog for each ini. Each ini-plugin also causes a menu item to be
generated.
2015-10-06 15:40:34 +02:00
Colomban Wendling
25bd24187b Merge pull request #621 from techee/remote_mtime
Fix the "source file has been modified" issue

Closes #605.
2015-10-06 15:00:11 +02:00
Thomas Martitz
8ac9d56fff plugins: reselect when toggling the current plugin
When enabling/disabling pluxys in the PM dialog the list of available
plugins might change. If plugins before the pluxy go/come then the wrong
plugin becomes selected (the selected row number stays the same). Re-apply
the selection to the current one in the toggle callback to overcome this issue.
2015-10-05 22:11:12 +02:00
Thomas Martitz
6e5ca69e2e plugins: add geany_plugin_register_proxy() to the plugin API
This function finally allows plugins to register themselves as a proxy
for one or more file extensions.

Lots of documentation is added to doc/plugins.dox, please refer to that for more
details.
2015-10-05 22:11:12 +02:00
Thomas Martitz
3ccf959013 plugins: introduce probe() for proxy plugins
When a file extension alone is ambigious as to whether a potential plugin is
really handled then the proxy should use the probe hook to find out. This can
be especially helpful when two pluxies work on the same file extension.

The proxy's probe() should return PROXY_IGNORED or PROXY_MATCHED accordingly.
A special flag value, PROXY_NOLOAD, can be or'ed into PROXY_MATCHED to say
that the file belongs to the proxy, but isn't directly loaded and should not
be handled by any other proxy or geany itself.

Example for PROXY_IGNORED:
geanypy only supports python2 at the moment. So, scripts written
for python3 aren't handled by it and should be skipped for the PM dialog.
Or perhaps they are handled by another proxy that supports python3.

Example for PROXY_NOLOAD:
A pluxy registers for the metadata file extension (.plugin) where author etc
is in. The actual implmentation is in a python script (.py). The .py file
is tied to the .plugin and should not be processed by other pluxies. Thus,
the pluxy also registers for the .py extension but returns
PROXY_MATCHED|PROXY_NOLOAD for it (if it would return only PROXY_MATCHED
the sub-plugin would show up twice in the PM dialog).
2015-10-05 22:11:12 +02:00
Thomas Martitz
e5bb6571c6 plugins: when loading active ones, loop until no more proxy plugins are added
During the loading of the active plugins they are also initialized (done at
startup). As a result, these plugins could be pluxys and make more plugins
available, some of which may be active as well.

Because of this the loop has to be restarted if pluxies become
available to also load active plugins that depend on the pluxy.

The loop is only restarted at the end so only nested pluxys could possibly
cause the loop to be run more than twice.
2015-10-05 22:11:12 +02:00
Thomas Martitz
203644a233 plugins: refactor GtkListStore population code into separate function 2015-10-05 22:11:12 +02:00
Thomas Martitz
bdaab9c837 plugins: generic load_data instead of module pointer in Plugin struct
Being a GModule is actually a detail of standard plugins. Future proxy plugins
might need different handles. Therefore replace the module field with a more
generic pointer and encapsulate the GModule detail further.

This pointer shall be returned from GeanyProxyFuncs::load and is passed back
to GeanyProxyFuncs::unload, and isn't interpreted by Geany.
2015-10-05 22:11:12 +02:00
Thomas Martitz
d008675b1b plugins: introduce load and unload functions for plugins
Currently they encapsulate loading and unloading of standard plugins. In
the future plugins can provide such functions to load their types of plugins.

Such a dummy proxy plugin is implemented now to load standard plugins so
that these aren't going to be specially handled.
2015-10-05 22:09:36 +02:00
Frank Lanitz
e7e5d51d0a Merge branch 'konsolebox-master' 2015-10-04 14:58:03 +02:00
Frank Lanitz
4742cac866 Merge branch 'master' of https://github.com/konsolebox/geany into konsolebox-master 2015-10-04 14:57:42 +02:00
Frank Lanitz
932e98fa91 Update of Greek translation 2015-10-04 12:24:39 +02:00
Jiří Techet
daf4dd45b8 Don't mix POSIX/GIO operations when opening/saving/stat()ing files
GVFS uses different backends for "native" GIO operations and POSIX
operations which use the FUSE backend. If the two kinds of operations are
mixed, we may get races.

The patch checks the value of file_prefs.use_gio_unsafe_file_saving and
based on it either uses GIO operations or POSIX operations for file loading,
saving and checking modification time.
2015-10-01 12:09:45 +02:00
Ross Konsolebox
c2b7c279e9 Update msgid for "Use multi-line matchin_g"
This also includes obvious changes to msgstr of some languages.
Languages that didn't explicitly use 'l' as previous shortcut or
didn't have 'g' on their translation were left untouched.
2015-09-23 18:30:55 +08:00
Colomban Wendling
04ef30ea06 Update Scintilla to version 3.6.1 2015-09-20 18:39:15 +02:00
Colomban Wendling
c081983e85 Scintilla update script: properly abort on lexer copy error 2015-09-20 17:53:13 +02:00
Colomban Wendling
7c0bb4c6ca Small update of the French translation 2015-09-10 14:47:37 +02:00
Colomban Wendling
83c5ddf353 Strip spurious backslashes in an UI string 2015-09-10 14:46:08 +02:00
Colomban Wendling
af3b15c5ef Small update of the French translation 2015-09-09 20:25:41 +02:00
Colomban Wendling
927b364311 Merge pull request #647 from konsolebox/master
Use 'g' as mnemonic key for "Use multi-line matching" instead of 'l'.

Closes #589.
2015-09-09 20:01:37 +02:00
Ross Konsolebox
8253e2bd48 Use 'g' as shortcut key for "Use multi-line matching" instead of 'l'.
The current shorcut key for "Use multi-line matching" conflicts with
"In Selection" when "Use regular expressions" is enabled.  It should be
convenient if we change it.

We choose 'g' since other letters are already in use:

   u: "Use regular expressions"
   s: "Search for"
   e: "Use escape sequences"
   m: "Mark"
   l: "In Selection"
   t: "Match from start of word"
   i: "In Document"
   n: "Replace & Find"
   a: "Case sensitive"
   c: "Close"
   h: "Replace with"
2015-09-09 13:37:10 +08:00
elextr
8b767fea49 Merge pull request #638 from Akronix/master
Added multiline comment for filetypes.haskell
2015-09-02 09:10:33 +10:00
Abel 'Akronix' Serrano Juste
80c4cd0de0 Added multiline comment for filetypes.haskell 2015-09-01 19:12:59 +02:00
Enrico Tröger
db7a13b478 Mark "Open in New Window" menu item as translatable 2015-08-25 21:53:23 +02:00
Colomban Wendling
b8a99752f0 Bump API version for new plugin entry points (oops)
Closes #624.
2015-08-24 19:40:17 +02:00
Colomban Wendling
280163a244 Merge pull request #469 from kugel-/new_hooks
Plugin loader redesign
2015-08-23 23:50:44 +02:00
Colomban Wendling
b7bcf14ddf Merge pull request #613 from SiegeLord/even_more_rust_updates
Rust updates
2015-08-23 23:48:39 +02:00
Thomas Martitz
765000be92 plugins: Clarify which API functions may be called within geany_load_module()
Since geany_load_module() is called for non-enabled plugins you may not
use the plugin API here yet. The only exceptions to this rule are API functions
required for plugin registration.

This rule is hard to enforce (would need to g_return_if_val(PLUGIN_LOADED_OK(p))
for all API functions (well, those taking a plugin pointer anyway), so this
rule is only documented for now.
2015-08-23 20:01:42 +02:00
Thomas Martitz
437837d3a5 plugins: separate geany_plugin_set_data() dual-use
It was found that because geany_plugin_set_data() could be used by both
plugin's init() and geany_load_module(), that it introduced some uncertainty
as to when to call the free_func. init() callers might expect the call
around the same time as cleanup() is called, while geany_load_module()
callers expected the call at module unload time.

It was indeed called at module unload time. But that means that init() callers
cannot call it again reliably after in a init()->cleanup()->init() flow (when
toggling the plugin) without fully unloading the plugin (which is what we do
currently but that's we would want to change).

With the separation we can actually destroy the data depending on where
it was set and do everything unambigiously.
2015-08-23 20:01:42 +02:00
Thomas Martitz
d54b65b9ac plugins: Updated doxygen for the new plugin loader
The documentation provides a quite detailed description of the new loader
In addition it adds a "how to transition" that briefly describes the old
loader (for curious newcomers) and lots of hints for porting legacy
plugins to the new loader.
2015-08-23 20:01:41 +02:00
Thomas Martitz
58c8144afc plugins: Pass pdata to PluginCallback function by default
If the plugin did not set its own user_data we set it to whatever it set
with geany_plugin_register_full() or geany_plugin_set_data().
This is particularly convinient because PluginCallback is usually statically
allocated, at which point dynamically allocated plugin data doesn't exists yet.
2015-08-23 20:01:41 +02:00
Thomas Martitz
43c58e0fdd plugins: change return codes of geany_load_module() and GeanyPluginFuncs::init
- The return value from geany_load_module is removed (void). It was ignored
  anyway and we have to check separately whether the plugin loaded OK or not
  anyway. If the plugin specific code fails it should simply not call
  geany_plugin_register() (which it should only call iff all other conditions
  are good).

- GeanyPluginFuncs::init() now returns a bool to allow failing initialization.
  Some plugins might want to defer work to their init() (i.e. only do
  it when the plugin was activated by the user), and some of that work can
  possibly fail (e.g. GtkBuilder fails to load .xml).

Note that the GUI integration of the latter is less than ideal but this kind
of GUI/policy work is out of scope for this patch set. Therefore a plugin
failing to init is simply removed from the PM dialog as if it became
incompatible. However, as the code that generates the list does not call init
they will show up again if the PM dialog is re-opened.
2015-08-23 20:01:41 +02:00
Thomas Martitz
8241278472 demoplugin: Adapt demoplugin to the new loader
Demoplugin, while not installed by default, is a nice starting point
and mini-howto. Therefore it should advertise the new loader from the
beginning.
2015-08-23 20:01:41 +02:00
Thomas Martitz
75827c69c0 plugins: Refactor legacy plugin support
With geany_plugin_set_data() the legacy plugin support can be made
more transparent by using wrapper functions that call the actual plugin_*
functions. This allows to remove the differentiation in code that's not
directly concerned with actually loading plugins.

This commit doesn't change anything except for one thing: legacy plugins now
cannot call geany_plugin_set_data(). But it is meant for new-style plugins
anyway.
2015-08-23 20:01:38 +02:00
Thomas Martitz
f2579141bb plugins: Replace geany_plugin_register() pdata with a separate API function
The API function adds a free_func parameter, and can also be called
after geany_plugin_register(), i.e. in the plugin's init() callback. This
fixes a by-design memory leak and gives greater flexibility.
2015-08-23 15:23:24 +02:00
Thomas Martitz
babf008335 plugins: Let plugins fill GeanyPlugin::callbacks instead of passing their own pointer
This is easier to handle if we decide to add callbacks. Since we can
zero-initialize callbacks before passing it to the plugin we can be certain as
to which callbacks the plugin knew about when it was compiled. This is exactly
the same method used for GeanyPlugin::info already and easier than inspecting
the API version.
2015-08-23 15:23:22 +02:00
Thomas Martitz
721009e262 plugins: plugin loader redesign
The old plugin loader has a number of deficiencies:

- plugins need to export a couple of callback functions into the global namespace
- plugins need to export data pointers, that are written by Geany
- the exported functions have no user_data param, so there is no way to
  pass context/state back to the plugin (it needs global storage for that)
- plugin registration is implicit, plugins have no way to not register themselves
  (it may want that due to missing runtime dependencies)
- plugins perform the ABI/API verification, and even though we provide a
  convinience wrapper, it may get that wrong

As a result, I designed a new loader with the following design principles
- semantics of callbacks should not change, but they they shouldn't be mess
  with the global namespace
- each callback receives a self-identifying param (the GeanyPlugin instance) and
  a plugin-defined data pointer for their own use
- explicit registration through a new API function
- in-core API/ABI checks

The following principles shall be left unchanged:
- The scan is done on startup and when the PM dialog is opened
- Geany allocates GeanyPluginPrivate for each plugin, and GeanyPlugin is
  a member of it
- Geany initially probes for the validity of the plugin, including file type
  and API/ABI check, thus Geany has the last word in determining what a
  plugin is
- the PM dialog is updated with the proper, translated plugin information
- the PM dialog GUI and user interaction in general is unchanged

With the redesign, plugins export a single function: geany_load_module().
This is called when the GModule is loaded. The main purpose of this function
is to call geany_plugin_register() (new API function) to register the plugin.
This is the only function that is learned about through g_module_symbol().
Within this call the plugin should
a) set the localized info fields of GeanyPlugin::info
b) pass compiled-against and minimum API version as well as compiled-against
   ABI version, to allow Geany to verify compatibility
c) pass a pointer to an instance of GeanyPluginFuncs
   which holds pointers to enhanced versions of the known callbacks (except
   configure_single which is dropped).
d) optionally pass a plugin-private data pointer for later callbacks

Enhanced means that all callbacks receive the GeanyPlugin pointer as the first
and a pdata pointer as the last. pdata is private to the plugin and is set
by geany_plugin_register().

The callbacks need (should) not be globally defined anymore, and the global
GeanyData, GeanyPlugin and GeanyFunctions pointers are ignored and not set
anymore. GeanyData is available through GeanyPlugin::geany_data.
2015-08-23 15:23:20 +02:00
Pavel Sountsov
568787bc2f Change Rust tests to be in line with the ones in the universal-ctags tests. 2015-08-21 21:21:18 -07:00
Pavel Sountsov
91ee437640 Parse 'where' bounds correctly. 2015-08-21 21:19:47 -07:00
Pavel Sountsov
6814fc1a62 Update Rust keywords. 2015-08-21 21:17:59 -07:00
Colomban Wendling
c251dcb45f Merge pull request #394 from SiegeLord/selection_document_mods
Make Document > Strip trailing spaces/Replace tabs/Replace spaces use
the current selection.
2015-08-21 22:26:41 +02:00
Jiří Techet
3495cf05ab Remove saved file's mtime check comparing it with the current time
As the edited file can be a remote file on a server with a different time
zone, the mtime can actually be in the future. In this case the check not
only shows the misleading warning but more importantly the

doc->priv->mtime < st.st_mtime

check never happens and the user doesn't get the modified file prompt.

Setting

doc->priv->mtime = time(NULL);

to the current time on file creation isn't harmful in any way because the
saved file's mtime is taken but it's a bit misleading so better to set it
to 0.
2015-08-18 19:48:12 +02:00
Colomban Wendling
624048ea5e Keep selection stable when replacing tabs and spaces 2015-08-16 11:38:51 -07:00
Pavel Sountsov
2a887fee30 Don't strip spaces from the next line when whole lines are selected. 2015-08-16 11:22:01 -07:00
Pavel Sountsov
186a43c1d1 Document the changes to space/tab replacement 2015-08-16 11:22:01 -07:00