diff --git a/src/backends/lua/luasession.cpp b/src/backends/lua/luasession.cpp index 3ecf6940..932373d4 100644 --- a/src/backends/lua/luasession.cpp +++ b/src/backends/lua/luasession.cpp @@ -1,215 +1,215 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2014 Lucas Hermann Negri */ #include "luasession.h" #include "luaexpression.h" #include "luacompletionobject.h" #include "luahighlighter.h" #include "luahelper.h" #include #include "ui_settings.h" #include LuaSession::LuaSession( Cantor::Backend* backend) : Session(backend), m_L(nullptr), m_process(nullptr), m_currentExpression(nullptr) { } LuaSession::~LuaSession() { if (m_process) { m_process->kill(); m_process->deleteLater(); m_process = nullptr; } } void LuaSession::login() { emit loginStarted(); /* * setup Qprocess here * load the autoscripts */ m_process = new QProcess(this); - m_process->setProgram(QLatin1String("/usr/bin/lua")); + m_process->setProgram(LuaSettings::self()->path().toLocalFile()); m_process->setArguments(QStringList() << QLatin1String("-i")); m_process->setProcessChannelMode(QProcess::SeparateChannels); connect(m_process, SIGNAL(readyReadStandardOutput()), this, SLOT(readIntroMessage())); connect(m_process, SIGNAL(started()), this, SLOT(processStarted())); m_process->start(); m_process->waitForStarted(); m_process->waitForReadyRead(); // we need this for tab completion m_L = luaL_newstate(); luaL_openlibs(m_L); changeStatus(Cantor::Session::Done); emit loginDone(); } void LuaSession::readIntroMessage() { while(m_process->bytesAvailable()) { m_output.append(QString::fromLocal8Bit(m_process->readLine())); } if(!m_output.isEmpty() && m_output.trimmed().endsWith(QLatin1String(">"))) { qDebug() << " reading the intro message " << m_output ; m_output.clear(); disconnect(m_process, SIGNAL(readyReadStandardOutput()), this , SLOT(readIntroMessage())); connect(m_process, SIGNAL(readyReadStandardOutput()), this, SLOT(readOutput())); connect(m_process, SIGNAL(readyReadStandardError()), this, SLOT(readError())); } } void LuaSession::readOutput() { /* * parse the output * clear all the garbage * set it as output */ // keep reading till the output ends with '>'. // '>' marks the end of output for a particular command; while(m_process->bytesAvailable()) { m_output.append(QString::fromLocal8Bit(m_process->readLine())); } //merge outputs until lua's promt "> " appears, take care of the comment characters "-->" if(m_currentExpression && !m_output.isEmpty() && m_output.endsWith(QLatin1String("> ")) && !m_output.endsWith(QLatin1String("-> "))) { // we have our complete output // clean the output and parse it and clear m_output; m_currentExpression->parseOutput(m_output); m_output.clear(); } } void LuaSession::readError() { qDebug() << "readError"; QString error = QString::fromLocal8Bit(m_process->readAllStandardError()); if (!m_currentExpression || error.isEmpty()) { return; } m_currentExpression->parseError(error); } void LuaSession::processStarted() { qDebug() << m_process->program() << " pid " << m_process->processId() << " started " << endl; } void LuaSession::logout() { if (!m_process) return; if(status() == Cantor::Session::Running) interrupt(); m_process->kill(); m_process->deleteLater(); m_process = nullptr; Session::logout(); } void LuaSession::interrupt() { if (status() == Cantor::Session::Running && m_currentExpression) m_currentExpression->interrupt(); // Lua backend is synchronous, there is no way to currently interrupt an expression (in a clean way) changeStatus(Cantor::Session::Done); } Cantor::Expression* LuaSession::evaluateExpression(const QString& cmd, Cantor::Expression::FinishingBehavior behave, bool internal) { changeStatus(Cantor::Session::Running); m_currentExpression = new LuaExpression(this, internal); connect(m_currentExpression, SIGNAL(statusChanged(Cantor::Expression::Status)), this, SLOT(expressionFinished(Cantor::Expression::Status))); m_currentExpression->setFinishingBehavior(behave); m_currentExpression->setCommand(cmd); m_currentExpression->evaluate(); return m_currentExpression; } void LuaSession::runExpression(LuaExpression *currentExpression) { /* * get the current command * format it and write to m_process */ QString command = currentExpression->command(); command += QLatin1String("\n"); qDebug() << "final command to be executed " << command << endl; m_process->write(command.toLocal8Bit()); } Cantor::CompletionObject* LuaSession::completionFor(const QString& command, int index) { return new LuaCompletionObject(command, index, this); } void LuaSession::expressionFinished(Cantor::Expression::Status status) { switch(status) { case Cantor::Expression::Computing: break; case Cantor::Expression::Done: case Cantor::Expression::Error: case Cantor::Expression::Interrupted: changeStatus(Cantor::Session::Done); break; } } QSyntaxHighlighter* LuaSession::syntaxHighlighter(QObject* parent) { LuaHighlighter* highlighter = new LuaHighlighter(parent); return highlighter; } lua_State* LuaSession::getState() const { return m_L; }