Skip to content

Commit 511edf1

Browse files
committed
feat: add WXML formatting support
1 parent 4c9d03b commit 511edf1

File tree

3 files changed

+90
-5
lines changed

3 files changed

+90
-5
lines changed

src/formatting.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use glass_easel_template_compiler::stringify::{Stringifier, StringifyOptions};
2+
use lsp_types::{DocumentFormattingParams, TextEdit};
3+
4+
use crate::ServerContext;
5+
6+
pub(crate) async fn formatting(
7+
ctx: ServerContext,
8+
params: DocumentFormattingParams,
9+
) -> anyhow::Result<Vec<TextEdit>> {
10+
let ret = ctx
11+
.clone()
12+
.project_thread_task(
13+
&params.text_document.uri,
14+
move |project, abs_path| -> anyhow::Result<Vec<TextEdit>> {
15+
let ret = match abs_path.extension().and_then(|x| x.to_str()) {
16+
Some("wxml") => {
17+
let template = project.get_wxml_tree(&abs_path)?;
18+
let options = StringifyOptions {
19+
tab_size: params.options.tab_size,
20+
use_tab_character: !params.options.insert_spaces,
21+
..Default::default()
22+
};
23+
let mut out = String::new();
24+
Stringifier::new(&mut out, "", "", options)
25+
.run(template)?;
26+
let text_edit = TextEdit {
27+
range: lsp_types::Range {
28+
start: lsp_types::Position {
29+
line: 0,
30+
character: 0,
31+
},
32+
end: lsp_types::Position {
33+
line: u32::MAX,
34+
character: u32::MAX,
35+
},
36+
},
37+
new_text: out,
38+
};
39+
vec![text_edit]
40+
}
41+
_ => vec![],
42+
};
43+
Ok(ret)
44+
},
45+
)
46+
.await??;
47+
Ok(ret)
48+
}

src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ mod completion;
88
mod context;
99
mod file;
1010
mod folding;
11+
mod formatting;
1112
mod hover;
1213
mod logger;
1314
mod reference;
@@ -76,6 +77,8 @@ fn server_capabilities() -> lsp_types::ServerCapabilities {
7677
},
7778
),
7879
),
80+
document_formatting_provider: Some(lsp_types::OneOf::Left(true)),
81+
// document_range_formatting_provider: Some(lsp_types::OneOf::Left(true)),
7982
workspace: Some(lsp_types::WorkspaceServerCapabilities {
8083
workspace_folders: Some(lsp_types::WorkspaceFoldersServerCapabilities {
8184
supported: Some(true),
@@ -121,6 +124,7 @@ async fn handle_request(
121124
handler!("textDocument/completion", completion::completion);
122125
handler!("textDocument/documentColor", color::color);
123126
handler!("textDocument/colorPresentation", color::color_presentation);
127+
handler!("textDocument/formatting", formatting::formatting);
124128

125129
// method not found
126130
log::warn!("Missing LSP request handler for {:?}", method);

vscode-extension/src/middleware.ts

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,29 @@ const doCssValidation = async (uri: vscode.Uri, ls: LanguageService) => {
2121
return ls.doValidation(doc as any, sheet)
2222
}
2323

24+
const doFormatting = async (
25+
uri: vscode.Uri,
26+
range: vscode.Range | undefined,
27+
options: vscode.FormattingOptions,
28+
ls: LanguageService,
29+
) => {
30+
const doc = await vscode.workspace.openTextDocument(uri)
31+
return ls.format(doc as any, range, options) as unknown as vscode.TextEdit[]
32+
}
33+
34+
const selectCssLanguageService = (): LanguageService | null => {
35+
const mode = getWxssDiagnostics()
36+
if (mode === 'CSS') return cssLangService
37+
if (mode === 'LESS') return lessLangService
38+
if (mode === 'SCSS') return scssLangService
39+
return null
40+
}
41+
2442
const middleware: Middleware = {
2543
handleDiagnostics(uri, diagnostics, next) {
2644
if (path.extname(uri.path) === '.wxss') {
27-
const mode = getWxssDiagnostics()
28-
if (mode === 'CSS' || mode === 'LESS' || mode === 'SCSS') {
29-
let ls: LanguageService = cssLangService
30-
if (mode === 'LESS') ls = lessLangService
31-
else if (mode === 'SCSS') ls = scssLangService
45+
const ls = selectCssLanguageService()
46+
if (ls) {
3247
// eslint-disable-next-line @typescript-eslint/no-floating-promises
3348
doCssValidation(uri, ls)
3449
// eslint-disable-next-line promise/no-callback-in-promise
@@ -44,6 +59,24 @@ const middleware: Middleware = {
4459
}
4560
next(uri, diagnostics)
4661
},
62+
63+
provideDocumentFormattingEdits(document, options, token, next) {
64+
if (path.extname(document.uri.path) === '.wxss') {
65+
const ls = selectCssLanguageService()
66+
if (ls) {
67+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
68+
const ret = doFormatting(document.uri, undefined, options, ls)
69+
// eslint-disable-next-line promise/no-callback-in-promise
70+
.catch(() => {
71+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
72+
vscode.window.showErrorMessage('Failed to format CSS')
73+
return []
74+
})
75+
return ret
76+
}
77+
}
78+
return next(document, options, token)
79+
},
4780
}
4881

4982
export default middleware

0 commit comments

Comments
 (0)