rfmt 1.5.3-aarch64-linux → 1.6.1-aarch64-linux
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 +51 -0
- data/README.md +22 -18
- data/lib/rfmt/3.3/rfmt.so +0 -0
- data/lib/rfmt/3.4/rfmt.so +0 -0
- data/lib/rfmt/prism_bridge.rb +43 -12
- data/lib/rfmt/version.rb +1 -1
- data/lib/ruby_lsp/rfmt/formatter_runner.rb +2 -0
- 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: e36c79a715864d1545b7646e65a9de6afe9d2502fdc60702fe595c9c94fccba0
|
|
4
|
+
data.tar.gz: 40c48ce63e3d9d7f64593635dd13217079eab96e209861fe5529f715160c8ea3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d0e411f31a9c4c49be7cff8ecbe7f15f2196b4a005888eecdf206a7fdf6ba098e85fae7ce5ec8675920a43eb7a0fe22687930660b66a88c411d5353dcf3fbd23
|
|
7
|
+
data.tar.gz: 969b21932415241c2868e1adcda98e9c7e98942522c7aacb025fbaaa53b6543665142cebcdaaead4ff86c4f360e9d17286aa50b06599dddc7b2bf491b2799ad6
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,56 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [1.6.1] - 2026-04-24
|
|
4
|
+
|
|
5
|
+
Follow-up release consolidating the 1.6.0 architecture work.
|
|
6
|
+
|
|
7
|
+
### Rule-based formatter
|
|
8
|
+
|
|
9
|
+
The rule-based `format/` pipeline (`Formatter`, `Registry`, `Rule`) is the canonical formatting path, replacing the legacy monolithic emitter. Rules covering body indentation (`StatementsRule`), singleton classes (`SingletonClassRule`), and variable writes (`VariableWriteRule`) ship as part of the default registry. The Intermediate Representation (IR) module decouples parsing from emission for composability and testability.
|
|
10
|
+
|
|
11
|
+
### Method chain reformatting
|
|
12
|
+
|
|
13
|
+
Multi-line method chains can be reformatted from aligned style (indented under the first dot) to indented style (one level beyond the receiver), preserving the source's base indent. The pass is wired into the fallback path for resilience.
|
|
14
|
+
|
|
15
|
+
### Printer optimizations
|
|
16
|
+
|
|
17
|
+
The printer carries a pre-computed indent cache and inline hints for the hot path; `reformat_chain_lines` has been deduplicated across rules and uses `Cow<str>` to avoid allocations on pass-through.
|
|
18
|
+
|
|
19
|
+
### Editor integration
|
|
20
|
+
|
|
21
|
+
Setup guides for VSCode, Neovim, Helix, Emacs, and Zed land in the repository; every editor uses the Ruby LSP addon system, so there are no editor-specific plugins to maintain. The README's Editor Integration section replaces the previous "Coming Soon" placeholder with a VSCode quick start.
|
|
22
|
+
|
|
23
|
+
## [1.6.0] - 2026-04-23
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
- **Rule-based formatter architecture**: new modular `format/` pipeline (`Formatter`, `Registry`, `Rule`) replacing the legacy monolithic emitter
|
|
27
|
+
- **Intermediate Representation (IR) module**: decouples parsing from emission for composability and testability
|
|
28
|
+
- New formatter rules: `StatementsRule` (body indentation), `SingletonClassRule`, `VariableWriteRule`
|
|
29
|
+
- Method chain reformatting: convert aligned style to indented style when lines exceed the configured width
|
|
30
|
+
- Chain reformatting wired into the fallback path for resilience
|
|
31
|
+
- `config` module exported for test consumption
|
|
32
|
+
- **Editor Integration Documentation**: comprehensive setup guides for VSCode, Neovim, Helix, Emacs, and Zed
|
|
33
|
+
- VSCode: Format on Save configuration with Ruby LSP, settings reference table, project-specific setup
|
|
34
|
+
- Zed: full configuration with `initialization_options` and `format_on_save`
|
|
35
|
+
- All editors work through the Ruby LSP addon system — no editor-specific plugins required
|
|
36
|
+
- README: Editor Integration section updated with VSCode quick start (replacing "Coming Soon")
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
- Printer optimized with indent cache and inline hints
|
|
40
|
+
- `reformat_chain_lines` deduplicated across rules and optimized with `Cow` to reduce allocations
|
|
41
|
+
- README: Neovim integration updated from CLI-based to Ruby LSP-based approach
|
|
42
|
+
- Removed Sublime Text section from editor documentation (replaced by Zed)
|
|
43
|
+
|
|
44
|
+
### Fixed
|
|
45
|
+
- Prism comment JSON deserialization now accepts `comment_type` and `embdoc` fields (#97)
|
|
46
|
+
- BTreeMap range panic when computing comment indices on edge inputs
|
|
47
|
+
- Comment duplication during source extraction
|
|
48
|
+
- Empty source input handled gracefully by the formatter runner
|
|
49
|
+
- Clippy warnings: use `repeat_n`
|
|
50
|
+
|
|
51
|
+
### Removed
|
|
52
|
+
- Legacy `Emitter` module (1844 LOC) — superseded by the new `Formatter`
|
|
53
|
+
|
|
3
54
|
## [1.5.3] - 2026-02-22
|
|
4
55
|
|
|
5
56
|
### Changed
|
data/README.md
CHANGED
|
@@ -361,30 +361,34 @@ end
|
|
|
361
361
|
|
|
362
362
|
## Editor Integration
|
|
363
363
|
|
|
364
|
-
|
|
364
|
+
rfmt integrates with editors through [Ruby LSP](https://shopify.github.io/ruby-lsp/). For detailed setup instructions, see [Editor Integration Guide](docs/editors.md).
|
|
365
|
+
|
|
366
|
+
### VSCode (Quick Start)
|
|
365
367
|
|
|
366
|
-
|
|
368
|
+
1. Install [Ruby LSP extension](https://marketplace.visualstudio.com/items?itemName=Shopify.ruby-lsp)
|
|
369
|
+
2. Add to your `settings.json`:
|
|
370
|
+
|
|
371
|
+
```json
|
|
372
|
+
{
|
|
373
|
+
"rubyLsp.formatter": "rfmt",
|
|
374
|
+
"editor.formatOnSave": true,
|
|
375
|
+
"[ruby]": {
|
|
376
|
+
"editor.defaultFormatter": "Shopify.ruby-lsp"
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### Neovim
|
|
367
382
|
|
|
368
383
|
```lua
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
callback = function()
|
|
374
|
-
local filepath = vim.fn.expand("%:p")
|
|
375
|
-
local result = vim.fn.system({ "rfmt", filepath })
|
|
376
|
-
if vim.v.shell_error == 0 then
|
|
377
|
-
vim.cmd("edit!")
|
|
378
|
-
end
|
|
379
|
-
end,
|
|
384
|
+
require("lspconfig").ruby_lsp.setup({
|
|
385
|
+
init_options = {
|
|
386
|
+
formatter = "rfmt"
|
|
387
|
+
}
|
|
380
388
|
})
|
|
381
389
|
```
|
|
382
390
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
- **VS Code** - Extension in development
|
|
386
|
-
- **RubyMine** - Plugin in development
|
|
387
|
-
- **Zed** - Extension in development
|
|
391
|
+
See [Editor Integration Guide](docs/editors.md) for Helix, Emacs, Sublime Text, and more.
|
|
388
392
|
|
|
389
393
|
## Development
|
|
390
394
|
|
data/lib/rfmt/3.3/rfmt.so
CHANGED
|
Binary file
|
data/lib/rfmt/3.4/rfmt.so
CHANGED
|
Binary file
|
data/lib/rfmt/prism_bridge.rb
CHANGED
|
@@ -62,17 +62,28 @@ module Rfmt
|
|
|
62
62
|
# Serialize the Prism AST with comments to JSON
|
|
63
63
|
def self.serialize_ast_with_comments(result)
|
|
64
64
|
comments = result.comments.map do |comment|
|
|
65
|
+
loc = comment.location
|
|
66
|
+
end_line = loc.end_line
|
|
67
|
+
# Prism's `=begin ... =end` (EmbDocComment) location ends at
|
|
68
|
+
# `<=end_line>:0`, i.e. the column-0 start of the line AFTER the
|
|
69
|
+
# `=end` terminator. Reporting that larger end_line makes the
|
|
70
|
+
# comment appear to overlap with the next statement, so the
|
|
71
|
+
# comment gets misattributed to a deeper node (e.g. the first
|
|
72
|
+
# expression inside the next method body) and ends up emitted in
|
|
73
|
+
# the wrong place. Snap it back to the terminator line.
|
|
74
|
+
end_line = loc.end_line - 1 if loc.end_column.zero? && loc.end_line > loc.start_line
|
|
75
|
+
|
|
65
76
|
{
|
|
66
77
|
comment_type: comment.class.name.split('::').last.downcase.gsub('comment', ''),
|
|
67
78
|
location: {
|
|
68
|
-
start_line:
|
|
69
|
-
start_column:
|
|
70
|
-
end_line:
|
|
71
|
-
end_column:
|
|
72
|
-
start_offset:
|
|
73
|
-
end_offset:
|
|
79
|
+
start_line: loc.start_line,
|
|
80
|
+
start_column: loc.start_column,
|
|
81
|
+
end_line: end_line,
|
|
82
|
+
end_column: loc.end_column,
|
|
83
|
+
start_offset: loc.start_offset,
|
|
84
|
+
end_offset: loc.end_offset
|
|
74
85
|
},
|
|
75
|
-
text:
|
|
86
|
+
text: loc.slice,
|
|
76
87
|
position: 'leading' # Default position, will be refined by Rust
|
|
77
88
|
}
|
|
78
89
|
end
|
|
@@ -120,7 +131,7 @@ module Rfmt
|
|
|
120
131
|
closing = node.closing_loc
|
|
121
132
|
if closing.end_offset > end_offset
|
|
122
133
|
end_offset = closing.end_offset
|
|
123
|
-
end_line = closing
|
|
134
|
+
end_line = heredoc_terminator_line(closing)
|
|
124
135
|
end_column = closing.end_column
|
|
125
136
|
end
|
|
126
137
|
end
|
|
@@ -145,6 +156,19 @@ module Rfmt
|
|
|
145
156
|
}
|
|
146
157
|
end
|
|
147
158
|
|
|
159
|
+
# Prism reports a heredoc's `closing_loc` as `<terminator_line>:0..(terminator_line+1):0`,
|
|
160
|
+
# i.e. its `end_line` is the LINE AFTER the terminator. Using that as the
|
|
161
|
+
# node's `end_line` makes blank-line preservation fail: a real blank line
|
|
162
|
+
# right after the terminator looks identical (diff == 1) to two adjacent
|
|
163
|
+
# statements with no separator. Use the terminator's own line instead.
|
|
164
|
+
def self.heredoc_terminator_line(closing_loc)
|
|
165
|
+
if closing_loc.end_column.zero? && closing_loc.end_line > closing_loc.start_line
|
|
166
|
+
closing_loc.start_line
|
|
167
|
+
else
|
|
168
|
+
closing_loc.end_line
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
148
172
|
# Recursively find the maximum closing_loc among all descendant nodes
|
|
149
173
|
# Returns nil if no closing_loc found, otherwise { end_offset:, end_line:, end_column: }
|
|
150
174
|
def self.find_max_closing_loc_recursive(node, depth: 0)
|
|
@@ -158,7 +182,7 @@ module Rfmt
|
|
|
158
182
|
if max_closing.nil? || closing.end_offset > max_closing[:end_offset]
|
|
159
183
|
max_closing = {
|
|
160
184
|
end_offset: closing.end_offset,
|
|
161
|
-
end_line: closing
|
|
185
|
+
end_line: heredoc_terminator_line(closing),
|
|
162
186
|
end_column: closing.end_column
|
|
163
187
|
}
|
|
164
188
|
end
|
|
@@ -424,9 +448,16 @@ module Rfmt
|
|
|
424
448
|
metadata['name'] = name
|
|
425
449
|
end
|
|
426
450
|
when Prism::DefNode
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
451
|
+
# Prefer `name_loc.slice` over `name.to_s` so unary operator suffixes
|
|
452
|
+
# (`def !@`, `def +@`, `def -@`) survive the round-trip. Prism
|
|
453
|
+
# normalizes `name` to the symbol with the `@` stripped for `!@`,
|
|
454
|
+
# which would otherwise rewrite `def !@` to `def !` silently.
|
|
455
|
+
name = if node.respond_to?(:name_loc) && node.name_loc
|
|
456
|
+
node.name_loc.slice
|
|
457
|
+
else
|
|
458
|
+
extract_node_name(node)
|
|
459
|
+
end
|
|
460
|
+
metadata['name'] = name if name
|
|
430
461
|
metadata['parameters_count'] = extract_parameter_count(node).to_s
|
|
431
462
|
# Extract parameters text directly from source
|
|
432
463
|
if node.parameters
|
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.
|
|
4
|
+
version: 1.6.1
|
|
5
5
|
platform: aarch64-linux
|
|
6
6
|
authors:
|
|
7
7
|
- fujitani sora
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-04-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: diff-lcs
|