space_after_commas.ex (2294B)
1 defmodule Credo.Check.Readability.SpaceAfterCommas do 2 use Credo.Check, 3 tags: [:formatter], 4 explanations: [ 5 check: """ 6 You can use white-space after commas to make items of lists, 7 tuples and other enumerations easier to separate from one another. 8 9 # preferred 10 11 alias Project.{Alpha, Beta} 12 13 def some_func(first, second, third) do 14 list = [1, 2, 3, 4, 5] 15 # ... 16 end 17 18 # NOT preferred - items are harder to separate 19 20 alias Project.{Alpha,Beta} 21 22 def some_func(first,second,third) do 23 list = [1,2,3,4,5] 24 # ... 25 end 26 27 Like all `Readability` issues, this one is not a technical concern. 28 But you can improve the odds of others reading and liking your code by making 29 it easier to follow. 30 """ 31 ] 32 33 alias Credo.Code.Charlists 34 alias Credo.Code.Heredocs 35 alias Credo.Code.Sigils 36 alias Credo.Code.Strings 37 38 # Matches commas followed by non-whitespace unless preceded by 39 # a question mark that is not part of a variable or function name 40 @unspaced_commas ~r/(?<!\W\?)(\,\S)/ 41 42 @doc false 43 @impl true 44 # TODO: consider for experimental check front-loader (text) 45 def run(%SourceFile{} = source_file, params) do 46 issue_meta = IssueMeta.for(source_file, params) 47 48 source_file 49 |> Sigils.replace_with_spaces(" ", " ", source_file.filename) 50 |> Strings.replace_with_spaces(" ", " ", source_file.filename) 51 |> Heredocs.replace_with_spaces(" ", " ", "", source_file.filename) 52 |> Charlists.replace_with_spaces(" ", " ", source_file.filename) 53 |> String.replace(~r/(\A|[^\?])#.+/, "\\1") 54 |> Credo.Code.to_lines() 55 |> Enum.flat_map(&find_issues(issue_meta, &1)) 56 end 57 58 defp issue_for(issue_meta, trigger, line_no, column) do 59 format_issue( 60 issue_meta, 61 message: "Space missing after comma", 62 trigger: trigger, 63 line_no: line_no, 64 column: column 65 ) 66 end 67 68 defp find_issues(issue_meta, {line_no, line}) do 69 @unspaced_commas 70 |> Regex.scan(line, capture: :all_but_first, return: :index) 71 |> List.flatten() 72 |> Enum.map(fn {idx, len} -> 73 trigger = String.slice(line, idx, len) 74 issue_for(issue_meta, trigger, line_no, idx + 1) 75 end) 76 end 77 end