package coq-lsp
Language Server Protocol native server for Coq
Install
Dune Dependency
Authors
Maintainers
Sources
coq-lsp-0.2.3.9.0.tbz
sha256=8776582dddfe768623870cf540ff6ba1e96a44a36e85db18ab93d238d640f92a
sha512=2837889bf99bfe715bd0e752782211a76a14aac71ed37a4fb784f4f0abe338352c9c6d8caa37daf79c036997add1cb306c523f793625b38709f3b5e245380223
doc/src/coq-lsp.coq/workspace.ml.html
Source file workspace.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385
(************************************************************************) (* * The Coq Proof Assistant / The Coq Development Team *) (* v * INRIA, CNRS and contributors - Copyright 1999-2018 *) (* <O___,, * (see CREDITS file for the list of authors) *) (* \VV/ **************************************************************) (* // * This file is distributed under the terms of the *) (* * GNU Lesser General Public License Version 2.1 *) (* * (see LICENSE file for the text of the license) *) (************************************************************************) (************************************************************************) (* Coq Language Server Protocol *) (* Copyright 2016-2019 MINES ParisTech -- Dual License LGPL 2.1 / GPL3+ *) (* Copyright 2019-2024 Inria -- Dual License LGPL 2.1 / GPL3+ *) (* Written by: Emilio J. Gallego Arias *) (************************************************************************) module Flags_ = Flags module Flags = struct type t = { impredicative_set : bool ; indices_matter : bool ; type_in_type : bool ; rewrite_rules : bool } let default = { impredicative_set = false ; indices_matter = false ; type_in_type = false ; rewrite_rules = false } let apply { impredicative_set; indices_matter; type_in_type; rewrite_rules } = Global.set_impredicative_set impredicative_set; Global.set_indices_matter indices_matter; Global.set_check_universes (not type_in_type); Global.set_rewrite_rules_allowed rewrite_rules let pp fmt { impredicative_set; indices_matter; type_in_type; rewrite_rules } = Format.fprintf fmt "impredicative_set: %b; indices_matter: %b; type_in_type: %b; \ rewrite_rules: %b" impredicative_set indices_matter type_in_type rewrite_rules end module Warning : sig type t val make : string -> t (** Adds new warnings to the list of current warnings *) val apply : t list -> unit (** *) val pp : Format.formatter -> t -> unit end = struct type t = string let make x = x let apply w = let old_warn = CWarnings.get_flags () in let new_warn = String.concat "," w in CWarnings.set_flags (old_warn ^ "," ^ new_warn) let pp = Format.pp_print_string end module Require = struct type t = { library : string ; from : string option ; flags : Vernacexpr.export_with_cats option } end type t = { coqlib : string ; findlib_config : string option ; ocamlpath : string list ; vo_load_path : Loadpath.vo_path list ; require_libs : Require.t list ; flags : Flags.t ; warnings : Warning.t list ; kind : string ; debug : bool } let inject_requires ~extra_requires (ws : t) = { ws with require_libs = ws.require_libs @ extra_requires } let hash = Hashtbl.hash let compare = Stdlib.compare (* Lib setup, XXX unify with sysinit *) let coq_root = Names.DirPath.make [ Libnames.rocq_init_root ] let default_root = Libnames.default_root_prefix let mk_lp ~coq_path ~unix_path ~implicit = { Loadpath.unix_path; coq_path; implicit; recursive = true } let mk_stdlib ~implicit unix_path = mk_lp ~coq_path:coq_root ~implicit ~unix_path let mk_userlib unix_path = mk_lp ~coq_path:default_root ~implicit:false ~unix_path let getenv var else_ = try Sys.getenv var with Not_found -> else_ let rec parse_args args init boot libs f w = match args with | [] -> (init, boot, List.rev libs, f, List.rev w) | "-rifrom" :: from :: lib :: rest -> parse_args rest init boot ((Some from, lib) :: libs) f w | "-impredicative-set" :: rest -> parse_args rest init boot libs { f with Flags.impredicative_set = true } w | "-indices-matter" :: rest -> parse_args rest init boot libs { f with Flags.indices_matter = true } w | "-type-in-type" :: rest -> parse_args rest init boot libs { f with Flags.type_in_type = true } w | "-allow-rewrite-rules" :: rest -> parse_args rest init boot libs { f with Flags.rewrite_rules = true } w | "-noinit" :: rest -> parse_args rest false boot libs f w | "-boot" :: rest -> parse_args rest init true libs f w | "-w" :: warn :: rest -> let warn = Warning.make warn in parse_args rest init boot libs f (warn :: w) | _ :: rest -> (* emit warning? *) parse_args rest init boot libs f w module CmdLine = struct type t = { coqlib : string ; findlib_config : string option ; ocamlpath : string list ; vo_load_path : Loadpath.vo_path list ; args : string list ; require_libraries : (string option * string) list } end let mk_require_from (from, library) = let flags = Some (Lib.Import, None) in { Require.library; from; flags } let make ~cmdline ~implicit ~kind ~debug = let { CmdLine.coqlib ; findlib_config ; ocamlpath ; args ; vo_load_path ; require_libraries } = cmdline in let coqlib = getenv "ROCQLIB" (getenv "COQLIB" coqlib) in let mk_path_coqlib prefix = coqlib ^ "/" ^ prefix in let init, boot, libs, flags, warnings = parse_args args true false [] Flags.default [] in (* Setup ml_include for the core plugins *) let dft_vo_load_path = if boot then [] else (* vo_include path = user-contrib + stdlib *) let userpaths = mk_path_coqlib "user-contrib" :: Envars.coqpath in let user_vo_path = List.map mk_userlib userpaths in let stdlib_vo_path = mk_path_coqlib "theories" |> mk_stdlib ~implicit in stdlib_vo_path :: user_vo_path in let require_libs = let rq_list = if init then ((None, "Corelib.Init.Prelude") :: require_libraries) @ libs else require_libraries @ libs in List.map mk_require_from rq_list in let vo_load_path = dft_vo_load_path @ vo_load_path in { coqlib ; findlib_config ; ocamlpath ; vo_load_path ; require_libs ; flags ; warnings ; kind ; debug } let pp_load_path fmt { Loadpath.unix_path; coq_path; implicit = _; recursive = _ } = Format.fprintf fmt "Path %s ---> %s" (Names.DirPath.to_string coq_path) unix_path (* This is a bit messy upstream, as -I both extends Coq loadpath and OCAMLPATH loadpath *) let findlib_init ?findlib_config ~ocamlpath () = let config = findlib_config in let env_ocamlpath = try [ Sys.getenv "OCAMLPATH" ] with Not_found -> [] in let env_ocamlpath = env_ocamlpath @ ocamlpath in let ocamlpathsep = if Sys.unix then ":" else ";" in let env_ocamlpath = String.concat ocamlpathsep env_ocamlpath in Findlib.init ~env_ocamlpath ?config () let describe { coqlib ; findlib_config ; ocamlpath ; kind ; vo_load_path ; require_libs ; flags ; warnings ; debug } = let require_msg = String.concat " " (List.map (fun { Require.library; _ } -> library) require_libs) in let n_vo = List.length vo_load_path in (* We need to do this in order for the calls to Findlib to make sense, but really need to modify this *) findlib_init ?findlib_config ~ocamlpath (); let fl_packages = Findlib.list_packages' () in let fl_config = Findlib.config_file () in let fl_location = Findlib.default_location () in let fl_paths = Findlib.search_path () in let extra = Format.asprintf "@[ debug: %b@\n\ \ flags: @[%a@]@\n\ \ warnings: @[<h>%a@]@\n\ \ vo_paths:@\n\ \ @[<v>%a@]@\n\ \ findlib_paths:@\n\ \ @[<v>%a@]@\n\ \ findlib_packages:@\n\ \ @[<v>%a@]@]" debug Flags.pp flags (Format.pp_print_list Warning.pp) warnings (Format.pp_print_list pp_load_path) vo_load_path Format.(pp_print_list pp_print_string) fl_paths Format.(pp_print_list pp_print_string) fl_packages in ( Format.asprintf "@[Configuration loaded from %s@\n\ \ - findlib: %d search paths active@\n\ \ + findlib config: %s@\n\ \ + findlib default location: %s@\n\ \ - coqlib is at: %s@\n\ \ + %d Coq path directory bindings in scope@\n\ \ + Modules [%s] will be loaded by default@]" kind (List.length fl_paths) fl_config fl_location coqlib n_vo require_msg , extra ) let describe_guess = function | Ok w -> describe w | Error msg -> (msg, "") (* Require a set of libraries *) let load_objs ~intern libs = let rq_file { Require.library; from; flags } = let mp = Libnames.qualid_of_string library in let mfrom = Option.map Libnames.qualid_of_string from in Flags_.silently (Vernacentries.vernac_require ~intern mfrom flags) [ (mp, Vernacexpr.ImportAll) ] in List.(iter rq_file (rev libs)) let fleche_chop_extension basename = match Filename.chop_suffix_opt ~suffix:".v.tex" basename with | Some file -> file | None -> Filename.chop_extension basename (* We need to compute this with the right load path *) let dirpath_of_uri ~uri = let f = Lang.LUri.File.to_string_file uri in let ldir0 = try let lp = Loadpath.find_load_path (Filename.dirname f) in Loadpath.logical lp with Not_found -> Libnames.default_root_prefix in let f = try fleche_chop_extension (Filename.basename f) with Invalid_argument _ -> f in let id = Names.Id.of_string f in let ldir = Libnames.add_dirpath_suffix ldir0 id in ldir (* NOTE: Use exhaustive match below to avoid bugs by skipping fields *) let apply ~intern ~uri { coqlib = _ ; findlib_config ; ocamlpath ; vo_load_path ; require_libs ; flags ; warnings ; kind = _ ; debug } = if debug then CDebug.set_flags "backtrace"; Flags.apply flags; Warning.apply warnings; findlib_init ?findlib_config ~ocamlpath (); List.iter Loadpath.add_vo_path vo_load_path; Declaremods.start_library (dirpath_of_uri ~uri); load_objs ~intern require_libs (* This can raise, and will do in incorrect CoqProject files *) let dirpath_of_string_exn coq_path = Libnames.dirpath_of_string coq_path let workspace_from_coqproject ~cmdline ~debug cp_file : t = (* Io.Log.error "init" "Parsing _CoqProject"; *) let open CoqProject_file in let to_vo_loadpath f implicit = let open Loadpath in let unix_path, coq_path = f in (* Lsp.Io.log_error "init" * (Printf.sprintf "Path from _CoqProject: %s %s" unix_path.path coq_path); *) { implicit ; recursive = true ; unix_path = unix_path.path ; coq_path = dirpath_of_string_exn coq_path } in (* XXX: [read_project_file] will do [exit 1] on parsing error! Please someone fix upstream!! *) let { r_includes; q_includes; ml_includes; extra_args; _ } = read_project_file ~warning_fn:(fun _ -> ()) cp_file in let ml_include_path = List.map (fun f -> f.thing.path) ml_includes in let vo_path = List.map (fun f -> to_vo_loadpath f.thing false) q_includes in let vo_load_path = List.append vo_path (List.map (fun f -> to_vo_loadpath f.thing true) r_includes) in let args = List.map (fun f -> f.thing) extra_args in let cmdline = CmdLine. { cmdline with args = cmdline.args @ args ; vo_load_path = cmdline.vo_load_path @ vo_load_path ; ocamlpath = cmdline.ocamlpath @ ml_include_path } in let implicit = true in let kind = cp_file in make ~cmdline ~implicit ~kind ~debug let workspace_from_cmdline ~debug ~cmdline = let kind = "Command-line arguments" in let implicit = true in make ~cmdline ~implicit ~kind ~debug let guess ~debug ~cmdline ~dir () = let cp_file = Filename.concat dir "_CoqProject" in if Sys.file_exists cp_file then workspace_from_coqproject ~cmdline ~debug cp_file else workspace_from_cmdline ~debug ~cmdline let guess ~token ~debug ~cmdline ~dir = let { Protect.E.r; feedback } = Protect.eval ~token ~f:(guess ~debug ~cmdline ~dir) () in ignore feedback; match r with | Protect.R.Interrupted -> Error "Workspace Scanning Interrupted" | Protect.R.Completed (Error (User { msg; _ })) | Protect.R.Completed (Error (Anomaly { msg; _ })) -> Error (Format.asprintf "Workspace Scanning Errored: %a" Pp.pp_with msg) | Protect.R.Completed (Ok workspace) -> Ok workspace let default ~debug ~cmdline = workspace_from_cmdline ~debug ~cmdline
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>