aboutsummaryrefslogtreecommitdiff
path: root/toplevel/ide_slave.ml
diff options
context:
space:
mode:
Diffstat (limited to 'toplevel/ide_slave.ml')
-rw-r--r--toplevel/ide_slave.ml74
1 files changed, 46 insertions, 28 deletions
diff --git a/toplevel/ide_slave.ml b/toplevel/ide_slave.ml
index 8218302038..65b446ca00 100644
--- a/toplevel/ide_slave.ml
+++ b/toplevel/ide_slave.ml
@@ -113,9 +113,9 @@ let coqide_cmd_checks (loc,ast) =
(** Interpretation (cf. [Ide_intf.interp]) *)
let interp (id,raw,verbosely,s) =
- Pp.set_id_for_feedback id;
+ set_id_for_feedback (Interface.Edit id);
let pa = Pcoq.Gram.parsable (Stream.of_string s) in
- let loc_ast = Vernac.parse_sentence (pa,None) in
+ let loc, ast as loc_ast = Vernac.parse_sentence (pa,None) in
if not raw then coqide_cmd_checks loc_ast;
Flags.make_silent (not verbosely);
if id = 0 then Vernac.eval_expr (loc, VernacStm (Command ast))
@@ -191,6 +191,9 @@ let process_goal sigma g =
{ Interface.goal_hyp = hyps; Interface.goal_ccl = ccl; Interface.goal_id = id; }
let goals () =
+ Stm.finish ();
+ let s = read_stdout () in
+ if s <> "" then msg_info (str s);
try
let pfts = Proof_global.give_me_the_proof () in
let (goals, zipper, sigma) = Proof.proof pfts in
@@ -206,6 +209,9 @@ let goals () =
let evars () =
try
+ Stm.finish ();
+ let s = read_stdout () in
+ if s <> "" then msg_info (str s);
let pfts = Proof_global.give_me_the_proof () in
let { Evd.it = all_goals ; sigma = sigma } = Proof.V82.subgoals pfts in
let exl = Evarutil.non_instantiated sigma in
@@ -228,15 +234,20 @@ let hints () =
Some (hint_hyps, hint_goal)
with Proof_global.NoCurrentProof -> None
+
(** Other API calls *)
let inloadpath dir =
Loadpath.is_in_load_paths (CUnix.physical_path_of_string dir)
-let status () =
+let status force =
(** We remove the initial part of the current [DirPath.t]
(usually Top in an interactive session, cf "coqtop -top"),
and display the other parts (opened sections and modules) *)
+ Stm.finish ();
+ if force then Stm.join ();
+ let s = read_stdout () in
+ if s <> "" then msg_info (str s);
let path =
let l = Names.DirPath.repr (Lib.cwd ()) in
List.rev_map Names.Id.to_string l
@@ -253,7 +264,6 @@ let status () =
Interface.status_path = path;
Interface.status_proofname = proof;
Interface.status_allproofs = allproofs;
- Interface.status_statenum = Lib.current_command_label ();
Interface.status_proofnum = Stm.current_proof_depth ();
}
@@ -272,6 +282,8 @@ let set_options options =
in
List.iter iter options
+let mkcases s = Vernacentries.make_cases s
+
let about () = {
Interface.coqtop_version = Coq_config.version;
Interface.protocol_version = Serialize.protocol_version;
@@ -288,7 +300,16 @@ let handle_exn e =
match e with
| Errors.Drop -> dummy, None, "Drop is not allowed by coqide!"
| Errors.Quit -> dummy, None, "Quit is not allowed by coqide!"
- | e -> dummy, loc_of e, mk_msg e
+ | e ->
+ match Stateid.get_state_id e with
+ | Some (valid, _) -> valid, loc_of e, mk_msg e
+ | None -> dummy, loc_of e, mk_msg e
+
+let init =
+ let initialized = ref false in
+ fun () ->
+ if !initialized then anomaly (str "Already initialized")
+ else (initialized := true; Stm.get_current_state ())
(** When receiving the Quit call, we don't directly do an [exit 0],
but rather set this reference, in order to send a final answer
@@ -298,29 +319,19 @@ let quit = ref false
(** Grouping all call handlers together + error handling *)
-let eval_call c =
- let handle_exn e =
- catch_break := false;
- match e with
- | Errors.Drop -> None, "Drop is not allowed by coqide!"
- | Errors.Quit -> None, "Quit is not allowed by coqide!"
- | e ->
- let loc = match Loc.get_loc e with
- | Some loc when not (Loc.is_ghost loc) -> Some (Loc.unloc loc)
- | _ -> None
- in
- loc, (read_stdout ())^"\n"^(string_of_ppcmds (Errors.print e))
- in
+let eval_call xml_oc log c =
let interruptible f x =
catch_break := true;
Util.check_for_interrupt ();
let r = f x in
catch_break := false;
+ let out = read_stdout () in
+ if out <> "" then log (str out);
r
in
let handler = {
Interface.interp = interruptible interp;
- Interface.rewind = interruptible (fun _ -> 0);
+ Interface.backto = interruptible backto;
Interface.goals = interruptible goals;
Interface.evars = interruptible evars;
Interface.hints = interruptible hints;
@@ -331,28 +342,35 @@ let eval_call c =
Interface.set_options = interruptible set_options;
Interface.mkcases = interruptible Vernacentries.make_cases;
Interface.quit = (fun () -> quit := true);
+ Interface.init = interruptible init;
Interface.about = interruptible about;
Interface.handle_exn = handle_exn; }
in
- (* If the messages of last command are still there, we remove them *)
- ignore (read_stdout ());
Serialize.abstract_eval_call handler c
(** Message dispatching. *)
+let print_xml =
+ let m = Mutex.create () in
+ fun oc xml ->
+ Mutex.lock m;
+ try Xml_printer.print oc xml; Mutex.unlock m
+ with e -> let e = Errors.push e in Mutex.unlock m; raise e
+
let slave_logger xml_oc level message =
(* convert the message into XML *)
- let msg = Pp.string_of_ppcmds (hov 0 message) in
+ let msg = string_of_ppcmds (hov 0 message) in
let message = {
Interface.message_level = level;
Interface.message_content = msg;
} in
+ let () = pr_debug (Printf.sprintf "-> %S" msg) in
let xml = Serialize.of_message message in
- Xml_printer.print xml_oc xml
+ print_xml xml_oc xml
let slave_feeder xml_oc msg =
let xml = Serialize.of_feedback msg in
- Xml_printer.print xml_oc xml
+ print_xml xml_oc xml
(** The main loop *)
@@ -366,8 +384,8 @@ let loop () =
let xml_oc = Xml_printer.make (Xml_printer.TChannel !orig_stdout) in
let xml_ic = Xml_parser.make (Xml_parser.SChannel stdin) in
let () = Xml_parser.check_eof xml_ic false in
- Pp.set_logger (slave_logger xml_oc);
- Pp.set_feeder (slave_feeder xml_oc);
+ set_logger (slave_logger xml_oc);
+ set_feeder (slave_feeder xml_oc);
(* We'll handle goal fetching and display in our own way *)
Vernacentries.enable_goal_printing := false;
Vernacentries.qed_display_script := false;
@@ -377,9 +395,9 @@ let loop () =
let xml_query = Xml_parser.parse xml_ic in
let q = Serialize.to_call xml_query in
let () = pr_debug_call q in
- let r = eval_call q in
+ let r = eval_call xml_oc (slave_logger xml_oc Interface.Notice) q in
let () = pr_debug_answer q r in
- Xml_printer.print xml_oc (Serialize.of_answer q r);
+ print_xml xml_oc (Serialize.of_answer q r);
flush !orig_stdout
with
| Xml_parser.Error (Xml_parser.Empty, _) ->