[utilities/kate] /: Update documentation for script type snippets

Thomas Friedrichsmeier null at kde.org
Tue Jun 10 13:42:34 BST 2025


Git commit 3466f6dc98583254ea87c341a3289daf007ccca5 by Thomas Friedrichsmeier.
Committed on 10/06/2025 at 12:37.
Pushed by tfry into branch 'master'.

Update documentation for script type snippets

M  +11   -35   addons/snippets/editsnippet.cpp
M  +3    -5    addons/snippets/snippet.cpp
M  +65   -39   doc/kate/plugins.docbook
M  +8    -0    doc/katepart/development.docbook

https://invent.kde.org/utilities/kate/-/commit/3466f6dc98583254ea87c341a3289daf007ccca5

diff --git a/addons/snippets/editsnippet.cpp b/addons/snippets/editsnippet.cpp
index e42e6e261e..cc48a71774 100644
--- a/addons/snippets/editsnippet.cpp
+++ b/addons/snippets/editsnippet.cpp
@@ -72,28 +72,20 @@ EditSnippet::EditSnippet(SnippetRepository *repository, Snippet *snippet, QWidge
     connect(m_ui->modeComboBox, &QComboBox::currentIndexChanged, this, [this]() {
         if (m_ui->modeComboBox->currentData().toInt() == Snippet::TextTemplate) {
             m_ui->snippetLabel->setText(
-                i18n("The text your snippet will insert into the document. "
-                     "<a href=\"A template snippet can contain editable fields. They can be "
-                     "cycled by pressing Tab. The following expressions can be used "
-                     "in the template text to create fields: <br><tt>${field_name}</tt> "
-                     "creates a simple, editable field. All subsequent occurrences of the "
-                     "same field_name will mirror the contents of the first "
-                     "during editing.<br><tt>${field_name=default}</tt> can be used to "
-                     "specify a default value for the field, where <tt>default</tt> can be any "
-                     "JavaScript expression (use quotatio marks to specify "
-                     "a fixed string as default value).<br><tt>${func(other_field1, "
-                     "other_field2, ...)</tt> evaluates a JavaScript function defined in the "
-                     "'Scripts Library' tab on each edit, and is replaced by the value returned "
-                     "by that function.<br><tt>${cursor}</tt> "
-                     "can be used to mark the end position of the cursor after everything "
-                     "else was filled in.\">More...</a>"));
-            m_snippetView->document()->setMode(QStringLiteral("None")); // TODO
+                i18n("Text to insert into the document (see "
+                     "<a href=\"help:/kate/kate-application-plugin-snippets.html\">handbook</a> "
+                     "for special fields)."));
+            m_snippetView->document()->setMode(QStringLiteral("Normal"));
         } else {
             // TODO
-            m_ui->snippetLabel->setText(i18n("Explanation for script. Individual portion vs Script Library"));
+            m_ui->snippetLabel->setText(
+                i18n("Javascript code to evaluate (see "
+                     "<a href=\"help:/kate/kate-application-plugin-snippets.html\">handbook</a> "
+                     "for details)."));
             m_snippetView->document()->setMode(QStringLiteral("JavaScript"));
         }
     });
+    m_ui->snippetLabel->setOpenExternalLinks(true);
     m_ui->modeComboBox->addItem(i18n("Text template"), QVariant(Snippet::TextTemplate));
     m_ui->modeComboBox->addItem(i18n("Script"), QVariant(Snippet::Script));
 
