Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 31 additions & 9 deletions src/formatter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ struct Formatter {
input_tree: GdTree,
tree: Tree,
original_source: Option<String>,
indent_string: String,
}

impl Formatter {
Expand All @@ -72,6 +73,11 @@ impl Formatter {
} else {
None
};
let indent_string = if config.use_spaces {
" ".repeat(config.indent_size)
} else {
"\t".to_string()
};

Self {
original_source,
Expand All @@ -80,22 +86,17 @@ impl Formatter {
tree,
input_tree,
parser,
indent_string,
}
}

#[inline(always)]
fn format(&mut self) -> Result<&mut Self, Box<dyn std::error::Error>> {
let indent_string = if self.config.use_spaces {
" ".repeat(self.config.indent_size)
} else {
"\t".to_string()
};

let language = Language {
name: "gdscript".to_owned(),
query: TopiaryQuery::new(&tree_sitter_gdscript::LANGUAGE.into(), QUERY).unwrap(),
grammar: tree_sitter_gdscript::LANGUAGE.into(),
indent: Some(indent_string),
indent: Some(self.indent_string.clone()),
};

let mut output = Vec::new();
Expand Down Expand Up @@ -475,12 +476,31 @@ impl Formatter {
self
}

/// This function indents lines following a line continuation by two
/// levels to match style guide. Note that this function will only work
/// with an up-to-date tree-sitter tree.
#[inline(always)]
fn fix_line_continuation_indentation(&mut self) -> &mut Self {
let re = RegexBuilder::new(r"\\\r?\n")
.build()
.expect("line continuation regex should compile");

self.regex_replace_all_outside_strings(
re,
format!("$0{}{}", self.indent_string, self.indent_string),
);

self
}

/// This function runs postprocess passes that uses tree-sitter.
#[inline(always)]
fn postprocess_tree_sitter(&mut self) -> &mut Self {
self.tree = self.parser.parse(&self.content, None).unwrap();

self.handle_two_blank_line()
self.fix_line_continuation_indentation()
.handle_two_blank_line()

}

/// Replaces every match of regex `re` with `rep`, but only if the match is
Expand Down Expand Up @@ -509,7 +529,9 @@ impl Formatter {
.root_node()
.descendant_for_byte_range(start_byte, start_byte)
.unwrap();
if node.kind() == "string" {
// String nodes may also contain escape_sequence nodes. These are
// found when a backslash is present within a string.
if node.kind() == "string" || node.kind() == "escape_sequence" {
continue;
}

Expand Down
4 changes: 2 additions & 2 deletions tests/expected/line_continuation.gd
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
func _handles(resource: Resource) -> bool:
return resource is NoiseTexture2D \
or resource is GradientTexture1D \
or resource is GradientTexture2D
or resource is GradientTexture1D \
or resource is GradientTexture2D
15 changes: 15 additions & 0 deletions tests/expected/line_continuation_indent.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
var thing = \
my_long_function()

thing \
.calling(1) \
.a(12314) \
.long() \
.chain("a string breaks things") \
.of() \
.functions()

var string = "\
this is a really long \
string, but we don't want \
to change the indentation."
15 changes: 15 additions & 0 deletions tests/input/line_continuation_indent.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
var thing = \
my_long_function()

thing \
.calling(1) \
.a(12314) \
.long() \
.chain("a string breaks things") \
.of() \
.functions()

var string = "\
this is a really long \
string, but we don't want \
to change the indentation."