Notes / Observations while embedding KTextEditor::Plugin(s) into a new host application

Thomas Friedrichsmeier thomas.friedrichsmeier at ruhr-uni-bochum.de
Tue Jan 14 09:11:23 GMT 2020


Hi!

I'm quite happy to see that the plugins written for kate seem to work
reasonably well in RKWard, now, and most interface differences are in
fact abstracted away quite nicely. Kudos to the developers who
designed this!

However, here's a list of the troubles I ran into during the process of
getting the plugins to work in RKWard, and some ideas where applicable.
This is more a brainstorming list, rather than any sort of well thought
our proposal, but I hope some of this can be addressed for KF6 (in
general, what would be the best place to collect ideas for / discuss
KF6 plans)?

Ok, here's what I found:
- Overall the process is pretty tedious. For one thing documentation
  on writing a plugin host is still a bit lacking (importantly a
  well-defined starting point in the API docs). For another thing, the
  initial barrier is fairly high, already, with quite a heavy list of
  methods to be implemented.

- Could some of the functionality of KatePluginManger be brought into
  the KTextEditor-API? For RKWard I'm duplicating a whole lot of that.
  I know for KDevelop the case is somewhat different, because that
  supports different types of plugin. However, some basics might still
  be offered, such as:
	- getting a list of available plugins
	- loading / unloading plugins by their id
	- some of the bureaucracy around creating/discarding plugin
  views: Reading their config, emitting signals, keeping track of which
  plugins are loaded, and their created (tool) views

- Some plugins appear to violate the return value rules stated in
  KTextEditor::MainWindow. For instance at a few places, the search
  plugin assumes that activeView() cannot be 0. Patch submitted,
  accpeted, and pushed, however I'm quite afraid this is not the only
  instance of this and similar problems (as kate *always* has an active
  view). Therefore, I also resorted to creating a hidden dummy view on
  the fly, if and when asked for it. Now that is not so cool, either,
  as it means well behaved plugins have  not chance to detect whether
  or not there is an active view. Perhaps adding a new function "bool
  isEmpty()" to the MainWindow interface? (Note: Same issue for
  KTextEditor::Application::documents())

- There are also - lesser - nuisances, such as some plugins
  malfunctioning, until readSessionConfig() has been called on them
  (noteably search-and-replace: Search-box gets cleared "as you type").
  Reading config is a good thing to do at any rate, but debugging this
  has cost me an hour of frustration, while I was implementing things
  step-by-step.

- I suppose the reason for using Qt-slot-dispatch, instead of virtual
  functions is to avoid incompatibility nightmares between host and
  plugins compiled against different versions of ktexteditor. However,
  having no compile-time sanity check does make the hair on the back of
  my neck stand up. Would it make sense to add an intermediate layer in
  the form of - say - a KTextEditor::MainWindowImplementation that has
  virtual slots for all the dispatch functions, and require the parent
  of KTextEditor::MainWindow to be an instance of this class? I imagine
  this might also make it easier to provide default implementations,
  and related API (such as plugin manager stuff, see above), where
  applicable. "Grandfathered" interface functions could even be
  converted to plain virtual function calls from MainWindow to
  MainWindowImplementation, while any new additions during a major
  release would continue to be implemented as slot invocations for
  compatibility.

API suggestions:
- I plead for the removal of KTextEditor::MainWindow::guiFactory(). See 
https://mail.kde.org/pipermail/kwrite-devel/2020-January/006002.html .
The long term plan to make plugins KXMLGUIClient-derived sounds good to
me. Not sure whether my proposed interim solution is worth the trouble,
for now I have an ugly hack in place to achieve what I want.

- Application::findUrl() could be implemented on top of
Application::documents()

- MainWindow::(create|hide|show|delete|addWidgetTo)ViewBar: It took me
some time to figure out that these are not (currently?) used by any
existing plugins, but by the view, and that it really is optional. For
more clarity, could this be split out into an all-separate class /
interface, and then you can simply have one
MainWindow::(get|set)ViewBar to provide a custom implementation? (And
then it would also become trivial to share the code for such a viewbar
between host applications).

- (close)splitView() in KTextEditor::MainWindow: Took me a while to
figure these out, because in RKWard split views are a little different,
in that we do not put emphasis on having the same documents in split
parts of the view. They behave more like separate main windows, but if
one becomes empty (due to views being closed), it is merged with the
other split portion, automatically. Two splits can be completely
disjunct (having no shared documents). Well, that's not much of a
problem. What bugs me, again, is that it is not immediately obvious,
whether (or what for) these are required when hosting plugins.
Apparently not really (not used in plugins). The only win in
implementing these seems to be the ability to split view from the vi
command line. Not sure what conclusion to draw (if any). Perhaps
documenting the fact. Or perhaps moving split-view functionality to a
separate mini-interface for more clarity? 

- MainWindow::viewsInSameSplitView(): I am not sure, what exactly it's
supposed to achieve. (Nor what it's meant to mean: Does this mean two
views that are visible side-by-side in a split window? Or two views
that are never visible simultaneously, because they are stacked inside
the same area?

- MainWindow::createToolView(): I guess this was designed around the
good old KVBox. Now we need a dedicated override to insert added
children into the parent's layout (in kate: ToolView::childEvent()),
and again, that's a bit difficult to discover when writing a host. This
could be simplified, if the plugin would pass a pointer to the widget
it wants to add in createToolView(), so the host can add this to the
tool view's layout.

- Application::aboutToDeleteDocuments(), documentWillBeDeleted(),
documentDeleted(), documentsDeleted(); correponding signals for
document creation. Let's remove the single document variants of these
for KF6, so the host does not have to emit both.  

Plugin-specific notes:
- For the search plugin, I'd like to be able to specify a default file
filter

That's it for now, thanks for your time!
Thomas
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <http://mail.kde.org/pipermail/kwrite-devel/attachments/20200114/eb3e8581/attachment.sig>


More information about the KWrite-Devel mailing list