1/*
2 SPDX-FileCopyrightText: 2009-2018 Dominik Haumann <dhaumann@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "katecommandlinescript.h"
8
9#include <QJSEngine>
10#include <QJSValue>
11
12#include <KLocalizedString>
13#include <KShell>
14
15#include "katecmd.h"
16#include "katedocument.h"
17#include "katepartdebug.h"
18#include "kateview.h"
19
20KateCommandLineScript::KateCommandLineScript(const QString &url, const KateCommandLineScriptHeader &header)
21 : KateScript(url)
22 , KTextEditor::Command(header.functions())
23 , m_commandHeader(header)
24{
25}
26
27const KateCommandLineScriptHeader &KateCommandLineScript::commandHeader()
28{
29 return m_commandHeader;
30}
31
32bool KateCommandLineScript::callFunction(const QString &cmd, const QStringList &args, QString &errorMessage)
33{
34 clearExceptions();
35 QJSValue command = function(name: cmd);
36 if (!command.isCallable()) {
37 errorMessage = i18n("Function '%1' not found in script: %2", cmd, url());
38 return false;
39 }
40
41 // add the arguments that we are going to pass to the function
42 QJSValueList arguments;
43 arguments.reserve(asize: args.size());
44 for (const QString &arg : args) {
45 arguments << QJSValue(arg);
46 }
47
48 QJSValue result = command.call(args: arguments);
49 // error during the calling?
50 if (result.isError()) {
51 errorMessage = backtrace(error: result, i18n("Error calling %1", cmd));
52 return false;
53 }
54
55 return true;
56}
57
58bool KateCommandLineScript::exec(KTextEditor::View *view, const QString &cmd, QString &msg, const KTextEditor::Range &range)
59{
60 if (range.isValid()) {
61 view->setSelection(range);
62 }
63
64 KShell::Errors errorCode;
65 QStringList args(KShell::splitArgs(cmd, flags: KShell::NoOptions, err: &errorCode));
66
67 if (errorCode != KShell::NoError) {
68 msg = i18n("Bad quoting in call: %1. Please escape single quotes with a backslash.", cmd);
69 return false;
70 }
71
72 QString _cmd(args.first());
73 args.removeFirst();
74
75 if (!view) {
76 msg = i18n("Could not access view");
77 return false;
78 }
79
80 if (setView(qobject_cast<KTextEditor::ViewPrivate *>(object: view))) {
81 // setView fails if the script cannot be loaded
82 // balance edit stack in any case!
83 qobject_cast<KTextEditor::ViewPrivate *>(object: view)->doc()->pushEditState();
84 bool success = callFunction(cmd: _cmd, args, errorMessage&: msg);
85 qobject_cast<KTextEditor::ViewPrivate *>(object: view)->doc()->popEditState();
86 return success;
87 }
88
89 return false;
90}
91
92bool KateCommandLineScript::supportsRange(const QString &)
93{
94 return true;
95}
96
97bool KateCommandLineScript::help(KTextEditor::View *view, const QString &cmd, QString &msg)
98{
99 if (!setView(qobject_cast<KTextEditor::ViewPrivate *>(object: view))) {
100 // setView fails, if the script cannot be loaded
101 return false;
102 }
103
104 clearExceptions();
105 QJSValue helpFunction = function(QStringLiteral("help"));
106 if (!helpFunction.isCallable()) {
107 return false;
108 }
109
110 // add the arguments that we are going to pass to the function
111 QJSValueList arguments;
112 arguments << QJSValue(cmd);
113
114 QJSValue result = helpFunction.call(args: arguments);
115
116 // error during the calling?
117 if (result.isError()) {
118 msg = backtrace(error: result, i18n("Error calling 'help %1'", cmd));
119 return false;
120 }
121
122 if (result.isUndefined() || !result.isString()) {
123 qCDebug(LOG_KTE) << i18n("No help specified for command '%1' in script %2", cmd, url());
124 return false;
125 }
126 msg = result.toString();
127
128 return !msg.isEmpty();
129}
130

source code of ktexteditor/src/script/katecommandlinescript.cpp