Skip to content

Commit

Permalink
Add handling for when lsp client dies
Browse files Browse the repository at this point in the history
  • Loading branch information
mls-m5 committed Nov 20, 2023
1 parent f10465b commit ebf9a25
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 15 deletions.
2 changes: 1 addition & 1 deletion lib/lsp-client
17 changes: 13 additions & 4 deletions src/core/meditlog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ namespace {
class CustomStreamBuf : public std::streambuf {
private:
std::string currentString;
LogType type;

protected:
int_type overflow(int_type ch) override {
if (ch != traits_type::eof()) {
currentString += static_cast<char>(ch);
if (ch == '\n') {
impl::logInternal(LogType::Info, currentString);
impl::logInternal(type, currentString);
currentString.clear();
}
}
Expand All @@ -26,14 +27,15 @@ class CustomStreamBuf : public std::streambuf {

int sync() override {
if (!currentString.empty()) {
impl::logInternal(LogType::Info, currentString);
impl::logInternal(type, currentString);
currentString.clear();
}
return 0;
}

public:
CustomStreamBuf() {}
CustomStreamBuf(LogType type)
: type{type} {};
~CustomStreamBuf() override {
// Ensure everything is flushed
CustomStreamBuf::sync();
Expand Down Expand Up @@ -89,8 +91,10 @@ class MeditLog {
std::function<void(LogType, std::string_view)> _callback;
std::mutex _mutex;

CustomStreamBuf buf;
CustomStreamBuf buf{LogType::Info};
CustomStreamBuf errorBuf{LogType::Error};
std::streambuf *originalBuf = nullptr;
std::streambuf *originalErrorBuf = nullptr;
};

} // namespace
Expand All @@ -110,6 +114,8 @@ void subscribeToLog(std::function<void(LogType, std::string_view)> callback) {
auto &instance = MeditLog::instance();
instance.originalBuf = std::cout.rdbuf();
std::cout.rdbuf(&instance.buf);
instance.originalErrorBuf = std::cerr.rdbuf();
std::cerr.rdbuf(&instance.errorBuf);
instance.subscribe(callback);
}

Expand All @@ -119,4 +125,7 @@ void unsubscribeToLog() {
if (instance.originalBuf) {
std::cout.rdbuf(instance.originalBuf);
}
if (instance.originalErrorBuf) {
std::cerr.rdbuf(instance.originalErrorBuf);
}
}
9 changes: 8 additions & 1 deletion src/plugin/gdbdebugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@

GdbDebugger::GdbDebugger()
: _connection{"gdb --interpreter=mi3",
[this](std::istream &in) { inputThread(in); }} {}
[this](std::istream &in) { inputThread(in); },
[this]() { gdbExitedUnexpected(); }} {}

bool GdbDebugger::doesSupport(std::filesystem::path extension) {
return extension == ".cpp" || extension == ".go";
Expand Down Expand Up @@ -203,6 +204,12 @@ void GdbDebugger::changeState(DebuggerState state) {
}
}

void GdbDebugger::gdbExitedUnexpected() {
_gdbStatusCallback("gdb exited");
_isRunning = false;
// TODO: Make sure that this works
}

void GdbDebugger::inputThread(std::istream &in) {
std::smatch matches;

Expand Down
2 changes: 2 additions & 0 deletions src/plugin/gdbdebugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ class GdbDebugger : public IDebugger {

void changeState(DebuggerState state);

void gdbExitedUnexpected();

std::function<void(DebuggerState state)> _callback;
std::function<void(std::string_view)> _applicationOutputCallback;
std::function<void(std::string_view)> _debuggerOutputCallback;
Expand Down
26 changes: 19 additions & 7 deletions src/plugin/lsp/lspplugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "core/coreenvironment.h"
#include "core/ijobqueue.h"
#include "core/logtype.h"
#include "core/meditlog.h"
#include "core/plugins.h"
#include "core/profiler.h"
#include "files/project.h"
Expand Down Expand Up @@ -77,7 +78,7 @@ LspPlugin::Instance::Instance(LspConfiguration config, LspPlugin *parent)
: _config{std::move(config)} {
client = std::make_unique<LspClient>(_config.command);

auto initializedPromise = std::promise<void>{};
auto initializedPromise = std::promise<bool>{};
auto initializedFuture = initializedPromise.get_future();

auto rootPath = parent->_core->project().settings().root;
Expand All @@ -89,14 +90,17 @@ LspPlugin::Instance::Instance(LspConfiguration config, LspPlugin *parent)
[&initializedPromise](const nlohmann::json &j) {
// std::cout << "initialization response:\n";
// std::cout << std::setw(2) << j << std::endl;
initializedPromise.set_value();
initializedPromise.set_value(true);
},
[&initializedPromise](auto &&j) {
std::cerr << "error\n";
std::cerr << j << "\n";
initializedPromise.set_value();
initializedPromise.set_value(false);
});

client->unexpectedShutdownCallback(
[&] { initializedPromise.set_value(false); });

/// Todo: If the instance is created some time after the project is created
/// the old files will not be tracked. Make sure to feed in all the old
/// files into the instance once started
Expand Down Expand Up @@ -136,7 +140,9 @@ LspPlugin::Instance::Instance(LspConfiguration config, LspPlugin *parent)
std::cerr << std::setw(4) << j << "\n";
});

initializedFuture.get();
if (!initializedFuture.get()) {
throw std::runtime_error{"Failed to initialize lsp plugin"};
}
}

LspPlugin::LspPlugin(CoreEnvironment *core)
Expand Down Expand Up @@ -225,9 +231,15 @@ LspPlugin::Instance *LspPlugin::createInstance(std::filesystem::path path) {
return nullptr;
}

_instances.push_back(std::make_unique<Instance>(std::move(*config), this));

return _instances.back().get();
try {
_instances.push_back(
std::make_unique<Instance>(std::move(*config), this));
return _instances.back().get();
}
catch (std::runtime_error &e) {
logError(e.what());
return nullptr;
}
}

void LspPlugin::handleSemanticsTokens(std::shared_ptr<Buffer> buffer,
Expand Down
2 changes: 0 additions & 2 deletions src/syntax/basichighligting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include <array>
#include <cctype>
#include <filesystem>
#include <iostream>
#include <locale>
#include <string>
#include <string_view>
Expand Down Expand Up @@ -431,7 +430,6 @@ bool BasicHighlighting::highlightStatic(Buffer &buffer) {
size_t end = x;

auto range = CursorRange{buffer, {begin, y}, {end, y}};
// std::cout << "string: " << range << std::endl;
format(range, Palette::string);
}
}
Expand Down

0 comments on commit ebf9a25

Please sign in to comment.