rfmt 1.2.4 → 1.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/Cargo.lock +1 -1
- data/ext/rfmt/Cargo.toml +1 -1
- data/ext/rfmt/src/emitter/mod.rs +113 -6
- data/lib/rfmt/rfmt.so +0 -0
- data/lib/rfmt/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b43c4cd99b99ae5b4525bc2efc9a3759e315cdbb200853345e2422d161fc58b6
|
|
4
|
+
data.tar.gz: e2f2f9fe52c401fadcd509e2705cbfca4a5bf0e84265f3ce7f764c1916e73470
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9e728fee6c041313543cd631255e9ac6fdc3a69c7a22f32b2846be6cbed6a59e1d1ba2dd46d989850e9ac6bc8d4b31bd630a4477e6d0d767ef7dd73c4a5c76ed
|
|
7
|
+
data.tar.gz: 6a7d78ae563cc30ae96970562ddf027005631ae9a2d79755b49a44411fc0f90a2c81ba48a29150c326cc5e5ad793159890f46ae2ee4658a0baeeef7f5907a3d1
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [1.2.6] - 2026-01-04
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
- Version bump
|
|
7
|
+
|
|
8
|
+
## [1.2.5] - 2026-01-04
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- Fix trailing comments on `end` keyword (e.g., `end # rubocop:disable`)
|
|
12
|
+
- Fix block internal comments being moved outside the block
|
|
13
|
+
- Fix blank line preservation between code and comments inside blocks
|
|
14
|
+
- Fix leading blank line being added to comment-only files
|
|
15
|
+
|
|
3
16
|
## [1.2.4] - 2026-01-04
|
|
4
17
|
|
|
5
18
|
### Fixed
|
data/Cargo.lock
CHANGED
data/ext/rfmt/Cargo.toml
CHANGED
data/ext/rfmt/src/emitter/mod.rs
CHANGED
|
@@ -79,24 +79,37 @@ impl Emitter {
|
|
|
79
79
|
/// Emit all comments that haven't been emitted yet
|
|
80
80
|
fn emit_remaining_comments(&mut self, last_code_line: usize) -> Result<()> {
|
|
81
81
|
let mut last_end_line: Option<usize> = Some(last_code_line);
|
|
82
|
+
let mut is_first_comment = true;
|
|
83
|
+
|
|
82
84
|
for (idx, comment) in self.all_comments.iter().enumerate() {
|
|
83
85
|
if self.emitted_comment_indices.contains(&idx) {
|
|
84
86
|
continue;
|
|
85
87
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
+
|
|
89
|
+
// For the first remaining comment:
|
|
90
|
+
// - If buffer is empty, don't add any leading newline
|
|
91
|
+
// - If buffer has content, ensure we start on a new line
|
|
92
|
+
if is_first_comment && self.buffer.is_empty() {
|
|
93
|
+
// Don't add leading newline for first comment when buffer is empty
|
|
94
|
+
} else if !self.buffer.ends_with('\n') {
|
|
88
95
|
self.buffer.push('\n');
|
|
89
96
|
}
|
|
97
|
+
|
|
90
98
|
// Preserve blank lines between code/comments
|
|
91
|
-
if
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
99
|
+
// But only if this is not the first comment in an empty buffer
|
|
100
|
+
if !(is_first_comment && self.buffer.is_empty()) {
|
|
101
|
+
if let Some(prev_line) = last_end_line {
|
|
102
|
+
let gap = comment.location.start_line.saturating_sub(prev_line);
|
|
103
|
+
for _ in 1..gap {
|
|
104
|
+
self.buffer.push('\n');
|
|
105
|
+
}
|
|
95
106
|
}
|
|
96
107
|
}
|
|
108
|
+
|
|
97
109
|
writeln!(self.buffer, "{}", comment.text)?;
|
|
98
110
|
self.emitted_comment_indices.push(idx);
|
|
99
111
|
last_end_line = Some(comment.location.end_line);
|
|
112
|
+
is_first_comment = false;
|
|
100
113
|
}
|
|
101
114
|
Ok(())
|
|
102
115
|
}
|
|
@@ -221,6 +234,55 @@ impl Emitter {
|
|
|
221
234
|
Ok(())
|
|
222
235
|
}
|
|
223
236
|
|
|
237
|
+
/// Emit comments that are within a given line range, preserving blank lines from prev_line
|
|
238
|
+
fn emit_comments_in_range_with_prev_line(
|
|
239
|
+
&mut self,
|
|
240
|
+
start_line: usize,
|
|
241
|
+
end_line: usize,
|
|
242
|
+
indent_level: usize,
|
|
243
|
+
prev_line: usize,
|
|
244
|
+
) -> Result<()> {
|
|
245
|
+
let indent_str = match self.config.formatting.indent_style {
|
|
246
|
+
IndentStyle::Spaces => " ".repeat(self.config.formatting.indent_width * indent_level),
|
|
247
|
+
IndentStyle::Tabs => "\t".repeat(indent_level),
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
let mut comments_to_emit = Vec::new();
|
|
251
|
+
for (idx, comment) in self.all_comments.iter().enumerate() {
|
|
252
|
+
if self.emitted_comment_indices.contains(&idx) {
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if comment.location.start_line >= start_line && comment.location.end_line < end_line {
|
|
257
|
+
comments_to_emit.push((
|
|
258
|
+
idx,
|
|
259
|
+
comment.text.clone(),
|
|
260
|
+
comment.location.start_line,
|
|
261
|
+
comment.location.end_line,
|
|
262
|
+
));
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Sort by start_line to emit in order
|
|
267
|
+
comments_to_emit.sort_by_key(|(_, _, start, _)| *start);
|
|
268
|
+
|
|
269
|
+
let mut last_end_line: usize = prev_line;
|
|
270
|
+
|
|
271
|
+
for (idx, text, comment_start_line, comment_end_line) in comments_to_emit {
|
|
272
|
+
// Preserve blank lines between previous content and this comment
|
|
273
|
+
let gap = comment_start_line.saturating_sub(last_end_line);
|
|
274
|
+
for _ in 1..gap {
|
|
275
|
+
self.buffer.push('\n');
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
writeln!(self.buffer, "{}{}", indent_str, text)?;
|
|
279
|
+
self.emitted_comment_indices.push(idx);
|
|
280
|
+
last_end_line = comment_end_line;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
Ok(())
|
|
284
|
+
}
|
|
285
|
+
|
|
224
286
|
/// Emit comments that appear on the same line (trailing comments)
|
|
225
287
|
fn emit_trailing_comments(&mut self, line: usize) -> Result<()> {
|
|
226
288
|
let mut indices_to_emit = Vec::new();
|
|
@@ -376,6 +438,8 @@ impl Emitter {
|
|
|
376
438
|
|
|
377
439
|
self.emit_indent(indent_level)?;
|
|
378
440
|
write!(self.buffer, "end")?;
|
|
441
|
+
// Emit trailing comments on end line (e.g., `end # rubocop:disable`)
|
|
442
|
+
self.emit_trailing_comments(node.location.end_line)?;
|
|
379
443
|
|
|
380
444
|
Ok(())
|
|
381
445
|
}
|
|
@@ -421,6 +485,8 @@ impl Emitter {
|
|
|
421
485
|
|
|
422
486
|
self.emit_indent(indent_level)?;
|
|
423
487
|
write!(self.buffer, "end")?;
|
|
488
|
+
// Emit trailing comments on end line (e.g., `end # rubocop:disable`)
|
|
489
|
+
self.emit_trailing_comments(node.location.end_line)?;
|
|
424
490
|
|
|
425
491
|
Ok(())
|
|
426
492
|
}
|
|
@@ -493,6 +559,8 @@ impl Emitter {
|
|
|
493
559
|
|
|
494
560
|
self.emit_indent(indent_level)?;
|
|
495
561
|
write!(self.buffer, "end")?;
|
|
562
|
+
// Emit trailing comments on end line (e.g., `end # rubocop:disable`)
|
|
563
|
+
self.emit_trailing_comments(node.location.end_line)?;
|
|
496
564
|
|
|
497
565
|
Ok(())
|
|
498
566
|
}
|
|
@@ -524,6 +592,8 @@ impl Emitter {
|
|
|
524
592
|
|
|
525
593
|
self.emit_indent(indent_level)?;
|
|
526
594
|
write!(self.buffer, "end")?;
|
|
595
|
+
// Emit trailing comments on end line
|
|
596
|
+
self.emit_trailing_comments(node.location.end_line)?;
|
|
527
597
|
} else {
|
|
528
598
|
// Implicit begin - emit children directly
|
|
529
599
|
for (i, child) in node.children.iter().enumerate() {
|
|
@@ -714,6 +784,8 @@ impl Emitter {
|
|
|
714
784
|
// Emit "end" keyword
|
|
715
785
|
self.emit_indent(indent_level)?;
|
|
716
786
|
write!(self.buffer, "end")?;
|
|
787
|
+
// Emit trailing comments on end line
|
|
788
|
+
self.emit_trailing_comments(node.location.end_line)?;
|
|
717
789
|
|
|
718
790
|
Ok(())
|
|
719
791
|
}
|
|
@@ -931,6 +1003,8 @@ impl Emitter {
|
|
|
931
1003
|
if !is_elsif {
|
|
932
1004
|
self.emit_indent(indent_level)?;
|
|
933
1005
|
write!(self.buffer, "end")?;
|
|
1006
|
+
// Emit trailing comments on end line
|
|
1007
|
+
self.emit_trailing_comments(node.location.end_line)?;
|
|
934
1008
|
}
|
|
935
1009
|
|
|
936
1010
|
Ok(())
|
|
@@ -1021,17 +1095,46 @@ impl Emitter {
|
|
|
1021
1095
|
self.buffer.push('\n');
|
|
1022
1096
|
|
|
1023
1097
|
// Find and emit the body (StatementsNode among children)
|
|
1098
|
+
let block_start_line = block_node.location.start_line;
|
|
1099
|
+
let block_end_line = block_node.location.end_line;
|
|
1100
|
+
let mut last_stmt_end_line = block_start_line;
|
|
1101
|
+
|
|
1024
1102
|
for child in &block_node.children {
|
|
1025
1103
|
if matches!(child.node_type, NodeType::StatementsNode) {
|
|
1026
1104
|
self.emit_statements(child, indent_level + 1)?;
|
|
1105
|
+
// Track the last statement's end line for blank line preservation
|
|
1106
|
+
if let Some(last_child) = child.children.last() {
|
|
1107
|
+
last_stmt_end_line = last_child.location.end_line;
|
|
1108
|
+
}
|
|
1027
1109
|
self.buffer.push('\n');
|
|
1028
1110
|
break;
|
|
1029
1111
|
}
|
|
1030
1112
|
}
|
|
1031
1113
|
|
|
1114
|
+
// Emit comments that are inside the block but not attached to any node
|
|
1115
|
+
// (comments between last statement and 'end')
|
|
1116
|
+
let had_internal_comments =
|
|
1117
|
+
self.has_comments_in_range(block_start_line + 1, block_end_line);
|
|
1118
|
+
if had_internal_comments {
|
|
1119
|
+
// Preserve blank line between last statement and first comment
|
|
1120
|
+
self.emit_comments_in_range_with_prev_line(
|
|
1121
|
+
block_start_line + 1,
|
|
1122
|
+
block_end_line,
|
|
1123
|
+
indent_level + 1,
|
|
1124
|
+
last_stmt_end_line,
|
|
1125
|
+
)?;
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
// Add newline if there were internal comments
|
|
1129
|
+
if had_internal_comments && !self.buffer.ends_with('\n') {
|
|
1130
|
+
self.buffer.push('\n');
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1032
1133
|
// Emit 'end'
|
|
1033
1134
|
self.emit_indent(indent_level)?;
|
|
1034
1135
|
write!(self.buffer, "end")?;
|
|
1136
|
+
// Emit trailing comments on end line
|
|
1137
|
+
self.emit_trailing_comments(block_end_line)?;
|
|
1035
1138
|
|
|
1036
1139
|
Ok(())
|
|
1037
1140
|
}
|
|
@@ -1220,6 +1323,8 @@ impl Emitter {
|
|
|
1220
1323
|
|
|
1221
1324
|
self.emit_indent(indent_level)?;
|
|
1222
1325
|
write!(self.buffer, "end")?;
|
|
1326
|
+
// Emit trailing comments on end line
|
|
1327
|
+
self.emit_trailing_comments(node.location.end_line)?;
|
|
1223
1328
|
|
|
1224
1329
|
Ok(())
|
|
1225
1330
|
}
|
|
@@ -1271,6 +1376,8 @@ impl Emitter {
|
|
|
1271
1376
|
|
|
1272
1377
|
self.emit_indent(indent_level)?;
|
|
1273
1378
|
write!(self.buffer, "end")?;
|
|
1379
|
+
// Emit trailing comments on end line
|
|
1380
|
+
self.emit_trailing_comments(node.location.end_line)?;
|
|
1274
1381
|
|
|
1275
1382
|
Ok(())
|
|
1276
1383
|
}
|
data/lib/rfmt/rfmt.so
CHANGED
|
Binary file
|
data/lib/rfmt/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rfmt
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.2.
|
|
4
|
+
version: 1.2.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- fujitani sora
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-01-
|
|
11
|
+
date: 2026-01-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rb_sys
|