From 31eebb4baa772579ad5d2de6ce2f9521bbb370f6 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sun, 28 Jun 2026 15:16:33 +0200 Subject: [PATCH 1/3] Modularized bracket style --- crates/codegen/src/fmt/mod.rs | 5 +++++ crates/codegen/src/fmt/top_level.rs | 3 +-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/crates/codegen/src/fmt/mod.rs b/crates/codegen/src/fmt/mod.rs index b714300..2ee8491 100644 --- a/crates/codegen/src/fmt/mod.rs +++ b/crates/codegen/src/fmt/mod.rs @@ -46,6 +46,11 @@ impl MistCodegen { self.add(&line); } + pub fn start_indent(&mut self) { + self.addln(""); + self.add_indented(""); + } + pub fn start_bracket(&mut self) { self.addln(""); self.add_indentedln("{"); diff --git a/crates/codegen/src/fmt/top_level.rs b/crates/codegen/src/fmt/top_level.rs index 60923e0..fe614d4 100644 --- a/crates/codegen/src/fmt/top_level.rs +++ b/crates/codegen/src/fmt/top_level.rs @@ -78,8 +78,7 @@ impl GenMist for FunctionDecl { } if let Some(body) = &self.body { - cg.addln(""); - cg.add_indented(""); + cg.start_indent(); body.gen_mist(ctx, cg); cg.addln(""); } else { From 2174b99a3f024579234535f89526c9f3b9904f77 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sun, 28 Jun 2026 15:52:02 +0200 Subject: [PATCH 2/3] Fmt config --- Cargo.lock | 1 + crates/analyzer/Cargo.toml | 1 + crates/analyzer/src/lib.rs | 65 +++++++++++++++++++++---------- crates/analyzer/src/transpiler.rs | 8 ++-- crates/codegen/src/fmt/mod.rs | 22 ++++++++--- crates/parser/src/lib.rs | 5 +++ 6 files changed, 72 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d4bded0..3b80a40 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -488,6 +488,7 @@ dependencies = [ "serde", "serde_json", "tokio", + "toml", "tower-lsp", ] diff --git a/crates/analyzer/Cargo.toml b/crates/analyzer/Cargo.toml index 0b830f2..e418cb5 100644 --- a/crates/analyzer/Cargo.toml +++ b/crates/analyzer/Cargo.toml @@ -22,3 +22,4 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" ropey = "1" heck = "0.5.0" +toml = "1.1.2" diff --git a/crates/analyzer/src/lib.rs b/crates/analyzer/src/lib.rs index c7d2d53..3ce6236 100644 --- a/crates/analyzer/src/lib.rs +++ b/crates/analyzer/src/lib.rs @@ -7,10 +7,11 @@ use std::sync::Arc; use std::sync::atomic::{AtomicU64, Ordering}; use heck::ToSnakeCase; +use mist_parser::MistFmtConfig; use mist_parser::error::ParseError; use mist_parser::rev_mapper::{Mapping, MistMap, RustMap}; use ropey::Rope; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; use serde_json::Value; use tokio::sync::Mutex; use tower_lsp::lsp_types::{self, *}; @@ -1357,8 +1358,18 @@ impl LanguageServer for Backend { .get(&mist_path) .map_or_else(|| Err(tower_lsp::jsonrpc::Error::internal_error()), Ok)?; - let new_text = format_mist(&old_text.to_string()) - .map_err(|_| tower_lsp::jsonrpc::Error::internal_error())?; + let ws = match &*self.workspace_folder.lock().await { + Some(p) => p.clone(), + None => return Ok(None), + }; + + let new_text = format_mist( + &old_text.to_string(), + read_mist_fmt(&ws).unwrap_or_else(|| MistFmtConfig { + allman_bracket_style: true, + }), + ) + .map_err(|_| tower_lsp::jsonrpc::Error::internal_error())?; Ok(Some(vec![TextEdit { new_text, @@ -1820,24 +1831,38 @@ fn read_mist_package(workspace_root: &Path) -> String { let toml_path = workspace_root.join("Mist.toml"); let content = match std::fs::read_to_string(&toml_path) { Ok(c) => c, - Err(_) => return "main.mist".to_string(), - }; - for line in content.lines() { - let line = line.trim(); - if let Some(rest) = line.strip_prefix("package") { - if let Some(eq_pos) = rest.find('=') { - let val = rest[eq_pos + 1..] - .trim() - .trim_matches('"') - .trim() - .to_string(); - if !val.is_empty() { - return val; - } - } + Err(_) => { + return "main.mist".to_string(); } - } - "main.mist".to_string() + }; + + toml::from_str::(&content) + .ok() + .and_then(|v| v.package.to_str().map(String::from)) + .unwrap_or_else(|| "main.mist".to_string()) +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct MistConfig { + pub package: PathBuf, + pub packages: Vec, + pub fmt: Option, +} + +fn read_mist_fmt(workspace_root: &Path) -> Option { + let toml_path = workspace_root.join("Mist.toml"); + let content = match std::fs::read_to_string(&toml_path) { + Ok(c) => c, + Err(_) => { + return Some(MistFmtConfig { + allman_bracket_style: true, + }); + } + }; + + toml::from_str::(&content) + .ok() + .and_then(|v| v.fmt) } fn compute_mod_decls( diff --git a/crates/analyzer/src/transpiler.rs b/crates/analyzer/src/transpiler.rs index 8413a8e..7379da6 100644 --- a/crates/analyzer/src/transpiler.rs +++ b/crates/analyzer/src/transpiler.rs @@ -1,9 +1,9 @@ use std::path::{Path, PathBuf}; -use mist_codegen::fmt::MistCodegen; use mist_codegen::RustCodegen; -use mist_parser::parse; +use mist_codegen::fmt::MistCodegen; use mist_parser::rev_mapper::Mapping; +use mist_parser::{MistFmtConfig, parse}; pub struct TranspiledFile { pub mist_path: PathBuf, @@ -85,10 +85,10 @@ pub fn transpile_mist_no_sem( }) } -pub fn format_mist(source: &str) -> Result { +pub fn format_mist(source: &str, config: MistFmtConfig) -> Result { let parsed = parse(source).map_err(|e| format!("parse error: {e:?}"))?; - let mut codegen = MistCodegen::new(); + let mut codegen = MistCodegen::new(config); codegen.generate(parsed.mod_attributes); let output = codegen.generate(parsed.items); diff --git a/crates/codegen/src/fmt/mod.rs b/crates/codegen/src/fmt/mod.rs index 2ee8491..ccda804 100644 --- a/crates/codegen/src/fmt/mod.rs +++ b/crates/codegen/src/fmt/mod.rs @@ -2,21 +2,23 @@ pub mod expr; pub mod statement; pub mod top_level; -use mist_parser::ast::*; +use mist_parser::{MistFmtConfig, ast::*}; pub struct Context { pub expr_ensure_semicolon: bool, } pub struct MistCodegen { + config: MistFmtConfig, indent_amount: u8, output: String, indent: usize, } impl MistCodegen { - pub fn new() -> Self { + pub fn new(config: MistFmtConfig) -> Self { Self { + config, output: String::new(), indent: 0, indent_amount: 4, @@ -47,13 +49,21 @@ impl MistCodegen { } pub fn start_indent(&mut self) { - self.addln(""); - self.add_indented(""); + if self.config.allman_bracket_style { + self.addln(""); + self.add_indented(""); + } else { + self.add(" "); + } } pub fn start_bracket(&mut self) { - self.addln(""); - self.add_indentedln("{"); + if self.config.allman_bracket_style { + self.addln(""); + self.add_indentedln("{"); + } else { + self.add(" {"); + } self.indent += 1; } diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs index 910a175..aa08f60 100644 --- a/crates/parser/src/lib.rs +++ b/crates/parser/src/lib.rs @@ -20,6 +20,11 @@ pub struct Program { pub items: Vec, } +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +pub struct MistFmtConfig { + pub allman_bracket_style: bool, +} + pub fn parse<'a>(source: &'a str) -> Result> { let mut pairs = MistParser::parse(Rule::program, source)?; From 2426e585d641798eb48b6a0c1494a9a37ab5fafd Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sun, 28 Jun 2026 15:57:00 +0200 Subject: [PATCH 3/3] Fix constructor and non allman --- crates/codegen/src/fmt/mod.rs | 2 +- crates/codegen/src/fmt/top_level.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/codegen/src/fmt/mod.rs b/crates/codegen/src/fmt/mod.rs index ccda804..916ebe2 100644 --- a/crates/codegen/src/fmt/mod.rs +++ b/crates/codegen/src/fmt/mod.rs @@ -62,7 +62,7 @@ impl MistCodegen { self.addln(""); self.add_indentedln("{"); } else { - self.add(" {"); + self.addln(" {"); } self.indent += 1; diff --git a/crates/codegen/src/fmt/top_level.rs b/crates/codegen/src/fmt/top_level.rs index fe614d4..13439ab 100644 --- a/crates/codegen/src/fmt/top_level.rs +++ b/crates/codegen/src/fmt/top_level.rs @@ -307,8 +307,8 @@ impl GenMist for TopLevelKind { } param.gen_mist(ctx, cg); } - cg.addln(") "); - cg.add_indented(""); + cg.add(") "); + cg.start_indent(); constructor.item.body.gen_mist(ctx, cg); cg.addln("");