Share
Embed
Ruby Formatter
A presentation for the Ruby Association on the final report of the Ruby Formatter project.
Kevin Newton
July 12, 2022
Transcript
133 slides
-
Build a syntax tree Format the syntax tree Create a
CLI Ruby Formatter -
Build a syntax tree Format the syntax tree Create a
CLI Create a language server (LSP) Ruby Formatter -
Build a syntax tree Format the syntax tree Create a
CLI Create a language server (LSP) Translate the syntax tree Ruby Formatter -
Build a syntax tree Build · Format · CLI ·
LSP · Translate -
Define each node Build · Format · CLI · LSP
· Translate -
Build · Format · CLI · LSP · Translate class
VCall < Node attr_reader :value, :location, :comments def initialize(value:, location:, comments: []) @value = value @location = location @comments = comments end def accept(visitor) visitor.visit_vcall(self) end def child_nodes [value] end alias deconstruct child_nodes def deconstruct_keys(keys) { value: value, location: location, comments: comments } end end -
Build · Format · CLI · LSP · Translate class
VCall < Node attr_reader :value, :location, :comments def initialize(value:, location:, comments: []) @value = value @location = location @comments = comments end def accept(visitor) visitor.visit_vcall(self) end def child_nodes [value] end alias deconstruct child_nodes def deconstruct_keys(keys) { value: value, location: location, comments: comments } end end Named fields -
Build · Format · CLI · LSP · Translate class
VCall < Node attr_reader :value, :location, :comments def initialize(value:, location:, comments: []) @value = value @location = location @comments = comments end def accept(visitor) visitor.visit_vcall(self) end def child_nodes [value] end alias deconstruct child_nodes def deconstruct_keys(keys) { value: value, location: location, comments: comments } end end Named fields #location/#comments -
Build · Format · CLI · LSP · Translate class
VCall < Node attr_reader :value, :location, :comments def initialize(value:, location:, comments: []) @value = value @location = location @comments = comments end def accept(visitor) visitor.visit_vcall(self) end def child_nodes [value] end alias deconstruct child_nodes def deconstruct_keys(keys) { value: value, location: location, comments: comments } end end Named fields #location/#comments #accept/#child_nodes -
Build · Format · CLI · LSP · Translate class
VCall < Node attr_reader :value, :location, :comments def initialize(value:, location:, comments: []) @value = value @location = location @comments = comments end def accept(visitor) visitor.visit_vcall(self) end def child_nodes [value] end alias deconstruct child_nodes def deconstruct_keys(keys) { value: value, location: location, comments: comments } end end Named fields #location/#comments #accept/#child_nodes #deconstruct/ #deconstruct_keys -
Build · Format · CLI · LSP · Translate class
VCall < Node attr_reader :value, :location, :comments def initialize(value:, location:, comments: []) @value = value @location = location @comments = comments end def accept(visitor) visitor.visit_vcall(self) end def child_nodes [value] end alias deconstruct child_nodes def deconstruct_keys(keys) { value: value, location: location, comments: comments } end end Named fields #location/#comments #accept/#child_nodes #deconstruct/ #deconstruct_keys Immutable -
Define each node Build · Format · CLI · LSP
· Translate -
Ripper::EVENTS.count # => 190 Define each node Build · Format
· CLI · LSP · Translate -
Ripper::EVENTS.count # => 190 SyntaxTree::Node.descendants.count # => 162 Define
each node Build · Format · CLI · LSP · Translate -
Ripper::EVENTS.count # => 190 SyntaxTree::Node.descendants.count # => 162 qwords_new/qwords_add
-> SyntaxTree::QWords Define each node Build · Format · CLI · LSP · Translate -
How we use ripper Build · Format · CLI ·
LSP · Translate -
var_ref : user_variable { /*%%%*/ if (!($$ = gettable(p, $1,
&@$))) $$ = NEW_BEGIN(0, &@$); /*% if (id_is_var(p, get_id($1))) { $$ = dispatch1(var_ref, $1); } else { $$ = dispatch1(vcall, $1); } %*/ } | keyword_variable { /*%%%*/ if (!($$ = gettable(p, $1, &@$))) $$ = NEW_BEGIN(0, &@$); /*% %*/ /*% ripper: var_ref!($1) %*/ } ; Build · Format · CLI · LSP · Translate -
var_ref : user_variable { /*%%%*/ if (!($$ = gettable(p, $1,
&@$))) $$ = NEW_BEGIN(0, &@$); /*% if (id_is_var(p, get_id($1))) { $$ = dispatch1(var_ref, $1); } else { $$ = dispatch1(vcall, $1); } %*/ } | keyword_variable { /*%%%*/ if (!($$ = gettable(p, $1, &@$))) $$ = NEW_BEGIN(0, &@$); /*% %*/ /*% ripper: var_ref!($1) %*/ } ; Build · Format · CLI · LSP · Translate -
class Foo def bar baz end end Build · Format
· CLI · LSP · Translate -
class Foo def bar baz end end Build · Format
· CLI · LSP · Translate class Parser < Ripper def on_const(value) = [:@const, value] def on_ident(value) = [:@ident, value] def on_const_ref(const) = [:const_ref, const] def on_vcall(ident) = [:vcall, ident] def on_class(const, superclass, bodystmt) [:class, [const, superclass, bodystmt]] end def on_def(name, params, bodystmt) [:def, [name, params, bodystmt]] end end -
class Foo def bar baz end end Build · Format
· CLI · LSP · Translate class Parser < Ripper def on_const(value) = [:@const, value] def on_ident(value) = [:@ident, value] def on_const_ref(const) = [:const_ref, const] def on_vcall(ident) = [:vcall, ident] def on_class(const, superclass, bodystmt) [:class, [const, superclass, bodystmt]] end def on_def(name, params, bodystmt) [:def, [name, params, bodystmt]] end end -
class Foo def bar baz end end Build · Format
· CLI · LSP · Translate class Parser < Ripper def on_const(value) = [:@const, value] def on_ident(value) = [:@ident, value] def on_const_ref(const) = [:const_ref, const] def on_vcall(ident) = [:vcall, ident] def on_class(const, superclass, bodystmt) [:class, [const, superclass, bodystmt]] end def on_def(name, params, bodystmt) [:def, [name, params, bodystmt]] end end -
class Foo def bar baz end end Build · Format
· CLI · LSP · Translate class Parser < Ripper def on_const(value) = [:@const, value] def on_ident(value) = [:@ident, value] def on_const_ref(const) = [:const_ref, const] def on_vcall(ident) = [:vcall, ident] def on_class(const, superclass, bodystmt) [:class, [const, superclass, bodystmt]] end def on_def(name, params, bodystmt) [:def, [name, params, bodystmt]] end end -
class Foo def bar baz end end Build · Format
· CLI · LSP · Translate class Parser < Ripper def on_const(value) = [:@const, value] def on_ident(value) = [:@ident, value] def on_const_ref(const) = [:const_ref, const] def on_vcall(ident) = [:vcall, ident] def on_class(const, superclass, bodystmt) [:class, [const, superclass, bodystmt]] end def on_def(name, params, bodystmt) [:def, [name, params, bodystmt]] end end -
class Foo def bar baz end end Build · Format
· CLI · LSP · Translate class Parser < Ripper def on_const(value) = [:@const, value] def on_ident(value) = [:@ident, value] def on_const_ref(const) = [:const_ref, const] def on_vcall(ident) = [:vcall, ident] def on_class(const, superclass, bodystmt) [:class, [const, superclass, bodystmt]] end def on_def(name, params, bodystmt) [:def, [name, params, bodystmt]] end end -
class Foo def bar baz end end Build · Format
· CLI · LSP · Translate class Parser < Ripper def on_const(value) = [:@const, value] def on_ident(value) = [:@ident, value] def on_const_ref(const) = [:const_ref, const] def on_vcall(ident) = [:vcall, ident] def on_class(const, superclass, bodystmt) [:class, [const, superclass, bodystmt]] end def on_def(name, params, bodystmt) [:def, [name, params, bodystmt]] end end -
class Foo def bar baz end end Build · Format
· CLI · LSP · Translate class Parser < Ripper def on_const(value) = [:@const, value] def on_ident(value) = [:@ident, value] def on_const_ref(const) = [:const_ref, const] def on_vcall(ident) = [:vcall, ident] def on_class(const, superclass, bodystmt) [:class, [const, superclass, bodystmt]] end def on_def(name, params, bodystmt) [:def, [name, params, bodystmt]] end end -
Build · Format · CLI · LSP · Translate class
Parser < Ripper def on_const(value) = [:@const, value] def on_ident(value) = [:@ident, value] def on_const_ref(const) = [:const_ref, const] def on_vcall(ident) = [:vcall, ident] def on_class(const, superclass, bodystmt) [:class, [const, superclass, bodystmt]] end def on_def(name, params, bodystmt) [:def, [name, params, bodystmt]] end end -
Build · Format · CLI · LSP · Translate class
Parser < Ripper def on_const(value) = [:@const, value] def on_ident(value) = [:@ident, value] def on_kw(value) = @stack << [:@kw, value] def on_const_ref(const) = [:const_ref, const] def on_vcall(ident) = [:vcall, ident] def on_class(const, superclass, bodystmt) kw = @stack.rfind { |token| token in [:@kw, "class"] } [:class, [@stack.delete(kw), const, superclass, bodystmt]] end def on_def(name, params, bodystmt) kw = @stack.rfind { |token| token in [:@kw, "def"] } [:def, [@stack.delete(kw), name, params, bodystmt]] end end -
Build · Format · CLI · LSP · Translate class
Parser < Ripper def on_const(value) = [:@const, value] def on_ident(value) = [:@ident, value] def on_kw(value) = @stack << [:@kw, value] def on_const_ref(const) = [:const_ref, const] def on_vcall(ident) = [:vcall, ident] def on_class(const, superclass, bodystmt) kw = @stack.rfind { |token| token in [:@kw, "class"] } [:class, [@stack.delete(kw), const, superclass, bodystmt]] end def on_def(name, params, bodystmt) kw = @stack.rfind { |token| token in [:@kw, "def"] } [:def, [@stack.delete(kw), name, params, bodystmt]] end end -
Build · Format · CLI · LSP · Translate ->
(positional; local1, local2) {} -
Build · Format · CLI · LSP · Translate ->
(positional; local1, local2) {} range = (location.start_char + 1)...location.end_char locals = lambda_locals(source[range]) Paren.new( lparen: params.lparen, contents: LambdaVar.new( params: params.contents, locals: locals, location: location ), location: params.location, comments: params.comments ) -
class Foo def bar baz end end Build · Format
· CLI · LSP · Translate -
Build · Format · CLI · LSP · Translate class
Foo # comment def bar baz end end -
Build · Format · CLI · LSP · Translate class
Foo def bar # comment baz end end -
Build · Format · CLI · LSP · Translate class
Foo def bar baz # comment end end -
Build · Format · CLI · LSP · Translate #
comment class Foo def bar baz end end -
Build · Format · CLI · LSP · Translate class
Foo # comment def bar baz end end -
Build · Format · CLI · LSP · Translate #
comment1 class Foo # comment2 # comment3 def bar # comment4 baz # comment5 end end -
Build · Format · CLI · LSP · Translate #
comment1 class Foo # comment2 # comment3 def bar # comment4 baz # comment5 end end [ ] -
Build · Format · CLI · LSP · Translate #
comment1 class Foo # comment2 # comment3 def bar # comment4 baz # comment5 end end [ # comment1, ] -
Build · Format · CLI · LSP · Translate #
comment1 class Foo # comment2 # comment3 def bar # comment4 baz # comment5 end end [ # comment1, # comment2, ] -
Build · Format · CLI · LSP · Translate #
comment1 class Foo # comment2 # comment3 def bar # comment4 baz # comment5 end end [ # comment1, # comment2, # comment3, ] -
Build · Format · CLI · LSP · Translate #
comment1 class Foo # comment2 # comment3 def bar # comment4 baz # comment5 end end [ # comment1, # comment2, # comment3, # comment4, ] -
Build · Format · CLI · LSP · Translate #
comment1 class Foo # comment2 # comment3 def bar # comment4 baz # comment5 end end [ # comment1, # comment2, # comment3, # comment4, # comment5 ] -
Build · Format · CLI · LSP · Translate [
# comment1, # comment2, # comment3, # comment4, # comment5 ] (program (statements ((class (const_ref (const "Foo")) (bodystmt (statements ((void_stmt), (def (ident "bar") (params) (bodystmt (statements ((vcall (ident "baz"))))))))))))) -
Build · Format · CLI · LSP · Translate (program
(statements ((comment "# comment1"), (class (const_ref (const "Foo") ((comment "# comment2"))) (bodystmt (statements ((void_stmt), (comment "# comment3"), (def (ident "bar") (params ((comment "# comment4"))) (bodystmt (statements ((vcall (ident "baz") ((comment "# comment5")))))))))))))) -
Walking the tree Build · Format · CLI · LSP
· Translate -
Build · Format · CLI · LSP · Translate class
Visitor def visit(node) node&.accept(self) end def visit_child_nodes(node) node.child_nodes.map do |node| visit(node) end end end -
Build · Format · CLI · LSP · Translate class
VCall < Node def accept(visitor) visitor.visit_vcall(self) end end class Visitor def visit(node) node&.accept(self) end def visit_child_nodes(node) node.child_nodes.map do |node| visit(node) end end end -
Build · Format · CLI · LSP · Translate class
VCall < Node def accept(visitor) visitor.visit_vcall(self) end end # Visit an ARef node. alias visit_aref visit_child_nodes # Visit an ARefField node. alias visit_aref_field visit_child_nodes # Visit an Alias node. alias visit_alias visit_child_nodes # Visit an ArgBlock node. alias visit_arg_block visit_child_nodes # Visit an ArgParen node. alias visit_arg_paren visit_child_nodes # Visit an ArgStar node. alias visit_arg_star visit_child_nodes # Visit an Args node. alias visit_args visit_child_nodes # Visit an ArgsForward node. alias visit_args_forward visit_child_nodes # Visit an ArrayLiteral node. alias visit_array visit_child_nodes # Visit an AryPtn node. alias visit_aryptn visit_child_nodes # Visit an Assign node. alias visit_assign visit_child_nodes # Visit an Assoc node. alias visit_assoc visit_child_nodes # Visit an AssocSplat node. alias visit_assoc_splat visit_child_nodes # Visit a Backref node. alias visit_backref visit_child_nodes class Visitor def visit(node) node&.accept(self) end def visit_child_nodes(node) node.child_nodes.map do |node| visit(node) end end end -
Build · Format · CLI · LSP · Translate class
VCall < Node def accept(visitor) visitor.visit_vcall(self) end end alias visit_vcall visit_child_nodes # Visit a VoidStmt node. alias visit_void_stmt visit_child_nodes # Visit a When node. alias visit_when visit_child_nodes # Visit a While node. alias visit_while visit_child_nodes # Visit a WhileMod node. alias visit_while_mod visit_child_nodes # Visit a Word node. alias visit_word visit_child_nodes # Visit a Words node. alias visit_words visit_child_nodes # Visit a WordsBeg node. alias visit_words_beg visit_child_nodes # Visit a XString node. alias visit_xstring visit_child_nodes # Visit a XStringLiteral node. alias visit_xstring_literal visit_child_nodes # Visit a Yield node. alias visit_yield visit_child_nodes # Visit a Yield0 node. alias visit_yield0 visit_child_nodes # Visit a ZSuper node. alias visit_zsuper visit_child_nodes # Visit an EndContent node. alias visit___end__ visit_child_nodes class Visitor def visit(node) node&.accept(self) end def visit_child_nodes(node) node.child_nodes.map do |node| visit(node) end end end -
Build · Format · CLI · LSP · Translate class
RegexpVisitor < Visitor def visit_regexp_literal(node) # do something with regexp literal node here node.options # call super to continue walking the tree super end end -
Build · Format · CLI · LSP · Translate class
JSONVisitor < Visitor def visit_aref(node) node(node, "aref") do field("collection", node.collection) field("index", node.index) comments(node) end end def visit_aref_field(node) node(node, "aref_field") do field("collection", node.collection) field("index", node.index) comments(node) end end def visit_alias(node) node(node, "alias") do field("left", node.left) field("right", node.right) comments(node) end end -
Format the syntax tree Build · Format · CLI ·
LSP · Translate -
prettyprint Build group, text, breakable to layout content Algorithm Build
· Format · CLI · LSP · Translate -
prettyprint Build group, text, breakable to layout content Break outermost
groups to fit to print width Algorithm Build · Format · CLI · LSP · Translate -
Build · Format · CLI · LSP · Translate [foo1,
foo2, [bar1, bar2, bar3, bar4], foo3, foo4, [baz1, baz2]] -
Build · Format · CLI · LSP · Translate [foo1,
foo2, [bar1, bar2, bar3, bar4], foo3, foo4, [baz1, baz2]] -
Build · Format · CLI · LSP · Translate [foo1,
foo2, [bar1, bar2, bar3, bar4], foo3, foo4, [baz1, baz2]] -
Build · Format · CLI · LSP · Translate [
foo1, foo2, [bar1, bar2, bar3, bar4], foo3, foo4, [baz1, baz2] ] -
Build · Format · CLI · LSP · Translate [
foo1, foo2, [bar1, bar2, bar3, bar4], foo3, foo4, [baz1, baz2] ] -
Build · Format · CLI · LSP · Translate [
foo1, foo2, [ bar1, bar2, bar3, bar4 ], foo3, foo4, [baz1, baz2] ] -
breakGroup([group([text(["["]), indent([breakable, text(["foo1", ","]), breakable, text(["foo2", ","]), breakable, group([text(["["]), indent([breakable,
text(["bar1", ","]), breakable, text(["bar2", ","]), breakable, text(["bar3", ","]), breakable, text(["bar4"])]), breakable, text(["]"])]), text([","]), breakable, text(["foo3", ","]), breakable, text(["foo4", ","]), breakable, ... Build · Format · CLI · LSP · Translate -
breakGroup([group([text(["["]), indent([breakable, text(["foo1", ","]), breakable, text(["foo2", ","]), breakable, group([text(["["]), indent([breakable,
text(["bar1", ","]), breakable, text(["bar2", ","]), breakable, text(["bar3", ","]), breakable, text(["bar4"])]), breakable, text(["]"])]), text([","]), breakable, text(["foo3", ","]), breakable, text(["foo4", ","]), breakable, ... Build · Format · CLI · LSP · Translate -
breakGroup([group([text(["["]), indent([breakable, text(["foo1", ","]), breakable, text(["foo2", ","]), breakable, group([text(["["]), indent([breakable,
text(["bar1", ","]), breakable, text(["bar2", ","]), breakable, text(["bar3", ","]), breakable, text(["bar4"])]), breakable, text(["]"])]), text([","]), breakable, text(["foo3", ","]), breakable, text(["foo4", ","]), breakable, ... Build · Format · CLI · LSP · Translate -
breakGroup([group([text(["["]), indent([breakable, text(["foo1", ","]), breakable, text(["foo2", ","]), breakable, group([text(["["]), indent([breakable,
text(["bar1", ","]), breakable, text(["bar2", ","]), breakable, text(["bar3", ","]), breakable, text(["bar4"])]), breakable, text(["]"])]), text([","]), breakable, text(["foo3", ","]), breakable, text(["foo4", ","]), breakable, ... Build · Format · CLI · LSP · Translate -
breakGroup([group([text(["["]), indent([breakable, text(["foo1", ","]), breakable, text(["foo2", ","]), breakable, group([text(["["]), indent([breakable,
text(["bar1", ","]), breakable, text(["bar2", ","]), breakable, text(["bar3", ","]), breakable, text(["bar4"])]), breakable, text(["]"])]), text([","]), breakable, text(["foo3", ","]), breakable, text(["foo4", ","]), breakable, ... Build · Format · CLI · LSP · Translate -
I made too many additions to prettyprint Build · Format
· CLI · LSP · Translate 😅😅😅 -
Build · Format · CLI · LSP · Translate if
foo bar += baz end -
Build · Format · CLI · LSP · Translate if
foo bar += baz end -
Build · Format · CLI · LSP · Translate bar
+= baz if foo -
Build · Format · CLI · LSP · Translate if
foo bar else baz end -
Build · Format · CLI · LSP · Translate if
foo bar else baz end -
Build · Format · CLI · LSP · Translate foo
? bar : baz -
Build · Format · CLI · LSP · Translate here_is_a_method_call(1,
2, <<~HEREDOC this is the content of the heredoc HEREDOC ) -
Build · Format · CLI · LSP · Translate here_is_a_method_call(1,
2, <<~HEREDOC this is the content of the heredoc HEREDOC ) -
Build · Format · CLI · LSP · Translate here_is_a_method_call(1,
2, <<~HEREDOC) this is the content of the heredoc HEREDOC -
Build · Format · CLI · LSP · Translate def
foo return [1, 2, 3].map { |element| element * 2 } # comment end -
Build · Format · CLI · LSP · Translate def
foo return [1, 2, 3].map { |element| element * 2 } # comment end -
Build · Format · CLI · LSP · Translate def
foo return( [1, 2, 3].map do |element| element * 2 end ) # comment end -
Build · Format · CLI · LSP · Translate class
If < Node def format(q) if node.consequent || node.statements.empty? q.group { format_break(q, force: true) } else q.group do q .if_break { format_break(q, force: false) } .if_flat do Parentheses.flat(q) do q.format(node.statements) q.text(" if ") q.format(node.predicate) end end end end end end -
Build · Format · CLI · LSP · Translate class
If < Node def format(q) if node.consequent || node.statements.empty? q.group { format_break(q, force: true) } else q.group do q .if_break { format_break(q, force: false) } .if_flat do Parentheses.flat(q) do q.format(node.statements) q.text(" if ") q.format(node.predicate) end end end end end end -
Create a CLI Build · Format · CLI · LSP
· Translate -
Build · Format · CLI · LSP · Translate stree
ast [OPTIONS] [FILE] Print out the AST corresponding to the given files stree check [OPTIONS] [FILE] Check that the given files are formatted as syntax tree would format them stree debug [OPTIONS] [FILE] Check that the given files can be formatted idempotently stree doc [OPTIONS] [FILE] Print out the doc tree that would be used to format the given files stree format [OPTIONS] [FILE] Print out the formatted version of the given files stree json [OPTIONS] [FILE] Print out the JSON representation of the given files stree match [OPTIONS] [FILE] Print out a pattern-matching Ruby expression that would match the given files stree help Display this help message stree lsp Run syntax tree in language server mode stree version Output the current version of syntax tree stree write [OPTIONS] [FILE] Read, format, and write back the source of the given files -
Build · Format · CLI · LSP · Translate stree
ast [OPTIONS] [FILE] Print out the AST corresponding to the given files stree check [OPTIONS] [FILE] Check that the given files are formatted as syntax tree would format them stree debug [OPTIONS] [FILE] Check that the given files can be formatted idempotently stree doc [OPTIONS] [FILE] Print out the doc tree that would be used to format the given files stree format [OPTIONS] [FILE] Print out the formatted version of the given files stree json [OPTIONS] [FILE] Print out the JSON representation of the given files stree match [OPTIONS] [FILE] Print out a pattern-matching Ruby expression that would match the given files stree help Display this help message stree lsp Run syntax tree in language server mode stree version Output the current version of syntax tree stree write [OPTIONS] [FILE] Read, format, and write back the source of the given files -
Build · Format · CLI · LSP · Translate stree
ast [OPTIONS] [FILE] Print out the AST corresponding to the given files stree check [OPTIONS] [FILE] Check that the given files are formatted as syntax tree would format them stree debug [OPTIONS] [FILE] Check that the given files can be formatted idempotently stree doc [OPTIONS] [FILE] Print out the doc tree that would be used to format the given files stree format [OPTIONS] [FILE] Print out the formatted version of the given files stree json [OPTIONS] [FILE] Print out the JSON representation of the given files stree match [OPTIONS] [FILE] Print out a pattern-matching Ruby expression that would match the given files stree help Display this help message stree lsp Run syntax tree in language server mode stree version Output the current version of syntax tree stree write [OPTIONS] [FILE] Read, format, and write back the source of the given files -
Build · Format · CLI · LSP · Translate stree
ast [OPTIONS] [FILE] Print out the AST corresponding to the given files stree check [OPTIONS] [FILE] Check that the given files are formatted as syntax tree would format them stree debug [OPTIONS] [FILE] Check that the given files can be formatted idempotently stree doc [OPTIONS] [FILE] Print out the doc tree that would be used to format the given files stree format [OPTIONS] [FILE] Print out the formatted version of the given files stree json [OPTIONS] [FILE] Print out the JSON representation of the given files stree match [OPTIONS] [FILE] Print out a pattern-matching Ruby expression that would match the given files stree help Display this help message stree lsp Run syntax tree in language server mode stree version Output the current version of syntax tree stree write [OPTIONS] [FILE] Read, format, and write back the source of the given files -
Build · Format · CLI · LSP · Translate stree
ast [OPTIONS] [FILE] Print out the AST corresponding to the given files stree check [OPTIONS] [FILE] Check that the given files are formatted as syntax tree would format them stree debug [OPTIONS] [FILE] Check that the given files can be formatted idempotently stree doc [OPTIONS] [FILE] Print out the doc tree that would be used to format the given files stree format [OPTIONS] [FILE] Print out the formatted version of the given files stree json [OPTIONS] [FILE] Print out the JSON representation of the given files stree match [OPTIONS] [FILE] Print out a pattern-matching Ruby expression that would match the given files stree help Display this help message stree lsp Run syntax tree in language server mode stree version Output the current version of syntax tree stree write [OPTIONS] [FILE] Read, format, and write back the source of the given files -
Single quotes Formatting plugins Build · Format · CLI ·
LSP · Translate -
Single quotes Trailing commas Formatting plugins Build · Format ·
CLI · LSP · Translate -
Language plugins Build · Format · CLI · LSP ·
Translate rbs -
Language plugins Build · Format · CLI · LSP ·
Translate rbs haml -
Language plugins Build · Format · CLI · LSP ·
Translate rbs haml json -
Language plugins Build · Format · CLI · LSP ·
Translate rbs haml json xml -
Language plugins Build · Format · CLI · LSP ·
Translate rbs haml json xml css -
Build · Format · CLI · LSP · Translate stree
ast [OPTIONS] [FILE] Print out the AST corresponding to the given files stree check [OPTIONS] [FILE] Check that the given files are formatted as syntax tree would format them stree debug [OPTIONS] [FILE] Check that the given files can be formatted idempotently stree doc [OPTIONS] [FILE] Print out the doc tree that would be used to format the given files stree format [OPTIONS] [FILE] Print out the formatted version of the given files stree json [OPTIONS] [FILE] Print out the JSON representation of the given files stree match [OPTIONS] [FILE] Print out a pattern-matching Ruby expression that would match the given files stree help Display this help message stree lsp Run syntax tree in language server mode stree version Output the current version of syntax tree stree write [OPTIONS] [FILE] Read, format, and write back the source of the given files -
Build · Format · CLI · LSP · Translate stree
ast [OPTIONS] [FILE] Print out the AST corresponding to the given files stree check [OPTIONS] [FILE] Check that the given files are formatted as syntax tree would format them stree debug [OPTIONS] [FILE] Check that the given files can be formatted idempotently stree doc [OPTIONS] [FILE] Print out the doc tree that would be used to format the given files stree format [OPTIONS] [FILE] Print out the formatted version of the given files stree json [OPTIONS] [FILE] Print out the JSON representation of the given files stree match [OPTIONS] [FILE] Print out a pattern-matching Ruby expression that would match the given files stree help Display this help message stree lsp Run syntax tree in language server mode stree version Output the current version of syntax tree stree write [OPTIONS] [FILE] Read, format, and write back the source of the given files -
Create a language server Build · Format · CLI ·
LSP · Translate -
Language server protocol Runs a JSON RPC server behind an
editor Build · Format · CLI · LSP · Translate -
Language server protocol Runs a JSON RPC server behind an
editor textDocument/didChange textDocument/didOpen textDocument/didClose Build · Format · CLI · LSP · Translate -
Language server protocol Runs a JSON RPC server behind an
editor textDocument/didChange textDocument/didOpen textDocument/didClose textDocument/formatting Build · Format · CLI · LSP · Translate -
Language server protocol Runs a JSON RPC server behind an
editor textDocument/didChange textDocument/didOpen textDocument/didClose textDocument/formatting textDocument/inlayHint Build · Format · CLI · LSP · Translate -
Shopify/ruby-lsp Document highlight Document symbols Folding ranges Build · Format
· CLI · LSP · Translate -
Shopify/ruby-lsp Document highlight Document symbols Folding ranges Formatting Build ·
Format · CLI · LSP · Translate -
Shopify/ruby-lsp Document highlight Document symbols Folding ranges Formatting Selection ranges
Build · Format · CLI · LSP · Translate -
Shopify/ruby-lsp Document highlight Document symbols Folding ranges Formatting Selection ranges
Semantic highlighting Build · Format · CLI · LSP · Translate -
Translate the syntax tree Build · Format · CLI ·
LSP · Translate -
Translate the syntax tree Build · Format · CLI ·
LSP · Translate -
Translate the syntax tree seattlerb/ruby_parser Build · Format · CLI
· LSP · Translate -
Translate the syntax tree seattlerb/ruby_parser whitequark/parser Build · Format ·
CLI · LSP · Translate -
Translate the syntax tree seattlerb/ruby_parser whitequark/parser rubocop/rubocop-ast ruby-syntax-tree/ syntax_tree-translator
Build · Format · CLI · LSP · Translate