Now that there is a proper user indication for the "maintain history on
reload" feature we can toggle it on by default. The setting is also renamed
so that the default is effective for everyone (this was the plan).
6f5d5db and d6d4728 disabled "maintain history on reload" by default,
with the intention to reenable it when we have a better method to
make it discoverable for the user. This was necessary since it became
enabled by default but could be surprising given Geany warned about
losing data before.
This commit tries to resolve the discoverability, by providing an
informational doc message that is shown once to the user, after the first
reload. The doc message also gives the option to disable this feature.
configdir is initially in locale (glib) encoding. Converting it from
UTF-8 is wrong, and it must be converted _to_ UTF-8 when used in
geany_debug() - otherwise, Help -> Debug Messages fails assertion.
POSIX only, under Windows the glib encoding is also UTF-8.
Closes#658.
Drop the loop in mem_read() in favor of a single memcpy() call.
This greatly improves performances when nmemb > 1, for a small loss
for some values of size when nmemb == 1. Gain can theoretically be
infinite since swapping nmemb and size parameters changes almost
nothing while it had a dramatic performance impact previously. Loss
is up to about 25% in the worst case for some values of size when
nmemb is 1.
Also, now the function always copies as much data as possible, not only
whole blocks. This follows the glibc implementation of fread() and
simplifies the code. Doing so also fixes the position after a partial
read to be at the last readable character rather than the end of the
last read block.
In particular, the exec() and CreateProcess() errors are reported
directly, but failures in other any functions, which are extremely
rare, include some descriptive text, such as "Failed to set pipe
handle to inheritable (Access denied)". The example is artificial.
That is, do not cite the original text, program name, or the failed
OS function name (except when the testing program is compiled).
Also cut glib citing of the original text on bad quoting.
Fix handling of scopes starting with a non-ASCII character.
Actually, just drop the check on the first byte of the scope, as it
doesn't seem to serve any purpose as it only checks the first byte (so
isn't any kind of real validation; and as it predates Geany it's
impossible to know the real reason behind this check), and breaks
support for non-ASCII scopes.
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.
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.
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.
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.
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.
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.
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).
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.
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.
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.