Skip to content

Commit e449446

Browse files
authored
Support clang-format file and --fallback-style in slangd. (shader-slang#2412)
Co-authored-by: Yong He <yhe@nvidia.com>
1 parent fcc1a09 commit e449446

4 files changed

+63
-9
lines changed

source/slang/slang-language-server-auto-format.cpp

+50-2
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,52 @@ String parseXmlText(UnownedStringSlice text)
116116
return sb.ProduceString();
117117
}
118118

119+
bool shouldUseFallbackStyle(const FormatOptions& options)
120+
{
121+
if (!options.style.startsWith("file"))
122+
return false;
123+
124+
String clangFormatFileName = ".clang-format";
125+
bool standardFileName = true;
126+
if (options.style.startsWith("file:"))
127+
{
128+
auto fileName = options.style.getUnownedSlice().tail(5);
129+
if (fileName.startsWith("\""))
130+
fileName = fileName.head(fileName.getLength() - 1).tail(1);
131+
clangFormatFileName = fileName;
132+
standardFileName = false;
133+
}
134+
auto path = options.fileName;
135+
do
136+
{
137+
path = Path::getParentDirectory(path);
138+
auto expectedFormatFileName = Path::combine(path, clangFormatFileName);
139+
if (File::exists(expectedFormatFileName))
140+
{
141+
return false;
142+
}
143+
if (standardFileName)
144+
{
145+
expectedFormatFileName = Path::combine(path, "_clang_format");
146+
if (File::exists(expectedFormatFileName))
147+
{
148+
return false;
149+
}
150+
}
151+
} while (path.getLength());
152+
return true;
153+
}
154+
119155
List<Edit> formatSource(UnownedStringSlice text, Index lineStart, Index lineEnd, Index cursorOffset, const FormatOptions& options)
120156
{
121157
List<Edit> edits;
122158

123159
String clangProcessName = options.clangFormatLocation;
124160
CommandLine cmdLine;
125161
cmdLine.setExecutableLocation(ExecutableLocation(clangProcessName));
126-
cmdLine.addArg("--assume-filename=source.cs");
162+
163+
cmdLine.addArg("--assume-filename");
164+
cmdLine.addArg(options.fileName + ".cs");
127165
if (cursorOffset != -1)
128166
{
129167
cmdLine.addArg("--cursor=" + String(cursorOffset));
@@ -133,7 +171,17 @@ List<Edit> formatSource(UnownedStringSlice text, Index lineStart, Index lineEnd,
133171
cmdLine.addArg("--lines=" + String(lineStart) + ":" + String(lineEnd + 1));
134172
}
135173
cmdLine.addArg("--output-replacements-xml");
136-
if (options.style.getLength())
174+
// clang-format does not allow non-builtin style for `fallback-style`.
175+
// We detect if clang format file exists, and if not set style directly to user specified fallback style.
176+
if (shouldUseFallbackStyle(options))
177+
{
178+
if (options.fallbackStyle.getLength())
179+
{
180+
cmdLine.addArg("-style");
181+
cmdLine.addArg(options.fallbackStyle);
182+
}
183+
}
184+
else if (options.style.getLength())
137185
{
138186
cmdLine.addArg("-style");
139187
cmdLine.addArg(options.style);

source/slang/slang-language-server-auto-format.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ enum class FormatBehavior
2222
struct FormatOptions
2323
{
2424
String clangFormatLocation;
25-
String style = "{BasedOnStyle: Microsoft}";
25+
String style = "file";
26+
String fallbackStyle = "{BasedOnStyle: Microsoft}";
27+
String fileName;
2628
bool allowLineBreakInOnTypeFormatting = false;
2729
bool allowLineBreakInRangeFormatting = false;
2830
FormatBehavior behavior = FormatBehavior::Standard;

source/slang/slang-language-server.cpp

+9-5
Original file line numberDiff line numberDiff line change
@@ -167,15 +167,15 @@ SlangResult LanguageServer::parseNextMessage()
167167
if (response.result.getKind() == JSONValue::Kind::Array)
168168
{
169169
auto arr = m_connection->getContainer()->getArray(response.result);
170-
if (arr.getCount() == 11)
170+
if (arr.getCount() == 12)
171171
{
172172
updatePredefinedMacros(arr[0]);
173173
updateSearchPaths(arr[1]);
174174
updateSearchInWorkspace(arr[2]);
175175
updateCommitCharacters(arr[3]);
176-
updateFormattingOptions(arr[4], arr[5], arr[6], arr[7]);
177-
updateInlayHintOptions(arr[8], arr[9]);
178-
updateTraceOptions(arr[10]);
176+
updateFormattingOptions(arr[4], arr[5], arr[6], arr[7], arr[8]);
177+
updateInlayHintOptions(arr[9], arr[10]);
178+
updateTraceOptions(arr[11]);
179179
}
180180
}
181181
break;
@@ -1149,6 +1149,7 @@ SlangResult LanguageServer::formatting(const LanguageServerProtocol::DocumentFor
11491149
}
11501150
if (m_formatOptions.clangFormatLocation.getLength() == 0)
11511151
m_formatOptions.clangFormatLocation = findClangFormatTool();
1152+
m_formatOptions.fileName = canonicalPath;
11521153
auto edits = formatSource(doc->getText().getUnownedSlice(), -1, -1, -1, m_formatOptions);
11531154
auto textEdits = translateTextEdits(doc, edits);
11541155
m_connection->sendResult(&textEdits, responseId);
@@ -1332,12 +1333,13 @@ void LanguageServer::updateCommitCharacters(const JSONValue& jsonValue)
13321333
}
13331334
}
13341335

1335-
void LanguageServer::updateFormattingOptions(const JSONValue& clangFormatLoc, const JSONValue& clangFormatStyle, const JSONValue& allowLineBreakOnType, const JSONValue& allowLineBreakInRange)
1336+
void LanguageServer::updateFormattingOptions(const JSONValue& clangFormatLoc, const JSONValue& clangFormatStyle, const JSONValue& clangFormatFallbackStyle, const JSONValue& allowLineBreakOnType, const JSONValue& allowLineBreakInRange)
13361337
{
13371338
auto container = m_connection->getContainer();
13381339
JSONToNativeConverter converter(container, m_connection->getSink());
13391340
converter.convert(clangFormatLoc, &m_formatOptions.clangFormatLocation);
13401341
converter.convert(clangFormatStyle, &m_formatOptions.style);
1342+
converter.convert(clangFormatFallbackStyle, &m_formatOptions.fallbackStyle);
13411343
converter.convert(allowLineBreakOnType, &m_formatOptions.allowLineBreakInOnTypeFormatting);
13421344
converter.convert(allowLineBreakInRange, &m_formatOptions.allowLineBreakInRangeFormatting);
13431345
if (m_formatOptions.style.getLength() == 0)
@@ -1396,6 +1398,8 @@ void LanguageServer::sendConfigRequest()
13961398
args.items.add(item);
13971399
item.section = "slang.format.clangFormatStyle";
13981400
args.items.add(item);
1401+
item.section = "slang.format.clangFormatFallbackStyle";
1402+
args.items.add(item);
13991403
item.section = "slang.format.allowLineBreakChangesInOnTypeFormatting";
14001404
args.items.add(item);
14011405
item.section = "slang.format.allowLineBreakChangesInRangeFormatting";

source/slang/slang-language-server.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ class LanguageServer
141141
void updateSearchPaths(const JSONValue& value);
142142
void updateSearchInWorkspace(const JSONValue& value);
143143
void updateCommitCharacters(const JSONValue& value);
144-
void updateFormattingOptions(const JSONValue& clangFormatLoc, const JSONValue& clangFormatStyle, const JSONValue& allowLineBreakOnType, const JSONValue& allowLineBreakInRange);
144+
void updateFormattingOptions(const JSONValue& clangFormatLoc, const JSONValue& clangFormatStyle, const JSONValue& clangFormatFallbackStyle, const JSONValue& allowLineBreakOnType, const JSONValue& allowLineBreakInRange);
145145
void updateInlayHintOptions(const JSONValue& deducedTypes, const JSONValue& parameterNames);
146146
void updateTraceOptions(const JSONValue& value);
147147

0 commit comments

Comments
 (0)