class RuboCop::Cop::Layout::LineLength

}
baz: “0000000000”,
bar: “0000000000”,
foo: “0000000000”,
{
# good (with recommended cops enabled)
bar: “0000000000”, baz: “0000000000”}
{foo: “0000000000”,
# good
{foo: “0000000000”, bar: “0000000000”, baz: “0000000000”}
# bad
@example
is 25:
method calls, etc. For example, let’s say the max columns
Together, these cops will pretty print hashes, arrays,
* ParameterAlignment
* MultilineMethodArgumentLineBreaks
* MultilineHashKeyLineBreaks
* MultilineHashBraceLayout
* MultilineBlockLayout
* MultilineArrayLineBreaks
* IndentationWidth
* HashAlignment
* FirstParameterIndentation
* FirstHashElementIndentation
* FirstArrayElementIndentation
* FirstArgumentIndentation
* ClosingParenthesisIndentation
* BlockEndNewline
* BlockDelimiters
* BlockAlignment
* ArgumentAlignment
(Many of these are enabled by default.)
are recommended to further format the broken lines.
If autocorrection is enabled, the following Layout cops
method calls with argument lists.
split across lines. These include arrays, hashes, and
inserting line breaks into expressions that can be safely
It can programmatically shorten certain long lines by
This cop has some autocorrection capabilities.
It also ignores a shebang line by default.
of the ‘Layout/IndentationStyle` cop.
The tab size is configured in the `IndentationWidth`
The maximum length is configurable.
This cop checks the length of lines in the source code.

def allow_heredoc?

def allow_heredoc?
  allowed_heredoc
end

def allowed_heredoc

def allowed_heredoc
  cop_config['AllowHeredoc']
end

def breakable_block_range(block_node)

def breakable_block_range(block_node)
  if block_node.arguments? && !block_node.lambda?
    block_node.arguments.loc.end
  else
    block_node.loc.begin
  end
end

def breakable_range_after_semicolon(semicolon_token)

def breakable_range_after_semicolon(semicolon_token)
  range = semicolon_token.pos
  end_pos = range.end_pos
  next_range = range_between(end_pos, end_pos + 1)
  return nil unless next_range.line == range.line
  next_char = next_range.source
  return nil if /[\r\n]/.match?(next_char)
  return nil if next_char == ';'
  next_range
end

def breakable_range_by_line_index

def breakable_range_by_line_index
  @breakable_range_by_line_index ||= {}
end

def check_directive_line(line, line_index)

def check_directive_line(line, line_index)
  return if line_length_without_directive(line) <= max
  range = max..(line_length_without_directive(line) - 1)
  register_offense(
    source_range(
      processed_source.buffer,
      line_index + 1,
      range
    ),
    line,
    line_index
  )
end

def check_for_breakable_block(block_node)

def check_for_breakable_block(block_node)
  return unless block_node.single_line?
  line_index = block_node.loc.line - 1
  range = breakable_block_range(block_node)
  pos = range.begin_pos + 1
  breakable_range_by_line_index[line_index] =
    range_between(pos, pos + 1)
end

def check_for_breakable_node(node)

def check_for_breakable_node(node)
  breakable_node = extract_breakable_node(node, max)
  return if breakable_node.nil?
  line_index = breakable_node.first_line - 1
  range = breakable_node.source_range
  existing = breakable_range_by_line_index[line_index]
  return if existing
  breakable_range_by_line_index[line_index] = range
end

def check_for_breakable_semicolons(processed_source)

def check_for_breakable_semicolons(processed_source)
  tokens = processed_source.tokens.select { |t| t.type == :tSEMI }
  tokens.reverse_each do |token|
    range = breakable_range_after_semicolon(token)
    breakable_range_by_line_index[range.line - 1] = range if range
  end
end

def check_line(line, line_index)

def check_line(line, line_index)
  return if line_length(line) <= max
  return if ignored_line?(line, line_index)
  if ignore_cop_directives? && directive_on_source_line?(line_index)
    return check_directive_line(line, line_index)
  end
  return check_uri_line(line, line_index) if allow_uri?
  register_offense(
    excess_range(nil, line, line_index),
    line,
    line_index
  )
end

def check_uri_line(line, line_index)

def check_uri_line(line, line_index)
  uri_range = find_excessive_uri_range(line)
  return if uri_range && allowed_uri_position?(line, uri_range)
  register_offense(
    excess_range(uri_range, line, line_index),
    line,
    line_index
  )
end

def excess_range(uri_range, line, line_index)

def excess_range(uri_range, line, line_index)
  excessive_position = if uri_range && uri_range.begin < max
                         uri_range.end
                       else
                         highlight_start(line)
                       end
  source_range(processed_source.buffer, line_index + 1,
               excessive_position...(line_length(line)))
end

def extract_heredocs(ast)

def extract_heredocs(ast)
  return [] unless ast
  ast.each_node(:str, :dstr, :xstr).select(&:heredoc?).map do |node|
    body = node.location.heredoc_body
    delimiter = node.location.heredoc_end.source.strip
    [body.first_line...body.last_line, delimiter]
  end
end

def heredocs

def heredocs
  @heredocs ||= extract_heredocs(processed_source.ast)
end

def highlight_start(line)

def highlight_start(line)
  # TODO: The max with 0 is a quick fix to avoid crashes when a line
  # begins with many tabs, but getting a correct highlighting range
  # when tabs are used for indentation doesn't work currently.
  [max - indentation_difference(line), 0].max
end

def ignored_line?(line, line_index)

def ignored_line?(line, line_index)
  matches_ignored_pattern?(line) ||
    shebang?(line, line_index) ||
    heredocs && line_in_permitted_heredoc?(line_index.succ)
end

def line_in_heredoc?(line_number)

def line_in_heredoc?(line_number)
  heredocs.any? do |range, _delimiter|
    range.cover?(line_number)
  end
end

def line_in_permitted_heredoc?(line_number)

def line_in_permitted_heredoc?(line_number)
  return false unless allowed_heredoc
  heredocs.any? do |range, delimiter|
    range.cover?(line_number) &&
      (allowed_heredoc == true || allowed_heredoc.include?(delimiter))
  end
end

def max

def max
  cop_config['Max']
end

def on_block(node)

def on_block(node)
  check_for_breakable_block(node)
end

def on_investigation_end

def on_investigation_end
  processed_source.lines.each_with_index do |line, line_index|
    check_line(line, line_index)
  end
end

def on_new_investigation

def on_new_investigation
  check_for_breakable_semicolons(processed_source)
end

def on_potential_breakable_node(node)

def on_potential_breakable_node(node)
  check_for_breakable_node(node)
end

def register_offense(loc, line, line_index)

def register_offense(loc, line, line_index)
  message = format(MSG, length: line_length(line), max: max)
  self.breakable_range = breakable_range_by_line_index[line_index]
  add_offense(loc, message: message) do |corrector|
    self.max = line_length(line)
    corrector.insert_before(breakable_range, "\n") unless breakable_range.nil?
  end
end

def shebang?(line, line_index)

def shebang?(line, line_index)
  line_index.zero? && line.start_with?('#!')
end