diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index d17ad2984..a931137ca 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -506,9 +506,9 @@ jobs: - uses: ./.github/actions/setup-rust - name: run the formatter run: | - cargo run -p slint-fmt -- -i tests/cases/*/*.slint - cargo run -p slint-fmt -- -i examples/*/*.slint - cargo run -p slint-fmt -- -i examples/*/*/*.slint + cargo run -p slint-lsp -- format -i tests/cases/*/*.slint + cargo run -p slint-lsp -- format -i examples/*/*.slint + cargo run -p slint-lsp -- format -i examples/*/*/*.slint - name: Show the diff run: git diff - name: Run the intepreter test to make sure that the test are passing after format diff --git a/Cargo.toml b/Cargo.toml index 383b17c3a..50377aa96 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,7 +54,6 @@ members = [ 'tests/driver/rust', 'tests/screenshots', 'tools/compiler', - 'tools/fmt', 'tools/figma_import', 'tools/lsp', 'tools/updater', @@ -86,7 +85,6 @@ default-members = [ 'tests/driver/rust', 'tests/screenshots', 'tools/compiler', - 'tools/fmt', 'tools/figma_import', 'tools/lsp', 'tools/viewer', diff --git a/rustfmt.toml b/rustfmt.toml index 2a35f0230..65d48b6b0 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1 +1,2 @@ +edition = "2021" use_small_heuristics = "Max" diff --git a/tools/fmt/Cargo.toml b/tools/fmt/Cargo.toml deleted file mode 100644 index 1ee72e8e0..000000000 --- a/tools/fmt/Cargo.toml +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright © SixtyFPS GmbH -# SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial - -[package] -name = "slint-fmt" -description = "A code formatter for slint files" -authors.workspace = true -edition.workspace = true -homepage.workspace = true -license.workspace = true -repository.workspace = true -rust-version.workspace = true -version.workspace = true -publish = false -categories = ["gui", "development-tools", "command-line-utilities"] -keywords = ["formatter", "gui", "ui", "toolkit"] - -[dependencies] -i-slint-compiler = { workspace = true, features = ["default", "display-diagnostics"] } - -clap = { version = "4.0", features = ["derive", "wrap_help"] } -codemap = "0.1" -codemap-diagnostic = "0.1.1" - -[[bin]] -name = "slint-fmt" -path = "main.rs" - -[lib] -path = "lib.rs" diff --git a/tools/lsp/Cargo.toml b/tools/lsp/Cargo.toml index f35b0a344..a8865234d 100644 --- a/tools/lsp/Cargo.toml +++ b/tools/lsp/Cargo.toml @@ -79,7 +79,7 @@ preview-external = [] default = ["backend-qt", "backend-winit", "renderer-femtovg", "preview"] [dependencies] -i-slint-compiler = { workspace = true, features = ["default"] } +i-slint-compiler = { workspace = true, features = ["default", "display-diagnostics"] } euclid = "0.22" itertools = { workspace = true } @@ -96,9 +96,6 @@ i-slint-core = { workspace = true, features = ["std"], optional = true } slint = { workspace = true, features = ["compat-1-2"], optional = true } slint-interpreter = { workspace = true, features = ["compat-1-2", "highlight", "internal"], optional = true } -# for formatting support in lsp -slint-fmt = { path = "../fmt" } - [target.'cfg(not(target_arch = "wasm32"))'.dependencies] clap = { version = "4.0", features = ["derive", "wrap_help"] } crossbeam-channel = "0.5" # must match the version used by lsp-server diff --git a/tools/lsp/README.md b/tools/lsp/README.md index 633abfb20..8edc0b0d2 100644 --- a/tools/lsp/README.md +++ b/tools/lsp/README.md @@ -34,6 +34,9 @@ Alternatively, you can download one of our pre-built binaries for Linux or Windo As the next step, configure your editor to use the binary, no arguments are required +## Code formatting + +The slint code formatting tool is part of the lsp. To learn how to use it as a standalone tool, see [fmt README](./fmt/README.md) # Editor configuration diff --git a/tools/fmt/lib.rs b/tools/lsp/fmt.rs similarity index 92% rename from tools/fmt/lib.rs rename to tools/lsp/fmt.rs index fe1bbe48a..ce3fb6565 100644 --- a/tools/fmt/lib.rs +++ b/tools/lsp/fmt.rs @@ -1,5 +1,5 @@ // Copyright © SixtyFPS GmbH // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial - pub mod fmt; +pub mod tool; pub mod writer; diff --git a/tools/fmt/README.md b/tools/lsp/fmt/README.md similarity index 73% rename from tools/fmt/README.md rename to tools/lsp/fmt/README.md index 0445b7196..6986ebe22 100644 --- a/tools/fmt/README.md +++ b/tools/lsp/fmt/README.md @@ -7,15 +7,15 @@ If you find any such examples, please open an issue including the example and th ## Building -Use `cargo build --release` or similar to build this crate. +This tool is part of slint-lsp. See the README file in `lsp` for building information. ## Usage The built binary can be used in following ways: -- `slint-fmt ` - reads the file and outputs the formatted version to stdout -- `slint-fmt -i ` - reads the file and saves the output to the same file -- `slint-fmt /dev/stdin` - using /dev/stdin you can achieve the special behavior +- `slint-lsp format ` - reads the file and outputs the formatted version to stdout +- `slint-lsp format -i ` - reads the file and saves the output to the same file +- `slint-lsp format /dev/stdin` - using /dev/stdin you can achieve the special behavior of reading from stdin and writing to stdout Note that `.slint` files are formatted, while `.md` and `.rs` files are searched for `.slint` blocks. @@ -27,14 +27,14 @@ While we don't yet have a proper VSCode integration for this formatter, here is a simple way how you can get around it. 1. Install the extension Custom Format by Vehmloewff. [Marketplace link](https://marketplace.visualstudio.com/items?itemName=Vehmloewff.custom-format) -2. Build slint-fmt locally. +2. Build slint-lsp locally. 3. Add a section like this to your vscode `settings.json`: ``` { "custom-format.formatters": [ { "language": "slint", - "command": "/path/to/your/built/slint-fmt /dev/stdin" + "command": "/path/to/your/built/slint-lsp format /dev/stdin" } ] } diff --git a/tools/fmt/fmt.rs b/tools/lsp/fmt/fmt.rs similarity index 99% rename from tools/fmt/fmt.rs rename to tools/lsp/fmt/fmt.rs index 64c25ce2c..7febf8ae5 100644 --- a/tools/fmt/fmt.rs +++ b/tools/lsp/fmt/fmt.rs @@ -1,7 +1,7 @@ // Copyright © SixtyFPS GmbH // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial -use crate::writer::TokenWriter; +use super::writer::TokenWriter; use i_slint_compiler::parser::{syntax_nodes, NodeOrToken, SyntaxKind, SyntaxNode}; pub fn format_document( @@ -780,7 +780,7 @@ fn format_state( #[cfg(test)] mod tests { use super::*; - use crate::writer::FileWriter; + use crate::fmt::writer::FileWriter; use i_slint_compiler::diagnostics::BuildDiagnostics; use i_slint_compiler::parser::syntax_nodes; diff --git a/tools/fmt/main.rs b/tools/lsp/fmt/tool.rs similarity index 88% rename from tools/fmt/main.rs rename to tools/lsp/fmt/tool.rs index 2a0719683..a2b5f0580 100644 --- a/tools/fmt/main.rs +++ b/tools/lsp/fmt/tool.rs @@ -5,7 +5,7 @@ Work in progress for a formatter. Use like this to format a file: ```sh - cargo run --bin slint-fmt -- -i some_file.slint + cargo run --bin slint-lsp -- format -i some_file.slint ``` Some code in this main.rs file is duplicated with the slint-updater, i guess it could @@ -20,29 +20,13 @@ use i_slint_compiler::parser::{syntax_nodes, SyntaxNode}; use std::io::{BufWriter, Write}; use std::path::Path; -use clap::Parser; +use super::{fmt, writer}; -mod fmt; -mod writer; - -#[derive(clap::Parser)] -#[command(author, version, about, long_about = None)] -struct Cli { - #[arg(name = "path to .slint file(s)", action)] - paths: Vec, - - /// modify the file inline instead of printing to stdout - #[arg(short, long, action)] - inline: bool, -} - -fn main() -> std::io::Result<()> { - let args = Cli::parse(); - - for path in args.paths { +pub fn run(files: Vec, inplace: bool) -> std::io::Result<()> { + for path in files { let source = std::fs::read_to_string(&path)?; - if args.inline { + if inplace { let file = BufWriter::new(std::fs::File::create(&path)?); process_file(source, path, file)? } else { @@ -129,7 +113,7 @@ fn process_file( // Formatting .60 files because of backwards compatibility (project was recently renamed) Some(ext) if ext == "slint" || ext == ".60" => process_slint_file(source, path, file), _ => { - // This allows usage like `cat x.slint | slint-fmt /dev/stdin` + // This allows usage like `cat x.slint | slint-lsp format /dev/stdin` if path.as_path() == Path::new("/dev/stdin") { return process_slint_file(source, path, file); } diff --git a/tools/fmt/writer.rs b/tools/lsp/fmt/writer.rs similarity index 100% rename from tools/fmt/writer.rs rename to tools/lsp/fmt/writer.rs diff --git a/tools/lsp/language/formatting.rs b/tools/lsp/language/formatting.rs index ebd5a5f27..b9d8b5fb2 100644 --- a/tools/lsp/language/formatting.rs +++ b/tools/lsp/language/formatting.rs @@ -1,4 +1,7 @@ +// Copyright © SixtyFPS GmbH +// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial use super::DocumentCache; +use crate::fmt::{fmt, writer}; use crate::util::map_range; use dissimilar::Chunk; use i_slint_compiler::parser::SyntaxToken; @@ -9,7 +12,7 @@ struct StringWriter { text: String, } -impl slint_fmt::writer::TokenWriter for StringWriter { +impl writer::TokenWriter for StringWriter { fn no_change(&mut self, token: SyntaxToken) -> std::io::Result<()> { self.text += &token.text(); Ok(()) @@ -36,7 +39,7 @@ pub fn format_document( let doc = doc.node.as_ref()?; let mut writer = StringWriter { text: String::new() }; - slint_fmt::fmt::format_document(doc.clone(), &mut writer).ok()?; + fmt::format_document(doc.clone(), &mut writer).ok()?; let original: String = doc.text().into(); let diff = dissimilar::diff(&original, &writer.text); diff --git a/tools/lsp/main.rs b/tools/lsp/main.rs index 5ffe162ee..62fda3085 100644 --- a/tools/lsp/main.rs +++ b/tools/lsp/main.rs @@ -7,6 +7,7 @@ compile_error!("Feature preview-engine and preview-builtin need to be enabled together when building native LSP"); mod common; +mod fmt; mod language; pub mod lsp_ext; #[cfg(feature = "preview-engine")] @@ -22,7 +23,7 @@ use lsp_types::notification::{ }; use lsp_types::{DidChangeTextDocumentParams, DidOpenTextDocumentParams, InitializeParams, Url}; -use clap::Parser; +use clap::{Args, Parser, Subcommand}; use lsp_server::{Connection, ErrorCode, IoThreads, Message, RequestId, Response}; use std::cell::RefCell; use std::collections::HashMap; @@ -58,6 +59,25 @@ pub struct Cli { /// Hide the preview toolbar #[arg(long, action)] no_toolbar: bool, + + #[command(subcommand)] + command: Option, +} + +#[derive(Subcommand, Clone)] +enum Commands { + /// Format slint files + Format(Format), +} + +#[derive(Args, Clone)] +struct Format { + #[arg(name = "path to .slint file(s)", action)] + paths: Vec, + + /// modify the file inline instead of printing to stdout + #[arg(short, long, action)] + inline: bool, } enum OutgoingRequest { @@ -156,6 +176,14 @@ fn main() { std::env::set_var("SLINT_BACKEND", &args.backend); } + if let Some(Commands::Format(args)) = args.command { + let _ = fmt::tool::run(args.paths, args.inline).map_err(|e| { + eprintln!("{e}"); + std::process::exit(1); + }); + std::process::exit(0); + } + #[cfg(feature = "preview-engine")] { let cli_args = args.clone(); @@ -187,6 +215,7 @@ fn main() { preview::start_ui_event_loop(cli_args); lsp_thread.join().unwrap(); } + #[cfg(not(feature = "preview-engine"))] match run_lsp_server(args) { Ok(threads) => threads.join().unwrap(), diff --git a/tools/lsp/wasm_main.rs b/tools/lsp/wasm_main.rs index cb9952d14..87c96aacf 100644 --- a/tools/lsp/wasm_main.rs +++ b/tools/lsp/wasm_main.rs @@ -4,6 +4,7 @@ #![cfg(target_arch = "wasm32")] mod common; +mod fmt; mod language; pub mod lsp_ext; #[cfg(feature = "preview-engine")]