diff --git a/meson.build b/meson.build index 8265dd861..aea957e34 100644 --- a/meson.build +++ b/meson.build @@ -47,3 +47,4 @@ subdir('lspserver') subdir('libnixf') subdir('libnixt') subdir('nixd') +subdir('nixd-next') diff --git a/nixd-next/meson.build b/nixd-next/meson.build new file mode 100644 index 000000000..f39afc838 --- /dev/null +++ b/nixd-next/meson.build @@ -0,0 +1 @@ +subdir('tools') diff --git a/nixd-next/tools/meson.build b/nixd-next/tools/meson.build new file mode 100644 index 000000000..60111aaab --- /dev/null +++ b/nixd-next/tools/meson.build @@ -0,0 +1 @@ +subdir('nixd') diff --git a/nixd-next/tools/nixd/meson.build b/nixd-next/tools/nixd/meson.build new file mode 100644 index 000000000..861b7be3e --- /dev/null +++ b/nixd-next/tools/nixd/meson.build @@ -0,0 +1,6 @@ +nixd_next = executable('nixd-next', + 'src/Controller.cpp', + 'src/Main.cpp', + install: true, + dependencies: [ nixd_lsp_server, nixf, llvm ] +) diff --git a/nixd-next/tools/nixd/src/Controller.cpp b/nixd-next/tools/nixd/src/Controller.cpp new file mode 100644 index 000000000..a38b34680 --- /dev/null +++ b/nixd-next/tools/nixd/src/Controller.cpp @@ -0,0 +1,53 @@ +/// \file +/// \brief Controller. The process interacting with users. +#include "nixd-config.h" + +#include "lspserver/LSPServer.h" + +#include + +namespace { + +using namespace lspserver; +using namespace llvm::json; + +class Controller : public LSPServer { +public: + Controller(std::unique_ptr In, std::unique_ptr Out) + : LSPServer(std::move(In), std::move(Out)) { + + // Life Cycle + Registry.addMethod("initialize", this, &Controller::onInitialize); + Registry.addNotification("initialized", this, &Controller::onInitialized); + } + + void onInitialize( // NOLINT(readability-convert-member-functions-to-static) + [[maybe_unused]] const InitializeParams &Params, Callback Reply) { + + Object ServerCaps{ + {}, + }; + + Object Result{{ + {"serverInfo", + Object{ + {"name", "nixd"}, + {"version", NIXD_VERSION}, + }}, + {"capabilities", std::move(ServerCaps)}, + }}; + + Reply(std::move(Result)); + } + void onInitialized([[maybe_unused]] const InitializedParams &Params) {} +}; + +} // namespace + +namespace nixd { +void launchController(std::unique_ptr In, + std::unique_ptr Out) { + Controller C(std::move(In), std::move(Out)); + C.run(); +} +} // namespace nixd diff --git a/nixd-next/tools/nixd/src/Controller.h b/nixd-next/tools/nixd/src/Controller.h new file mode 100644 index 000000000..feb635f23 --- /dev/null +++ b/nixd-next/tools/nixd/src/Controller.h @@ -0,0 +1,13 @@ +#pragma once + +#include "lspserver/Connection.h" + +#include + +namespace nixd { + +[[noreturn]] void +launchController(std::unique_ptr In, + std::unique_ptr Out); + +} // namespace nixd diff --git a/nixd-next/tools/nixd/src/Main.cpp b/nixd-next/tools/nixd/src/Main.cpp new file mode 100644 index 000000000..4d24177bd --- /dev/null +++ b/nixd-next/tools/nixd/src/Main.cpp @@ -0,0 +1,83 @@ +#include "nixd-config.h" + +#include "lspserver/Connection.h" +#include "lspserver/Logger.h" + +#include "Controller.h" + +#include +#include + +using namespace lspserver; + +namespace { + +using namespace llvm::cl; + +OptionCategory Misc("miscellaneous options"); +OptionCategory Debug("debug-only options (for developers)"); + +const OptionCategory *NixdCatogories[] = {&Misc, &Debug}; + +opt InputStyle{ + "input-style", + desc("Input JSON stream encoding"), + values( + clEnumValN(JSONStreamStyle::Standard, "standard", "usual LSP protocol"), + clEnumValN(JSONStreamStyle::Delimited, "delimited", + "messages delimited by `// -----` lines, " + "with // comment support")), + init(JSONStreamStyle::Standard), + cat(Debug), + Hidden, +}; +opt LitTest{ + "lit-test", + desc("Abbreviation for -input-style=delimited -pretty -log=verbose. " + "Intended to simplify lit tests"), + init(false), cat(Debug)}; +opt LogLevel{ + "log", desc("Verbosity of log messages written to stderr"), + values( + clEnumValN(Logger::Level::Error, "error", "Error messages only"), + clEnumValN(Logger::Level::Info, "info", "High level execution tracing"), + clEnumValN(Logger::Level::Debug, "debug", "Debugging details"), + clEnumValN(Logger::Level::Verbose, "verbose", "Low level details")), + init(Logger::Level::Info), cat(Misc)}; +opt PrettyPrint{"pretty", desc("Pretty-print JSON output"), init(false), + cat(Debug)}; + +} // namespace + +int main(int argc, char *argv[]) { + SetVersionPrinter([](llvm::raw_ostream &OS) { + OS << "nixd, version: "; +#ifdef NIXD_VCS_TAG + OS << NIXD_VCS_TAG; +#else + OS << NIXD_VERSION; +#endif + OS << "\n"; + }); + + HideUnrelatedOptions(NixdCatogories); + ParseCommandLineOptions(argc, argv, "nixd language server", nullptr, + "NIXD_FLAGS"); + + if (LitTest) { + InputStyle = JSONStreamStyle::Delimited; + LogLevel = Logger::Level::Verbose; + PrettyPrint = true; + } + + StreamLogger Logger(llvm::errs(), LogLevel); + LoggingSession Session(Logger); + + auto In = std::make_unique(STDIN_FILENO, InputStyle); + + auto Out = std::make_unique(PrettyPrint); + + nixd::launchController(std::move(In), std::move(Out)); + + return 0; +}