Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
gpetiot committed Jan 4, 2021
1 parent c642524 commit 64ce012
Showing 1 changed file with 59 additions and 80 deletions.
139 changes: 59 additions & 80 deletions lib/Indent.ml
Original file line number Diff line number Diff line change
Expand Up @@ -37,101 +37,80 @@ let matching_loc loc locs locs' =
| Unequal_lengths ->
Error (`Msg "Cannot match pre-post formatting locations.")

let last_token x =
let lexbuf = Lexing.from_string x in
let rec loop acc =
match Lexer.token_with_comments lexbuf with
| Parser.EOF -> acc
| tok -> loop (Some tok)
in
loop None

let indentation_1_line ?prev (loctree, locs) (_, locs') formatted_src nlines
~i =
if i = nlines + 1 then Ok 0
else
match loc_of_line loctree locs i with
| Some loc -> (
matching_loc loc locs locs'
>>= fun (loc' : Location.t) ->
let indent =
match
Source.find_first_token_on_line formatted_src
loc'.loc_start.pos_lnum
with
| Some (_, loc) -> Position.column loc.loc_start
| None -> impossible "cannot happen"
in
match prev with
| Some (prev_indent, prev_line)
when indent = prev_indent || indent = 0 -> (
(* in case this is a line that is split but could fit on a single
line, consecutive lines will have the same indentation, we try
to infer some artificial indentation here, even though it will
be squeezed together and fit on a single line when the whole
file is reformatted *)
match last_token prev_line with
| Some tok -> (
match Source.indent_after_token tok with
| Some i -> Ok (prev_indent + i)
| None -> Ok indent )
| None -> Ok indent )
| _ -> Ok indent )
| None -> Ok 0

let indent_from_locs fragment ~unformatted:(ast, source)
~formatted:(formatted_ast, formatted_source) ~lines ~range:(low, high) =
let indent_aux ~lines ~range:(low, high) ~indentation_of_line =
let nlines = List.length lines in
let locs = Loc_tree.of_ast fragment ast source in
let locs' = Loc_tree.of_ast fragment formatted_ast formatted_source in
let rec aux ?prev acc i =
if i > high then Ok (List.rev acc)
else if i >= low then
let line = Option.value (List.nth lines (i - 1)) ~default:"" in
if String.is_empty (String.strip line) then aux ?prev (0 :: acc) (i + 1)
if String.(is_empty (strip line)) then aux ?prev (0 :: acc) (i + 1)
else
indentation_1_line ?prev locs locs' formatted_source nlines ~i
indentation_of_line ?prev ~i ~line nlines
>>= fun indent -> aux ~prev:(indent, line) (indent :: acc) (i + 1)
else
let line = Option.value (List.nth lines (i - 1)) ~default:"" in
if String.is_empty (String.strip line) then aux ?prev acc (i + 1)
if String.(is_empty (strip line)) then aux ?prev acc (i + 1)
else
indentation_1_line ?prev locs locs' formatted_source nlines ~i
indentation_of_line ?prev ~i ~line nlines
>>= fun indent -> aux ~prev:(indent, line) acc (i + 1)
in
aux [] low

let indentation_of_line l = String.(length l - length (lstrip l))
let last_token x =
let lexbuf = Lexing.from_string x in
let rec loop acc =
match Lexer.token_with_comments lexbuf with
| Parser.EOF -> acc
| tok -> loop (Some tok)
in
loop None

let indentation_1_line_fallback ?prev nlines ~i ~line =
if i = nlines + 1 then Ok 0
else
let indent = indentation_of_line line in
match prev with
| Some (prev_indent, prev_line) -> (
match last_token prev_line with
| Some tok -> (
match Source.indent_after_token tok with
| Some i -> Ok (prev_indent + i)
| None -> Ok indent )
| None -> Ok indent )
| _ -> Ok indent
let indent_from_locs fragment ~unformatted:(ast, source)
~formatted:(formatted_ast, formatted_source) ~lines ~range =
let loctree, locs = Loc_tree.of_ast fragment ast source in
let _, locs' = Loc_tree.of_ast fragment formatted_ast formatted_source in
let indentation_of_line ?prev ~i ~line:_ nlines =
if i = nlines + 1 then Ok 0
else
match loc_of_line loctree locs i with
| Some loc -> (
matching_loc loc locs locs'
>>= fun (loc' : Location.t) ->
let indent =
match
Source.find_first_token_on_line formatted_source
loc'.loc_start.pos_lnum
with
| Some (_, loc) -> Position.column loc.loc_start
| None -> impossible "cannot happen"
in
match prev with
| Some (prev_indent, prev_line)
when indent = prev_indent || indent = 0 -> (
match last_token prev_line with
| Some tok -> (
match Source.indent_after_token tok with
| Some i -> Ok (prev_indent + i)
| None -> Ok indent )
| None -> Ok indent )
| _ -> Ok indent )
| None -> Ok 0
in
indent_aux ~lines ~range ~indentation_of_line

let indent_from_lines ~lines ~range:(low, high) =
let nlines = List.length lines in
let rec aux ?prev acc i =
if i > high then Ok (List.rev acc)
else if i >= low then
let line = Option.value (List.nth lines (i - 1)) ~default:"" in
if String.is_empty (String.strip line) then aux ?prev (0 :: acc) (i + 1)
else
indentation_1_line_fallback ?prev nlines ~i ~line
>>= fun indent -> aux ~prev:(indent, line) (indent :: acc) (i + 1)
let indent_from_lines ~lines ~range =
let indentation_of_line ?prev ~i ~line nlines =
if i = nlines + 1 then Ok 0
else
let line = Option.value (List.nth lines (i - 1)) ~default:"" in
if String.is_empty (String.strip line) then aux ?prev acc (i + 1)
else
let indent = indentation_of_line line in
aux ~prev:(indent, line) acc (i + 1)
let indent = String.(length line - length (lstrip line)) in
match prev with
| Some (prev_indent, prev_line) -> (
match last_token prev_line with
| Some tok -> (
match Source.indent_after_token tok with
| Some i -> Ok (prev_indent + i)
| None -> Ok indent )
| None -> Ok indent )
| _ -> Ok indent
in
aux [] low
indent_aux ~lines ~range ~indentation_of_line

0 comments on commit 64ce012

Please sign in to comment.