forked from arduino/arduino-ide
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use
clang-format
as the default sketch formatter.
- Bumped `clangd` to `14.0.0`, - Can use `.clang-format` from: - current sketch folder, - `~/.arduinoIDE/.clang-format`, - `directories#data/.clang-format`, or - falls back to default formatter styles. Closes arduino#1009 Closes arduino#566 Signed-off-by: Akos Kitta <a.kitta@arduino.cc>
- Loading branch information
Showing
9 changed files
with
461 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import { MaybePromise } from '@theia/core'; | ||
import { inject, injectable } from '@theia/core/shared/inversify'; | ||
import * as monaco from '@theia/monaco-editor-core'; | ||
import { Formatter } from '../../common/protocol/formatter'; | ||
import { Contribution, URI } from './contribution'; | ||
|
||
@injectable() | ||
export class Format | ||
extends Contribution | ||
implements | ||
monaco.languages.DocumentRangeFormattingEditProvider, | ||
monaco.languages.DocumentFormattingEditProvider | ||
{ | ||
@inject(Formatter) | ||
private readonly formatter: Formatter; | ||
|
||
override onStart(): MaybePromise<void> { | ||
const selector = this.selectorOf('ino', 'c', 'cpp', 'h', 'hpp', 'pde'); | ||
monaco.languages.registerDocumentRangeFormattingEditProvider( | ||
selector, | ||
this | ||
); | ||
monaco.languages.registerDocumentFormattingEditProvider(selector, this); | ||
} | ||
async provideDocumentRangeFormattingEdits( | ||
model: monaco.editor.ITextModel, | ||
range: monaco.Range, | ||
options: monaco.languages.FormattingOptions, | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
_token: monaco.CancellationToken | ||
): Promise<monaco.languages.TextEdit[]> { | ||
const text = await this.format(model, range, options); | ||
return [{ range, text }]; | ||
} | ||
|
||
async provideDocumentFormattingEdits( | ||
model: monaco.editor.ITextModel, | ||
options: monaco.languages.FormattingOptions, | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
_token: monaco.CancellationToken | ||
): Promise<monaco.languages.TextEdit[]> { | ||
const range = this.fullRange(model); | ||
const text = await this.format(model, range, options); | ||
return [{ range, text }]; | ||
} | ||
|
||
private fullRange(model: monaco.editor.ITextModel): monaco.Range { | ||
const lastLine = model.getLineCount(); | ||
const lastLineMaxColumn = model.getLineMaxColumn(lastLine); | ||
const end = new monaco.Position(lastLine, lastLineMaxColumn); | ||
return monaco.Range.fromPositions(new monaco.Position(1, 1), end); | ||
} | ||
|
||
/** | ||
* From the currently opened workspaces (IDE2 has always one), it calculates all possible | ||
* folder locations where the `.clang-format` file could be. | ||
*/ | ||
private formatterConfigFolderUris(model: monaco.editor.ITextModel): string[] { | ||
const editorUri = new URI(model.uri.toString()); | ||
return this.workspaceService | ||
.tryGetRoots() | ||
.map(({ resource }) => resource) | ||
.filter((workspaceUri) => workspaceUri.isEqualOrParent(editorUri)) | ||
.map((uri) => uri.toString()); | ||
} | ||
|
||
private format( | ||
model: monaco.editor.ITextModel, | ||
range: monaco.Range, | ||
options: monaco.languages.FormattingOptions | ||
): Promise<string> { | ||
console.info( | ||
`Formatting ${model.uri.toString()} [Range: ${JSON.stringify( | ||
range.toJSON() | ||
)}]` | ||
); | ||
const content = model.getValueInRange(range); | ||
const formatterConfigFolderUris = this.formatterConfigFolderUris(model); | ||
return this.formatter.format({ | ||
content, | ||
formatterConfigFolderUris, | ||
options, | ||
}); | ||
} | ||
|
||
private selectorOf( | ||
...languageId: string[] | ||
): monaco.languages.LanguageSelector { | ||
return languageId.map((language) => ({ | ||
language, | ||
exclusive: true, // <-- this should make sure the custom formatter has higher precedence over the LS formatter. | ||
})); | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
arduino-ide-extension/src/browser/theia/monaco/monaco-formatting-conflicts.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { injectable } from '@theia/core/shared/inversify'; | ||
import { MonacoFormattingConflictsContribution as TheiaMonacoFormattingConflictsContribution } from '@theia/monaco/lib/browser/monaco-formatting-conflicts'; | ||
|
||
@injectable() | ||
export class MonacoFormattingConflictsContribution extends TheiaMonacoFormattingConflictsContribution { | ||
override async initialize(): Promise<void> { | ||
// NOOP - does not register a custom formatting conflicts selects. | ||
// Does not get and set formatter preferences when selecting from multiple formatters. | ||
// Does not show quick-pick input when multiple formatters are available for the text model. | ||
// Uses the default behavior from VS Code: https://github.com/microsoft/vscode/blob/fb9f488e51af2e2efe95a34f24ca11e1b2a3f744/src/vs/editor/editor.api.ts#L19-L21 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
export const FormatterPath = '/services/formatter'; | ||
export const Formatter = Symbol('Formatter'); | ||
export interface Formatter { | ||
format({ | ||
content, | ||
formatterConfigFolderUris, | ||
options, | ||
}: { | ||
content: string; | ||
formatterConfigFolderUris: string[]; | ||
options?: FormatterOptions; | ||
}): Promise<string>; | ||
} | ||
export interface FormatterOptions { | ||
/** | ||
* Size of a tab in spaces. | ||
*/ | ||
tabSize: number; | ||
/** | ||
* Prefer spaces over tabs. | ||
*/ | ||
insertSpaces: boolean; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.