@@ -102,19 +94,9 @@ EditSnippet::EditSnippet(SnippetRepository *repository, Snippet *snippet, QWidge
     m_scriptsView->document()->setText(m_repo->script());
     m_scriptsView->document()->setModified(false);
 
-    // TODO: link to handbook
     m_ui->scriptLabel->setText(
-        i18n("Write down JavaScript helper functions to use in your snippets here. "
-             "<a href=\"Editable template fields are accessible as local variables. "
-             "For example in a template snippet containing <tt>${field}</tt>, a "
-             "variable called <tt>field</tt> will be present which contains the "
-             "up-to-date contents of the template field. Those variables can either "
-             "be used in the function statically or passed as arguments, by using the "
-             "<tt>${func(field)}</tt> or <tt>${field2=func(field)}</tt> syntax in the "
-             "snippet string.<br>You can use the kate scripting API to get the "
-             "selected text, full text, file name and more by using the appropriate "
-             "methods of the <tt>document</tt> and <tt>view</tt> objects. Refer to "
-             "the scripting API documentation for more information.\">More...</a>"));
+        i18n("JavaScript functions shared between all snippets in this repository (see "
+             "<a href=\"help:/kate/kate-application-plugin-snippets.html\">handbook</a>)."));
 
     m_ui->descriptionLabel->setText(i18n("(Optional) description to show in tooltips. May contain HTML formatting."));
     m_descriptionView = createView(m_ui->descriptionTab);
@@ -134,12 +116,6 @@ EditSnippet::EditSnippet(SnippetRepository *repository, Snippet *snippet, QWidge
     connect(m_ui->snippetShortcut, &KKeySequenceWidget::keySequenceChanged, this, &EditSnippet::topBoxModified);
     connect(m_snippetView->document(), &KTextEditor::Document::textChanged, this, &EditSnippet::validate);
 
-    auto showHelp = [](const QString &text) {
-        QWhatsThis::showText(QCursor::pos(), text);
-    };
-    connect(m_ui->snippetLabel, &QLabel::linkActivated, showHelp);
-    connect(m_ui->scriptLabel, &QLabel::linkActivated, showHelp);
-
     // if we edit a snippet, add all existing data
     if (m_snippet) {
         setWindowTitle(i18n("Edit Snippet %1 in %2", m_snippet->text(), m_repo->text()));
diff --git a/addons/snippets/snippet.cpp b/addons/snippets/snippet.cpp
index 51d0ba135b..422f502c96 100644
--- a/addons/snippets/snippet.cpp
+++ b/addons/snippets/snippet.cpp
@@ -98,11 +98,9 @@ void Snippet::apply(KTextEditor::View *view, const QString &repoScript) const
         view->insertTemplate(view->cursorPosition(), snippet(), repoScript);
     } else {
         QVariant res;
-        auto ok = view->evaluateScript(repoScript + u'\n' + snippet(), &res);
-        if (!ok) {
-            // show error message, by simply inserting it
-            view->document()->insertText(view->cursorPosition(), res.toString());
-        }
+        view->evaluateScript(repoScript + u'\n' + snippet(), &res);
+        // for convenience, insert result (or error message) at cursor position
+        view->document()->insertText(view->cursorPosition(), res.toString());
     }
 }
 
diff --git a/doc/kate/plugins.docbook b/doc/kate/plugins.docbook
index d673beab72..a61fdf50a6 100644
--- a/doc/kate/plugins.docbook
+++ b/doc/kate/plugins.docbook
@@ -3355,7 +3355,7 @@ that are for the currently opened file type.</para></listitem>
 </menuchoice></term>
 <listitem>
 <para>Create a new snippet, which is a reusable chunk of text you
-may insert in any part of any document.</para>
+may insert in any part of any document, or a small script.</para>
 </listitem>
 </varlistentry>
 
@@ -3463,16 +3463,24 @@ than one file type pressing the &Shift; while adding types.</para></listitem>
 
 <varlistentry>
 <term><guilabel>Name</guilabel></term>
-<listitem><para>The name will be shown in the completion list.</para></listitem>
+<listitem><para>The name as shown in the list of snippets, and in the completion list (required).</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term><guilabel>Type</guilabel></term>
+<listitem><para>Snippets may either be defined as text templates or scripts. Both types allow to use &javascript; functions
+(see below, for details), and can thus be used to similar effect. However, as a rule of thumb, text templates will be more
+suiteable, if you mostly want to <emphasis>insert</emphasis> text, while scripts are often an easier solution, if you want to
+<emphasis>modify</emphasis> text).</para></listitem>
 </varlistentry>
 
 <varlistentry>
 <term>Shortcut</term>
-<listitem><para>Pressing this shortcut will insert the snippet into the document.</para></listitem>
+<listitem><para>Pressing this shortcut will insert (or run) the snippet into the current document.</para></listitem>
 </varlistentry>
 
 <varlistentry>
