bool FormatOptions::GetPhpFixerCommand(const wxFileName& fileName, wxString& command) { command.Clear(); m_optionsPhp.Load(); wxString phar, php, parameters, filePath; php = m_optionsPhp.GetPhpExe(); if(php.IsEmpty()) { clDEBUG() << "CodeForamtter: GetPhpFixerCommand(): empty php command" << clEndl; return false; } ::WrapWithQuotes(php); phar = GetPHPCSFixerPhar(); if(phar.IsEmpty()) { clDEBUG() << "CodeForamtter: GetPhpFixerCommand(): empty php-cs-fixer phar path" << clEndl; return false; } ::WrapWithQuotes(phar); parameters = GetPHPCSFixerPharOptions(); if(parameters.IsEmpty()) { if(m_PHPCSFixerPharSettings & kPcfAllowRisky) { parameters << " --allow-risky=yes"; } parameters << GetPhpFixerRules(fileName); } parameters.Trim().Trim(false); clDEBUG() << parameters << clEndl; filePath = fileName.GetFullPath(); ::WrapWithQuotes(filePath); command << php << " " << phar << " fix " << parameters << " " << filePath; return true; }
void PHPWorkspace::OnProjectSyncEnd(clCommandEvent& event) { const wxString& name = event.GetString(); if(m_inSyncProjects.count(name) == 0) { clWARNING() << "PHPWorkspace::OnProjectSyncEnd: unable to find project '" << name << "' in the workspace..." << clEndl; return; } clDEBUG() << "PHPWorkspace::OnProjectSyncEnd: project" << name << "completed sync" << clEndl; m_inSyncProjects.erase(name); // Load the project PHPProject::Ptr_t pProj = GetProject(name); CHECK_PTR_RET(pProj); // Update the project files pProj->SetFiles(event.GetStrings()); if(m_inSyncProjects.empty()) { clDEBUG() << "PHPWorkspace::OnProjectSyncEnd: all projects completed sync" << clEndl; if(m_projectSyncOwner) { clCommandEvent endEvent(wxEVT_PHP_WORKSPACE_FILES_SYNC_END); m_projectSyncOwner->AddPendingEvent(endEvent); } } }
void WebUpdateJob::ParseFile() { wxString os, arch, codename; GetPlatformDetails(os, codename, arch); clDEBUG() << "Current platform details:" << os << "," << codename << "," << arch << "," << CODELITE_VERSION_STRING << clEndl; JSON root(m_dataRead); JSONItem platforms = root.toElement().namedObject("platforms"); int count = platforms.arraySize(); for(int i = 0; i < count; ++i) { CodeLiteVersion v(platforms.arrayItem(i)); v.Print(); if(!v.IsReleaseVersion() && m_onlyRelease) { // User wishes to be prompted for new releases only // skip weekly builds continue; } if(v.IsNewer(os, codename, arch)) { clDEBUG() << "A new version of CodeLite found" << clEndl; wxCommandEvent event(wxEVT_CMD_NEW_VERSION_AVAILABLE); event.SetClientData(new WebUpdateJobData("https://codelite.org/support.php", v.GetUrl(), CODELITE_VERSION_STRING, "", false, true)); m_parent->AddPendingEvent(event); return; } } // If we got here, then the version is up to date wxCommandEvent event(wxEVT_CMD_VERSION_UPTODATE); m_parent->AddPendingEvent(event); }
wxString MemCheckPlugin::PrepareCommand(const wxString& projectName, wxString& wd) { wd.clear(); if(!clCxxWorkspaceST::Get()->IsOpen()) { return ""; } ProjectPtr proj = clCxxWorkspaceST::Get()->GetProject(projectName); if(!proj) { clWARNING() << "MemCheckPlugin::PrepareCommand(): could not find project:" << projectName; return wxEmptyString; } BuildConfigPtr bldConf = clCxxWorkspaceST::Get()->GetProjBuildConf(projectName, wxEmptyString); if(!bldConf) { clWARNING() << "MemCheckPlugin::PrepareCommand(): failed to find project configuration for project:" << projectName; return wxEmptyString; } wxString projectPath = proj->GetFileName().GetPath(); // expand variables wxString cmd = bldConf->GetCommand(); cmd = MacroManager::Instance()->Expand(cmd, NULL, projectName); wxString cmdArgs = bldConf->GetCommandArguments(); cmdArgs = MacroManager::Instance()->Expand(cmdArgs, NULL, projectName); // Execute command & cmdArgs wd = bldConf->GetWorkingDirectory(); wd = MacroManager::Instance()->Expand(wd, NULL, projectName); wxFileName workingDir(wd, ""); if(workingDir.IsRelative()) { workingDir.MakeAbsolute(projectPath); } wxFileName fileExe(cmd); if(fileExe.IsRelative()) { fileExe.MakeAbsolute(workingDir.GetPath()); } fileExe.Normalize(); #ifdef __WXMSW__ if(!fileExe.Exists() && fileExe.GetExt().IsEmpty()) { // Try with .exe wxFileName withExe(fileExe); withExe.SetExt("exe"); if(withExe.Exists()) { fileExe = withExe; } } #endif wd = workingDir.GetPath(); cmd = fileExe.GetFullPath(); cmd = ::WrapWithQuotes(cmd); cmd << " " << cmdArgs; clDEBUG() << "Command to execute:" << cmd; clDEBUG() << "Working directory:" << wd; return cmd; }
bool clEditorConfig::LoadForFile(const wxFileName& filename, wxFileName& editorConfigFile) { editorConfigFile = wxFileName(filename.GetPath(), ".editorconfig"); bool foundFile = false; while(editorConfigFile.GetDirCount()) { if(editorConfigFile.FileExists()) { foundFile = true; break; } editorConfigFile.RemoveLastDir(); } if(!foundFile) return false; wxString content; if(!FileUtils::ReadFileContent(editorConfigFile, content)) { clDEBUG() << "Failed to read file:" << editorConfigFile << clEndl; return false; } clEditorConfigSection section; m_sections.push_back(section); clEditorConfigSection* cursection = &(m_sections.back()); wxUnusedVar(cursection); // for debug purposes wxArrayString lines = ::wxStringTokenize(content, "\n", wxTOKEN_STRTOK); for(size_t i = 0; i < lines.size(); ++i) { // Remove comments wxString strLine = lines.Item(i); strLine = strLine.BeforeFirst('#'); strLine = strLine.BeforeFirst(';'); strLine.Trim().Trim(false); if(strLine.IsEmpty()) continue; // Process the line if(strLine.StartsWith("[") && strLine.EndsWith("]")) { strLine.RemoveLast().Remove(0, 1); // remove the [] clEditorConfigSection section; section.patterns = ProcessSection(strLine); m_sections.push_back(section); cursection = &(m_sections.back()); } else { ProcessDirective(strLine); } } clDEBUG() << "Using .editorconfig file:" << editorConfigFile << clEndl; return true; }
void PhpSFTPHandler::DoSyncFileWithRemote(const wxFileName& localFile) { // Check to see if we got a remote-upload setup PHPProject::Ptr_t pProject = PHPWorkspace::Get()->GetProjectForFile(localFile); if(!pProject) { // Not a workspace file clDEBUG() << localFile << "is not a PHP workspace file, will not sync it with remote" << clEndl; return; } SSHWorkspaceSettings workspaceSettings; workspaceSettings.Load(); if(!EnsureAccountExists(workspaceSettings)) { return; } // Convert the local path to remote path wxString remotePath = GetRemotePath(workspaceSettings, localFile.GetFullPath()); if(remotePath.IsEmpty()) { return; } // Fire this event, if the sftp plugin is ON, it will handle it clSFTPEvent eventSave(wxEVT_SFTP_SAVE_FILE); eventSave.SetAccount(workspaceSettings.GetAccount()); eventSave.SetLocalFile(localFile.GetFullPath()); eventSave.SetRemoteFile(remotePath); EventNotifier::Get()->AddPendingEvent(eventSave); }
void PhpPlugin::DoSyncFileWithRemote(const wxFileName& localFile) { // Check to see if we got a remote-upload setup PHPProject::Ptr_t pProject = PHPWorkspace::Get()->GetProjectForFile(localFile); if(!pProject) { // Not a workspace file clDEBUG() << localFile << "is not a PHP workspace file, will not sync it with remote" << clEndl; return; } SSHWorkspaceSettings settings; settings.Load(); if(settings.IsRemoteUploadSet() && settings.IsRemoteUploadEnabled()) { // Post an event to the SFTP plugin and ask it to save our file wxFileName fnLocalFile = localFile; fnLocalFile.MakeRelativeTo(PHPWorkspace::Get()->GetFilename().GetPath()); fnLocalFile.MakeAbsolute(wxFileName(settings.GetRemoteFolder(), "", wxPATH_UNIX).GetPath()); wxString remoteFile = fnLocalFile.GetFullPath(wxPATH_UNIX); // Fire this event, if the sftp plugin is ON, it will handle it clSFTPEvent eventSave(wxEVT_SFTP_SAVE_FILE); eventSave.SetAccount(settings.GetAccount()); eventSave.SetLocalFile(localFile.GetFullPath()); eventSave.SetRemoteFile(remoteFile); EventNotifier::Get()->AddPendingEvent(eventSave); } }
void NodeJSDevToolsProtocol::ProcessMessage(const wxString& msg, clWebSocketClient& socket) { JSON root(msg); if(!root.isOk()) { return; } JSONItem rootElement = root.toElement(); wxString method = rootElement.namedObject("method").toString(); long replyId = rootElement.namedObject("id").toInt(wxNOT_FOUND); if(!method.IsEmpty()) { // Debugger event arrived NodeMessageBase::Ptr_t handler = m_handlers.GetHandler(method); if(handler) { clDEBUG() << "Invoking handler:" << handler->GetEventName(); handler->Process(socket, rootElement.namedObject("params")); } } else if(replyId != wxNOT_FOUND) { if(rootElement.hasNamedObject("result")) { // Invoke the action for this reply if(m_waitingReplyCommands.count(replyId)) { CommandHandler& handler = m_waitingReplyCommands[replyId]; if(handler.action) { handler.action(rootElement.namedObject("result")); } // Delete the handler m_waitingReplyCommands.erase(replyId); } } } }
bool LLDBConnector::ConnectToRemoteDebugger(const wxString& ip, int port, LLDBConnectReturnObject& ret, int timeout) { m_socket.reset(NULL); clSocketClient* client = new clSocketClient(); m_socket.reset(client); clDEBUG() << "Connecting to codelite-lldb on" << ip << ":" << port; try { bool would_block = false; if(!client->ConnectRemote(ip, port, would_block, true)) { // select the socket if(!would_block) { m_socket.reset(NULL); return false; } try { if(client->SelectWrite(timeout) == clSocketBase::kTimeout) { m_socket.reset(NULL); return false; } } catch(clSocketException& e) { clDEBUG() << "SelectWrite error:" << e.what(); } } // Connected! // Read the negotiation packet (part of the protocol only when doing remote connection) wxString message; if(m_socket->ReadMessage(message, 2) != clSocketBase::kSuccess) { m_socket.reset(NULL); return false; } LLDBRemoteHandshakePacket handshake(message); ret.SetRemoteHostName(handshake.GetHost()); ret.SetPivotNeeded(handshake.GetHost() != ::wxGetHostName()); } catch(clSocketException& e) { clWARNING() << "LLDBConnector::ConnectToRemoteDebugger:" << e.what(); m_socket.reset(NULL); return false; } clDEBUG() << "Successfully connected to codelite-lldb"; return true; }
wxString FileUtils::GetOSXTerminalCommand(const wxString& command, const wxString& workingDirectory) { wxFileName script(clStandardPaths::Get().GetBinFolder(), "osx-terminal.sh"); wxString cmd; cmd << EscapeString(script.GetFullPath()) << " \""; if(!workingDirectory.IsEmpty()) { cmd << "cd " << EscapeString(workingDirectory) << " && "; } cmd << EscapeString(command) << "\""; clDEBUG() << "GetOSXTerminalCommand returned:" << cmd << clEndl; return cmd; }
void clGotoAnythingManager::Initialise() { // Register the core actions m_actions.clear(); wxFrame* mainFrame = EventNotifier::Get()->TopFrame(); wxMenuBar* mb = mainFrame->GetMenuBar(); if(!mb) return; clDEBUG() << "clGotoAnythingManager::Initialise called." << (wxUIntPtr)this << clEndl; // Get list of menu entries std::queue<std::pair<wxString, wxMenu*> > q; for(size_t i = 0; i < mb->GetMenuCount(); ++i) { q.push(std::make_pair("", mb->GetMenu(i))); } static wxBitmap defaultBitmap = clGetManager()->GetStdIcons()->LoadBitmap("placeholder"); while(!q.empty()) { wxMenu* menu = q.front().second; wxString prefix = q.front().first; q.pop(); // Call this to ensure that any checkable items are marked as "checked" if needed menu->UpdateUI(mainFrame->GetEventHandler()); const wxMenuItemList& L = menu->GetMenuItems(); wxMenuItemList::const_iterator iter = L.begin(); for(; iter != L.end(); ++iter) { wxMenuItem* menuItem = *iter; if(menuItem->GetSubMenu()) { wxString labelText = menuItem->GetItemLabelText(); if((labelText == "Recent Files") || (labelText == "Recent Workspaces")) { continue; } q.push(std::make_pair(menuItem->GetItemLabelText() + " > ", menuItem->GetSubMenu())); } else if((menuItem->GetId() != wxNOT_FOUND) && (menuItem->GetId() != wxID_SEPARATOR)) { clGotoEntry entry; wxString desc = menuItem->GetItemLabelText(); entry.SetDesc(prefix + desc); if(menuItem->IsCheck()) { entry.SetFlags(clGotoEntry::kItemCheck); entry.SetChecked(menuItem->IsChecked()); } if(menuItem->GetAccel()) { entry.SetKeyboardShortcut(menuItem->GetAccel()->ToString()); } entry.SetResourceID(menuItem->GetId()); entry.SetBitmap(menuItem->GetBitmap().IsOk() ? menuItem->GetBitmap() : defaultBitmap); if(!entry.GetDesc().IsEmpty()) { // Dont add empty entries m_actions[entry.GetDesc()] = entry; } } } } }
bool LLDBConnector::LaunchLocalDebugServer() { #if !BUILD_CODELITE_LLDB // Not supported :( ::wxMessageBox(_("Locally debugging with LLDB on Windows is not supported by LLDB"), "CodeLite", wxICON_WARNING | wxOK | wxCENTER); return false; #endif clDEBUG() << "Launching codelite-lldb"; // Start the debugger if(m_process) { // another debugger process is already running return false; } // Apply the environment before we start // set the LLDB_DEBUGSERVER_PATH env variable wxStringMap_t om; om["LLDB_DEBUGSERVER_PATH"] = m_debugserver; EnvSetter es(NULL, &om); wxFileName fnCodeLiteLLDB(clStandardPaths::Get().GetBinaryFullPath("codelite-lldb")); wxString command; command << fnCodeLiteLLDB.GetFullPath() << " -s " << GetDebugServerPath(); clDEBUG() << "LLDB_DEBUGSERVER_PATH is set to" << m_debugserver; m_process = ::CreateAsyncProcess(this, command); if(!m_process) { clERROR() << "LLDBConnector: failed to launch codelite-lldb:" << fnCodeLiteLLDB.GetFullPath(); return false; } else { clDEBUG() << "codelite-lldb launched successfully. PID=" << m_process->GetPid(); } return true; }
bool LLDBConnector::ConnectToLocalDebugger(LLDBConnectReturnObject& ret, int timeout) { #ifndef __WXMSW__ clSocketClient* client = new clSocketClient(); m_socket.reset(client); clDEBUG() << "Connecting to codelite-lldb on:" << GetDebugServerPath(); long msTimeout = timeout * 1000; long retriesCount = msTimeout / 250; // We try every 250 ms to connect bool connected = false; for(long i = 0; i < retriesCount; ++i) { if(!client->ConnectLocal(GetDebugServerPath())) { wxThread::Sleep(250); continue; } connected = true; break; } if(!connected) { return false; } // Start the lldb event thread // and start a listener thread which will read replies // from codelite-lldb and convert them into LLDBEvent socket_t fd = m_socket->GetSocket(); m_pivot.Clear(); m_thread = new LLDBNetworkListenerThread(this, m_pivot, fd); m_thread->Start(); clDEBUG() << "Successfully connected to codelite-lldb"; return true; #else clWARNING() << "LLDB Debugger: can't connect to local debugger - this is not support on MSW"; return false; #endif }
/** * @brief return true of this codelite version object is newer than the provided input */ bool IsNewer(const wxString& os, const wxString& codename, const wxString& arch) const { wxString strVersionNumer = CODELITE_VERSION_STRING; strVersionNumer.Replace(".", ""); long nVersionNumber = -1; strVersionNumer.ToCLong(&nVersionNumber); if((m_os == os) && (m_arch == arch) && (m_codename == codename)) { bool res = (m_version > nVersionNumber); if(res) { clDEBUG() << "Found new version!" << clEndl; } return res; } return false; }
bool FormatOptions::GetPhpcbfCommand(const wxFileName& fileName, wxString& command) { command.Clear(); m_optionsPhp.Load(); wxString phar, php, parameters, filePath; php = m_optionsPhp.GetPhpExe(); if(php.IsEmpty()) { clDEBUG() << "CodeForamtter: GetPhpcbfCommand(): empty php command" << clEndl; return false; } ::WrapWithQuotes(php); phar = GetPhpcbfPhar(); if(phar.IsEmpty()) { clDEBUG() << "CodeForamtter: GetPhpcbfCommand(): empty phpcbf phar path" << clEndl; return false; } ::WrapWithQuotes(phar); parameters << GetPhpcbfStandard(fileName); if(m_PhpcbfEncoding != "") { parameters << " --encoding=" << m_PhpcbfEncoding; } if(m_phpcbfSeverity) { parameters << " --severity=" << m_phpcbfSeverity; } if(m_PhpcbfPharOptions & kWarningSeverity0) { parameters << " -n"; } parameters.Trim().Trim(false); filePath = fileName.GetFullPath(); ::WrapWithQuotes(filePath); command << php << " " << phar << " " << parameters << " " << filePath; return true; }
void NodeJSDevToolsProtocol::SendSimpleCommand(clWebSocketClient& socket, const wxString& command, const JSONItem& params) { try { JSON root(cJSON_Object); JSONItem e = root.toElement(); e.addProperty("id", ++message_id); e.addProperty("method", command); if(params.isOk()) { e.append(params); } wxString command = e.format(false); clDEBUG() << "-->" << command; socket.Send(command); } catch(clSocketException& e) { clWARNING() << e.what(); } }
void LanguageServerCluster::OnSymbolFound(LSPEvent& event) { const LSP::Location& location = event.GetLocation(); wxFileName fn(location.GetUri()); clDEBUG() << "LSP: Opening file:" << fn << "(" << location.GetRange().GetStart().GetLine() << ":" << location.GetRange().GetStart().GetCharacter() << ")"; // Manage the browser (BACK and FORWARD) ourself BrowseRecord from; IEditor* oldEditor = clGetManager()->GetActiveEditor(); if(oldEditor) { from = oldEditor->CreateBrowseRecord(); } IEditor* editor = clGetManager()->OpenFile(fn.GetFullPath(), "", wxNOT_FOUND, OF_None); if(editor) { editor->SelectRange(location.GetRange()); if(oldEditor) { NavMgr::Get()->AddJump(from, editor->CreateBrowseRecord()); } } }
void CodeCompletionManager::CompileCommandsFileProcessed(const wxArrayString& includePaths) { if(m_compileCommandsThread) { m_compileCommandsThread->join(); wxDELETE(m_compileCommandsThread); } if(includePaths.IsEmpty()) { return; } // Update the parser search paths wxArrayString inc, exc; ParseThreadST::Get()->GetSearchPaths(inc, exc); for(size_t i = 0; i < includePaths.size(); ++i) { if(inc.Index(includePaths.Item(i)) == wxNOT_FOUND) { inc.Add(includePaths.Item(i)); } } ParseThreadST::Get()->SetSearchPaths(inc, exc); clDEBUG() << "Parser thread search paths are now updated to:" << inc; // Trigger a quick parse wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, XRCID("retag_workspace")); clMainFrame::Get()->GetEventHandler()->AddPendingEvent(event); }
void LanguageServerCluster::RestartServer(const wxString& name) { { // Incase a server terminated, remove it from the list of servers // We do this in an inner block because 'server' (line below) will have // ref-count of 2 to make sure it is destroyed (i.e. unregister itself from // the service provider manager) the ref count needs to get to 0 // Hence the inner block LanguageServerProtocol::Ptr_t server = GetServerByName(name); if(!server) { return; } clDEBUG() << "Restarting LSP server:" << name; server->Stop(); // Remove the old instance m_servers.erase(name); } // Create new instance if(LanguageServerConfig::Get().GetServers().count(name) == 0) { return; } const LanguageServerEntry& entry = LanguageServerConfig::Get().GetServers().at(name); StartServer(entry); }
void PhpSFTPHandler::OnFileRenamed(clFileSystemEvent& e) { e.Skip(); if(!PHPWorkspace::Get()->IsOpen()) { return; } SSHWorkspaceSettings settings; settings.Load(); if(!EnsureAccountExists(settings)) { return; } wxString oldPath = GetRemotePath(settings, e.GetPath()); wxString newPath = GetRemotePath(settings, e.GetNewpath()); if(oldPath.IsEmpty() || newPath.IsEmpty()) { return; } clDEBUG() << "PHP SFTP: Renaming:" << oldPath << "->" << newPath; // Fire this event, if the sftp plugin is ON, it will handle it clSFTPEvent eventRename(wxEVT_SFTP_RENAME_FILE); eventRename.SetAccount(settings.GetAccount()); eventRename.SetRemoteFile(oldPath); eventRename.SetNewRemoteFile(newPath); EventNotifier::Get()->AddPendingEvent(eventRename); }
void LanguageServerCluster::StartServer(const LanguageServerEntry& entry) { if(entry.IsEnabled()) { if(!entry.IsValid()) { clWARNING() << "LSP Server" << entry.GetName() << "is not valid and it will not be started (one of the specified paths do not " "exist)"; LanguageServerConfig::Get().GetServers()[entry.GetName()].SetEnabled(false); LanguageServerConfig::Get().Save(); return; } LanguageServerProtocol::Ptr_t lsp(new LanguageServerProtocol(entry.GetName(), entry.GetNetType(), this)); lsp->SetPriority(entry.GetPriority()); lsp->SetDisaplayDiagnostics(entry.IsDisaplayDiagnostics()); lsp->SetUnimplementedMethods(entry.GetUnimplementedMethods()); wxArrayString lspCommand; lspCommand.Add(entry.GetExepath()); if(!entry.GetArgs().IsEmpty()) { wxArrayString args = ::wxStringTokenize(entry.GetArgs(), " ", wxTOKEN_STRTOK); lspCommand.insert(lspCommand.end(), args.begin(), args.end()); } wxString rootDir; if(clWorkspaceManager::Get().GetWorkspace()) { rootDir = clWorkspaceManager::Get().GetWorkspace()->GetFileName().GetPath(); } clDEBUG() << "Starting lsp:"; clDEBUG() << "Connection string:" << entry.GetConnectionString(); clDEBUG() << "lspCommand:" << lspCommand; clDEBUG() << "entry.GetWorkingDirectory():" << entry.GetWorkingDirectory(); clDEBUG() << "rootDir:" << rootDir; clDEBUG() << "entry.GetLanguages():" << entry.GetLanguages(); size_t flags = 0; lsp->Start(lspCommand, entry.GetConnectionString(), entry.GetWorkingDirectory(), rootDir, entry.GetLanguages(), flags); m_servers.insert({ entry.GetName(), lsp }); } }
void WebUpdateJob::OnConnectionError(clCommandEvent& e) { clDEBUG() << "WebUpdateJob: Connection error:" << e.GetString() << clEndl; m_socket.reset(nullptr); NotifyError("Connection error:" + e.GetString()); }
void Print() { clDEBUG() << "--->" << m_os << "," << m_codename << "," << m_arch << "," << m_version << clEndl; }
void SvnShowFileChangesHandler::Process(const wxString& output) { clDEBUG() << "Show file changes returned:" << clEndl; clDEBUG() << output << clEndl; SvnShowDiffChunk::List_t changes; SvnShowDiffChunk curchange; wxArrayString lines = ::wxStringTokenize(output, "\n", wxTOKEN_RET_DELIMS); if(lines.IsEmpty()) return; // Remove everything until we find the first line that starts with "---------..." // Remove it and then break the loop while(!lines.IsEmpty()) { wxString firstLine = lines.Item(0); lines.RemoveAt(0); if(firstLine.StartsWith("------")) { break; } } eState state = kWaitingHeader; while(!lines.IsEmpty()) { wxString curline = lines.Item(0); switch(state) { case kWaitingHeader: curchange.description = curline.Trim().Trim(false); lines.RemoveAt(0); state = kWaitingDiffBlock; break; case kWaitingDiffBlock: if(curline.StartsWith("======")) { // the line above us was the file name of the diff, restore it if(!curchange.commentArr.IsEmpty()) { wxString fileNameLine = curchange.commentArr.Last(); curchange.commentArr.RemoveAt(curchange.commentArr.size() - 1); // Remove the last line lines.Insert(fileNameLine, 0); } state = kWaitingSeparator; } else { curchange.commentArr.Add(curline); lines.RemoveAt(0); } break; case kWaitingSeparator: if(curline.StartsWith("---------")) { // our chunk is complete, add it curchange.Finalize(); changes.push_back(curchange); state = kWaitingHeader; curchange = SvnShowDiffChunk(); } else { curchange.diff << curline; } lines.RemoveAt(0); break; } } m_plugin->CallAfter(&Subversion2::ShowRecentChangesDialog, changes); }
void* XDebugComThread::Entry() { clDEBUG() << "CodeLite >>> XDebugComThread started" << clEndl; //---------------------------------------------------------------- // Start the debugger server and wait for XDebug to connect to us //---------------------------------------------------------------- clSocketBase::Ptr_t client; int retry(0); try { wxString connectionString; connectionString << "tcp://" << m_host << ":" << m_port; clDEBUG() << "CodeLite >>> Creating server on:" << connectionString << clEndl; m_server.Start(connectionString); clDEBUG() << "CodeLite >>> Listening on" << m_host << ":" << m_port << clEndl; // Wait for new connection (up to m_waitForConnTimeout seconds, which defaults to 5 seconds ) do { if((m_waitForConnTimeout > 0) && (retry > m_waitForConnTimeout)) { // Don't wait any longer for XDebug m_xdebugMgr->CallAfter(&XDebugManager::XDebugNotConnecting); return NULL; } client = m_server.WaitForNewConnection(1); ++retry; clDEBUG() << "CodeLite >>> Waiting for connection.." << clEndl; } while(!TestDestroy() && !client); CL_DEBUG("CodeLite >>> Successfully accepted connection from XDebug!"); m_xdebugMgr->CallAfter(&XDebugManager::SetConnected, true); //---------------------------------------------------------------- // Protocol: // First we read the init XML //---------------------------------------------------------------- std::string initXML; if(DoReadReply(initXML, client)) { m_xdebugMgr->CallAfter(&XDebugManager::OnSocketInput, initXML); } else { // Something bad happened m_xdebugMgr->CallAfter(&XDebugManager::OnCommThreadTerminated); return NULL; } // The main loop: request-reply mode while(!TestDestroy()) { wxString command; if(m_queue.ReceiveTimeout(20, command) == wxMSGQUEUE_NO_ERROR) { DoSendCommand(command, client); // Wait for the reply std::string reply; if(!DoReadReply(reply, client)) { // AN error occurred - close session break; } // Notify XDebugManager m_xdebugMgr->CallAfter(&XDebugManager::OnSocketInput, reply); } } } catch(clSocketException& e) { CL_DEBUG("XDebugComThread caught an exception: %s", e.what()); m_xdebugMgr->CallAfter(&XDebugManager::OnCommThreadTerminated); return NULL; } m_xdebugMgr->CallAfter(&XDebugManager::OnCommThreadTerminated); return NULL; }
void DbgGdb::Poke() { static wxRegEx reCommand(wxT("^([0-9]{8})")); // poll the debugger output wxString curline; if(!m_gdbProcess || m_gdbOutputArr.IsEmpty()) { return; } while(DoGetNextLine(curline)) { GetDebugeePID(curline); // For string manipulations without damaging the original line read wxString tmpline(curline); StripString(tmpline); tmpline.Trim().Trim(false); if(m_info.enableDebugLog) { // Is logging enabled? if(curline.IsEmpty() == false && !tmpline.StartsWith(wxT(">"))) { wxString strdebug(wxT("DEBUG>>")); strdebug << curline; clDEBUG() << strdebug << clEndl; m_observer->UpdateAddLine(strdebug); } } if(reConnectionRefused.Matches(curline)) { StripString(curline); #ifdef __WXGTK__ m_consoleFinder.FreeConsole(); #endif m_observer->UpdateAddLine(curline); m_observer->UpdateGotControl(DBG_EXITED_NORMALLY); return; } // Check for "Operation not permitted" usually means // that the process does not have enough permission to // attach to the process if(curline.Contains(wxT("Operation not permitted"))) { #ifdef __WXGTK__ m_consoleFinder.FreeConsole(); #endif m_observer->UpdateAddLine(_("Failed to start debugger: permission denied")); m_observer->UpdateGotControl(DBG_EXITED_NORMALLY); return; } if(tmpline.StartsWith(wxT(">"))) { // Shell line, probably user command line continue; } if(curline.StartsWith(wxT("~")) || curline.StartsWith(wxT("&")) || curline.StartsWith("@")) { // lines starting with ~ are considered "console stream" message // and are important to the CLI handler bool consoleStream(false); bool targetConsoleStream(false); if(curline.StartsWith(wxT("~"))) { consoleStream = true; } if(curline.StartsWith(wxT("@"))) { targetConsoleStream = true; } // Filter out some gdb error lines... if(FilterMessage(curline)) { continue; } StripString(curline); // If we got a valid "CLI Handler" instead of writing the output to // the output view, concatenate it into the handler buffer if(targetConsoleStream) { m_observer->UpdateAddLine(curline); } else if(consoleStream && GetCliHandler()) { GetCliHandler()->Append(curline); } else if(consoleStream) { // log message m_observer->UpdateAddLine(curline); } } else if(reCommand.Matches(curline)) { // not a gdb message, get the command associated with the message wxString id = reCommand.GetMatch(curline, 1); if(GetCliHandler() && GetCliHandler()->GetCommandId() == id) { // probably the "^done" message of the CLI command GetCliHandler()->ProcessOutput(curline); SetCliHandler(NULL); // we are done processing the CLI } else { // strip the id from the line curline = curline.Mid(8); DoProcessAsyncCommand(curline, id); } } else if(curline.StartsWith(wxT("^done")) || curline.StartsWith(wxT("*stopped"))) { // Unregistered command, use the default AsyncCommand handler to process the line DbgCmdHandlerAsyncCmd cmd(m_observer, this); cmd.ProcessOutput(curline); } else { // Unknow format, just log it if(m_info.enableDebugLog && !FilterMessage(curline)) { m_observer->UpdateAddLine(curline); } } } }
void WebUpdateJob::OnSocketError(clCommandEvent& e) { clDEBUG() << "WebUpdateJob: socket error:" << e.GetString() << clEndl; m_socket.reset(nullptr); NotifyError("Socker error:" + e.GetString()); }
void wxCodeCompletionBoxManager::InsertSelection(wxCodeCompletionBoxEntry::Ptr_t match) { IManager* manager = ::clGetManager(); IEditor* editor = manager->GetActiveEditor(); wxString entryText = match->GetInsertText(); if(editor) { wxStyledTextCtrl* ctrl = editor->GetCtrl(); bool addParens(false); bool moveCaretRight = false; bool moveCaretLeft = false; int start = wxNOT_FOUND, end = wxNOT_FOUND; std::vector<std::pair<int, int> > ranges; if(ctrl->GetSelections() > 1) { for(int i = 0; i < ctrl->GetSelections(); ++i) { int nStart = GetWordStartPos(ctrl, ctrl->GetSelectionNCaret(i), entryText.Contains(":")); int nEnd = ctrl->GetSelectionNCaret(i); ranges.push_back(std::make_pair(nStart, nEnd)); } std::sort(ranges.begin(), ranges.end(), [&](const std::pair<int, int>& e1, const std::pair<int, int>& e2) { return e1.first < e2.first; }); } else { // Default behviour: remove the partial text from the editor and replace it // with the selection start = GetWordStartPos(ctrl, ctrl->GetCurrentPos(), entryText.Contains(":")); end = ctrl->GetCurrentPos(); ctrl->SetSelection(start, end); wxChar endChar = ctrl->GetCharAt(end); if((ctrl->GetCharAt(end) != '(')) { addParens = true; moveCaretLeft = true; } else if(endChar == '(') { moveCaretRight = true; } } if(match->IsFunction()) { // a function like wxString textToInsert = entryText.BeforeFirst('('); // Build the function signature wxString funcSig = match->GetSignature(); bool userProvidedSignature = (match->GetText().Find("(") != wxNOT_FOUND); clDEBUG() << "Inserting selection:" << textToInsert; clDEBUG() << "Signature is:" << funcSig; // Check if already have an open paren, don't add another if(addParens) { textToInsert << "()"; } if(!ranges.empty()) { // Multiple carets int offset = 0; for(size_t i = 0; i < ranges.size(); ++i) { int from = ranges.at(i).first; int to = ranges.at(i).second; from += offset; to += offset; // Once we enter that text into the editor, it will change the original // offsets (in most cases the entered text is larger than that typed text) offset += textToInsert.length() - (to - from); ctrl->Replace(from, to, textToInsert); ctrl->SetSelectionNStart(i, from + textToInsert.length()); ctrl->SetSelectionNEnd(i, from + textToInsert.length()); } } else { ctrl->ReplaceSelection(textToInsert); if(!userProvidedSignature || (!funcSig.IsEmpty() && (funcSig != "()"))) { // Place the caret between the parenthesis int caretPos(wxNOT_FOUND); if(moveCaretLeft) { caretPos = start + textToInsert.length() - 1; } else if(moveCaretRight) { // Move the caret one char to the right caretPos = start + textToInsert.length() + 1; } else { caretPos = start + textToInsert.length(); } ctrl->SetCurrentPos(caretPos); ctrl->SetSelection(caretPos, caretPos); // trigger a code complete for function calltip. // We do this by simply mimicing the user action of going to the menubar: // Edit->Display Function Calltip wxCommandEvent event(wxEVT_MENU, XRCID("function_call_tip")); wxTheApp->GetTopWindow()->GetEventHandler()->AddPendingEvent(event); } } } else { if(!ranges.empty()) { // Multiple carets int offset = 0; for(size_t i = 0; i < ranges.size(); ++i) { int from = ranges.at(i).first; int to = ranges.at(i).second; from += offset; to += offset; // Once we enter that text into the editor, it will change the original // offsets (in most cases the entered text is larger than that typed text) offset += entryText.length() - (to - from); ctrl->Replace(from, to, entryText); ctrl->SetSelectionNStart(i, from + entryText.length()); ctrl->SetSelectionNEnd(i, from + entryText.length()); } } else { // Default ctrl->ReplaceSelection(entryText); } } } }
void FileUtils::OSXOpenDebuggerTerminalAndGetTTY(const wxString& path, const wxString& appname, wxString& tty, long& pid) { tty.Clear(); wxString command; wxString tmpfile; tmpfile << "/tmp/terminal.tty." << ::wxGetProcessId(); wxFileName helperScript("/tmp", "codelite-lldb-helper.sh"); wxString fileContent; fileContent << "#!/bin/bash\n"; fileContent << "tty > " << tmpfile << "\n"; fileContent << "sleep 12345"; FileUtils::WriteFileContent(helperScript, fileContent); int rc = system("chmod +x /tmp/codelite-lldb-helper.sh"); wxUnusedVar(rc); command << "/usr/bin/open -a " << appname << " /tmp/codelite-lldb-helper.sh"; clDEBUG() << "Executing: " << command; long res = ::wxExecute(command); if(res == 0) { clWARNING() << "Failed to execute command:" << command; return; } // Read the tty from the file, wait for it up to 10 seconds wxFileName ttyFile(tmpfile); pid = wxNOT_FOUND; for(size_t i = 0; i < 10; ++i) { if(!ttyFile.Exists()) { ::wxSleep(1); continue; } ReadFileContent(ttyFile, tty); tty.Trim().Trim(false); // Remove the file clRemoveFile(ttyFile.GetFullPath()); // Get the parent process ID (we want the parent PID and not // the sleep command PID) wxString psCommand; psCommand << "ps -A -o ppid,command"; wxString psOutput = ProcUtils::SafeExecuteCommand(psCommand); clDEBUG() << "ps command output:\n" << psOutput; wxArrayString lines = ::wxStringTokenize(psOutput, "\n", wxTOKEN_STRTOK); for(size_t u = 0; u < lines.GetCount(); ++u) { wxString l = lines.Item(u); l.Trim().Trim(false); if(l.Contains("sleep") && l.Contains("12345")) { // we got a match clDEBUG() << "Got a match!"; wxString ppidString = l.BeforeFirst(' '); ppidString.ToCLong(&pid); break; } } break; } clDEBUG() << "PID is:" << pid; clDEBUG() << "TTY is:" << tty; }