diff options
Diffstat (limited to 'Build/source/utils/asymptote/LspCpp/LibLsp/lsp/working_files.cpp')
-rw-r--r-- | Build/source/utils/asymptote/LspCpp/LibLsp/lsp/working_files.cpp | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/Build/source/utils/asymptote/LspCpp/LibLsp/lsp/working_files.cpp b/Build/source/utils/asymptote/LspCpp/LibLsp/lsp/working_files.cpp new file mode 100644 index 00000000000..370a0382741 --- /dev/null +++ b/Build/source/utils/asymptote/LspCpp/LibLsp/lsp/working_files.cpp @@ -0,0 +1,186 @@ +#include "working_files.h" +#include <algorithm> +#include <climits> +#include <numeric> +#include "utils.h" +#include <memory> +#include "LibLsp/lsp/AbsolutePath.h" +using namespace lsp; +struct WorkingFilesData +{ + std::map<AbsolutePath, std::shared_ptr<WorkingFile> > files; + std::mutex files_mutex; // Protects |d_ptr->files|. +}; + +WorkingFile::WorkingFile(WorkingFiles& _parent, const AbsolutePath& filename, + const std::string& buffer_content) + : filename(filename), directory(filename), parent(_parent), counter(0), buffer_content(buffer_content) +{ + directory = Directory(GetDirName(filename.path)); +} + +WorkingFile::WorkingFile(WorkingFiles& _parent, const AbsolutePath& filename, + std::string&& buffer_content) + : filename(filename), directory(filename), parent(_parent), counter(0), buffer_content(buffer_content) +{ + directory = Directory(GetDirName(filename.path)); +} + +WorkingFiles::WorkingFiles():d_ptr(new WorkingFilesData()) +{ +} + +WorkingFiles::~WorkingFiles() +{ + delete d_ptr; + +} + + + +void WorkingFiles::CloseFilesInDirectory(const std::vector<Directory>& directories) +{ + std::lock_guard<std::mutex> lock(d_ptr->files_mutex); + std::vector<AbsolutePath> files_to_be_delete; + + for(auto& it : d_ptr->files) + { + for (auto& dir : directories) + { + if (it.second->directory == dir) { + files_to_be_delete.emplace_back(it.first); + } + } + } + + for(auto& it : files_to_be_delete) + { + d_ptr->files.erase(it); + } +} + + + + +std::shared_ptr<WorkingFile> WorkingFiles::GetFileByFilename(const AbsolutePath& filename) { + std::lock_guard<std::mutex> lock(d_ptr->files_mutex); + return GetFileByFilenameNoLock(filename); +} + +std::shared_ptr<WorkingFile> WorkingFiles::GetFileByFilenameNoLock( + const AbsolutePath& filename) { + const auto findIt = d_ptr->files.find(filename); + if ( findIt != d_ptr->files.end()) + { + return findIt->second; + } + return nullptr; +} + + + +std::shared_ptr<WorkingFile> WorkingFiles::OnOpen( lsTextDocumentItem& open) { + std::lock_guard<std::mutex> lock(d_ptr->files_mutex); + + AbsolutePath filename = open.uri.GetAbsolutePath(); + + // The file may already be open. + if (auto file = GetFileByFilenameNoLock(filename)) { + file->version = open.version; + file->buffer_content.swap(open.text); + + return file; + } + + const auto& it = d_ptr->files.insert({ filename,std::make_shared<WorkingFile>(*this,filename, std::move(open.text)) }); + return it.first->second; +} + + +std::shared_ptr<WorkingFile> WorkingFiles::OnChange(const lsTextDocumentDidChangeParams& change) { + std::lock_guard<std::mutex> lock(d_ptr->files_mutex); + + AbsolutePath filename = change.textDocument.uri.GetAbsolutePath(); + auto file = GetFileByFilenameNoLock(filename); + if (!file) { + return {}; + } + + if (change.textDocument.version) + file->version = *change.textDocument.version; + file->counter.fetch_add(1, std::memory_order_relaxed); + for (const lsTextDocumentContentChangeEvent& diff : change.contentChanges) { + // Per the spec replace everything if the rangeLength and range are not set. + // See https://github.com/Microsoft/language-server-protocol/issues/9. + if (!diff.range) { + file->buffer_content = diff.text; + + } else { + int start_offset = + GetOffsetForPosition(diff.range->start, file->buffer_content); + // Ignore TextDocumentContentChangeEvent.rangeLength which causes trouble + // when UTF-16 surrogate pairs are used. + int end_offset = + GetOffsetForPosition(diff.range->end, file->buffer_content); + file->buffer_content.replace(file->buffer_content.begin() + start_offset, + file->buffer_content.begin() + end_offset, + diff.text); + + } + } + return file; +} + +bool WorkingFiles::OnClose(const lsTextDocumentIdentifier& close) { + std::lock_guard<std::mutex> lock(d_ptr->files_mutex); + + AbsolutePath filename = close.uri.GetAbsolutePath(); + const auto findIt = d_ptr->files.find(filename); + if( findIt != d_ptr->files.end()) + { + d_ptr->files.erase(findIt); + return true; + } + return false; +} + +std::shared_ptr<WorkingFile> WorkingFiles::OnSave(const lsTextDocumentIdentifier& _save) +{ + std::lock_guard<std::mutex> lock(d_ptr->files_mutex); + + AbsolutePath filename = _save.uri.GetAbsolutePath(); + const auto findIt = d_ptr->files.find(filename); + if (findIt != d_ptr->files.end()) + { + std::shared_ptr<WorkingFile>& file = findIt->second; + lsp::WriteToFile(file->filename, file->GetContentNoLock()); + return findIt->second; + } + return {}; + +} + +bool WorkingFiles::GetFileBufferContent(std::shared_ptr<WorkingFile>&file, std::string& out) +{ + std::lock_guard<std::mutex> lock(d_ptr->files_mutex); + if (file) + { + out = file->buffer_content; + return true; + } + return false; +} +bool WorkingFiles::GetFileBufferContent(std::shared_ptr<WorkingFile>& file, std::wstring& out) +{ + std::lock_guard<std::mutex> lock(d_ptr->files_mutex); + if (file) + { + out = lsp::s2ws(file->buffer_content); + return true; + } + return false; +} +void WorkingFiles::Clear() { + std::lock_guard<std::mutex> lock(d_ptr->files_mutex); + d_ptr->files.clear(); +}
\ No newline at end of file |