diff --git a/src/Lint/Fix.elm b/src/Lint/Fix.elm index 96b9d45b..6168284a 100644 --- a/src/Lint/Fix.elm +++ b/src/Lint/Fix.elm @@ -77,7 +77,8 @@ fix : List Fix -> String -> String fix fixes sourceCode = fixes |> List.sortBy (rangePosition >> negate) - |> List.foldl applyFix sourceCode + |> List.foldl applyFix (String.lines sourceCode) + |> String.join "\n" rangePosition : Fix -> Int @@ -101,6 +102,86 @@ rangePosition fix_ = row * 1000000 + column +comparePosition : { row : Int, column : Int } -> { row : Int, column : Int } -> Order +comparePosition a b = + let + order : Order + order = + compare a.row b.row + in + case order of + EQ -> + compare a.column b.column + + _ -> + order + + +applyFix : Fix -> List String -> List String +applyFix fix_ lines = + lines + |> (case fix_ of + Replacement range replacement -> + applyReplace range replacement + + Removal range -> + applyReplace range "" + + InsertAt position insertion -> + applyReplace { start = position, end = position } insertion + ) + + +applyReplace : Range -> String -> List String -> List String +applyReplace range replacement lines = + let + linesBefore : List String + linesBefore = + lines + |> List.take (range.start.row - 1) + + linesAfter : List String + linesAfter = + lines + |> List.drop range.end.row + + startLine : String + startLine = + getRowAtLine lines (range.start.row - 1) + + startLineBefore : String + startLineBefore = + String.slice 0 (range.start.column - 1) startLine + + endLine : String + endLine = + getRowAtLine lines (range.end.row - 1) + + endLineAfter : String + endLineAfter = + String.dropLeft (range.end.column - 1) endLine + in + List.concat + [ linesBefore + , startLineBefore ++ replacement ++ endLineAfter |> String.lines + , linesAfter + ] + + +getRowAtLine : List String -> Int -> String +getRowAtLine lines rowIndex = + case lines |> Array.fromList |> Array.get rowIndex of + Just line -> + if String.trim line /= "" then + line + + else + "" + + Nothing -> + "" + + -- UTILITARIES FOR WORKING WITH RANGES @@ -144,134 +225,3 @@ mergeRanges a b = a.end in { start = start, end = end } - - -comparePosition : { row : Int, column : Int } -> { row : Int, column : Int } -> Order -comparePosition a b = - let - order : Order - order = - compare a.row b.row - in - case order of - EQ -> - compare a.column b.column - - _ -> - order - - -applyFix : Fix -> String -> String -applyFix fix_ source = - source - |> (case fix_ of - Replacement range replacement -> - applyReplace range replacement - - Removal range -> - applyReplace range "" - - InsertAt position insertion -> - applyReplace { start = position, end = position } insertion - ) - - -applyReplace : Range -> String -> String -> String -applyReplace range replacement source = - if range.start.row == range.end.row then - applySingleLineReplace - range - replacement - source - - else - applyMultiLineReplace - range - replacement - source - - -applySingleLineReplace : Range -> String -> String -> String -applySingleLineReplace range replacement source = - let - lines : List String - lines = - String.lines source - - linesBefore : String - linesBefore = - lines - |> List.take (range.start.row - 1) - |> String.join "\n" - - linesAfter : String - linesAfter = - lines - |> List.drop range.end.row - |> String.join "\n" - - line : String - line = - getRowAtLine lines (range.start.row - 1) - - lineBefore : String - lineBefore = - String.slice 0 (range.start.column - 1) line - - lineAfter : String - lineAfter = - String.dropLeft (range.end.column - 1) line - in - linesBefore ++ "\n" ++ lineBefore ++ replacement ++ lineAfter ++ "\n" ++ linesAfter - - -applyMultiLineReplace : Range -> String -> String -> String -applyMultiLineReplace range replacement source = - let - lines : List String - lines = - String.lines source - - linesBefore : String - linesBefore = - lines - |> List.take (range.start.row - 1) - |> String.join "\n" - - linesAfter : String - linesAfter = - lines - |> List.drop range.end.row - |> String.join "\n" - - startLine : String - startLine = - getRowAtLine lines (range.start.row - 1) - - startLineBefore : String - startLineBefore = - String.slice 0 (range.start.column - 1) startLine - - endLine : String - endLine = - getRowAtLine lines (range.end.row - 1) - - endLineAfter : String - endLineAfter = - String.dropLeft (range.end.column - 1) endLine - in - linesBefore ++ "\n" ++ startLineBefore ++ replacement ++ endLineAfter ++ "\n" ++ linesAfter - - -getRowAtLine : List String -> Int -> String -getRowAtLine lines rowIndex = - case lines |> Array.fromList |> Array.get rowIndex of - Just line -> - if String.trim line /= "" then - line - - else - "" - - Nothing -> - ""