Module: Jade::Formatter::InfixApplication

Extended by:
Helper, InfixApplication
Included in:
InfixApplication
Defined in:
lib/jade/formatter/infix_application.rb

Instance Method Summary collapse

Methods included from Helper

and_indent, dispatch_for, format_delimited, format_exposing, format_leading_comments, format_node, format_pattern, format_trailing_comment, format_type, format_type_atom, too_long?

Instance Method Details

#collect_chain(node, op) ⇒ Object

Walk a left-associative chain and return the operands in order (‘a op b op c` → [a, b, c]).



49
50
51
52
53
54
55
56
# File 'lib/jade/formatter/infix_application.rb', line 49

def collect_chain(node, op)
  case node
  in AST::InfixApplication(left:, operator: AST::InfixOperator(value: ^op), right:)
    collect_chain(left, op) + [right]
  else
    [node]
  end
end

#format(node, indent:, source:) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
# File 'lib/jade/formatter/infix_application.rb', line 7

def format(node, indent:, source:)
  node => AST::InfixApplication(left:, operator:, right:)

  case operator.value
  when '|>'
    format_pipe_chain(node, indent, source:)
  when '++'
    format_concat_chain(node, indent, source:)
  else
    "#{format_node(left, source:)} #{operator.value} #{format_node(right, source:)}"
      .then(&and_indent(indent))
  end
end

#format_concat_chain(node, indent, source:) ⇒ Object

‘++` chains stay inline when they fit, ladder when they don’t.



36
37
38
39
40
41
42
43
44
45
# File 'lib/jade/formatter/infix_application.rb', line 36

def format_concat_chain(node, indent, source:)
  chain  = collect_chain(node, '++')
  inline = chain.map { format_node(it, source:) }.join(' ++ ')

  if chain.length > 1 && too_long?(inline, indent)
    format_ladder(chain, '++', indent, source:)
  else
    inline.then(&and_indent(indent))
  end
end

#format_ladder(chain, op, indent, source:) ⇒ Object

Emit a chain ladder: head on its own line, each subsequent operand prefixed by ‘op` indented one level deeper.



60
61
62
63
64
65
66
# File 'lib/jade/formatter/infix_application.rb', line 60

def format_ladder(chain, op, indent, source:)
  cont = INDENT * (indent + 1)
  head = format_node(chain.first, indent:, source:)
  tail = chain[1..].map { "#{cont}#{op} #{format_node(it, source:)}" }

  ([head] + tail).join("\n")
end

#format_pipe_chain(node, indent, source:) ⇒ Object

‘|>` chains of 3 or more arms always render as a ladder; the vertical shape reads as “transform stage by stage”. Two-arm chains stay inline unless they bust the line budget.



24
25
26
27
28
29
30
31
32
33
# File 'lib/jade/formatter/infix_application.rb', line 24

def format_pipe_chain(node, indent, source:)
  chain  = collect_chain(node, '|>')
  inline = chain.map { format_node(it, source:) }.join(' |> ')

  if chain.length > 2 || too_long?(inline, indent)
    format_ladder(chain, '|>', indent, source:)
  else
    inline.then(&and_indent(indent))
  end
end