1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
#include "LSPNetworkSTDIO.h"
#include "ChildProcess.h"
#include "JSON.h"
#include "asyncprocess.h"
#include "cl_exception.h"
#include "clcommandlineparser.h"
#include "dirsaver.h"
#include "file_logger.h"
#include "processreaderthread.h"
#include "sftp_settings.h"
#include <sstream>
static const char separator_str[] = "\n************\n";
static size_t separator_str_len = sizeof(separator_str) - 1;
LSPNetworkSTDIO::LSPNetworkSTDIO()
{
wxFileName logfile(clStandardPaths::Get().GetUserDataDir(), "codelite-lsp.log");
m_log.Open(logfile.GetFullPath(), "a+b");
}
LSPNetworkSTDIO::~LSPNetworkSTDIO()
{
Close();
m_log.Close();
}
void LSPNetworkSTDIO::Close() { wxDELETE(m_server); }
void LSPNetworkSTDIO::Open(const LSPStartupInfo& siInfo)
{
m_startupInfo = siInfo;
// Start the LSP server first
Close();
DoStartLocalProcess();
}
void LSPNetworkSTDIO::Send(const std::string& data)
{
if(m_server) {
m_server->Write(data);
if(FileLogger::CanLog(FileLogger::Dbg)) {
m_log.Write(separator_str, separator_str_len);
m_log.Write(data.c_str(), data.length());
m_log.Flush();
}
} else {
clWARNING() << "LSPNetworkSTDIO: no process !?" << endl;
}
}
bool LSPNetworkSTDIO::IsConnected() const { return m_server != nullptr; }
void LSPNetworkSTDIO::OnProcessTerminated(clProcessEvent& event)
{
wxDELETE(m_server);
clDEBUG() << "LSPNetworkSTDIO: program terminated:" << m_startupInfo.GetLspServerCommand() << endl;
clDEBUG() << "LSPNetworkSTDIO:" << event.GetString() << endl;
clCommandEvent evt(wxEVT_LSP_NET_ERROR);
AddPendingEvent(evt);
}
void LSPNetworkSTDIO::OnProcessOutput(clProcessEvent& event)
{
const wxString& dataRead = event.GetOutput();
clCommandEvent evt(wxEVT_LSP_NET_DATA_READY);
evt.SetString(dataRead);
if(FileLogger::CanLog(FileLogger::Dbg)) {
m_log.Write(separator_str, separator_str_len);
m_log.Write(dataRead);
m_log.Flush();
}
AddPendingEvent(evt);
}
void LSPNetworkSTDIO::OnProcessStderr(clProcessEvent& event)
{
if(FileLogger::CanLog(FileLogger::Dbg)) {
m_log.Write(wxString() << "[**STDERR**]");
m_log.Write(event.GetOutput());
}
}
void LSPNetworkSTDIO::DoStartLocalProcess()
{
m_server = new ChildProcess();
BindEvents();
DirSaver ds;
if(!m_startupInfo.GetWorkingDirectory().IsEmpty() && wxFileName::DirExists(m_startupInfo.GetWorkingDirectory())) {
::wxSetWorkingDirectory(m_startupInfo.GetWorkingDirectory());
}
wxArrayString args = m_startupInfo.GetLspServerCommand();
try {
m_server->Start(args);
} catch(clException& e) {
clERROR() << "failed to execute LSP proceess with args:" << args << endl;
clERROR() << e.What() << endl;
clCommandEvent eventError(wxEVT_LSP_NET_ERROR);
eventError.SetString(e.What());
AddPendingEvent(eventError);
return;
}
clCommandEvent evtReady(wxEVT_LSP_NET_CONNECTED);
AddPendingEvent(evtReady);
if(FileLogger::CanLog(FileLogger::Dbg)) {
m_log.Write(wxString("\n\n =============== Process Started =============== \n\n"));
m_log.Flush();
}
}
void LSPNetworkSTDIO::BindEvents()
{
m_server->Bind(wxEVT_ASYNC_PROCESS_OUTPUT, &LSPNetworkSTDIO::OnProcessOutput, this);
m_server->Bind(wxEVT_ASYNC_PROCESS_STDERR, &LSPNetworkSTDIO::OnProcessStderr, this);
m_server->Bind(wxEVT_ASYNC_PROCESS_TERMINATED, &LSPNetworkSTDIO::OnProcessTerminated, this);
}
|