Allow people to set format options (#389)

* better naming

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* up[dates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* bump version

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fix tests

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* whitespace

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
Jess Frazelle
2023-09-06 10:36:03 -07:00
committed by GitHub
parent 1181f33e9d
commit 84d08bad16
10 changed files with 334 additions and 188 deletions

View File

@ -1564,7 +1564,7 @@ const key = 'c'`
start: code.indexOf('\n// this is a comment'),
end: code.indexOf('const key'),
value: {
type: 'block',
type: 'blockComment',
value: 'this is a comment',
},
}
@ -1602,7 +1602,7 @@ const key = 'c'`
start: 106,
end: 166,
value: {
type: 'block',
type: 'blockComment',
value: 'this is\n a comment\n spanning a few lines',
},
})
@ -1625,7 +1625,7 @@ const key = 'c'`
start: 125,
end: 141,
value: {
type: 'block',
type: 'blockComment',
value: 'a comment',
},
})

View File

@ -1094,7 +1094,7 @@ dependencies = [
[[package]]
name = "kcl-lib"
version = "0.1.20"
version = "0.1.21"
dependencies = [
"anyhow",
"bson",

View File

@ -1,7 +1,7 @@
[package]
name = "kcl-lib"
description = "KittyCAD Language"
version = "0.1.20"
version = "0.1.21"
edition = "2021"
license = "MIT"

View File

@ -27,12 +27,16 @@ pub struct Program {
}
impl Program {
pub fn recast(&self, indentation: &str, is_with_block: bool) -> String {
self.body
pub fn recast(&self, options: &FormatOptions, indentation_level: usize) -> String {
let indentation = options.get_indentation(indentation_level);
let result = self
.body
.iter()
.map(|statement| match statement.clone() {
BodyItem::ExpressionStatement(expression_statement) => {
expression_statement.expression.recast(indentation, false)
expression_statement
.expression
.recast(options, indentation_level, false)
}
BodyItem::VariableDeclaration(variable_declaration) => variable_declaration
.declarations
@ -43,56 +47,44 @@ impl Program {
indentation,
variable_declaration.kind,
declaration.id.name,
declaration.init.recast("", false)
declaration.init.recast(options, 0, false)
)
})
.collect::<String>(),
BodyItem::ReturnStatement(return_statement) => {
format!("{}return {}", indentation, return_statement.argument.recast("", false))
format!(
"{}return {}",
indentation,
return_statement.argument.recast(options, 0, false)
)
}
})
.enumerate()
.map(|(index, recast_str)| {
let is_legit_custom_whitespace_or_comment = |s: String| s != " " && s != "\n" && s != " " && s != "\t";
// determine the value of startString
let last_white_space_or_comment = if index > 0 {
let tmp = if let Some(non_code_node) = self.non_code_meta.none_code_nodes.get(&(index - 1)) {
non_code_node.format(indentation)
} else {
" ".to_string()
};
tmp
} else {
" ".to_string()
};
// indentation of this line will be covered by the previous if we're using a custom whitespace or comment
let mut start_string = if is_legit_custom_whitespace_or_comment(last_white_space_or_comment) {
String::new()
} else {
indentation.to_owned()
};
if index == 0 {
let start_string = if index == 0 {
// We need to indent.
if let Some(start) = self.non_code_meta.start.clone() {
start_string = start.format(indentation);
start.format(&indentation)
} else {
start_string = indentation.to_owned();
}
indentation.to_string()
}
} else {
// Do nothing, we already applied the indentation elsewhere.
String::new()
};
// determine the value of endString
let maybe_line_break: String = if index == self.body.len() - 1 && !is_with_block {
// determine the value of the end string
// basically if we are inside a nested function we want to end with a new line
let maybe_line_break: String = if index == self.body.len() - 1 && indentation_level == 0 {
String::new()
} else {
"\n".to_string()
};
let mut custom_white_space_or_comment = match self.non_code_meta.none_code_nodes.get(&index) {
Some(custom_white_space_or_comment) => custom_white_space_or_comment.format(indentation),
let custom_white_space_or_comment = match self.non_code_meta.none_code_nodes.get(&index) {
Some(custom_white_space_or_comment) => custom_white_space_or_comment.format(&indentation),
None => String::new(),
};
if !is_legit_custom_whitespace_or_comment(custom_white_space_or_comment.clone()) {
custom_white_space_or_comment = String::new();
}
let end_string = if custom_white_space_or_comment.is_empty() {
maybe_line_break
} else {
@ -103,7 +95,14 @@ impl Program {
})
.collect::<String>()
.trim()
.to_string()
.to_string();
// Insert a final new line if the user wants it.
if options.insert_final_newline {
format!("{}\n", result)
} else {
result
}
}
/// Returns the body item that includes the given character position.
@ -249,19 +248,18 @@ pub enum Value {
}
impl Value {
fn recast(&self, indentation: &str, is_in_pipe_expression: bool) -> String {
let indentation = indentation.to_string() + if is_in_pipe_expression { " " } else { "" };
fn recast(&self, options: &FormatOptions, indentation_level: usize, is_in_pipe: bool) -> String {
match &self {
Value::BinaryExpression(bin_exp) => bin_exp.recast(),
Value::ArrayExpression(array_exp) => array_exp.recast(&indentation, is_in_pipe_expression),
Value::ObjectExpression(ref obj_exp) => obj_exp.recast(&indentation, is_in_pipe_expression),
Value::BinaryExpression(bin_exp) => bin_exp.recast(options),
Value::ArrayExpression(array_exp) => array_exp.recast(options, indentation_level, is_in_pipe),
Value::ObjectExpression(ref obj_exp) => obj_exp.recast(options, indentation_level, is_in_pipe),
Value::MemberExpression(mem_exp) => mem_exp.recast(),
Value::Literal(literal) => literal.recast(),
Value::FunctionExpression(func_exp) => func_exp.recast(&indentation),
Value::CallExpression(call_exp) => call_exp.recast(&indentation, is_in_pipe_expression),
Value::FunctionExpression(func_exp) => func_exp.recast(options, indentation_level),
Value::CallExpression(call_exp) => call_exp.recast(options, indentation_level, is_in_pipe),
Value::Identifier(ident) => ident.name.to_string(),
Value::PipeExpression(pipe_exp) => pipe_exp.recast(&indentation),
Value::UnaryExpression(unary_exp) => unary_exp.recast(),
Value::PipeExpression(pipe_exp) => pipe_exp.recast(options, indentation_level),
Value::UnaryExpression(unary_exp) => unary_exp.recast(options),
Value::PipeSubstitution(_) => crate::parser::PIPE_SUBSTITUTION_OPERATOR.to_string(),
}
}
@ -355,13 +353,13 @@ impl From<&BinaryPart> for crate::executor::SourceRange {
}
impl BinaryPart {
fn recast(&self, indentation: &str) -> String {
fn recast(&self, options: &FormatOptions, indentation_level: usize) -> String {
match &self {
BinaryPart::Literal(literal) => literal.recast(),
BinaryPart::Identifier(identifier) => identifier.name.to_string(),
BinaryPart::BinaryExpression(binary_expression) => binary_expression.recast(),
BinaryPart::CallExpression(call_expression) => call_expression.recast(indentation, false),
BinaryPart::UnaryExpression(unary_expression) => unary_expression.recast(),
BinaryPart::BinaryExpression(binary_expression) => binary_expression.recast(options),
BinaryPart::CallExpression(call_expression) => call_expression.recast(options, indentation_level, false),
BinaryPart::UnaryExpression(unary_expression) => unary_expression.recast(options),
}
}
@ -436,17 +434,17 @@ pub struct NoneCodeNode {
impl NoneCodeNode {
pub fn value(&self) -> String {
match &self.value {
NoneCodeValue::Inline { value } => value.clone(),
NoneCodeValue::Block { value } => value.clone(),
NoneCodeValue::NewLineBlock { value } => value.clone(),
NoneCodeValue::InlineComment { value } => value.clone(),
NoneCodeValue::BlockComment { value } => value.clone(),
NoneCodeValue::NewLineBlockComment { value } => value.clone(),
NoneCodeValue::NewLine => "\n\n".to_string(),
}
}
pub fn format(&self, indentation: &str) -> String {
match &self.value {
NoneCodeValue::Inline { value } => format!(" // {}\n", value),
NoneCodeValue::Block { value } => {
NoneCodeValue::InlineComment { value } => format!(" // {}\n", value),
NoneCodeValue::BlockComment { value } => {
let add_start_new_line = if self.start == 0 { "" } else { "\n" };
if value.contains('\n') {
format!("{}{}/* {} */\n", add_start_new_line, indentation, value)
@ -454,7 +452,7 @@ impl NoneCodeNode {
format!("{}{}// {}\n", add_start_new_line, indentation, value)
}
}
NoneCodeValue::NewLineBlock { value } => {
NoneCodeValue::NewLineBlockComment { value } => {
let add_start_new_line = if self.start == 0 { "" } else { "\n\n" };
if value.contains('\n') {
format!("{}{}/* {} */\n", add_start_new_line, indentation, value)
@ -471,9 +469,29 @@ impl NoneCodeNode {
#[ts(export)]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum NoneCodeValue {
Inline { value: String },
Block { value: String },
NewLineBlock { value: String },
/// An inline comment.
/// An example of this is the following: `1 + 1 // This is an inline comment`.
InlineComment {
value: String,
},
/// A block comment.
/// An example of this is the following:
/// ```python,no_run
/// /* This is a
/// block comment */
/// 1 + 1
/// ```
/// Now this is important. The block comment is attached to the next line.
/// This is always the case. Also the block comment doesnt have a new line above it.
/// If it did it would be a `NewLineBlockComment`.
BlockComment {
value: String,
},
/// A block comment that has a new line above it.
/// The user explicitly added a new line above the block comment.
NewLineBlockComment {
value: String,
},
// A new line like `\n\n` NOT a new line like `\n`.
// This is also not a comment.
NewLine,
@ -539,13 +557,13 @@ pub struct CallExpression {
impl_value_meta!(CallExpression);
impl CallExpression {
fn recast(&self, indentation: &str, is_in_pipe_expression: bool) -> String {
fn recast(&self, options: &FormatOptions, indentation_level: usize, is_in_pipe: bool) -> String {
format!(
"{}({})",
self.callee.name,
self.arguments
.iter()
.map(|arg| arg.recast(indentation, is_in_pipe_expression))
.map(|arg| arg.recast(options, indentation_level, is_in_pipe))
.collect::<Vec<String>>()
.join(", ")
)
@ -923,27 +941,35 @@ pub struct ArrayExpression {
impl_value_meta!(ArrayExpression);
impl ArrayExpression {
fn recast(&self, indentation: &str, is_in_pipe_expression: bool) -> String {
fn recast(&self, options: &FormatOptions, indentation_level: usize, is_in_pipe: bool) -> String {
let flat_recast = format!(
"[{}]",
self.elements
.iter()
.map(|el| el.recast("", false))
.map(|el| el.recast(options, 0, false))
.collect::<Vec<String>>()
.join(", ")
);
let max_array_length = 40;
if flat_recast.len() > max_array_length {
let indentation = indentation.to_string() + " ";
let inner_indentation = if is_in_pipe {
options.get_indentation_offset_pipe(indentation_level + 1)
} else {
options.get_indentation(indentation_level + 1)
};
format!(
"[\n{}{}\n{}]",
indentation,
inner_indentation,
self.elements
.iter()
.map(|el| el.recast(&indentation, false))
.map(|el| el.recast(options, indentation_level, false))
.collect::<Vec<String>>()
.join(format!(",\n{}", indentation).as_str()),
if is_in_pipe_expression { " " } else { "" }
.join(format!(",\n{}", inner_indentation).as_str()),
if is_in_pipe {
options.get_indentation_offset_pipe(indentation_level)
} else {
options.get_indentation(indentation_level)
},
)
} else {
flat_recast
@ -1031,27 +1057,35 @@ pub struct ObjectExpression {
}
impl ObjectExpression {
fn recast(&self, indentation: &str, is_in_pipe_expression: bool) -> String {
fn recast(&self, options: &FormatOptions, indentation_level: usize, is_in_pipe: bool) -> String {
let flat_recast = format!(
"{{ {} }}",
self.properties
.iter()
.map(|prop| { format!("{}: {}", prop.key.name, prop.value.recast("", false)) })
.map(|prop| { format!("{}: {}", prop.key.name, prop.value.recast(options, 0, false)) })
.collect::<Vec<String>>()
.join(", ")
);
let max_array_length = 40;
if flat_recast.len() > max_array_length {
let indentation = indentation.to_owned() + " ";
let inner_indentation = if is_in_pipe {
options.get_indentation_offset_pipe(indentation_level + 1)
} else {
options.get_indentation(indentation_level + 1)
};
format!(
"{{\n{}{}\n{}}}",
indentation,
inner_indentation,
self.properties
.iter()
.map(|prop| { format!("{}: {}", prop.key.name, prop.value.recast("", is_in_pipe_expression)) })
.map(|prop| { format!("{}: {}", prop.key.name, prop.value.recast(options, 0, false)) })
.collect::<Vec<String>>()
.join(format!(",\n{}", indentation).as_str()),
if is_in_pipe_expression { " " } else { "" }
.join(format!(",\n{}", inner_indentation).as_str()),
if is_in_pipe {
options.get_indentation_offset_pipe(indentation_level)
} else {
options.get_indentation(indentation_level)
},
)
} else {
flat_recast
@ -1370,7 +1404,7 @@ impl BinaryExpression {
self.operator.precedence()
}
fn recast(&self) -> String {
fn recast(&self, options: &FormatOptions) -> String {
let maybe_wrap_it = |a: String, doit: bool| -> String {
if doit {
format!("({})", a)
@ -1393,9 +1427,9 @@ impl BinaryExpression {
format!(
"{} {} {}",
maybe_wrap_it(self.left.recast(""), should_wrap_left),
maybe_wrap_it(self.left.recast(options, 0), should_wrap_left),
self.operator,
maybe_wrap_it(self.right.recast(""), should_wrap_right)
maybe_wrap_it(self.right.recast(options, 0), should_wrap_right)
)
}
@ -1532,8 +1566,8 @@ pub struct UnaryExpression {
impl_value_meta!(UnaryExpression);
impl UnaryExpression {
fn recast(&self) -> String {
format!("{}{}", &self.operator, self.argument.recast(""))
fn recast(&self, options: &FormatOptions) -> String {
format!("{}{}", &self.operator, self.argument.recast(options, 0))
}
pub fn get_result(
@ -1595,13 +1629,13 @@ pub struct PipeExpression {
impl_value_meta!(PipeExpression);
impl PipeExpression {
fn recast(&self, indentation: &str) -> String {
fn recast(&self, options: &FormatOptions, indentation_level: usize) -> String {
self.body
.iter()
.enumerate()
.map(|(index, statement)| {
let indentation = indentation.to_string() + " ";
let mut s = statement.recast(&indentation, true);
let indentation = options.get_indentation(indentation_level + 1);
let mut s = statement.recast(options, indentation_level + 1, true);
let non_code_meta = self.non_code_meta.clone();
if let Some(non_code_meta_value) = non_code_meta.none_code_nodes.get(&index) {
s += non_code_meta_value.format(&indentation).trim_end_matches('\n')
@ -1706,17 +1740,16 @@ pub struct FunctionExpression {
impl_value_meta!(FunctionExpression);
impl FunctionExpression {
pub fn recast(&self, indentation: &str) -> String {
pub fn recast(&self, options: &FormatOptions, indentation_level: usize) -> String {
format!(
"({}) => {{\n{}{}{}\n}}",
"({}) => {{\n{}{}\n}}",
self.params
.iter()
.map(|param| param.name.clone())
.collect::<Vec<String>>()
.join(", "),
indentation,
" ",
self.body.recast(" ", true)
options.get_indentation(indentation_level + 1),
self.body.recast(options, indentation_level + 1)
)
}
@ -1756,6 +1789,58 @@ pub enum Hover {
},
}
/// Format options.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct FormatOptions {
/// Size of a tab in spaces.
pub tab_size: usize,
/// Prefer tabs over spaces.
pub use_tabs: bool,
/// How to handle the final newline in the file.
/// If true, ensure file ends with a newline.
/// If false, ensure file does not end with a newline.
pub insert_final_newline: bool,
}
impl Default for FormatOptions {
fn default() -> Self {
Self::new()
}
}
impl FormatOptions {
/// Define the default format options.
/// We use 2 spaces for indentation.
pub fn new() -> Self {
Self {
tab_size: 2,
use_tabs: false,
insert_final_newline: false,
}
}
/// Get the indentation string for the given level.
pub fn get_indentation(&self, level: usize) -> String {
if self.use_tabs {
"\t".repeat(level)
} else {
" ".repeat(level * self.tab_size)
}
}
/// Get the indentation string for the given level.
/// But offset the pipe operator (and a space) by one level.
pub fn get_indentation_offset_pipe(&self, level: usize) -> String {
if self.use_tabs {
"\t".repeat(level + 1)
} else {
" ".repeat(level * self.tab_size) + " ".repeat(PIPE_OPERATOR.len() + 1).as_str()
}
}
}
#[cfg(test)]
mod tests {
use super::*;
@ -1797,7 +1882,7 @@ show(part001)"#;
let some_program: crate::abstract_syntax_tree_types::Program =
serde_json::from_str(some_program_string).unwrap();
let recasted = some_program.recast("", false);
let recasted = some_program.recast(&Default::default(), 0);
assert_eq!(
recasted,
r#"const part001 = startSketchAt('default')
@ -1816,7 +1901,7 @@ show(part001)"#
let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap();
let recasted = program.recast("", false);
let recasted = program.recast(&Default::default(), 0);
assert_eq!(
recasted,
r#"const part001 = startSketchAt([0.0, 5.0])
@ -1834,7 +1919,7 @@ show(part001)"#
let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap();
let recasted = program.recast("", false);
let recasted = program.recast(&Default::default(), 0);
assert_eq!(
recasted,
r#"const part001 = startSketchAt([0.0, 5.0])
@ -1852,7 +1937,7 @@ show(part001)"#
let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap();
let recasted = program.recast("", false);
let recasted = program.recast(&Default::default(), 0);
assert_eq!(
recasted,
r#"const part001 = startSketchAt([0.0, 5.0])
@ -1877,7 +1962,7 @@ show(part001)"#
let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap();
let recasted = program.recast("", false);
let recasted = program.recast(&Default::default(), 0);
assert_eq!(
recasted,
r#"const myFn = () => {
@ -1913,7 +1998,7 @@ const mySk1 = startSketchAt([0, 0])
let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap();
let recasted = program.recast("", false);
let recasted = program.recast(&Default::default(), 0);
assert_eq!(
recasted,
r#"// comment at start
@ -1951,7 +2036,7 @@ show(part001)"#;
let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap();
let recasted = program.recast("", false);
let recasted = program.recast(&Default::default(), 0);
assert_eq!(recasted, some_program_string);
}
@ -1964,12 +2049,19 @@ const yo = {
anum: 2,
identifier: three,
binExp: 4 + 5
}"#;
}
const yo = [
1,
" 2,",
"three",
4 + 5,
" hey oooooo really long long long"
]"#;
let tokens = crate::tokeniser::lexer(some_program_string);
let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap();
let recasted = program.recast("", false);
let recasted = program.recast(&Default::default(), 0);
assert_eq!(recasted, some_program_string);
}
@ -1987,7 +2079,7 @@ const things = "things"
let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap();
let recasted = program.recast("", false);
let recasted = program.recast(&Default::default(), 0);
assert_eq!(recasted, some_program_string.trim());
}
@ -2005,7 +2097,65 @@ const things = "things"
let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap();
let recasted = program.recast("", false);
let recasted = program.recast(&Default::default(), 0);
assert_eq!(recasted, some_program_string.trim());
}
#[test]
fn test_recast_array_new_line_in_pipe() {
let some_program_string = r#"const myVar = 3
const myVar2 = 5
const myVar3 = 6
const myAng = 40
const myAng2 = 134
const part001 = startSketchAt([0, 0])
|> line({ to: [1, 3.82], tag: 'seg01' }, %) // ln-should-get-tag
|> angledLineToX([
-angleToMatchLengthX('seg01', myVar, %),
myVar
], %) // ln-lineTo-xAbsolute should use angleToMatchLengthX helper
|> angledLineToY([
-angleToMatchLengthY('seg01', myVar, %),
myVar
], %) // ln-lineTo-yAbsolute should use angleToMatchLengthY helper"#;
let tokens = crate::tokeniser::lexer(some_program_string);
let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap();
let recasted = program.recast(&Default::default(), 0);
assert_eq!(recasted, some_program_string);
}
#[test]
fn test_recast_array_new_line_in_pipe_custom() {
let some_program_string = r#"const myVar = 3
const myVar2 = 5
const myVar3 = 6
const myAng = 40
const myAng2 = 134
const part001 = startSketchAt([0, 0])
|> line({ to: [1, 3.82], tag: 'seg01' }, %) // ln-should-get-tag
|> angledLineToX([
-angleToMatchLengthX('seg01', myVar, %),
myVar
], %) // ln-lineTo-xAbsolute should use angleToMatchLengthX helper
|> angledLineToY([
-angleToMatchLengthY('seg01', myVar, %),
myVar
], %) // ln-lineTo-yAbsolute should use angleToMatchLengthY helper
"#;
let tokens = crate::tokeniser::lexer(some_program_string);
let parser = crate::parser::Parser::new(tokens);
let program = parser.ast().unwrap();
let recasted = program.recast(
&FormatOptions {
tab_size: 3,
use_tabs: false,
insert_final_newline: true,
},
0,
);
assert_eq!(recasted, some_program_string);
}
}

View File

@ -336,11 +336,11 @@ impl Parser {
value: if start_end_string.starts_with("\n\n") && is_new_line_comment {
// Preserve if they want a whitespace line before the comment.
// But let's just allow one.
NoneCodeValue::NewLineBlock { value: full_string }
NoneCodeValue::NewLineBlockComment { value: full_string }
} else if is_new_line_comment {
NoneCodeValue::Block { value: full_string }
NoneCodeValue::BlockComment { value: full_string }
} else {
NoneCodeValue::Inline { value: full_string }
NoneCodeValue::InlineComment { value: full_string }
},
};
Ok((Some(node), end_index - 1))
@ -1665,7 +1665,7 @@ const key = 'c'"#,
Some(NoneCodeNode {
start: 38,
end: 60,
value: NoneCodeValue::Block {
value: NoneCodeValue::BlockComment {
value: "this is a comment".to_string(),
},
}),
@ -1687,7 +1687,7 @@ const key = 'c'"#,
Some(NoneCodeNode {
start: 106,
end: 166,
value: NoneCodeValue::Block {
value: NoneCodeValue::BlockComment {
value: "this is\n a comment\n spanning a few lines".to_string(),
},
}),

View File

@ -552,19 +552,14 @@ impl LanguageServer for Backend {
return Ok(None);
};
// Now recast it.
// Make spaces for the tab size.
/*let mut tab_size = String::new();
for _ in 0..params.options.tab_size {
tab_size.push(' ');
}*/
// TODO: use the tab size.
let mut recast = ast.recast("", false).trim().to_string();
if let Some(insert_final_newline) = params.options.insert_final_newline {
if insert_final_newline {
recast.push('\n');
}
}
let recast = ast.recast(
&crate::abstract_syntax_tree_types::FormatOptions {
tab_size: params.options.tab_size as usize,
insert_final_newline: params.options.insert_final_newline.unwrap_or(false),
use_tabs: !params.options.insert_spaces,
},
0,
);
let source_range = SourceRange([0, current_code.len() - 1]);
let range = source_range.to_lsp_range(&current_code);
Ok(Some(vec![TextEdit {

View File

@ -76,7 +76,8 @@ pub fn recast_wasm(json_str: &str) -> Result<JsValue, JsError> {
let program: kcl_lib::abstract_syntax_tree_types::Program =
serde_json::from_str(json_str).map_err(JsError::from)?;
let result = program.recast("", false);
// Use the default options until we integrate into the UI the ability to change them.
let result = program.recast(&Default::default(), 0);
Ok(JsValue::from_serde(&result)?)
}