Kate
katescript.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "katescript.h"
00020 #include "katescriptdocument.h"
00021 #include "katescriptview.h"
00022 #include "kateview.h"
00023 #include "katedocument.h"
00024
00025 #include <iostream>
00026
00027 #include <QFile>
00028
00029 #include <QScriptEngine>
00030 #include <QScriptValue>
00031 #include <QScriptContext>
00032
00033 #include <kdebug.h>
00034 #include <klocale.h>
00035
00039 static QScriptValue cursorToScriptValue(QScriptEngine *engine, const KTextEditor::Cursor &cursor)
00040 {
00041 QScriptValue obj = engine->newObject();
00042 obj.setProperty("line", QScriptValue(engine, cursor.line()));
00043 obj.setProperty("column", QScriptValue(engine, cursor.column()));
00044 return obj;
00045 }
00046
00047 static void cursorFromScriptValue(const QScriptValue &obj, KTextEditor::Cursor &cursor)
00048 {
00049 cursor.setLine (obj.property("line").toInt32());
00050 cursor.setColumn (obj.property("column").toInt32());
00051 }
00052
00053 namespace Kate {
00054 namespace Script {
00055
00056 QScriptValue debug(QScriptContext *context, QScriptEngine *engine) {
00057 QStringList message;
00058 for(int i = 0; i < context->argumentCount(); ++i) {
00059 message << context->argument(i).toString();
00060 }
00061
00062 std::cerr << "\033[34m" << qPrintable(message.join(" ")) << "\033[0m\n";
00063 return engine->nullValue();
00064 }
00065
00066 }
00067 }
00068
00069 KateScript::KateScript(const QString &url, const KateScriptInformation &information) :
00070 m_loaded(false), m_loadSuccessful(false), m_url(url), m_information(information), m_engine(0)
00071 , m_document (0), m_view (0)
00072 {
00073 }
00074
00075 KateScript::~KateScript()
00076 {
00077 if(m_loadSuccessful) {
00078
00079 delete m_engine;
00080 delete m_document;
00081 delete m_view;
00082 }
00083 }
00084
00085 void KateScript::displayBacktrace(const QScriptValue &error, const QString &header)
00086 {
00087 if(!m_engine) {
00088 std::cerr << "KateScript::displayBacktrace: no engine, cannot display error\n";
00089 return;
00090 }
00091 std::cerr << "\033[31m";
00092 if(!header.isNull())
00093 std::cerr << qPrintable(header) << ":\n";
00094 if(error.isError())
00095 std::cerr << qPrintable(error.toString()) << '\n';
00096 std::cerr << qPrintable(m_engine->uncaughtExceptionBacktrace().join("\n"));
00097 std::cerr << "\033[0m" << '\n';
00098 }
00099
00100 void KateScript::clearExceptions()
00101 {
00102 m_engine->clearExceptions();
00103 }
00104
00105 QScriptValue KateScript::global(const QString &name)
00106 {
00107
00108 if(!load())
00109 return QScriptValue();
00110 return m_engine->globalObject().property(name);
00111 }
00112
00113 QScriptValue KateScript::function(const QString &name)
00114 {
00115 QScriptValue value = global(name);
00116 if(!value.isFunction())
00117 return QScriptValue();
00118 return value;
00119 }
00120
00121 bool KateScript::load()
00122 {
00123 if(m_loaded)
00124 return m_loadSuccessful;
00125
00126 m_loaded = true;
00127
00128 QFile file(m_url);
00129 if (!file.open(QIODevice::ReadOnly)) {
00130 m_errorMessage = i18n("Unable to read file: '%1'", m_url);
00131 kDebug( 13050 ) << m_errorMessage;
00132 m_loadSuccessful = false;
00133 return false;
00134 }
00135 QTextStream stream(&file);
00136 stream.setCodec("UTF-8");
00137 QString source = stream.readAll();
00138 file.close();
00139
00140
00141 m_engine = new QScriptEngine();
00142
00143
00144 qScriptRegisterMetaType (m_engine, cursorToScriptValue, cursorFromScriptValue);
00145
00146 QScriptValue result = m_engine->evaluate(source, m_url);
00147 if(m_engine->hasUncaughtException()) {
00148 displayBacktrace(result, QString("Error loading %1\n").arg(m_url));
00149 m_errorMessage = i18n("Error loading script %1", m_url);
00150 m_loadSuccessful = false;
00151 return false;
00152 }
00153
00154 initEngine();
00155 m_loadSuccessful = true;
00156 return true;
00157 }
00158
00159 void KateScript::initEngine() {
00160
00161 m_engine->globalObject().setProperty("document", m_engine->newQObject(m_document = new KateScriptDocument()));
00162 m_engine->globalObject().setProperty("view", m_engine->newQObject(m_view = new KateScriptView()));
00163
00164 m_engine->globalObject().setProperty("debug", m_engine->newFunction(Kate::Script::debug));
00165 }
00166
00167 bool KateScript::setView(KateView *view)
00168 {
00169 if (!load())
00170 return false;
00171
00172 m_document->setDocument (view->doc());
00173 m_view->setView (view);
00174 return true;
00175 }
00176
00177