From 61d08c74615922bc160d8b459bfa8d1962c2aa3e Mon Sep 17 00:00:00 2001 From: Eran Ifrah Date: Sun, 31 Jan 2021 21:46:04 +0200 Subject: [PATCH] on macOS, set the generic notebook tab height to "Tiny" while on other platforms, set it to "Short" --- CodeLite/file_logger.h | 6 ++++ CodeLite/fileutils.cpp | 56 ++++++++++++++++++------------ CodeLite/fileutils.h | 1 + LiteEditor/CodeLiteIDE.project | 8 ++--- Plugin/LanguageServerProtocol.cpp | 57 +++++++++++++++++++++++++++++++ Plugin/LanguageServerProtocol.h | 1 + Plugin/optionsconfig.cpp | 6 +++- 7 files changed, 108 insertions(+), 27 deletions(-) diff --git a/CodeLite/file_logger.h b/CodeLite/file_logger.h index 014c34631e..db436c3a61 100644 --- a/CodeLite/file_logger.h +++ b/CodeLite/file_logger.h @@ -171,6 +171,12 @@ inline FileLogger& clEndl(FileLogger& d) return d; } +inline FileLogger& endl(FileLogger& d) +{ + d.Flush(); + return d; +} + template FileLogger& operator<<(FileLogger& logger, const T& obj) { logger.Append(obj, logger.GetRequestedLogLevel()); diff --git a/CodeLite/fileutils.cpp b/CodeLite/fileutils.cpp index a007df2f2d..4d84341472 100644 --- a/CodeLite/fileutils.cpp +++ b/CodeLite/fileutils.cpp @@ -52,8 +52,10 @@ #include #include #endif +#include +#include #include - +using namespace std; void FileUtils::OpenFileExplorer(const wxString& path) { // Wrap the path with quotes if needed @@ -96,6 +98,22 @@ bool FileUtils::WriteFileContent(const wxFileName& fn, const wxString& content, } bool FileUtils::ReadFileContent(const wxFileName& fn, wxString& data, const wxMBConv& conv) +{ + std::string rawdata; + if(!ReadFileContentRaw(fn, rawdata)) { + return false; + } + + // convert + data = wxString(rawdata.c_str(), conv, rawdata.length()); + if(data.IsEmpty() && !rawdata.empty()) { + // Conversion failed + data = wxString::From8BitData(rawdata.c_str(), rawdata.length()); + } + return true; +} + +bool FileUtils::ReadFileContentRaw(const wxFileName& fn, std::string& data) { wxString filename = fn.GetFullPath(); data.clear(); @@ -112,29 +130,23 @@ bool FileUtils::ReadFileContent(const wxFileName& fn, wxString& data, const wxMB fseek(fp, 0, SEEK_SET); // Allocate buffer for the read - char* buffer = (char*)malloc(fsize + 1); - long bytes_read = fread(buffer, 1, fsize, fp); + data.reserve(fsize + 1); + + // use unique_ptr to auto release the buffer + unique_ptr> buffer(new char[fsize + 1], [](char* d) { delete[] d; }); + + long bytes_read = fread(buffer.get(), 1, fsize, fp); if(bytes_read != fsize) { // failed to read clERROR() << "Failed to read file content:" << fn << "." << strerror(errno); fclose(fp); - free(buffer); return false; } - buffer[fsize] = 0; - - // Close the handle + buffer.get()[fsize] = 0; fclose(fp); - // Convert it into wxString - data = wxString(buffer, conv, fsize); - if(data.IsEmpty() && fsize != 0) { - // Conversion failed - data = wxString::From8BitData(buffer, fsize); - } - - // Release the C-buffer allocated earlier - free(buffer); + // Close the handle + data = buffer.get(); return true; } @@ -333,12 +345,12 @@ wxString FileUtils::DecodeURI(const wxString& uri) wxString FileUtils::EncodeURI(const wxString& uri) { - static std::unordered_map sEncodeMap = { - { (int)'!', "%21" }, { (int)'#', "%23" }, { (int)'$', "%24" }, { (int)'&', "%26" }, { (int)'\'', "%27" }, - { (int)'(', "%28" }, { (int)')', "%29" }, { (int)'*', "%2A" }, { (int)'+', "%2B" }, { (int)',', "%2C" }, - { (int)';', "%3B" }, { (int)'=', "%3D" }, { (int)'?', "%3F" }, { (int)'@', "%40" }, { (int)'[', "%5B" }, - { (int)']', "%5D" }, { (int)' ', "%20" } - }; + static unordered_map sEncodeMap = { { (int)'!', "%21" }, { (int)'#', "%23" }, { (int)'$', "%24" }, + { (int)'&', "%26" }, { (int)'\'', "%27" }, { (int)'(', "%28" }, + { (int)')', "%29" }, { (int)'*', "%2A" }, { (int)'+', "%2B" }, + { (int)',', "%2C" }, { (int)';', "%3B" }, { (int)'=', "%3D" }, + { (int)'?', "%3F" }, { (int)'@', "%40" }, { (int)'[', "%5B" }, + { (int)']', "%5D" }, { (int)' ', "%20" } }; wxString encoded; for(size_t i = 0; i < uri.length(); ++i) { diff --git a/CodeLite/fileutils.h b/CodeLite/fileutils.h index f7813d3921..eec24d26f6 100644 --- a/CodeLite/fileutils.h +++ b/CodeLite/fileutils.h @@ -57,6 +57,7 @@ class WXDLLIMPEXP_CL FileUtils public: static bool ReadFileContent(const wxFileName& fn, wxString& data, const wxMBConv& conv = wxConvUTF8); + static bool ReadFileContentRaw(const wxFileName& fn, std::string& data); /** * @brief attempt to read up to bufferSize from the beginning of file diff --git a/LiteEditor/CodeLiteIDE.project b/LiteEditor/CodeLiteIDE.project index 5e36debbca..c5947abed6 100644 --- a/LiteEditor/CodeLiteIDE.project +++ b/LiteEditor/CodeLiteIDE.project @@ -2138,8 +2138,7 @@ resources.cpp: resources.xrc resources.cpp resources.cpp: resources.xrc - wxrc /c /v /o resources.cpp resources.xrc - + wxrc /c /v /o resources.cpp resources.xrc @@ -2232,7 +2231,7 @@ resources.cpp: resources.xrc - + @@ -2260,7 +2259,8 @@ resources.cpp: resources.xrc resources.cpp resources.cpp: resources.xrc - wxrc /c /v /o resources.cpp resources.xrc + wxrc /c /v /o resources.cpp resources.xrc + diff --git a/Plugin/LanguageServerProtocol.cpp b/Plugin/LanguageServerProtocol.cpp index 3cd7af70dc..701cc85872 100644 --- a/Plugin/LanguageServerProtocol.cpp +++ b/Plugin/LanguageServerProtocol.cpp @@ -24,6 +24,7 @@ #include "event_notifier.h" #include "file_logger.h" #include "fileextmanager.h" +#include "fileutils.h" #include "globals.h" #include "ieditor.h" #include "imanager.h" @@ -303,6 +304,27 @@ void LanguageServerProtocol::FindDefinition(IEditor* editor) CHECK_PTR_RET(editor); CHECK_COND_RET(ShouldHandleFile(editor)); + // clangd will return the match for the declaration incase it never parsed the implementation file + // so we apply this logic: + // - if the file is header then: + // - find all possible implementation files (based on file extension) + // - check to see if these files were parsed already + // - for every file that was not parsed, send SendOpenRequest request + + wxArrayString others; + if(FindImplFile(editor->GetFileName().GetFullPath(), others)) { + for(const wxString& cppFile : others) { + if(m_filesSent.count(cppFile) == 0 && ShouldHandleFile(cppFile)) { + // we never parsed this file before + clDEBUG() << "Before calling 'FindDefintion' parsing implementation file:" << cppFile << endl; + std::string fileContent; + if(FileUtils::ReadFileContentRaw(cppFile, fileContent)) { + SendOpenRequest(cppFile, fileContent, GetLanguageId(fileContent)); + } + } + } + } + // If the editor is modified, we need to tell the LSP to reparse the source file const wxFileName& filename = editor->GetFileName(); if(m_filesSent.count(filename.GetFullPath()) && editor->IsModified()) { @@ -814,6 +836,41 @@ bool LanguageServerProtocol::IsFileChangedSinceLastParse(const wxFileName& filen return m_filesSent.find(filename.GetFullPath())->second != checksum; } +bool LanguageServerProtocol::FindImplFile(const wxString& headerFile, wxArrayString& implfilesArr) +{ + wxFileName fnHeaderFile(headerFile); + wxString ext = fnHeaderFile.GetExt(); + + // sanity + if(!FileExtManager::IsCxxFile(headerFile)) { + return false; + } + + if(FileExtManager::GetType(fnHeaderFile.GetFullName()) != FileExtManager::TypeHeader) { + return false; + } + + wxArrayString cppExtensions; + + // try to find a implementation file + cppExtensions.Add("cpp"); + cppExtensions.Add("cxx"); + cppExtensions.Add("cc"); + cppExtensions.Add("c++"); + cppExtensions.Add("c"); + cppExtensions.Add("ipp"); + + // Try to locate a file in the same folder first + wxFileName cppFile = fnHeaderFile; + for(const wxString& extension : cppExtensions) { + cppFile.SetExt(extension); + if(cppFile.FileExists()) { + implfilesArr.Add(cppFile.GetFullPath()); + } + } + return !implfilesArr.IsEmpty(); +} + //===------------------------------------------------------------------ // LSPRequestMessageQueue //===------------------------------------------------------------------ diff --git a/Plugin/LanguageServerProtocol.h b/Plugin/LanguageServerProtocol.h index 1f075ccd9d..b8e09416df 100644 --- a/Plugin/LanguageServerProtocol.h +++ b/Plugin/LanguageServerProtocol.h @@ -96,6 +96,7 @@ class WXDLLIMPEXP_SDK LanguageServerProtocol : public ServiceProvider static wxString GetLanguageId(const wxString& fn); void UpdateFileSent(const wxFileName& filename, const std::string& fileContent); bool IsFileChangedSinceLastParse(const wxFileName& filename, const std::string& fileContent) const; + bool FindImplFile(const wxString& headerFile, wxArrayString& implfilesArr); protected: /** diff --git a/Plugin/optionsconfig.cpp b/Plugin/optionsconfig.cpp index cb93e08b06..43f45bbbc4 100644 --- a/Plugin/optionsconfig.cpp +++ b/Plugin/optionsconfig.cpp @@ -127,7 +127,11 @@ OptionsConfig::OptionsConfig(wxXmlNode* node) , m_workspaceTabsDirection(wxUP) , m_outputTabsDirection(wxUP) , m_indentedComments(false) - , m_nbTabHeight(nbTabHt_Tall) +#ifdef __WXOSX__ + , m_nbTabHeight(nbTabHt_Tiny) +#else + , m_nbTabHeight(nbTabHt_Short) +#endif , m_webSearchPrefix(wxT("https://www.google.com/search?q=")) , m_smartParen(true) {