class Rufo::Formatter

def consume_end_of_line(at_prefix: false, want_semicolon: false, want_multiline: true, needs_two_lines_on_comment: false)

- want_multiline: do we want multiple lines to appear, or at most one?
- want_semicolon: do we want do print a semicolon to separate expressions?
- at_prefix: are we at a point before an expression? (if so, we don't need a space before the first comment)

Consume and print an end of line, handling semicolons and comments
def consume_end_of_line(at_prefix: false, want_semicolon: false, want_multiline: true, needs_two_lines_on_comment: false)
  found_newline = false            # Did we find any newline during this method?
  last = nil                       # Last token kind found
  multilple_lines = false          # Did we pass through more than one newline?
  last_comment_has_newline = false # Does the last comment has a newline?
  newline_count = 0                # Number of newlines we passed
  loop do
    case current_token_kind
    when :on_sp
      # Ignore spaces
      next_token
    when :on_nl, :on_ignored_nl
      # I don't know why but sometimes a on_ignored_nl
      # can appear with nil as the "text", and that's wrong
      if current_token[2].nil?
        next_token
        next
      end
      if last == :newline
        # If we pass through consecutive newlines, don't print them
        # yet, but remember this fact
        multilple_lines = true unless last_comment_has_newline
      else
        # If we just printed a comment that had a newline,
        # we must print two newlines because we remove newlines from comments (rstrip call)
        if last == :comment && last_comment_has_newline
          write_line
          multilple_lines = true
        else
          write_line
          multilple_lines = false
        end
      end
      found_newline = true
      next_token
      last = :newline
      newline_count += 1
    when :on_semicolon
      next_token
      # If we want to print semicolons and we didn't find a newline yet,
      # print it, but only if it's not followed by a newline
      if !found_newline && want_semicolon && last != :semicolon
        skip_space
        case current_token_kind
        when :on_ignored_nl, :on_eof
        else
          write "; "
          last = :semicolon
        end
      end
      multilple_lines = false
    when :on_comment
      if last == :comment
        # Since we remove newlines from comments, we must add the last
        # one if it was a comment
        write_line
        write_indent
      else
        if found_newline
          if newline_count == 1 && needs_two_lines_on_comment
            if multilple_lines
              write_line
              multilple_lines = false
            else
              multilple_lines = true
            end
            needs_two_lines_on_comment = false
          end
          # Write line or second line if needed
          write_line if last != :newline || multilple_lines
          write_indent
        else
          # If we didn't find any newline yet, this is the first comment,
          # so append a space if needed (for example after an expression)
          write_space unless at_prefix
          track_comment
        end
      end
      last_comment_has_newline = current_token_value.end_with?("\n")
      write current_token_value.rstrip
      next_token
      last = :comment
      multilple_lines = false
    when :on_embdoc_beg
      write_line if multilple_lines
      consume_embedded_comment
      last = :comment
      last_comment_has_newline = true
    else
      break
    end
  end
  # Output a newline if we didn't do so yet:
  # either we didn't find a newline and we are at the end of a line (and we didn't just pass a semicolon),
  # or the last thing was a comment (from which we removed the newline)
  # or we just passed multiple lines (but printed only one)
  if (!found_newline && !at_prefix && !(want_semicolon && last == :semicolon)) ||
    last == :comment ||
    (multilple_lines && want_multiline)
    write_line
  end
end