nixd
Loading...
Searching...
No Matches
Utils.cpp
Go to the documentation of this file.
1/// \file
2/// \brief Implementation of shared utilities for code actions.
3
4#include "Utils.h"
5
6#include <set>
7
8namespace nixd {
9
11 llvm::StringLiteral Kind,
12 const std::string &FileURI,
13 const lspserver::Range &EditRange,
14 std::string NewText) {
15 std::vector<lspserver::TextEdit> Edits;
16 Edits.emplace_back(
17 lspserver::TextEdit{.range = EditRange, .newText = std::move(NewText)});
18 using Changes = std::map<std::string, std::vector<lspserver::TextEdit>>;
19 lspserver::WorkspaceEdit WE{.changes = Changes{{FileURI, std::move(Edits)}}};
21 .title = Title,
22 .kind = std::string(Kind),
23 .edit = std::move(WE),
24 };
25}
26
27bool isValidNixIdentifier(const std::string &S) {
28 if (S.empty())
29 return false;
30
31 // Check first character: must be letter or underscore
32 char First = S[0];
33 if (!((First >= 'a' && First <= 'z') || (First >= 'A' && First <= 'Z') ||
34 First == '_'))
35 return false;
36
37 // Check remaining characters
38 for (size_t I = 1; I < S.size(); ++I) {
39 char C = S[I];
40 if (!((C >= 'a' && C <= 'z') || (C >= 'A' && C <= 'Z') ||
41 (C >= '0' && C <= '9') || C == '_' || C == '-' || C == '\''))
42 return false;
43 }
44
45 // Check against Nix keywords and reserved literals
46 static const std::set<std::string> Keywords = {
47 "if", "then", "else", "assert", "with", "let", "in",
48 "rec", "inherit", "or", "true", "false", "null"};
49 return Keywords.find(S) == Keywords.end();
50}
51
52std::string escapeNixString(llvm::StringRef S) {
53 std::string Result;
54 Result.reserve(S.size() + S.size() / 4 + 2);
55 for (size_t I = 0; I < S.size(); ++I) {
56 char C = S[I];
57 switch (C) {
58 case '"':
59 Result += "\\\"";
60 break;
61 case '\\':
62 Result += "\\\\";
63 break;
64 case '\n':
65 Result += "\\n";
66 break;
67 case '\r':
68 Result += "\\r";
69 break;
70 case '\t':
71 Result += "\\t";
72 break;
73 case '$':
74 // Only escape ${ to prevent interpolation
75 if (I + 1 < S.size() && S[I + 1] == '{') {
76 Result += "\\${";
77 ++I; // Skip the '{'
78 } else {
79 Result += C;
80 }
81 break;
82 default:
83 Result += C;
84 }
85 }
86 return Result;
87}
88
89std::string quoteNixAttrKey(const std::string &Key) {
91 return Key;
92
93 return "\"" + escapeNixString(Key) + "\"";
94}
95
96} // namespace nixd
Shared utilities for code actions.
bool isValidNixIdentifier(const std::string &S)
Check if a string is a valid Nix identifier that can be unquoted.
Definition Utils.cpp:27
lspserver::CodeAction createSingleEditAction(const std::string &Title, llvm::StringLiteral Kind, const std::string &FileURI, const lspserver::Range &EditRange, std::string NewText)
Create a CodeAction with a single text edit.
Definition Utils.cpp:10
std::string escapeNixString(llvm::StringRef S)
Escape special characters for Nix double-quoted string literals.
Definition Utils.cpp:52
std::string quoteNixAttrKey(const std::string &Key)
Quote and escape a Nix attribute key if necessary.
Definition Utils.cpp:89