Skip to content

Commit 436276b

Browse files
authored
Merge pull request #69 from arduino/do-not-consider-preprocessed-section
Do not consider preprocessed section as part of the sketch.
2 parents e436a82 + 4083356 commit 436276b

File tree

2 files changed

+210
-3
lines changed

2 files changed

+210
-3
lines changed

Diff for: handler/handler.go

+207-2
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,16 @@ import (
3030

3131
var globalCliPath string
3232
var globalClangdPath string
33+
var globalFormatterConf *paths.Path
3334
var enableLogging bool
3435

3536
// Setup initializes global variables.
36-
func Setup(cliPath string, clangdPath string, _enableLogging bool) {
37+
func Setup(cliPath string, clangdPath string, formatFilePath string, _enableLogging bool) {
3738
globalCliPath = cliPath
3839
globalClangdPath = clangdPath
40+
if formatFilePath != "" {
41+
globalFormatterConf = paths.New(formatFilePath)
42+
}
3943
enableLogging = _enableLogging
4044
}
4145

@@ -411,6 +415,11 @@ func (handler *InoHandler) HandleMessageFromIDE(ctx context.Context, conn *jsonr
411415
p.TextDocument, err = handler.ino2cppTextDocumentIdentifier(p.TextDocument)
412416
cppURI = p.TextDocument.URI
413417
log.Printf(" --> formatting(%s)", p.TextDocument.URI)
418+
if cleanup, e := handler.createClangdFormatterConfig(cppURI); e != nil {
419+
err = e
420+
} else {
421+
defer cleanup()
422+
}
414423

415424
case *lsp.DocumentRangeFormattingParams:
416425
// Method: "textDocument/rangeFormatting"
@@ -420,6 +429,11 @@ func (handler *InoHandler) HandleMessageFromIDE(ctx context.Context, conn *jsonr
420429
params = cppParams
421430
cppURI = cppParams.TextDocument.URI
422431
log.Printf(" --> %s(%s:%s)", req.Method, cppParams.TextDocument.URI, cppParams.Range)
432+
if cleanup, e := handler.createClangdFormatterConfig(cppURI); e != nil {
433+
err = e
434+
} else {
435+
defer cleanup()
436+
}
423437
} else {
424438
err = e
425439
}
@@ -1062,7 +1076,13 @@ func (handler *InoHandler) cpp2inoDocumentURI(cppURI lsp.DocumentURI, cppRange l
10621076
if cppPath.EquivalentTo(handler.buildSketchCpp) {
10631077
inoPath, inoRange, err := handler.sketchMapper.CppToInoRangeOk(cppRange)
10641078
if err == nil {
1065-
log.Printf(" URI: converted %s to %s:%s", cppRange, inoPath, inoRange)
1079+
if handler.sketchMapper.IsPreprocessedCppLine(cppRange.Start.Line) {
1080+
inoPath = sourcemapper.NotIno.File
1081+
log.Printf(" URI: is in preprocessed section")
1082+
log.Printf(" converted %s to %s:%s", cppRange, inoPath, inoRange)
1083+
} else {
1084+
log.Printf(" URI: converted %s to %s:%s", cppRange, inoPath, inoRange)
1085+
}
10661086
} else if _, ok := err.(sourcemapper.AdjustedRangeErr); ok {
10671087
log.Printf(" URI: converted %s to %s:%s (END LINE ADJUSTED)", cppRange, inoPath, inoRange)
10681088
err = nil
@@ -1743,6 +1763,191 @@ func (handler *InoHandler) FromClangd(ctx context.Context, connection *jsonrpc2.
17431763
return result, err
17441764
}
17451765

1766+
func (handler *InoHandler) createClangdFormatterConfig(cppuri lsp.DocumentURI) (func(), error) {
1767+
// clangd looks for a .clang-format configuration file on the same directory
1768+
// pointed by the uri passed in the lsp command parameters.
1769+
// https://github.com/llvm/llvm-project/blob/64d06ed9c9e0389cd27545d2f6e20455a91d89b1/clang-tools-extra/clangd/ClangdLSPServer.cpp#L856-L868
1770+
// https://github.com/llvm/llvm-project/blob/64d06ed9c9e0389cd27545d2f6e20455a91d89b1/clang-tools-extra/clangd/ClangdServer.cpp#L402-L404
1771+
1772+
config := `# See: https://releases.llvm.org/11.0.1/tools/clang/docs/ClangFormatStyleOptions.html
1773+
---
1774+
Language: Cpp
1775+
# LLVM is the default style setting, used when a configuration option is not set here
1776+
BasedOnStyle: LLVM
1777+
AccessModifierOffset: -2
1778+
AlignAfterOpenBracket: Align
1779+
AlignConsecutiveAssignments: false
1780+
AlignConsecutiveBitFields: false
1781+
AlignConsecutiveDeclarations: false
1782+
AlignConsecutiveMacros: false
1783+
AlignEscapedNewlines: DontAlign
1784+
AlignOperands: Align
1785+
AlignTrailingComments: true
1786+
AllowAllArgumentsOnNextLine: true
1787+
AllowAllConstructorInitializersOnNextLine: true
1788+
AllowAllParametersOfDeclarationOnNextLine: true
1789+
AllowShortBlocksOnASingleLine: Always
1790+
AllowShortCaseLabelsOnASingleLine: true
1791+
AllowShortEnumsOnASingleLine: true
1792+
AllowShortFunctionsOnASingleLine: Empty
1793+
AllowShortIfStatementsOnASingleLine: Always
1794+
AllowShortLambdasOnASingleLine: Empty
1795+
AllowShortLoopsOnASingleLine: true
1796+
AlwaysBreakAfterDefinitionReturnType: None
1797+
AlwaysBreakAfterReturnType: None
1798+
AlwaysBreakBeforeMultilineStrings: false
1799+
AlwaysBreakTemplateDeclarations: No
1800+
BinPackArguments: true
1801+
BinPackParameters: true
1802+
# Only used when "BreakBeforeBraces" set to "Custom"
1803+
BraceWrapping:
1804+
AfterCaseLabel: false
1805+
AfterClass: false
1806+
AfterControlStatement: Never
1807+
AfterEnum: false
1808+
AfterFunction: false
1809+
AfterNamespace: false
1810+
#AfterObjCDeclaration:
1811+
AfterStruct: false
1812+
AfterUnion: false
1813+
AfterExternBlock: false
1814+
BeforeCatch: false
1815+
BeforeElse: false
1816+
BeforeLambdaBody: false
1817+
BeforeWhile: false
1818+
IndentBraces: false
1819+
SplitEmptyFunction: false
1820+
SplitEmptyRecord: false
1821+
SplitEmptyNamespace: false
1822+
# Java-specific
1823+
#BreakAfterJavaFieldAnnotations:
1824+
BreakBeforeBinaryOperators: NonAssignment
1825+
BreakBeforeBraces: Attach
1826+
BreakBeforeTernaryOperators: true
1827+
BreakConstructorInitializers: BeforeColon
1828+
BreakInheritanceList: BeforeColon
1829+
BreakStringLiterals: false
1830+
ColumnLimit: 0
1831+
# "" matches none
1832+
CommentPragmas: ""
1833+
CompactNamespaces: false
1834+
ConstructorInitializerAllOnOneLineOrOnePerLine: true
1835+
ConstructorInitializerIndentWidth: 2
1836+
ContinuationIndentWidth: 2
1837+
Cpp11BracedListStyle: false
1838+
DeriveLineEnding: true
1839+
DerivePointerAlignment: true
1840+
DisableFormat: false
1841+
# Docs say "Do not use this in config files". The default (LLVM 11.0.1) is "false".
1842+
#ExperimentalAutoDetectBinPacking:
1843+
FixNamespaceComments: false
1844+
ForEachMacros: []
1845+
IncludeBlocks: Preserve
1846+
IncludeCategories: []
1847+
# "" matches none
1848+
IncludeIsMainRegex: ""
1849+
IncludeIsMainSourceRegex: ""
1850+
IndentCaseBlocks: true
1851+
IndentCaseLabels: true
1852+
IndentExternBlock: Indent
1853+
IndentGotoLabels: false
1854+
IndentPPDirectives: None
1855+
IndentWidth: 2
1856+
IndentWrappedFunctionNames: false
1857+
InsertTrailingCommas: None
1858+
# Java-specific
1859+
#JavaImportGroups:
1860+
# JavaScript-specific
1861+
#JavaScriptQuotes:
1862+
#JavaScriptWrapImports
1863+
KeepEmptyLinesAtTheStartOfBlocks: true
1864+
MacroBlockBegin: ""
1865+
MacroBlockEnd: ""
1866+
# Set to a large number to effectively disable
1867+
MaxEmptyLinesToKeep: 100000
1868+
NamespaceIndentation: None
1869+
NamespaceMacros: []
1870+
# Objective C-specific
1871+
#ObjCBinPackProtocolList:
1872+
#ObjCBlockIndentWidth:
1873+
#ObjCBreakBeforeNestedBlockParam:
1874+
#ObjCSpaceAfterProperty:
1875+
#ObjCSpaceBeforeProtocolList
1876+
PenaltyBreakAssignment: 1
1877+
PenaltyBreakBeforeFirstCallParameter: 1
1878+
PenaltyBreakComment: 1
1879+
PenaltyBreakFirstLessLess: 1
1880+
PenaltyBreakString: 1
1881+
PenaltyBreakTemplateDeclaration: 1
1882+
PenaltyExcessCharacter: 1
1883+
PenaltyReturnTypeOnItsOwnLine: 1
1884+
# Used as a fallback if alignment style can't be detected from code (DerivePointerAlignment: true)
1885+
PointerAlignment: Right
1886+
RawStringFormats: []
1887+
ReflowComments: false
1888+
SortIncludes: false
1889+
SortUsingDeclarations: false
1890+
SpaceAfterCStyleCast: false
1891+
SpaceAfterLogicalNot: false
1892+
SpaceAfterTemplateKeyword: false
1893+
SpaceBeforeAssignmentOperators: true
1894+
SpaceBeforeCpp11BracedList: false
1895+
SpaceBeforeCtorInitializerColon: true
1896+
SpaceBeforeInheritanceColon: true
1897+
SpaceBeforeParens: ControlStatements
1898+
SpaceBeforeRangeBasedForLoopColon: true
1899+
SpaceBeforeSquareBrackets: false
1900+
SpaceInEmptyBlock: false
1901+
SpaceInEmptyParentheses: false
1902+
SpacesBeforeTrailingComments: 2
1903+
SpacesInAngles: false
1904+
SpacesInCStyleCastParentheses: false
1905+
SpacesInConditionalStatement: false
1906+
SpacesInContainerLiterals: false
1907+
SpacesInParentheses: false
1908+
SpacesInSquareBrackets: false
1909+
Standard: Auto
1910+
StatementMacros: []
1911+
TabWidth: 2
1912+
TypenameMacros: []
1913+
# Default to LF if line endings can't be detected from the content (DeriveLineEnding).
1914+
UseCRLF: false
1915+
UseTab: Never
1916+
WhitespaceSensitiveMacros: []
1917+
`
1918+
1919+
try := func(conf *paths.Path) bool {
1920+
if c, err := conf.ReadFile(); err != nil {
1921+
log.Printf(" error reading custom formatter config file %s: %s", conf, err)
1922+
} else {
1923+
log.Printf(" using custom formatter config file %s", conf)
1924+
config = string(c)
1925+
}
1926+
return true
1927+
}
1928+
1929+
if sketchFormatterConf := handler.sketchRoot.Join(".clang-format"); sketchFormatterConf.Exist() {
1930+
// If a custom config is present in the sketch folder, use that one
1931+
try(sketchFormatterConf)
1932+
} else if globalFormatterConf != nil && globalFormatterConf.Exist() {
1933+
// Otherwise if a global config file is present, use that one
1934+
try(globalFormatterConf)
1935+
}
1936+
1937+
targetFile := cppuri.AsPath()
1938+
if targetFile.IsNotDir() {
1939+
targetFile = targetFile.Parent()
1940+
}
1941+
targetFile = targetFile.Join(".clang-format")
1942+
cleanup := func() {
1943+
targetFile.Remove()
1944+
log.Printf(" formatter config cleaned")
1945+
}
1946+
log.Printf(" writing formatter config in: %s", targetFile)
1947+
err := targetFile.WriteFile([]byte(config))
1948+
return cleanup, err
1949+
}
1950+
17461951
func (handler *InoHandler) showMessage(ctx context.Context, msgType lsp.MessageType, message string) {
17471952
defer streams.CatchAndLogPanic()
17481953

Diff for: main.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ var initialFqbn string
2020
var initialBoardName string
2121
var enableLogging bool
2222
var loggingBasePath string
23+
var formatFilePath string
2324

2425
func main() {
2526
flag.StringVar(&clangdPath, "clangd", "clangd", "Path to clangd executable")
@@ -29,6 +30,7 @@ func main() {
2930
flag.StringVar(&initialBoardName, "board-name", "", "User-friendly board name to use initially (can be changed via JSON-RPC)")
3031
flag.BoolVar(&enableLogging, "log", false, "Enable logging to files")
3132
flag.StringVar(&loggingBasePath, "logpath", ".", "Location where to write logging files to when logging is enabled")
33+
flag.StringVar(&formatFilePath, "format-conf-path", "", "Path to global clang-format configuration file")
3234
flag.Parse()
3335

3436
if loggingBasePath != "" {
@@ -45,7 +47,7 @@ func main() {
4547
log.SetOutput(os.Stderr)
4648
}
4749

48-
handler.Setup(cliPath, clangdPath, enableLogging)
50+
handler.Setup(cliPath, clangdPath, formatFilePath, enableLogging)
4951
initialBoard := lsp.Board{Fqbn: initialFqbn, Name: initialBoardName}
5052

5153
stdio := streams.NewReadWriteCloser(os.Stdin, os.Stdout)

0 commit comments

Comments
 (0)