Skip to content

Commit 1851bc4

Browse files
authored
Add module indent option (#2711)
* Add module-indent argument * Use module-indent option to indent structs and sigs * Add tests for module-indent option * Update documentation for module-indent option
1 parent 806d083 commit 1851bc4

17 files changed

+383
-5
lines changed

CHANGES.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,20 @@ profile. This started with version 0.26.0.
66

77
## unreleased
88

9-
### Added
9+
### Added
1010

1111
- Support for OCaml 5.4 (#2717, @Julow)
1212

13+
- Added option `module-indent` option (#2711, @HPRIOR) to control the indentation
14+
of items within modules. This affects modules and signatures. For example,
15+
module-indent=4:
16+
```ocaml
17+
module type M = sig
18+
type t
19+
20+
val f : (string * int) list -> int
21+
end
22+
```
1323
### Deprecated
1424

1525
- Starting in this release, ocamlformat can use cmdliner >= 2.0.0. When that is

doc/manpage_ocamlformat.mld

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,10 @@ OPTIONS (CODE FORMATTING STYLE)
295295
the offset of the previous line. The default value is 68. Cannot
296296
be set in attributes.
297297

298+
--module-indent=COLS
299+
Indentation of items within struct ... end and sig ... end (COLS
300+
columns). The default value is 2.
301+
298302
--module-item-spacing={compact|sparse|preserve}
299303
Spacing between items of structures and signatures. compact will
300304
not leave open lines between one-liners of similar sorts. sparse

lib/Conf.ml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ let conventional_profile from =
9191
; match_indent= elt 0
9292
; match_indent_nested= elt `Never
9393
; max_indent= elt None
94+
; module_indent= elt 2
9495
; module_item_spacing= elt `Compact
9596
; nested_match= elt `Wrap
9697
; ocp_indent_compat= elt false
@@ -160,6 +161,7 @@ let ocamlformat_profile from =
160161
; match_indent= elt 0
161162
; match_indent_nested= elt `Never
162163
; max_indent= elt None
164+
; module_indent= elt 2
163165
; module_item_spacing= elt `Sparse
164166
; nested_match= elt `Wrap
165167
; ocp_indent_compat= elt false
@@ -228,6 +230,7 @@ let janestreet_profile from =
228230
; match_indent= elt 0
229231
; match_indent_nested= elt `Never
230232
; max_indent= elt None
233+
; module_indent= elt 2
231234
; module_item_spacing= elt `Compact
232235
; nested_match= elt `Wrap
233236
; ocp_indent_compat= elt true
@@ -1063,6 +1066,14 @@ module Formatting = struct
10631066
(fun conf elt -> update conf ~f:(fun f -> {f with max_indent= elt}))
10641067
(fun conf -> conf.fmt_opts.max_indent)
10651068

1069+
let module_indent =
1070+
let docv = "COLS" in
1071+
let doc = "Indentation of items within struct ... end and sig ... end ($(docv) columns)." in
1072+
let names = ["module-indent"] in
1073+
Decl.int ~names ~default ~doc ~docv ~kind
1074+
(fun conf elt -> update conf ~f:(fun f -> {f with module_indent= elt}))
1075+
(fun conf -> conf.fmt_opts.module_indent)
1076+
10661077
let module_item_spacing =
10671078
let doc = "Spacing between items of structures and signatures." in
10681079
let names = ["module-item-spacing"] in
@@ -1344,6 +1355,7 @@ module Formatting = struct
13441355
; elt match_indent
13451356
; elt match_indent_nested
13461357
; elt max_indent
1358+
; elt module_indent
13471359
; elt module_item_spacing
13481360
; elt nested_match
13491361
; elt ocp_indent_compat

lib/Conf_t.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ type fmt_opts =
9999
; match_indent: int elt
100100
; match_indent_nested: [`Always | `Auto | `Never] elt
101101
; max_indent: int option elt
102+
; module_indent: int elt
102103
; module_item_spacing: [`Compact | `Preserve | `Sparse] elt
103104
; nested_match: [`Wrap | `Align] elt
104105
; ocp_indent_compat: bool elt

lib/Conf_t.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ type fmt_opts =
9797
; match_indent: int elt
9898
; match_indent_nested: [`Always | `Auto | `Never] elt
9999
; max_indent: int option elt
100+
; module_indent: int elt
100101
; module_item_spacing: [`Compact | `Preserve | `Sparse] elt
101102
; nested_match: [`Wrap | `Align] elt
102103
; ocp_indent_compat: bool elt (** Try to indent like ocp-indent *)

lib/Fmt_ast.ml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3822,8 +3822,9 @@ and fmt_module_type c ?(rec_ = false) ({ast= mty; _} as xmty) =
38223822
; pro= Some (before $ str "sig" $ fmt_if empty (str " "))
38233823
; psp=
38243824
fmt_if (not empty)
3825-
( if c.conf.fmt_opts.break_struct.v then break 1000 2
3826-
else break 1 2 )
3825+
( if c.conf.fmt_opts.break_struct.v then
3826+
break 1000 c.conf.fmt_opts.module_indent.v
3827+
else break 1 c.conf.fmt_opts.module_indent.v )
38273828
; bdy= (within $ if empty then noop else fmt_signature c ctx s)
38283829
; cls= noop
38293830
; esp=
@@ -4469,8 +4470,9 @@ and fmt_module_expr ?(dock_struct = true) c ({ast= m; ctx= ctx0} as xmod) =
44694470
; pro= Some (before $ str "struct" $ fmt_if empty (str " "))
44704471
; psp=
44714472
fmt_if (not empty)
4472-
( if c.conf.fmt_opts.break_struct.v then break 1000 2
4473-
else break 1 2 )
4473+
( if c.conf.fmt_opts.break_struct.v then
4474+
break 1000 c.conf.fmt_opts.module_indent.v
4475+
else break 1 c.conf.fmt_opts.module_indent.v )
44744476
; bdy= within $ fmt_structure c ctx sis
44754477
; cls= noop
44764478
; esp=

test/cli/print_config.t

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ No redundant values:
6363
match-indent=0 (profile conventional (file .ocamlformat:1))
6464
match-indent-nested=never (profile conventional (file .ocamlformat:1))
6565
max-indent=68 (profile conventional (file .ocamlformat:1))
66+
module-indent=2 (profile conventional (file .ocamlformat:1))
6667
module-item-spacing=compact (profile conventional (file .ocamlformat:1))
6768
nested-match=wrap (profile conventional (file .ocamlformat:1))
6869
ocp-indent-compat=false (profile conventional (file .ocamlformat:1))
@@ -142,6 +143,7 @@ Redundant values from the conventional profile:
142143
match-indent=0 (profile conventional (file .ocamlformat:1))
143144
match-indent-nested=never (profile conventional (file .ocamlformat:1))
144145
max-indent=68 (profile conventional (file .ocamlformat:1))
146+
module-indent=2 (profile conventional (file .ocamlformat:1))
145147
module-item-spacing=compact (profile conventional (file .ocamlformat:1))
146148
nested-match=wrap (profile conventional (file .ocamlformat:1))
147149
ocp-indent-compat=false (profile conventional (file .ocamlformat:1))
@@ -221,6 +223,7 @@ Redundant values from the ocamlformat profile:
221223
match-indent=0 (profile ocamlformat (file .ocamlformat:1))
222224
match-indent-nested=never (profile ocamlformat (file .ocamlformat:1))
223225
max-indent=68 (profile ocamlformat (file .ocamlformat:1))
226+
module-indent=2 (profile ocamlformat (file .ocamlformat:1))
224227
module-item-spacing=sparse (profile ocamlformat (file .ocamlformat:1))
225228
nested-match=wrap (profile ocamlformat (file .ocamlformat:1))
226229
ocp-indent-compat=false (profile ocamlformat (file .ocamlformat:1))

test/passing/gen/dune.inc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3993,6 +3993,24 @@
39933993
(package ocamlformat)
39943994
(action (diff module_attributes.ml.err module_attributes.ml.stderr)))
39953995

3996+
(rule
3997+
(deps .ocamlformat)
3998+
(package ocamlformat)
3999+
(action
4000+
(with-stdout-to module_indent.ml.stdout
4001+
(with-stderr-to module_indent.ml.stderr
4002+
(run %{bin:ocamlformat} --name module_indent.ml --margin-check --module-indent=4 %{dep:../tests/module_indent.ml})))))
4003+
4004+
(rule
4005+
(alias runtest)
4006+
(package ocamlformat)
4007+
(action (diff module_indent.ml.ref module_indent.ml.stdout)))
4008+
4009+
(rule
4010+
(alias runtest)
4011+
(package ocamlformat)
4012+
(action (diff module_indent.ml.err module_indent.ml.stderr)))
4013+
39964014
(rule
39974015
(deps .ocamlformat)
39984016
(package ocamlformat)

test/passing/refs.ahrefs/module_indent.ml.err

Whitespace-only changes.
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
(* Signature module type with attributes and comments *)
2+
module type M = sig
3+
(** Type of elements *)
4+
type t
5+
[@@ocaml.doc
6+
"Abstract type....................................................."]
7+
8+
(** Function operating on a list of (string * int) *)
9+
val f : (string * int) list -> int
10+
[@@ocaml.doc "Processes a list of (string * int) pairs"]
11+
12+
(** Inner module type *)
13+
module type Inner = sig
14+
type inner
15+
[@@ocaml.doc
16+
"Inner abstract \
17+
type.................................................."]
18+
19+
val f : int -> int
20+
[@@deprecated "Use the outer module’s `f` instead"]
21+
[@@ocaml.doc "Deprecated inner function"]
22+
end
23+
end
24+
25+
(* Module implementing part of M *)
26+
module A : sig
27+
type t
28+
29+
val f : (string * int) list -> int
30+
[@@ocaml.doc "Dummy implementation of M.f"]
31+
end = struct
32+
type t
33+
34+
(* Function with extra params *)
35+
let f s l =
36+
(* ignore params and return dummy result *)
37+
0
38+
end
39+
40+
(* Core module hierarchy with attributes *)
41+
module Core = struct
42+
module Int = struct
43+
module T = struct
44+
type t = int
45+
[@@ocaml.doc
46+
"Int alias with core extensions..........................."]
47+
48+
let compare = compare [@inline always]
49+
50+
let ( + ) x y = x + y
51+
[@@ocaml.doc "Addition for core ints..........................."]
52+
end
53+
54+
include T
55+
56+
(* Map functor application with inline doc *)
57+
module Map = Map.Make (T)
58+
[@@ocaml.doc "Map over core ints......................"]
59+
end
60+
61+
(* Re-export with comment *)
62+
module Std = struct
63+
module Int = Int
64+
[@@ocaml.doc "Standard Int re-export......................"]
65+
end
66+
end

0 commit comments

Comments
 (0)