From 80564c1e6833406914c8ddc86884ccebaa7f5c79 Mon Sep 17 00:00:00 2001 From: Yingchi Long Date: Sat, 10 Aug 2024 09:20:45 +0800 Subject: [PATCH] nixd/Controller: allow setting initial configuration via CLI Add a CLI flag `-config` used to set initial configuration. For editor clients which does not support workspace configuration, the flag could be used as a fallback. --- nixd/include/nixd/CommandLine/Configuration.h | 11 ++++ nixd/lib/CommandLine/Configuration.cpp | 50 +++++++++++++++ nixd/lib/Controller/LifeTime.cpp | 2 + nixd/lib/meson.build | 1 + nixd/tools/nixd/test/format/format.md | 62 +++++++++++++++++++ nixd/tools/nixd/test/format/nixfmt | 2 + 6 files changed, 128 insertions(+) create mode 100644 nixd/include/nixd/CommandLine/Configuration.h create mode 100644 nixd/lib/CommandLine/Configuration.cpp create mode 100644 nixd/tools/nixd/test/format/format.md create mode 100755 nixd/tools/nixd/test/format/nixfmt diff --git a/nixd/include/nixd/CommandLine/Configuration.h b/nixd/include/nixd/CommandLine/Configuration.h new file mode 100644 index 000000000..47a1aeb32 --- /dev/null +++ b/nixd/include/nixd/CommandLine/Configuration.h @@ -0,0 +1,11 @@ +/// \file +/// \brief Allow default configuration being passed via CLI + +#include "nixd/Controller/Configuration.h" + +namespace nixd { + +/// \brief Parse the CLI flag and initialize the config nixd::DefaultConfig +nixd::Configuration parseCLIConfig(); + +} // namespace nixd diff --git a/nixd/lib/CommandLine/Configuration.cpp b/nixd/lib/CommandLine/Configuration.cpp new file mode 100644 index 000000000..14c1a5b6a --- /dev/null +++ b/nixd/lib/CommandLine/Configuration.cpp @@ -0,0 +1,50 @@ +/// \file +/// \brief This file implements CLI initialized configuration. + +#include "nixd/CommandLine/Configuration.h" +#include "nixd/CommandLine/Options.h" +#include "nixd/Controller/Configuration.h" + +#include "lspserver/Logger.h" + +#include +#include + +#include +#include + +using namespace nixd; +using namespace llvm::cl; + +namespace { + +opt DefaultConfigJSON{"config", + desc("JSON-encoded initial configuration"), + init(""), cat(NixdCategory)}; + +} // namespace + +Configuration nixd::parseCLIConfig() { + if (DefaultConfigJSON.empty()) + return {}; + + llvm::Expected V = llvm::json::parse(DefaultConfigJSON); + + if (!V) { + llvm::errs() + << "The JSON string of default configuration cannot be parsed, reason: " + << V.takeError() << "\n"; + std::exit(-1); + } + + llvm::json::Path::Root R; + Configuration C; + if (!fromJSON(*V, C, R)) { + // JSON is valid, but it has incorrect schema + llvm::errs() + << "The JSON string of default configuration has invalid schema: " + << R.getError() << "\n"; + std::exit(-1); + } + return C; +} diff --git a/nixd/lib/Controller/LifeTime.cpp b/nixd/lib/Controller/LifeTime.cpp index 5912c79e9..414c6d1f3 100644 --- a/nixd/lib/Controller/LifeTime.cpp +++ b/nixd/lib/Controller/LifeTime.cpp @@ -5,6 +5,7 @@ #include "nixd-config.h" +#include "nixd/CommandLine/Configuration.h" #include "nixd/CommandLine/Options.h" #include "nixd/Controller/Controller.h" #include "nixd/Eval/Launch.h" @@ -183,6 +184,7 @@ void Controller:: evalExprWithProgress(*Client, getDefaultNixOSOptionsExpr(), "nixos options"); } + Config = parseCLIConfig(); fetchConfig(); } diff --git a/nixd/lib/meson.build b/nixd/lib/meson.build index 6dfc3588e..f1e2ac934 100644 --- a/nixd/lib/meson.build +++ b/nixd/lib/meson.build @@ -4,6 +4,7 @@ libnixd_deps = [ nixd_lsp_server, nixf, llvm, nixt ] libnixd_lib = library( 'nixd', + 'CommandLine/Configuration.cpp', 'CommandLine/Options.cpp', 'Controller/AST.cpp', 'Controller/CodeAction.cpp', diff --git a/nixd/tools/nixd/test/format/format.md b/nixd/tools/nixd/test/format/format.md new file mode 100644 index 000000000..274aa83a4 --- /dev/null +++ b/nixd/tools/nixd/test/format/format.md @@ -0,0 +1,62 @@ +# RUN: nixd --lit-test -config='{ "formatting": { "command": ["%S/nixfmt"] } }' < %s | FileCheck %s + +<-- initialize(0) + +```json +{ + "jsonrpc":"2.0", + "id":0, + "method":"initialize", + "params":{ + "processId":123, + "rootPath":"", + "capabilities":{ + }, + "trace":"off" + } +} +``` + +```json +{ + "jsonrpc":"2.0", + "method":"textDocument/didOpen", + "params":{ + "textDocument":{ + "uri":"file:///format.nix", + "languageId":"nix", + "version":1, + "text":"{ stdenv,\npkgs}: \n let x=1; in { y = x; }" + } + } +} +``` + +<-- textDocument/formatting + +```json +{ + "jsonrpc": "2.0", + "id": 2, + "method": "textDocument/formatting", + "params": { + "textDocument": { + "uri": "file:///format.nix" + }, + "options": { + "tabSize": 2, + "insertSpaces": true, + "trimTrailingWhitespace": true, + "insertFinalNewline": true + } + } +} +``` + +``` +CHECK: "newText": "Hello\n", +``` + +```json +{"jsonrpc":"2.0","method":"exit"} +``` diff --git a/nixd/tools/nixd/test/format/nixfmt b/nixd/tools/nixd/test/format/nixfmt new file mode 100755 index 000000000..e5d398670 --- /dev/null +++ b/nixd/tools/nixd/test/format/nixfmt @@ -0,0 +1,2 @@ +#!/bin/sh +echo "Hello"