trailing_white_space.ex (1825B)
1 defmodule Credo.Check.Readability.TrailingWhiteSpace do 2 use Credo.Check, 3 base_priority: :low, 4 tags: [:formatter], 5 param_defaults: [ 6 ignore_strings: true 7 ], 8 explanations: [ 9 check: """ 10 There should be no white-space (i.e. tabs, spaces) at the end of a line. 11 12 Most text editors provide a way to remove them automatically. 13 """, 14 params: [ 15 ignore_strings: "Set to `false` to check lines that are strings or in heredocs" 16 ] 17 ] 18 19 alias Credo.Code.Heredocs 20 alias Credo.Code.Strings 21 22 @doc false 23 @impl true 24 def run(%SourceFile{} = source_file, params) do 25 issue_meta = IssueMeta.for(source_file, params) 26 ignore_strings = Params.get(params, :ignore_strings, __MODULE__) 27 28 source_file 29 |> to_lines(ignore_strings) 30 |> traverse_line([], issue_meta) 31 end 32 33 defp to_lines(source_file, true) do 34 source_file 35 |> Strings.replace_with_spaces(".", ".") 36 |> Heredocs.replace_with_spaces(".", ".", ".", source_file.filename) 37 |> Credo.Code.to_lines() 38 end 39 40 defp to_lines(source_file, false) do 41 SourceFile.lines(source_file) 42 end 43 44 defp traverse_line([{line_no, line} | tail], issues, issue_meta) do 45 issues = 46 case Regex.run(~r/\h+$/u, line, return: :index) do 47 [{column, line_length}] -> 48 [issue_for(issue_meta, line_no, column + 1, line_length) | issues] 49 50 nil -> 51 issues 52 end 53 54 traverse_line(tail, issues, issue_meta) 55 end 56 57 defp traverse_line([], issues, _issue_meta), do: issues 58 59 defp issue_for(issue_meta, line_no, column, line_length) do 60 format_issue( 61 issue_meta, 62 message: "There should be no trailing white-space at the end of a line.", 63 line_no: line_no, 64 column: column, 65 trigger: String.duplicate(" ", line_length) 66 ) 67 end 68 end