RFC: Live document preview plugin (technical preview (pun-o-pun))
Friedrich W. H. Kossebau
kossebau at kde.org
Mon Aug 21 15:52:33 UTC 2017
[[cc:kdevelop-devel only for heads-up, please only reply to kwrite-devel]]
who is in for having a live preview when editing some Markdown file? Or Dot
graph sources, SVG sources, Qt UI sources, you name it...
Seems some people are in, including me. And since last WE I have ended up
with a simple prototype, which has served already with some real world
markdown editing :)
Get an idea and see examples:
* Markdown file: https://share.kde.org/index.php/s/B5imqnzmU3MkI8p
(KDev, using new Markdown KPart, kde:scratch/kossebau/kmarkdownwebview)
* Qt UI file: https://share.kde.org/index.php/s/BLHvh4fG242SVyd
(KDev, using kuiviewerpart)
* SVG file: https://share.kde.org/index.php/s/sfK4X8eOLqbh7Dp
(Kate, using svgpart. could see improvements)
Get the code and try yourself:
git clone kde:scratch/kossebau/ktexteditorpreviewplugin
And while I myself want this feature for KDevelop, doing the plugin based on
KTextEditor::Plugin extends the userbase to Kate users. By the price though
that it is restricted to source files that are KTextEditor::Documents. Which
works for me (tm) for now.
With that said, now to the section where I want your comments on:
I made a few more architecture decisions which I had to reason about to
myself, so would like you to do the same and then tell what you think.
Sorry for the braindump, but there is no other place for it :)
Using KParts plugins:
In my perfect world, any rendering of the target format (like SVG) would be
done from a target document built over the source document, enriched with
tags with info which parts of the target document are created from which
parts of the source document, so there could be a mapping. E.g. to highlight
the counterpart in the source/target when selecting something. And of course
the target model would also support multiple target views.
Just, all that would need people coding this first for any document type. And
right now we do not even have simpler plugins/kparts for all interesting
types (like I had to write a quick'n'dirty kpart for markdown). So for a
pragmatism-driven initial solution, going for kparts with their single-model-
single-view/widget design and the existing implementations solves quite a few
And reusing kparts instead of own preview plugins will result in sharing
improvements made to the individual kparts with everyone else using them.
But also see below on some kpart-using issues.
Making it a tool-view plugin:
Given the MDI UI for text documents in Kate & KDevelop, together with the
options for split views, there might use-cases to have previews for more than
one document at the same time. One option could be to have the preview as
part of the document view element, like the text-search-bar or the I/O
message boxes. The other option is to have a tool-view which shows the
preview of the currently focussed document (not sure if there could be
multiple ones per tool-view type?).
Being familiar with writing tool-view plugins and a tool-view not needing to
write additional code for showing/hiding the preview or selecting the
position, I for now implemented it as tool-view. A lock-to-document toggle
option allows to cover the use-case of having preview for a given document,
while switching focus to other document views. Surely could have different
solutions one day.
Correctly working only for single source document -> single target document:
There are target documents which make use of multiple source documents (e.g.
HTML page pulling in CSS files). There could be some (k)io-mechanism to
connect to other loaded documents and get their live data, but that needs
some infrastructure work first. As there is no metadata in kparts available
to filter out such multi-source document cases, there is no protection
against partially broken previews right now, as e.g. can happen with HTML
files. Not sure what to do here, so done nothing :)
Avoiding to stress the filesystem:
Best preview often is continuous live preview. And when one types a letter
and wants a preview update, ideally only the one-letter diff would be passed
to the preview module and that would update the preview accordingly.
As a matter of fact though all kparts currently have no idea about the
KTextEditor working memory model (i.e. the KTextEditor API). For I/O of
documents/files they themselves only support reading complete blobs from the
filesystem (with KParts module transparently handling remote urls via
temporary files passed to the actual kpart plugin). While the KPart API has
some alternative streaming methods (ReadOnlyPart::openStream() & Co) as
option to implement, seems no (interesting) kpart supports it (cmp. https://
With the markdown kpart I am already using the streaming API. For any other
kpart that ideally should be added as well, not sure why there is no
primitive default implementation instead.
Right now the preview plugin first tries the streaming API (as only the call
to openStream() would tell if streaming is supported?) and then falls back to
passing the data blob via a QTemporaryFile.
Not sure how much of an issue that is.
Knowing what preview is wanted:
Right now selection of the kpart to use for the preview is done based on
"KTextEditor::Document::mimeType()". Which only seems to work for documents
which already are stored as file in the filesystem.
Any proposal how to fix this for new documents not yet saved? Something based
on currently selected syntax highlighting?
Selecting KParts plugin to use:
Using the mimetype string, the preview code currently simply queries the
currently configured preferred service:
Which might be an issue in non-Plasma workspaces, given they do not have any
configuration options for kparts in their system settings UI.
Perhaps also people would like to prefer a different kpart for the live
preview? Needs more thinking how to enable any configuration.
Next there is also the issue that with the mimetype "text/plain" we get the
kate part as preview module :) As first primitive approach the code for now
simply filters out any kparts which list "text/plain" in their supported
mimetypes. But that runs the chance of blocking also kparts which support
importing plain text into whatever richer format they are about. Like the
That might need some additional metadata in the kparts, something with the
semantics of "native" and "imported" mimetypes? No clear idea myself yet.
Where should the preview plugin sources live?
The Preview plugin is similar to the Snippets plugin, usable both by Kate &
KDevelop (as marked by ServiceTypes=KTextEditor/Plugin,KDevelop/Plugin).
Just, the Snippets plugin is right now part of the Kate sources. Adding the
Preview plugin there as well is slightly unfortunate, as it both means for
the developer working on the plugin they have to checkout and build the whole
of kate (or hack the buildsystem locally) and for the user the chance that
packagers put the plugin in a package which pulls all of Kate and its deps,
even if ones only want the plugin for KDevelop.
So having a separate repo for plugins shared by Kate & KDevelop (and perhaps
other KTextEditor apps?) would be nice to have.
I learned there once was a thread started on this ml discussing such a
separate repo, on Aug 25, 2015, "Moving KTextEditor plugins out of kate.git?"
Time to continue it almost exactly 2 years later :)
Thanks for reading until here.
So far the feedback I have got on irc (#kde-devel/#kdevelop) on the current
prototype was positive, and my own usage also showed it to be good enough for
a first version. So besides the open questions I would be fine with the
current approach to become an official plugin.
But what do you Katies think about it? :)
Will also propose alternatively as patch for the kate repo, in case the
separate-kte-plugins-repo discussion will take some more time.
More information about the KDevelop-devel