diff options
| author | Yong He <yonghe@outlook.com> | 2022-09-26 12:58:48 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-09-26 12:58:48 -0700 |
| commit | e449446d540b6cc3d5fcd70a8f05886ef2be7547 (patch) | |
| tree | a8060d5ea497a5289fa5410ab8f489bca3d59e10 | |
| parent | fcc1a0973f91f0daff9c5c2d0a00208ecb7b91c2 (diff) | |
Support clang-format `file` and `--fallback-style` in slangd. (#2412)
Co-authored-by: Yong He <yhe@nvidia.com>
| -rw-r--r-- | source/slang/slang-language-server-auto-format.cpp | 52 | ||||
| -rw-r--r-- | source/slang/slang-language-server-auto-format.h | 4 | ||||
| -rw-r--r-- | source/slang/slang-language-server.cpp | 14 | ||||
| -rw-r--r-- | source/slang/slang-language-server.h | 2 |
4 files changed, 63 insertions, 9 deletions
diff --git a/source/slang/slang-language-server-auto-format.cpp b/source/slang/slang-language-server-auto-format.cpp index f7089bd4a..5bc9031ee 100644 --- a/source/slang/slang-language-server-auto-format.cpp +++ b/source/slang/slang-language-server-auto-format.cpp @@ -116,6 +116,42 @@ String parseXmlText(UnownedStringSlice text) return sb.ProduceString(); } +bool shouldUseFallbackStyle(const FormatOptions& options) +{ + if (!options.style.startsWith("file")) + return false; + + String clangFormatFileName = ".clang-format"; + bool standardFileName = true; + if (options.style.startsWith("file:")) + { + auto fileName = options.style.getUnownedSlice().tail(5); + if (fileName.startsWith("\"")) + fileName = fileName.head(fileName.getLength() - 1).tail(1); + clangFormatFileName = fileName; + standardFileName = false; + } + auto path = options.fileName; + do + { + path = Path::getParentDirectory(path); + auto expectedFormatFileName = Path::combine(path, clangFormatFileName); + if (File::exists(expectedFormatFileName)) + { + return false; + } + if (standardFileName) + { + expectedFormatFileName = Path::combine(path, "_clang_format"); + if (File::exists(expectedFormatFileName)) + { + return false; + } + } + } while (path.getLength()); + return true; +} + List<Edit> formatSource(UnownedStringSlice text, Index lineStart, Index lineEnd, Index cursorOffset, const FormatOptions& options) { List<Edit> edits; @@ -123,7 +159,9 @@ List<Edit> formatSource(UnownedStringSlice text, Index lineStart, Index lineEnd, String clangProcessName = options.clangFormatLocation; CommandLine cmdLine; cmdLine.setExecutableLocation(ExecutableLocation(clangProcessName)); - cmdLine.addArg("--assume-filename=source.cs"); + + cmdLine.addArg("--assume-filename"); + cmdLine.addArg(options.fileName + ".cs"); if (cursorOffset != -1) { cmdLine.addArg("--cursor=" + String(cursorOffset)); @@ -133,7 +171,17 @@ List<Edit> formatSource(UnownedStringSlice text, Index lineStart, Index lineEnd, cmdLine.addArg("--lines=" + String(lineStart) + ":" + String(lineEnd + 1)); } cmdLine.addArg("--output-replacements-xml"); - if (options.style.getLength()) + // clang-format does not allow non-builtin style for `fallback-style`. + // We detect if clang format file exists, and if not set style directly to user specified fallback style. + if (shouldUseFallbackStyle(options)) + { + if (options.fallbackStyle.getLength()) + { + cmdLine.addArg("-style"); + cmdLine.addArg(options.fallbackStyle); + } + } + else if (options.style.getLength()) { cmdLine.addArg("-style"); cmdLine.addArg(options.style); diff --git a/source/slang/slang-language-server-auto-format.h b/source/slang/slang-language-server-auto-format.h index b30a2f039..a2668dbe1 100644 --- a/source/slang/slang-language-server-auto-format.h +++ b/source/slang/slang-language-server-auto-format.h @@ -22,7 +22,9 @@ enum class FormatBehavior struct FormatOptions { String clangFormatLocation; - String style = "{BasedOnStyle: Microsoft}"; + String style = "file"; + String fallbackStyle = "{BasedOnStyle: Microsoft}"; + String fileName; bool allowLineBreakInOnTypeFormatting = false; bool allowLineBreakInRangeFormatting = false; FormatBehavior behavior = FormatBehavior::Standard; diff --git a/source/slang/slang-language-server.cpp b/source/slang/slang-language-server.cpp index e2469a88a..bb662db91 100644 --- a/source/slang/slang-language-server.cpp +++ b/source/slang/slang-language-server.cpp @@ -167,15 +167,15 @@ SlangResult LanguageServer::parseNextMessage() if (response.result.getKind() == JSONValue::Kind::Array) { auto arr = m_connection->getContainer()->getArray(response.result); - if (arr.getCount() == 11) + if (arr.getCount() == 12) { updatePredefinedMacros(arr[0]); updateSearchPaths(arr[1]); updateSearchInWorkspace(arr[2]); updateCommitCharacters(arr[3]); - updateFormattingOptions(arr[4], arr[5], arr[6], arr[7]); - updateInlayHintOptions(arr[8], arr[9]); - updateTraceOptions(arr[10]); + updateFormattingOptions(arr[4], arr[5], arr[6], arr[7], arr[8]); + updateInlayHintOptions(arr[9], arr[10]); + updateTraceOptions(arr[11]); } } break; @@ -1149,6 +1149,7 @@ SlangResult LanguageServer::formatting(const LanguageServerProtocol::DocumentFor } if (m_formatOptions.clangFormatLocation.getLength() == 0) m_formatOptions.clangFormatLocation = findClangFormatTool(); + m_formatOptions.fileName = canonicalPath; auto edits = formatSource(doc->getText().getUnownedSlice(), -1, -1, -1, m_formatOptions); auto textEdits = translateTextEdits(doc, edits); m_connection->sendResult(&textEdits, responseId); @@ -1332,12 +1333,13 @@ void LanguageServer::updateCommitCharacters(const JSONValue& jsonValue) } } -void LanguageServer::updateFormattingOptions(const JSONValue& clangFormatLoc, const JSONValue& clangFormatStyle, const JSONValue& allowLineBreakOnType, const JSONValue& allowLineBreakInRange) +void LanguageServer::updateFormattingOptions(const JSONValue& clangFormatLoc, const JSONValue& clangFormatStyle, const JSONValue& clangFormatFallbackStyle, const JSONValue& allowLineBreakOnType, const JSONValue& allowLineBreakInRange) { auto container = m_connection->getContainer(); JSONToNativeConverter converter(container, m_connection->getSink()); converter.convert(clangFormatLoc, &m_formatOptions.clangFormatLocation); converter.convert(clangFormatStyle, &m_formatOptions.style); + converter.convert(clangFormatFallbackStyle, &m_formatOptions.fallbackStyle); converter.convert(allowLineBreakOnType, &m_formatOptions.allowLineBreakInOnTypeFormatting); converter.convert(allowLineBreakInRange, &m_formatOptions.allowLineBreakInRangeFormatting); if (m_formatOptions.style.getLength() == 0) @@ -1396,6 +1398,8 @@ void LanguageServer::sendConfigRequest() args.items.add(item); item.section = "slang.format.clangFormatStyle"; args.items.add(item); + item.section = "slang.format.clangFormatFallbackStyle"; + args.items.add(item); item.section = "slang.format.allowLineBreakChangesInOnTypeFormatting"; args.items.add(item); item.section = "slang.format.allowLineBreakChangesInRangeFormatting"; diff --git a/source/slang/slang-language-server.h b/source/slang/slang-language-server.h index e7a5f3244..8ece0cc41 100644 --- a/source/slang/slang-language-server.h +++ b/source/slang/slang-language-server.h @@ -141,7 +141,7 @@ private: void updateSearchPaths(const JSONValue& value); void updateSearchInWorkspace(const JSONValue& value); void updateCommitCharacters(const JSONValue& value); - void updateFormattingOptions(const JSONValue& clangFormatLoc, const JSONValue& clangFormatStyle, const JSONValue& allowLineBreakOnType, const JSONValue& allowLineBreakInRange); + void updateFormattingOptions(const JSONValue& clangFormatLoc, const JSONValue& clangFormatStyle, const JSONValue& clangFormatFallbackStyle, const JSONValue& allowLineBreakOnType, const JSONValue& allowLineBreakInRange); void updateInlayHintOptions(const JSONValue& deducedTypes, const JSONValue& parameterNames); void updateTraceOptions(const JSONValue& value); |
