module; export module lsp.cli.launcher; import spdlog; import std; import lsp.core.server; import lsp.provider.manifest; import lsp.utils.args_parser; namespace { void SetupLogger(const lsp::utils::ServerConfig& config) { spdlog::set_pattern("%Y-%m-%d %H:%M:%S.%e [%t] [%^%l%$] %v"); auto logger = config.log_file.empty() ? spdlog::stderr_logger_mt("console_logger") : spdlog::basic_logger_mt("file_logger", config.log_file); logger->set_level(config.log_level); spdlog::set_default_logger(logger); spdlog::set_level(config.log_level); } } export int Run(int argc, char* argv[]) { auto parsed = lsp::utils::ParseArgs(argc, argv); if (!parsed) { std::cerr << "[TSL-LSP] Argument error: " << parsed.error() << '\n'; return 2; } if (parsed->action == lsp::utils::ParseAction::kShowHelp) { lsp::utils::PrintHelp(std::cout, argv[0]); return 0; } const auto& config = parsed->config; try { SetupLogger(config); } catch (const std::exception& error) { std::cerr << "[TSL-LSP] Failed to initialize logger: " << error.what() << '\n'; return 1; } int exit_code = 1; try { spdlog::info("TSL-LSP server starting..."); lsp::core::LspServer server( std::cin, std::cout, lsp::provider::RegisterAllProviders, config.thread_count, config.interpreter_path); exit_code = server.Run(); } catch (const std::exception& error) { std::cerr << "[TSL-LSP] Server fatal error: " << error.what() << '\n'; spdlog::error("Server fatal error: {}", error.what()); spdlog::shutdown(); return 1; } catch (...) { std::cerr << "[TSL-LSP] Server unknown fatal error\n"; spdlog::error("Server unknown fatal error"); spdlog::shutdown(); return 1; } spdlog::info("TSL-LSP server stopped with exit code {}", exit_code); spdlog::shutdown(); return exit_code; }