-<term><guilabel>Snippets</guilabel></term>
+<term><guilabel>Snippet</guilabel> (type <userinput>Text Template</userinput>)</term>
 <listitem><para>The text your snippet will insert into the document.</para>
 <para>A snippet can contain editable fields. They can be cycled by
 pressing 	. The following expressions can be used in the template
@@ -3484,64 +3492,81 @@ of the first during editing.</para>
 <para><userinput>${<replaceable>field_name=default</replaceable>}</userinput>
 can be used to specify a default value for the field.
 <replaceable>default</replaceable> can be any &javascript; expression.</para>
-<para>Use <userinput>${<replaceable>field_name</replaceable>=<replaceable>text</replaceable>}</userinput>
+<para>Use quotes (<userinput>${<replaceable>field_name</replaceable>=<replaceable>"text"</replaceable>}</userinput>)
 to specify a fixed string as default value.</para>
 <para><userinput>${func(<replaceable>other_field1</replaceable>,
 <replaceable>other_field2</replaceable>, ...)}</userinput> can be used to create a
-field which evaluates a &javascript; function on each edit and contains its
-contents. See the <guilabel>Scripts</guilabel> tab for more information.</para>
+field which evaluates a &javascript; function on each edit and is replaced by that
+function's return value. See the <guilabel>Script Library</guilabel> tab for more information.</para>
 <para><userinput>${cursor}</userinput> can be used to mark the end position
 of the cursor after everything else was filled in.</para>
 </listitem>
 </varlistentry>
 
 <varlistentry>
-<term><guilabel>Scripts</guilabel></term>
-<listitem><para>&javascript; helper functions to use in your snippets.</para>
-<para>All &javascript; functions should return the contents you want to place in a
-template field as a string.</para>
-<para>Functions are called in a scope which contains the contents of all
-editable template fields as local variables. For example in a snippet
+<term><guilabel>Snippet</guilabel> (type <userinput>Script</userinput>)</term>
+<listitem><para>The &javascript; code to evaluate for this snippet</para>
+<para>If this code contains a <userinput>return</userinput>, the returned string will be inserted at the current
+cursor position, but you can also use the <ulink url="help:/katepart/dev-scripting.html#dev-scripting-api">&kate;
+scripting API</ulink> to modify the document, directly.</para>
+<para>Additionally, your code may use functions defined in the <guilabel>Script Library</guilabel> tab, which
+are shared between all snippets in a repository.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term><guilabel>Script Library</guilabel></term>
+<listitem><para>&javascript; helper functions to use in your snippets. These functions are shared between all snippets in a repository.</para>
+<para>You can use the <ulink url="help:/katepart/dev-scripting.html#dev-scripting-api">&kate; scripting API</ulink>
+to get the selected text, full text, file name and more by using the appropriate methods of the <userinput>document</userinput>
+and <userinput>view</userinput> objects. Refer to the scripting API
+documentation for more information.</para>
+
+<para>When scripting in conjuction with <userinput>Text Template</userinput> snippets, you should keep the
+following details/hints in mind:</para>
+<itemizedlist>
+<listitem><para>Remember that only the <emphasis>return value</emphasis> of a function is inserted in a field.</para></listitem>
+<listitem><para>The contents of all editable template fields are available as variables in this scope. For example in a snippet
 containing <userinput>${<replaceable>field</replaceable>}</userinput>,
 a variable called <userinput>field</userinput> will be present which contains
 the up-to-date contents of the template field. Those variables can either
 be used in the function statically or passed as arguments, by using the
 <userinput>${func(field)}</userinput> or <userinput>${<replaceable>field2=func(field)</replaceable>}</userinput>
-syntax in the snippet string.</para>
-<para>You can use
-the <ulink url="help:/katepart/dev-scripting.html#dev-scripting-api">&kate; scripting API</ulink>
-to get the selected text, full text, file name and
-more by using the appropriate methods of the <userinput>document</userinput>
-and <userinput>view</userinput> objects. Refer to the scripting API
-documentation for more information.</para>
-<para>For more complex scripts it may be important to understand that
+syntax in the snippet string.</para></listitem>
+<listitem><para>For more complex scripts it may be important to understand that
 <emphasis>first</emphasis>, the raw snippet is inserted into the document, and <emphasis>then</emphasis>
 functions are being evaluated. E.g., if a function retrieves the text on the
 line where the snippet is being inserted, that text will also contain
