|
27 | 27 |
|
28 | 28 | open Import |
29 | 29 | open Fiber.O |
| 30 | +open Merlin_kernel |
30 | 31 | module Std = Merlin_utils.Std |
31 | 32 | module Misc = Merlin_utils.Misc |
32 | 33 |
|
33 | | -module List = struct |
34 | | - include List |
35 | | - |
36 | | - let filter_dup' ~equiv lst = |
37 | | - let tbl = Hashtbl.create 17 in |
38 | | - let f a b = |
39 | | - let b' = equiv b in |
40 | | - if Hashtbl.mem tbl b' |
41 | | - then a |
42 | | - else ( |
43 | | - Hashtbl.add tbl b' (); |
44 | | - b :: a) |
45 | | - in |
46 | | - rev (fold_left ~f ~init:[] lst) |
47 | | - ;; |
48 | | - |
49 | | - let filter_dup lst = filter_dup' ~equiv:(fun x -> x) lst |
50 | | -end |
51 | | - |
52 | | -module Config = struct |
53 | | - type t = |
54 | | - { build_path : string list |
55 | | - ; source_path : string list |
56 | | - ; cmi_path : string list |
57 | | - ; cmt_path : string list |
58 | | - ; flags : string list Std.with_workdir list |
59 | | - ; extensions : string list |
60 | | - ; suffixes : (string * string) list |
61 | | - ; stdlib : string option |
62 | | - ; reader : string list |
63 | | - ; exclude_query_dir : bool |
64 | | - ; use_ppx_cache : bool |
65 | | - } |
66 | | - |
67 | | - let empty = |
68 | | - { build_path = [] |
69 | | - ; source_path = [] |
70 | | - ; cmi_path = [] |
71 | | - ; cmt_path = [] |
72 | | - ; extensions = [] |
73 | | - ; suffixes = [] |
74 | | - ; flags = [] |
75 | | - ; stdlib = None |
76 | | - ; reader = [] |
77 | | - ; exclude_query_dir = false |
78 | | - ; use_ppx_cache = false |
79 | | - } |
80 | | - ;; |
81 | | - |
82 | | - (* Parses suffixes pairs that were supplied as whitespace separated pairs |
83 | | - designating implementation/interface suffixes. These would be supplied in |
84 | | - the .merlin file as: |
85 | | -
|
86 | | - SUFFIX .sfx .sfxi *) |
87 | | - let parse_suffix str = |
88 | | - match |
89 | | - let trimmed = String.trim str in |
90 | | - String.extract_blank_separated_words trimmed |
91 | | - with |
92 | | - | [ first; second ] -> |
93 | | - if String.get first 0 <> '.' || String.get second 0 <> '.' |
94 | | - then [] |
95 | | - else [ first, second ] |
96 | | - | _ -> [] |
97 | | - ;; |
98 | | - |
99 | | - let prepend ~dir:cwd (directives : Merlin_dot_protocol.directive list) config = |
100 | | - List.fold_left ~init:(config, []) directives ~f:(fun (config, errors) -> |
101 | | - function |
102 | | - | `B path -> { config with build_path = path :: config.build_path }, errors |
103 | | - | `S path -> { config with source_path = path :: config.source_path }, errors |
104 | | - | `CMI path -> { config with cmi_path = path :: config.cmi_path }, errors |
105 | | - | `CMT path -> { config with cmt_path = path :: config.cmt_path }, errors |
106 | | - | `EXT exts -> { config with extensions = exts @ config.extensions }, errors |
107 | | - | `SUFFIX suffix -> |
108 | | - { config with suffixes = parse_suffix suffix @ config.suffixes }, errors |
109 | | - | `FLG flags -> |
110 | | - let flags = { Std.workdir = cwd; workval = flags } in |
111 | | - { config with flags = flags :: config.flags }, errors |
112 | | - | `STDLIB path -> { config with stdlib = Some path }, errors |
113 | | - | `READER reader -> { config with reader }, errors |
114 | | - | `EXCLUDE_QUERY_DIR -> { config with exclude_query_dir = true }, errors |
115 | | - | `USE_PPX_CACHE -> { config with use_ppx_cache = true }, errors |
116 | | - | `UNKNOWN_TAG _ -> |
117 | | - (* For easier forward compatibility we ignore unknown configuration tags |
118 | | - when they are provided by dune *) |
119 | | - config, errors |
120 | | - | `ERROR_MSG str -> config, str :: errors) |
121 | | - ;; |
122 | | - |
123 | | - let postprocess = |
124 | | - let clean list = List.rev (List.filter_dup list) in |
125 | | - fun config -> |
126 | | - { build_path = clean config.build_path |
127 | | - ; source_path = clean config.source_path |
128 | | - ; cmi_path = clean config.cmi_path |
129 | | - ; cmt_path = clean config.cmt_path |
130 | | - ; extensions = clean config.extensions |
131 | | - ; suffixes = clean config.suffixes |
132 | | - ; flags = clean config.flags |
133 | | - ; stdlib = config.stdlib |
134 | | - ; reader = config.reader |
135 | | - ; exclude_query_dir = config.exclude_query_dir |
136 | | - ; use_ppx_cache = config.use_ppx_cache |
137 | | - } |
138 | | - ;; |
139 | | - |
140 | | - let merge t (merlin : Mconfig.merlin) failures config_path = |
141 | | - { merlin with |
142 | | - build_path = t.build_path @ merlin.build_path |
143 | | - ; source_path = t.source_path @ merlin.source_path |
144 | | - ; cmi_path = t.cmi_path @ merlin.cmi_path |
145 | | - ; cmt_path = t.cmt_path @ merlin.cmt_path |
146 | | - ; exclude_query_dir = t.exclude_query_dir || merlin.exclude_query_dir |
147 | | - ; extensions = t.extensions @ merlin.extensions |
148 | | - ; suffixes = t.suffixes @ merlin.suffixes |
149 | | - ; stdlib = (if t.stdlib = None then merlin.stdlib else t.stdlib) |
150 | | - ; reader = (if t.reader = [] then merlin.reader else t.reader) |
151 | | - ; flags_to_apply = t.flags @ merlin.flags_to_apply |
152 | | - ; failures = failures @ merlin.failures |
153 | | - ; config_path = Some config_path |
154 | | - } |
155 | | - ;; |
156 | | -end |
| 34 | +let empty = Mconfig_dot.empty_config |
157 | 35 |
|
158 | 36 | module Process = struct |
159 | 37 | type nonrec t = |
@@ -324,11 +202,17 @@ let get_config (p : Process.t) ~workdir path_abs = |
324 | 202 | in |
325 | 203 | match answer with |
326 | 204 | | Ok directives -> |
327 | | - let cfg, failures = Config.prepend ~dir:workdir directives Config.empty in |
328 | | - Config.postprocess cfg, failures |
329 | | - | Error (Merlin_dot_protocol.Unexpected_output msg) -> Config.empty, [ msg ] |
| 205 | + let cfg, failures = |
| 206 | + Mconfig_dot.prepend_config |
| 207 | + ~dir:workdir |
| 208 | + Mconfig_dot.Configurator.Dune |
| 209 | + directives |
| 210 | + empty |
| 211 | + in |
| 212 | + Mconfig_dot.postprocess_config cfg, failures |
| 213 | + | Error (Merlin_dot_protocol.Unexpected_output msg) -> empty, [ msg ] |
330 | 214 | | Error (Csexp_parse_error _) -> |
331 | | - ( Config.empty |
| 215 | + ( empty |
332 | 216 | , [ "ocamllsp could not load its configuration from the external reader. Building \ |
333 | 217 | your project with `dune` might solve this issue." |
334 | 218 | ] ) |
@@ -437,7 +321,9 @@ let config (t : t) : Mconfig.t Fiber.t = |
437 | 321 | use_entry entry |
438 | 322 | in |
439 | 323 | let+ dot, failures = get_config entry.process ~workdir:ctx.workdir t.path in |
440 | | - let merlin = Config.merge dot t.initial.merlin failures config_path in |
| 324 | + let merlin = |
| 325 | + Mconfig.merge_merlin_config dot t.initial.merlin ~failures ~config_path |
| 326 | + in |
441 | 327 | Mconfig.normalize { t.initial with merlin }) |
442 | 328 | ;; |
443 | 329 |
|
|
0 commit comments