-<userinput>${functionCall()}</userinput>.</para>
-<para>As an example of working with selections using the scripting API, a simple way
-to wrap selected text inside tags is this snippet:
-<userinput><strong>${view.selectedText()}</strong></userinput>
-</para>
-<para>The following example invokes a script that inserts a default text in case
-there is no selection. Snippet:</para>
+<userinput>${functionCall()}</userinput>. Where this causes complications, consider using a
+<userinput>Script</userinput>-type snippet, instead.</para></listitem>
+<listitem><para>To simply wrap the currently selected text into tags, use: <userinput><strong>${view.selectedText()}</strong></userinput></para></listitem>
+</itemizedlist>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term><guilabel>Description</guilabel></term>
+<listitem><para>An optional description of what this snippet does. This will be shown in tooltips. The description
+may contain basic HTML formatting.</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term>Usage example</term>
+<listitem><para>The following example invokes a script that wraps the selected text, or - if
+there is no selection - a default text, into tags (Snippet type <userinput>Script</userinput>):</para>
 <para>
-<userinput>${rangeCommand("<strong>%%1</strong>", "Bold")}</userinput></para>
-<para>Script:
 <programlisting>
-function rangeCommand(command, def) {
-    if (view.selectedText().length > 0) {
-        return command.replace("%%1", view.selectedText());
-    } else {
-        return command.replace("%%1", def);
-    }
-}
+let range = view.hasSelection() ? view.selection() : new Range(view.cursorPosition(), view.cursorPosition());
+let innertext = range.isEmpty() ? "Bold" : document.text(range);
+document.removeText(range);
+document.insertText(range.start, "<strong>" + innertext + "</strong>");
 </programlisting>
 </para>
 </listitem>
 </varlistentry>
 
 </variablelist>
+
 </sect3>
 </sect2>
 
@@ -3557,10 +3582,11 @@ function rangeCommand(command, def) {
 </mediaobject>
 </screenshot>
 
-<para>You can call snippets in two ways:</para>
+<para>You can call snippets in several ways:</para>
 
 <itemizedlist>
-<listitem><para>By choosing the snippet from the tool view.</para></listitem>
+<listitem><para>By clicking on the snippet from the tool view.</para></listitem>
+<listitem><para>Using a keyboard shortcut, if you have assigned one.</para></listitem>
 <listitem><para>While writing, you can press <keycombo action="simul">&Ctrl;
 &Space;</keycombo>, which will display all the snippets in a
 convenient window from which you can choose.  This key combination provides
diff --git a/doc/katepart/development.docbook b/doc/katepart/development.docbook
index a9bc121605..86fbd50148 100644
--- a/doc/katepart/development.docbook
+++ b/doc/katepart/development.docbook
@@ -2584,6 +2584,8 @@ a theme.</para>
 The &kappname; editor component is easily extensible by writing scripts.
 The scripting language is ECMAScript (widely known as &javascript;).
 &kappname; supports two kinds of scripts: indentation and command line scripts.
+A functionality similar to command line scripts is also provided in the
+<ulink url="help:/kate/kate-application-plugin-snippets.html">snippets plugin</ulink>
 </para>
 
 <sect2 id="dev-scripting-indentation">
@@ -2742,6 +2744,12 @@ by <ulink url="mailto:kwrite-devel at kde.org">contacting the mailing list</ulink>.
 <sect2 id="dev-scripting-command-line">
 <title>Command Line Scripts</title>
 
+<note>
+<para>A functionality similar the command line scripts, detailed here, is also provided in the
+<ulink url="help:/kate/kate-application-plugin-snippets.html">snippets plugin</ulink>.
+This plugin may provide an easier starting point, especially for small custom scripts.</para>
+</note>
+
 <para>
 As it is hard to satisfy everyone's needs, &kappname; supports little helper tools
 for quick text manipulation through the



More information about the kde-doc-english mailing list