diff options
author | Benjamin Barenblat <bbaren@debian.org> | 2018-12-29 14:31:27 -0500 |
---|---|---|
committer | Benjamin Barenblat <bbaren@debian.org> | 2018-12-29 14:31:27 -0500 |
commit | 9043add656177eeac1491a73d2f3ab92bec0013c (patch) | |
tree | 2b0092c84bfbf718eca10c81f60b2640dc8cab05 /ide | |
parent | a4c7f8bd98be2a200489325ff7c5061cf80ab4f3 (diff) |
Imported Upstream version 8.8.2upstream/8.8.2
Diffstat (limited to 'ide')
91 files changed, 1904 insertions, 8910 deletions
diff --git a/ide/config_lexer.mli b/ide/config_lexer.mli new file mode 100644 index 00000000..4719612c --- /dev/null +++ b/ide/config_lexer.mli @@ -0,0 +1,12 @@ +(************************************************************************) +(* * 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) *) +(************************************************************************) + +val print_file : string -> string list Util.String.Map.t -> unit +val load_file : string -> string list Util.String.Map.t diff --git a/ide/config_lexer.mll b/ide/config_lexer.mll index ac9cc57b..55d8d969 100644 --- a/ide/config_lexer.mll +++ b/ide/config_lexer.mll @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) { diff --git a/ide/coq-ssreflect.lang b/ide/coq-ssreflect.lang index 7cfc1670..bd9cb4bf 100644 --- a/ide/coq-ssreflect.lang +++ b/ide/coq-ssreflect.lang @@ -228,7 +228,7 @@ <keyword>Implicit\%{space}+Arguments</keyword> <keyword>(Import)|(Include)</keyword> <keyword>Require(\%{space}+((Import)|(Export)))?</keyword> - <keyword>(Recursive\%{space}+)?Extraction(\%{space}+(Language\%{space}+(Ocaml)|(Haskell)|(Scheme)|(Toplevel))|(Library)|((No)?Inline)|(Blacklist))?</keyword> + <keyword>(Recursive\%{space}+)?Extraction(\%{space}+(Language\%{space}+(OCaml)|(Haskell)|(Scheme)|(Toplevel))|(Library)|((No)?Inline)|(Blacklist))?</keyword> <keyword>Extract\%{space}+(Inlined\%{space}+)?(Constant)|(Inductive)</keyword> <include> <context sub-pattern="1" style-ref="vernac-keyword"/> diff --git a/ide/coq.lang b/ide/coq.lang index 484264ec..e9eab48d 100644 --- a/ide/coq.lang +++ b/ide/coq.lang @@ -188,7 +188,7 @@ <keyword>(\%{locality}|(Reserved|Tactic)\%{space})?Notation</keyword> <keyword>\%{locality}Infix</keyword> <keyword>Declare\%{space}ML\%{space}Module</keyword> - <keyword>Extraction\%{space}Language\%{space}(Ocaml|Haskell|Scheme|JSON)</keyword> + <keyword>Extraction\%{space}Language\%{space}(OCaml|Haskell|Scheme|JSON)</keyword> </context> <context id="hint-command" style-ref="vernac-keyword"> @@ -1,14 +1,18 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) open Ideutils open Preferences +let ideslave_coqtop_flags = ref None + (** * Version and date *) let get_version_date () = @@ -205,7 +209,7 @@ type handle = { proc : CoqTop.process; xml_oc : Xml_printer.t; mutable alive : bool; - mutable waiting_for : (ccb * logger) option; (* last call + callback + log *) + mutable waiting_for : ccb option; (* last call + callback *) } (** Coqtop process status : @@ -290,18 +294,6 @@ let rec check_errors = function | `NVAL :: _ -> raise (TubeError "NVAL") | `OUT :: _ -> raise (TubeError "OUT") -let handle_intermediate_message handle level content = - let logger = match handle.waiting_for with - | Some (_, l) -> l - | None -> function - | Feedback.Error -> fun s -> Minilib.log ~level:`ERROR (xml_to_string s) - | Feedback.Info -> fun s -> Minilib.log ~level:`INFO (xml_to_string s) - | Feedback.Notice -> fun s -> Minilib.log ~level:`NOTICE (xml_to_string s) - | Feedback.Warning -> fun s -> Minilib.log ~level:`WARNING (xml_to_string s) - | Feedback.Debug -> fun s -> Minilib.log ~level:`DEBUG (xml_to_string s) - in - logger level content - let handle_feedback feedback_processor xml = let feedback = Xmlprotocol.to_feedback xml in feedback_processor feedback @@ -310,7 +302,7 @@ let handle_final_answer handle xml = let () = Minilib.log "Handling coqtop answer" in let ccb = match handle.waiting_for with | None -> raise (AnswerWithoutRequest (Xml_printer.to_string_fmt xml)) - | Some (c, _) -> c in + | Some c -> c in let () = handle.waiting_for <- None in with_ccb ccb { bind_ccb = fun (c, f) -> f (Xmlprotocol.to_answer c xml) } @@ -332,18 +324,13 @@ let unsafe_handle_input handle feedback_processor state conds ~read_all = let l_end = Lexing.lexeme_end lex in state.fragment <- String.sub s l_end (String.length s - l_end); state.lexerror <- None; - match Xmlprotocol.is_message xml with - | Some (lvl, _loc, msg) -> - handle_intermediate_message handle lvl msg; + if Xmlprotocol.is_feedback xml then begin + handle_feedback feedback_processor xml; loop () - | None -> - if Xmlprotocol.is_feedback xml then begin - handle_feedback feedback_processor xml; - loop () - end else - begin - ignore (handle_final_answer handle xml) - end + end else + begin + ignore (handle_final_answer handle xml) + end in try loop () with Xml_parser.Error _ as e -> @@ -383,9 +370,16 @@ let bind_self_as f = (** This launches a fresh handle from its command line arguments. *) let spawn_handle args respawner feedback_processor = let prog = coqtop_path () in - let args = Array.of_list ("-async-proofs" :: "on" :: "-ideslave" :: args) in + let async_default = + (* disable async processing by default in Windows *) + if List.mem Sys.os_type ["Win32"; "Cygwin"] then + "off" + else + "on" + in + let args = Array.of_list ("--xml_format=Ppcmds" :: "-async-proofs" :: async_default :: "-ideslave" :: args) in let env = - match !Flags.ideslave_coqtop_flags with + match !ideslave_coqtop_flags with | None -> None | Some s -> let open Str in @@ -420,8 +414,19 @@ let clear_handle h = let mkready coqtop = fun () -> coqtop.status <- Ready; Void +let save_all = ref (fun () -> assert false) + let rec respawn_coqtop ?(why=Unexpected) coqtop = - if why = Unexpected then warning "Coqtop died badly. Resetting."; + let () = match why with + | Unexpected -> + let title = "Warning" in + let icon = (warn_image ())#coerce in + let buttons = ["Reset"; "Save all and quit"; "Quit without saving"] in + let ans = GToolbox.question_box ~title ~buttons ~icon "Coqtop died badly." in + if ans = 2 then (!save_all (); GtkMain.Main.quit ()) + else if ans = 3 then GtkMain.Main.quit () + | Planned -> () + in clear_handle coqtop.handle; ignore_error (fun () -> coqtop.handle <- @@ -493,20 +498,20 @@ let init_coqtop coqtop task = type 'a query = 'a Interface.value task -let eval_call ?(logger=default_logger) call handle k = +let eval_call call handle k = (** Send messages to coqtop and prepare the decoding of the answer *) Minilib.log ("Start eval_call " ^ Xmlprotocol.pr_call call); assert (handle.alive && handle.waiting_for = None); - handle.waiting_for <- Some (mk_ccb (call,k), logger); + handle.waiting_for <- Some (mk_ccb (call,k)); Xml_printer.print handle.xml_oc (Xmlprotocol.of_call call); Minilib.log "End eval_call"; Void -let add ?(logger=default_logger) x = eval_call ~logger (Xmlprotocol.add x) +let add x = eval_call (Xmlprotocol.add x) let edit_at i = eval_call (Xmlprotocol.edit_at i) -let query ?(logger=default_logger) x = eval_call ~logger (Xmlprotocol.query x) +let query x = eval_call (Xmlprotocol.query x) let mkcases s = eval_call (Xmlprotocol.mkcases s) -let status ?logger force = eval_call ?logger (Xmlprotocol.status force) +let status force = eval_call (Xmlprotocol.status force) let hints x = eval_call (Xmlprotocol.hints x) let search flags = eval_call (Xmlprotocol.search flags) let init x = eval_call (Xmlprotocol.init x) @@ -536,6 +541,7 @@ struct let all_basic = ["Printing"; "All"] let existential = ["Printing"; "Existential"; "Instances"] let universes = ["Printing"; "Universes"] + let unfocused = ["Printing"; "Unfocused"] type bool_descr = { opts : t list; init : bool; label : string } @@ -551,7 +557,8 @@ struct label = "Display _existential variable instances" }; { opts = [universes]; init = false; label = "Display _universe levels" }; { opts = [all_basic;existential;universes]; init = false; - label = "Display all _low-level contents" } + label = "Display all _low-level contents" }; + { opts = [unfocused]; init = false; label = "Display _unfocused goals" } ] (** The current status of the boolean options *) @@ -566,18 +573,13 @@ struct let _ = reset () - (** Integer option *) - - let width = ["Printing"; "Width"] - let width_state = ref None - let set_printing_width w = width_state := Some w + let printing_unfocused () = Hashtbl.find current_state unfocused (** Transmitting options to coqtop *) let enforce h k = let mkopt o v acc = (o, Interface.BoolValue v) :: acc in let opts = Hashtbl.fold mkopt current_state [] in - let opts = (width, Interface.IntValue !width_state) :: opts in eval_call (Xmlprotocol.set_options opts) h (function | Interface.Good () -> k () @@ -585,8 +587,8 @@ struct end -let goals ?logger x h k = - PrintOpt.enforce h (fun () -> eval_call ?logger (Xmlprotocol.goals x) h k) +let goals x h k = + PrintOpt.enforce h (fun () -> eval_call (Xmlprotocol.goals x) h k) let evars x h k = PrintOpt.enforce h (fun () -> eval_call (Xmlprotocol.evars x) h k) diff --git a/ide/coq.mli b/ide/coq.mli index 8a1fa3ed..40a6dea8 100644 --- a/ide/coq.mli +++ b/ide/coq.mli @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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 : Interaction with the Coq toplevel *) @@ -115,15 +117,11 @@ val try_grab : coqtop -> unit task -> (unit -> unit) -> unit type 'a query = 'a Interface.value task (** A type abbreviation for coqtop specific answers *) -val add : ?logger:Ideutils.logger -> - Interface.add_sty -> Interface.add_rty query +val add : Interface.add_sty -> Interface.add_rty query val edit_at : Interface.edit_at_sty -> Interface.edit_at_rty query -val query : ?logger:Ideutils.logger -> - Interface.query_sty -> Interface.query_rty query -val status : ?logger:Ideutils.logger -> - Interface.status_sty -> Interface.status_rty query -val goals : ?logger:Ideutils.logger -> - Interface.goals_sty -> Interface.goals_rty query +val query : Interface.query_sty -> Interface.query_rty query +val status : Interface.status_sty -> Interface.status_rty query +val goals : Interface.goals_sty -> Interface.goals_rty query val evars : Interface.evars_sty -> Interface.evars_rty query val hints : Interface.hints_sty -> Interface.hints_rty query val mkcases : Interface.mkcases_sty -> Interface.mkcases_rty query @@ -143,7 +141,8 @@ sig val bool_items : bool_descr list val set : t -> bool -> unit - val set_printing_width : int -> unit + + val printing_unfocused: unit -> bool (** [enforce] transmits to coq the current option values. It is also called by [goals] and [evars] above. *) @@ -173,3 +172,7 @@ val check_connection : string list -> unit may terminate coqide in case of trouble *) val interrupter : (int -> unit) ref +val save_all : (unit -> unit) ref + +(* Flags to be used for ideslave *) +val ideslave_coqtop_flags : string option ref diff --git a/ide/coqOps.ml b/ide/coqOps.ml index 1563c7ff..6c3438a4 100644 --- a/ide/coqOps.ml +++ b/ide/coqOps.ml @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) open Util @@ -14,7 +16,7 @@ open Feedback let b2c = byte_offset_to_char_offset -type flag = [ `INCOMPLETE | `UNSAFE | `PROCESSING | `ERROR of Loc.t * string | `WARNING of Loc.t * string ] +type flag = [ `INCOMPLETE | `UNSAFE | `PROCESSING | `ERROR of string Loc.located | `WARNING of string Loc.located ] type mem_flag = [ `INCOMPLETE | `UNSAFE | `PROCESSING | `ERROR | `WARNING ] let mem_flag_of_flag : flag -> mem_flag = function | `ERROR _ -> `ERROR @@ -58,7 +60,7 @@ module SentenceId : sig val connect : sentence -> signals val dbg_to_string : - GText.buffer -> bool -> Stateid.t option -> sentence -> Pp.std_ppcmds + GText.buffer -> bool -> Stateid.t option -> sentence -> Pp.t end = struct @@ -117,7 +119,7 @@ end = struct (b#get_iter_at_mark s.start)#offset (b#get_iter_at_mark s.stop)#offset (ellipsize - ((b#get_iter_at_mark s.start)#get_slice (b#get_iter_at_mark s.stop))) + ((b#get_iter_at_mark s.start)#get_slice ~stop:(b#get_iter_at_mark s.stop))) (String.concat "," (List.map str_of_flag s.flags)) (ellipsize (String.concat "," @@ -139,7 +141,8 @@ object method process_next_phrase : unit task method process_until_end_or_error : unit task method handle_reset_initial : unit task - method raw_coq_query : string -> unit task + method raw_coq_query : + route_id:int -> next:(query_rty value -> unit task) -> string -> unit task method show_goals : unit task method backtrack_last_phrase : unit task method initialize : unit task @@ -162,14 +165,6 @@ let flags_to_color f = else if List.mem `INCOMPLETE f then `NAME "gray" else `NAME Preferences.processed_color#get -let validate s = - let open Xml_datatype in - let rec validate = function - | PCData s -> Glib.Utf8.validate s - | Element (_, _, children) -> List.for_all validate children - in - validate (Richpp.repr s) - module Doc = Document let segment_model (doc : sentence Doc.document) : Wg_Segment.model = @@ -201,7 +196,7 @@ object (self) in List.iter (fun s -> set_index s (s.index + 1)) after; set_index s (document_length - List.length after); - ignore ((SentenceId.connect s)#changed self#on_changed); + ignore ((SentenceId.connect s)#changed ~callback:self#on_changed); document_length <- document_length + 1; List.iter (fun f -> f `INSERT) cbs @@ -215,8 +210,8 @@ object (self) List.iter (fun f -> f `REMOVE) cbs initializer - let _ = (Doc.connect doc)#pushed self#on_push in - let _ = (Doc.connect doc)#popped self#on_pop in + let _ = (Doc.connect doc)#pushed ~callback:self#on_push in + let _ = (Doc.connect doc)#popped ~callback:self#on_pop in () end @@ -224,7 +219,7 @@ end class coqops (_script:Wg_ScriptView.script_view) (_pv:Wg_ProofView.proof_view) - (_mv:Wg_MessageView.message_view) + (_mv:Wg_RoutedMessageViews.message_views_router) (_sg:Wg_Segment.segment) (_ct:Coq.coqtop) get_filename = @@ -267,15 +262,15 @@ object(self) else iter in let iter = sentence_start iter in - script#buffer#place_cursor iter; + script#buffer#place_cursor ~where:iter; ignore (script#scroll_to_iter ~use_align:true ~yalign:0. iter) in - let _ = segment#connect#clicked on_click in + let _ = segment#connect#clicked ~callback:on_click in () method private tooltip_callback ~x ~y ~kbd tooltip = - let x, y = script#window_to_buffer_coords `WIDGET x y in - let iter = script#get_iter_at_location x y in + let x, y = script#window_to_buffer_coords ~tag:`WIDGET ~x ~y in + let iter = script#get_iter_at_location ~x ~y in if iter#has_tag Tags.Script.tooltip then begin let s = let rec aux iter = @@ -305,7 +300,7 @@ object(self) method private print_stack = Minilib.log "document:"; - Minilib.log (Pp.string_of_ppcmds (Doc.print document (dbg_to_string buffer))) + Minilib.log_pp (Doc.print document (dbg_to_string buffer)) method private enter_focus start stop = let at id id' _ = Stateid.equal id' id in @@ -337,7 +332,6 @@ object(self) buffer#get_iter_at_mark `INSERT method private show_goals_aux ?(move_insert=false) () = - Coq.PrintOpt.set_printing_width proof#width; if move_insert then begin let dest = self#get_start_of_input in if (buffer#get_iter_at_mark `INSERT)#compare dest <= 0 then begin @@ -345,7 +339,7 @@ object(self) script#recenter_insert end end; - Coq.bind (Coq.goals ~logger:messages#push ()) (function + Coq.bind (Coq.goals ()) (function | Fail x -> self#handle_failure_aux ~move_insert x | Good goals -> Coq.bind (Coq.evars ()) (function @@ -353,32 +347,28 @@ object(self) | Good evs -> proof#set_goals goals; proof#set_evars evs; - proof#refresh (); + proof#refresh ~force:true; Coq.return () ) ) method show_goals = self#show_goals_aux () (* This method is intended to perform stateless commands *) - method raw_coq_query phrase = - let action = log "raw_coq_query starting now" in - let display_error s = - if not (validate s) then - flash_info "This error is so nasty that I can't even display it." - else messages#add s; - in - let query = - Coq.query ~logger:messages#push (phrase,Stateid.dummy) in - let next = function - | Fail (_, _, err) -> display_error err; Coq.return () - | Good msg -> - messages#add_string msg; Coq.return () + method raw_coq_query ~route_id ~next phrase : unit Coq.task = + let sid = try Document.tip document + with Document.Empty -> Stateid.initial in + let action = log "raw_coq_query starting now" in + let query = Coq.query (route_id,(phrase,sid)) in Coq.bind (Coq.seq action query) next + method private still_valid { edit_id = id } = + try ignore(Doc.find_id document (fun _ { edit_id = id1 } -> id = id1)); true + with Not_found -> false + method private mark_as_needed sentence = - Minilib.log("Marking " ^ - Pp.string_of_ppcmds (dbg_to_string buffer false None sentence)); + if self#still_valid sentence then begin + Minilib.log_pp Pp.(str "Marking " ++ dbg_to_string buffer false None sentence); let start = buffer#get_iter_at_mark sentence.start in let stop = buffer#get_iter_at_mark sentence.stop in let to_process = Tags.Script.to_process in @@ -398,11 +388,11 @@ object(self) in List.iter (fun t -> buffer#remove_tag t ~start ~stop) all_tags; List.iter (fun t -> buffer#apply_tag t ~start ~stop) tags + end - method private attach_tooltip sentence loc text = + method private attach_tooltip ?loc sentence text = let start_sentence, stop_sentence, phrase = self#get_sentence sentence in - let pre_chars, post_chars = - if Loc.is_ghost loc then 0, String.length phrase else Loc.unloc loc in + let pre_chars, post_chars = Option.cata Loc.unloc (0, String.length phrase) loc in let pre = b2c phrase pre_chars in let post = b2c phrase post_chars in let start = start_sentence#forward_chars pre in @@ -411,95 +401,93 @@ object(self) buffer#apply_tag Tags.Script.tooltip ~start ~stop; add_tooltip sentence pre post markup - method private is_dummy_id id = - match id with - | Edit 0 -> true - | State id when Stateid.equal id Stateid.dummy -> true - | _ -> false - method private enqueue_feedback msg = - let id = msg.id in - if self#is_dummy_id id then () else Queue.add msg feedbacks - + (* Minilib.log ("Feedback received: " ^ Xml_printer.to_string_fmt Xmlprotocol.(of_feedback Ppcmds msg)); *) + Queue.add msg feedbacks + method private process_feedback () = let rec eat_feedback n = if n = 0 then true else let msg = Queue.pop feedbacks in - let id = msg.id in + let id = msg.span_id in let sentence = let finder _ state_id s = match state_id, id with - | Some id', State id when Stateid.equal id id' -> Some (state_id, s) - | _, Edit id when id = s.edit_id -> Some (state_id, s) + | Some id', id when Stateid.equal id id' -> Some (state_id, s) | _ -> None in try Some (Doc.find_map document finder) with Not_found -> None in - let log s state_id = - Minilib.log ("Feedback " ^ s ^ " on " ^ Stateid.to_string - (Option.default Stateid.dummy state_id)) in + let log_pp ?id s= + Minilib.log_pp Pp.(seq + [str "Feedback "; s; pr_opt (fun id -> str " on " ++ str (Stateid.to_string id)) id]) + in + let log ?id s = log_pp ?id (Pp.str s) in begin match msg.contents, sentence with | AddedAxiom, Some (id,sentence) -> - log "AddedAxiom" id; + log ?id "AddedAxiom"; remove_flag sentence `PROCESSING; remove_flag sentence `ERROR; add_flag sentence `UNSAFE; self#mark_as_needed sentence | Processed, Some (id,sentence) -> - log "Processed" id; + log ?id "Processed" ; remove_flag sentence `PROCESSING; self#mark_as_needed sentence | ProcessingIn _, Some (id,sentence) -> - log "ProcessingIn" id; + log ?id "ProcessingIn"; add_flag sentence `PROCESSING; self#mark_as_needed sentence | Incomplete, Some (id, sentence) -> - log "Incomplete" id; + log ?id "Incomplete"; add_flag sentence `INCOMPLETE; self#mark_as_needed sentence | Complete, Some (id, sentence) -> - log "Complete" id; + log ?id "Complete"; remove_flag sentence `INCOMPLETE; self#mark_as_needed sentence | GlobRef(loc, filepath, modpath, ident, ty), Some (id,sentence) -> - log "GlobRef" id; - self#attach_tooltip sentence loc + log ?id "GlobRef"; + self#attach_tooltip ~loc sentence (Printf.sprintf "%s %s %s" filepath ident ty) | Message(Error, loc, msg), Some (id,sentence) -> - let loc = Option.default Loc.ghost loc in - let msg = Richpp.raw_print msg in - log "ErrorMsg" id; + log_pp ?id Pp.(str "ErrorMsg " ++ msg); remove_flag sentence `PROCESSING; - add_flag sentence (`ERROR (loc, msg)); + let rmsg = Pp.string_of_ppcmds msg in + add_flag sentence (`ERROR (loc, rmsg)); self#mark_as_needed sentence; - self#attach_tooltip sentence loc msg; - if not (Loc.is_ghost loc) then - self#position_error_tag_at_sentence sentence (Some (Loc.unloc loc)) - | Message(Warning, loc, msg), Some (id,sentence) -> - let loc = Option.default Loc.ghost loc in - let msg = Richpp.raw_print msg in - log "WarningMsg" id; - add_flag sentence (`WARNING (loc, msg)); - self#attach_tooltip sentence loc msg; - self#position_warning_tag_at_sentence sentence loc - | Message((Info|Notice|Debug as lvl), _, msg), _ -> - messages#push lvl msg + self#attach_tooltip ?loc sentence rmsg; + self#position_tag_at_sentence ?loc Tags.Script.error sentence + | Message(Warning, loc, message), Some (id,sentence) -> + log_pp ?id Pp.(str "WarningMsg " ++ message); + let rmsg = Pp.string_of_ppcmds message in + add_flag sentence (`WARNING (loc, rmsg)); + self#attach_tooltip ?loc sentence rmsg; + self#position_tag_at_sentence ?loc Tags.Script.warning sentence; + (messages#route msg.route)#push Warning message + | Message(lvl, loc, message), Some (id,sentence) -> + log_pp ?id Pp.(str "Msg " ++ message); + (messages#route msg.route)#push lvl message + (* We do nothing here as for BZ#5583 *) + | Message(Error, loc, msg), None -> + log_pp Pp.(str "Error Msg without a sentence" ++ msg) + | Message(lvl, loc, message), None -> + log_pp Pp.(str "Msg without a sentence " ++ message); + (messages#route msg.route)#push lvl message | InProgress n, _ -> if n < 0 then processed <- processed + abs n else to_process <- to_process + n | WorkerStatus(id,status), _ -> - log "WorkerStatus" None; + log "WorkerStatus"; slaves_status <- CString.Map.add id status slaves_status - | _ -> if sentence <> None then Minilib.log "Unsupported feedback message" else if Doc.is_empty document then () else try match id, Doc.tip document with - | Edit _, _ -> () - | State id1, id2 when Stateid.newer_than id2 id1 -> () + | id1, id2 when Stateid.newer_than id2 id1 -> () | _ -> Queue.add msg feedbacks - with Doc.Empty | Invalid_argument _ -> Queue.add msg feedbacks + with Doc.Empty | Invalid_argument _ -> Queue.add msg feedbacks end; eat_feedback (n-1) in @@ -513,40 +501,30 @@ object(self) let stop = buffer#get_iter_at_mark sentence.stop in buffer#move_mark ~where:stop (`NAME "start_of_input"); - method private position_error_tag_at_iter iter phrase = function - | None -> () - | Some (start, stop) -> - buffer#apply_tag Tags.Script.error - ~start:(iter#forward_chars (b2c phrase start)) - ~stop:(iter#forward_chars (b2c phrase stop)) - - method private position_error_tag_at_sentence sentence loc = - let start, _, phrase = self#get_sentence sentence in - self#position_error_tag_at_iter start phrase loc - - method private position_warning_tag_at_iter iter_start iter_stop phrase loc = - if Loc.is_ghost loc then - buffer#apply_tag Tags.Script.warning ~start:iter_start ~stop:iter_stop - else - buffer#apply_tag Tags.Script.warning - ~start:(iter_start#forward_chars (b2c phrase loc.Loc.bp)) - ~stop:(iter_stop#forward_chars (b2c phrase loc.Loc.ep)) + method private position_tag_at_iter ?loc iter_start iter_stop tag phrase = match loc with + | None -> + buffer#apply_tag tag ~start:iter_start ~stop:iter_stop + | Some loc -> + let start, stop = Loc.unloc loc in + buffer#apply_tag tag + ~start:(iter_start#forward_chars (b2c phrase start)) + ~stop:(iter_start#forward_chars (b2c phrase stop)) - method private position_warning_tag_at_sentence sentence loc = + method private position_tag_at_sentence ?loc tag sentence = let start, stop, phrase = self#get_sentence sentence in - self#position_warning_tag_at_iter start stop phrase loc + self#position_tag_at_iter ?loc start stop tag phrase - method private process_interp_error queue sentence loc msg tip id = + method private process_interp_error ?loc queue sentence msg tip id = Coq.bind (Coq.return ()) (function () -> let start, stop, phrase = self#get_sentence sentence in buffer#remove_tag Tags.Script.to_process ~start ~stop; self#discard_command_queue queue; pop_info (); if Stateid.equal id tip || Stateid.equal id Stateid.dummy then begin - self#position_error_tag_at_iter start phrase loc; + self#position_tag_at_iter ?loc start stop Tags.Script.error phrase; buffer#place_cursor ~where:stop; - messages#clear; - messages#push Feedback.Error msg; + messages#default_route#clear; + messages#default_route#push Feedback.Error msg; self#show_goals end else self#show_goals_aux ~move_insert:true () @@ -604,12 +582,12 @@ object(self) (** Compute the phrases until [until] returns [true]. *) method private process_until ?move_insert until verbose = - let logger lvl msg = if verbose then messages#push lvl msg in + let logger lvl msg = if verbose then messages#default_route#push lvl msg in let fill_queue = Coq.lift (fun () -> let queue = Queue.create () in (* Lock everything and fill the waiting queue *) push_info "Coq is computing"; - messages#clear; + messages#default_route#clear; script#set_editable false; self#fill_command_queue until queue; (* Now unlock and process asynchronously. Since [until] @@ -628,10 +606,9 @@ object(self) if Queue.is_empty queue then conclude topstack else match Queue.pop queue, topstack with | `Skip(start,stop), [] -> - - logger Feedback.Error (Richpp.richpp_of_string "You must close the proof with Qed or Admitted"); + logger Feedback.Error (Pp.str "You must close the proof with Qed or Admitted"); self#discard_command_queue queue; - conclude [] + conclude [] | `Skip(start,stop), (_,s) :: topstack -> assert(start#equal (buffer#get_iter_at_mark s.start)); assert(stop#equal (buffer#get_iter_at_mark s.stop)); @@ -641,11 +618,11 @@ object(self) add_flag sentence `PROCESSING; Doc.push document sentence; let _, _, phrase = self#get_sentence sentence in - let coq_query = Coq.add ~logger ((phrase,edit_id),(tip,verbose)) in + let coq_query = Coq.add ((phrase,edit_id),(tip,verbose)) in let handle_answer = function | Good (id, (Util.Inl (* NewTip *) (), msg)) -> Doc.assign_tip_id document id; - logger Feedback.Notice (Richpp.richpp_of_string msg); + logger Feedback.Notice (Pp.str msg); self#commit_queue_transaction sentence; loop id [] | Good (id, (Util.Inr (* Unfocus *) tip, msg)) -> @@ -653,13 +630,14 @@ object(self) let topstack, _ = Doc.context document in self#exit_focus; self#cleanup (Doc.cut_at document tip); - logger Feedback.Notice (Richpp.richpp_of_string msg); + logger Feedback.Notice (Pp.str msg); self#mark_as_needed sentence; if Queue.is_empty queue then loop tip [] else loop tip (List.rev topstack) | Fail (id, loc, msg) -> + let loc = Option.map Loc.make_loc loc in let sentence = Doc.pop document in - self#process_interp_error queue sentence loc msg tip id in + self#process_interp_error ?loc queue sentence msg tip id in Coq.bind coq_query handle_answer in let tip = @@ -667,15 +645,16 @@ object(self) with Doc.Empty -> initial_state | Invalid_argument _ -> assert false in loop tip [] in Coq.bind fill_queue process_queue - + method join_document = let next = function | Good _ -> - messages#clear; - messages#push Feedback.Info (Richpp.richpp_of_string "All proof terms checked by the kernel"); + messages#default_route#clear; + messages#default_route#push + Feedback.Info (Pp.str "All proof terms checked by the kernel"); Coq.return () | Fail x -> self#handle_failure x in - Coq.bind (Coq.status ~logger:messages#push true) next + Coq.bind (Coq.status true) next method stop_worker n = Coq.bind (Coq.stop_worker n) (fun _ -> Coq.return ()) @@ -689,14 +668,13 @@ object(self) let extract_error s = match List.find (function `ERROR _ -> true | _ -> false) s.flags with | `ERROR (loc, msg) -> - let iter = - if Loc.is_ghost loc then - buffer#get_iter_at_mark s.start - else + let iter = begin match loc with + | None -> buffer#get_iter_at_mark s.start + | Some loc -> let (iter, _, phrase) = self#get_sentence s in let (start, _) = Loc.unloc loc in - iter#forward_chars (b2c phrase start) in - iter#line + 1, msg + iter#forward_chars (b2c phrase start) + end in iter#line + 1, msg | _ -> assert false in List.rev (Doc.fold_all document [] (fun acc _ _ s -> @@ -775,7 +753,7 @@ object(self) conclusion () | Fail (safe_id, loc, msg) -> (* if loc <> None then messages#push Feedback.Error (Richpp.richpp_of_string "Fixme LOC"); *) - messages#push Feedback.Error msg; + messages#default_route#push Feedback.Error msg; if Stateid.equal safe_id Stateid.dummy then self#show_goals else undo safe_id (Doc.focused document && Doc.is_in_focus document safe_id)) @@ -792,7 +770,7 @@ object(self) method private handle_failure_aux ?(move_insert=false) (safe_id, (loc : (int * int) option), msg) = - messages#push Feedback.Error msg; + messages#default_route#push Feedback.Error msg; ignore(self#process_feedback ()); if Stateid.equal safe_id Stateid.dummy then Coq.lift (fun () -> ()) else @@ -804,7 +782,7 @@ object(self) method handle_failure f = self#handle_failure_aux f method backtrack_last_phrase = - messages#clear; + messages#default_route#clear; try let tgt = Doc.before_tip document in self#backtrack_to_id tgt @@ -812,7 +790,7 @@ object(self) method go_to_insert = Coq.bind (Coq.return ()) (fun () -> - messages#clear; + messages#default_route#clear; let point = self#get_insert in if point#compare self#get_start_of_input >= 0 then self#process_until_iter point @@ -820,7 +798,7 @@ object(self) method go_to_mark m = Coq.bind (Coq.return ()) (fun () -> - messages#clear; + messages#default_route#clear; let point = buffer#get_iter_at_mark m in if point#compare self#get_start_of_input >= 0 then Coq.seq (self#process_until_iter point) @@ -845,25 +823,21 @@ object(self) ~stop:(`MARK (buffer#create_mark stop)) [] in Doc.push document sentence; - messages#clear; + messages#default_route#clear; self#show_goals in let display_error (loc, s) = - if not (validate s) then - flash_info "This error is so nasty that I can't even display it." - else messages#add s - in + messages#default_route#add (Ideutils.validate s) in let try_phrase phrase stop more = let action = log "Sending to coq now" in - let query = Coq.query (phrase,Stateid.dummy) in + let route_id = 0 in + let query = Coq.query (route_id,(phrase,Stateid.dummy)) in let next = function | Fail (_, l, str) -> (* FIXME: check *) display_error (l, str); - messages#add (Richpp.richpp_of_string ("Unsuccessfully tried: "^phrase)); + messages#default_route#add (Pp.str ("Unsuccessfully tried: "^phrase)); more - | Good msg -> - messages#add_string msg; - stop Tags.Script.processed + | Good () -> stop Tags.Script.processed in Coq.bind (Coq.seq action query) next in @@ -891,7 +865,7 @@ object(self) buffer#move_mark ~where:buffer#end_iter (`NAME "stop_of_input"); Sentence.tag_all buffer; (* clear the views *) - messages#clear; + messages#default_route#clear; proof#clear (); clear_info (); processed <- 0; @@ -905,7 +879,7 @@ object(self) let get_initial_state = let next = function | Fail (_, _, message) -> - let message = "Couldn't initialize coqtop\n\n" ^ (Richpp.raw_print message) in + let message = "Couldn't initialize coqtop\n\n" ^ (Pp.string_of_ppcmds message) in let popup = GWindow.message_dialog ~buttons:GWindow.Buttons.ok ~message_type:`ERROR ~message () in ignore (popup#run ()); exit 1 | Good id -> initial_state <- id; Coq.return () in diff --git a/ide/coqOps.mli b/ide/coqOps.mli index 332c18f2..3685fea9 100644 --- a/ide/coqOps.mli +++ b/ide/coqOps.mli @@ -1,12 +1,15 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) open Coq +open Interface class type ops = object @@ -16,7 +19,8 @@ object method process_next_phrase : unit task method process_until_end_or_error : unit task method handle_reset_initial : unit task - method raw_coq_query : string -> unit task + method raw_coq_query : + route_id:int -> next:(query_rty value -> unit task) -> string -> unit task method show_goals : unit task method backtrack_last_phrase : unit task method initialize : unit task @@ -28,7 +32,7 @@ object method get_slaves_status : int * int * string CString.Map.t - method handle_failure : Interface.handle_exn_rty -> unit task + method handle_failure : handle_exn_rty -> unit task method destroy : unit -> unit end @@ -36,7 +40,7 @@ end class coqops : Wg_ScriptView.script_view -> Wg_ProofView.proof_view -> - Wg_MessageView.message_view -> + Wg_RoutedMessageViews.message_views_router -> Wg_Segment.segment -> coqtop -> (unit -> string option) -> diff --git a/ide/coq_commands.ml b/ide/coq_commands.ml index d55e7f9d..f5dba208 100644 --- a/ide/coq_commands.ml +++ b/ide/coq_commands.ml @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) let commands = [ @@ -105,8 +107,7 @@ let commands = [ "Reset Extraction Inline"; "Restore State"; ]; - [ "Save."; - "Scheme"; + [ "Scheme"; "Section"; "Set Extraction AutoInline"; "Set Extraction Optimize"; diff --git a/ide/coq_commands.mli b/ide/coq_commands.mli new file mode 100644 index 00000000..259d790e --- /dev/null +++ b/ide/coq_commands.mli @@ -0,0 +1,13 @@ +(************************************************************************) +(* * 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) *) +(************************************************************************) + +val tactics : string list list +val commands : string list list +val state_preserving : string list diff --git a/ide/coq_lex.mli b/ide/coq_lex.mli new file mode 100644 index 00000000..10041193 --- /dev/null +++ b/ide/coq_lex.mli @@ -0,0 +1,13 @@ +(************************************************************************) +(* * 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) *) +(************************************************************************) + +val delimit_sentences : (int -> GText.tag -> unit) -> string -> unit + +exception Unterminated diff --git a/ide/coq_lex.mll b/ide/coq_lex.mll index b6286c49..1fdd7317 100644 --- a/ide/coq_lex.mll +++ b/ide/coq_lex.mll @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) { @@ -17,7 +19,13 @@ let space = [' ' '\n' '\r' '\t' '\012'] (* '\012' is form-feed *) -let undotted_sep = '{' | '}' | '-'+ | '+'+ | '*'+ +let number = [ '0'-'9' ]+ + +let string = "\"" _+ "\"" + +let undotted_sep = (number space* ':' space*)? '{' | '}' | '-'+ | '+'+ | '*'+ + +let vernac_control = "Fail" | "Time" | "Redirect" space+ string | "Timeout" space+ number let dot_sep = '.' (space | eof) @@ -65,7 +73,7 @@ and sentence initial stamp = parse stamp (utf8_lexeme_start lexbuf) Tags.Script.sentence; sentence true stamp lexbuf } - | undotted_sep { + | (vernac_control space+)* undotted_sep { (* Separators like { or } and bullets * - + are only active at the start of a sentence *) if initial then stamp (utf8_lexeme_start lexbuf + String.length (Lexing.lexeme lexbuf) - 1) Tags.Script.sentence; diff --git a/ide/coqide.ml b/ide/coqide.ml index 450bfcdf..f5ff0899 100644 --- a/ide/coqide.ml +++ b/ide/coqide.ml @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) open Preferences @@ -46,7 +48,7 @@ open Session (** The arguments that will be passed to coqtop. No quoting here, since no /bin/sh when using create_process instead of open_process. *) -let custom_project_files = ref [] +let custom_project_file = ref None let sup_args = ref [] let logfile = ref None @@ -81,17 +83,27 @@ let pr_exit_status = function | Unix.WEXITED 0 -> " succeeded" | _ -> " failed" -let make_coqtop_args = function - |None -> "", !sup_args - |Some the_file -> - let get_args f = Project_file.args_from_project f - !custom_project_files project_file_name#get - in - match read_project#get with - |Ignore_args -> "", !sup_args - |Append_args -> - let fname, args = get_args the_file in fname, args @ !sup_args - |Subst_args -> get_args the_file +let make_coqtop_args fname = + let open CoqProject_file in + let base_args = match read_project#get with + | Ignore_args -> !sup_args + | Append_args -> !sup_args + | Subst_args -> [] in + if read_project#get = Ignore_args then "", base_args + else + match !custom_project_file, fname with + | Some (d,proj), _ -> d, coqtop_args_from_project proj @ base_args + | None, None -> "", base_args + | None, Some the_file -> + match + CoqProject_file.find_project_file + ~from:(Filename.dirname the_file) + ~projfile_name:project_file_name#get + with + | None -> "", base_args + | Some proj -> + proj, coqtop_args_from_project (read_project_file proj) @ base_args +;; (** Setting drag & drop on widgets *) @@ -274,6 +286,8 @@ let saveall _ = | Some f -> ignore (sn.fileops#save f)) notebook#pages +let () = Coq.save_all := saveall + let revert_all _ = List.iter (fun sn -> if sn.fileops#changed_on_disk then sn.fileops#revert) @@ -318,10 +332,10 @@ let export kind sn = local_cd f ^ cmd_coqdoc#get ^ " --" ^ kind ^ " -o " ^ (Filename.quote output) ^ " " ^ (Filename.quote basef) ^ " 2>&1" in - sn.messages#set (Richpp.richpp_of_string ("Running: "^cmd)); + sn.messages#default_route#set (Pp.str ("Running: "^cmd)); let finally st = flash_info (cmd ^ pr_exit_status st) in - run_command (fun msg -> sn.messages#add_string msg) finally cmd + run_command (fun msg -> sn.messages#default_route#add_string msg) finally cmd let export kind = cb_on_current_term (export kind) @@ -427,13 +441,15 @@ let compile sn = match sn.fileops#filename with |None -> flash_info "Active buffer has no name" |Some f -> - let cmd = cmd_coqc#get ^ " -I " ^ (Filename.quote (Filename.dirname f)) + let args = Coq.get_arguments sn.coqtop in + let cmd = cmd_coqc#get + ^ " " ^ String.concat " " args ^ " " ^ (Filename.quote f) ^ " 2>&1" in let buf = Buffer.create 1024 in - sn.messages#set (Richpp.richpp_of_string ("Running: "^cmd)); + sn.messages#default_route#set (Pp.str ("Running: "^cmd)); let display s = - sn.messages#add_string s; + sn.messages#default_route#add_string s; Buffer.add_string buf s in let finally st = @@ -441,8 +457,8 @@ let compile sn = flash_info (f ^ " successfully compiled") else begin flash_info (f ^ " failed to compile"); - sn.messages#set (Richpp.richpp_of_string "Compilation output:\n"); - sn.messages#add (Richpp.richpp_of_string (Buffer.contents buf)); + sn.messages#default_route#set (Pp.str "Compilation output:\n"); + sn.messages#default_route#add (Pp.str (Buffer.contents buf)); end in run_command display finally cmd @@ -464,13 +480,13 @@ let make sn = |Some f -> File.saveall (); let cmd = local_cd f ^ cmd_make#get ^ " 2>&1" in - sn.messages#set (Richpp.richpp_of_string "Compilation output:\n"); + sn.messages#default_route#set (Pp.str "Compilation output:\n"); Buffer.reset last_make_buf; last_make := ""; last_make_index := 0; last_make_dir := Filename.dirname f; let display s = - sn.messages#add_string s; + sn.messages#default_route#add_string s; Buffer.add_string last_make_buf s in let finally st = flash_info (cmd_make#get ^ pr_exit_status st) @@ -508,11 +524,11 @@ let next_error sn = let stopi = b#get_iter_at_byte ~line:(line-1) stop in b#apply_tag Tags.Script.error ~start:starti ~stop:stopi; b#place_cursor ~where:starti; - sn.messages#set (Richpp.richpp_of_string error_msg); + sn.messages#default_route#set (Pp.str error_msg); sn.script#misc#grab_focus () with Not_found -> last_make_index := 0; - sn.messages#set (Richpp.richpp_of_string "No more errors.\n") + sn.messages#default_route#set (Pp.str "No more errors.\n") let next_error = cb_on_current_term next_error @@ -536,7 +552,7 @@ let update_status sn = display ("Ready"^ (if nanoPG#get then ", [μPG]" else "") ^ path ^ name); Coq.return () in - Coq.bind (Coq.status ~logger:sn.messages#push false) next + Coq.bind (Coq.status false) next let find_next_occurrence ~backward sn = (** go to the next occurrence of the current word, forward or backward *) @@ -593,16 +609,14 @@ let get_current_word term = (** Then look at the current selected word *) let buf1 = term.script#buffer in let buf2 = term.proof#buffer in - let buf3 = term.messages#buffer in if buf1#has_selection then let (start, stop) = buf1#selection_bounds in buf1#get_text ~slice:true ~start ~stop () else if buf2#has_selection then let (start, stop) = buf2#selection_bounds in buf2#get_text ~slice:true ~start ~stop () - else if buf3#has_selection then - let (start, stop) = buf3#selection_bounds in - buf3#get_text ~slice:true ~start ~stop () + else if term.messages#has_selection then + term.messages#get_selected_text (** Otherwise try to find the word around the cursor *) else let it = term.script#buffer#get_iter_at_mark `INSERT in @@ -652,36 +666,18 @@ let match_callback = cb_on_current_term match_callback module Query = struct -let searchabout sn = - let word = get_current_word sn in - let buf = sn.messages#buffer in - let insert result = - let qualid = result.Interface.coq_object_qualid in - let name = String.concat "." qualid in - let tpe = result.Interface.coq_object_object in - buf#insert ~tags:[Tags.Message.item] name; - buf#insert "\n"; - buf#insert tpe; - buf#insert "\n"; - in - let display_results r = - sn.messages#clear; - List.iter insert (match r with Interface.Good l -> l | _ -> []); - Coq.return () - in - let launch_query = - let search = Coq.search [Interface.SubType_Pattern word, true] in - Coq.bind search display_results - in - Coq.try_grab sn.coqtop launch_query ignore - -let searchabout () = on_current_term searchabout - let doquery query sn = - sn.messages#clear; - Coq.try_grab sn.coqtop (sn.coqops#raw_coq_query query) ignore - -let otherquery command sn = + sn.messages#default_route#clear; + Coq.try_grab sn.coqtop (sn.coqops#raw_coq_query query ~route_id:0 + ~next:(function + | Interface.Fail (_, _, err) -> + let err = Ideutils.validate err in + sn.messages#default_route#add err; + Coq.return () + | Interface.Good () -> Coq.return ())) + ignore + +let queryif command sn = Option.iter (fun query -> doquery (query ^ ".") sn) begin try let i = CString.string_index_from command 0 "..." in @@ -690,12 +686,7 @@ let otherquery command sn = else Some (CString.sub command 0 i ^ " " ^ word) with Not_found -> Some command end -let otherquery command = cb_on_current_term (otherquery command) - -let query command _ = - if command = "Search" || command = "SearchAbout" - then searchabout () - else otherquery command () +let query command _ = cb_on_current_term (queryif command) () end @@ -724,7 +715,7 @@ let initial_about () = else "" in let msg = initial_string ^ version_info ^ log_file_message () in - on_current_term (fun term -> term.messages#add_string msg) + on_current_term (fun term -> term.messages#default_route#add_string msg) let coq_icon () = (* May raise Nof_found *) @@ -788,15 +779,15 @@ let coqtop_arguments sn = | args -> let args = String.concat " " args in let msg = Printf.sprintf "Invalid arguments: %s" args in - let () = sn.messages#clear in - sn.messages#push Feedback.Error (Richpp.richpp_of_string msg) + let () = sn.messages#default_route#clear in + sn.messages#default_route#push Feedback.Error (Pp.str msg) else dialog#destroy () in - let _ = entry#connect#activate ok_cb in - let _ = ok#connect#clicked ok_cb in + let _ = entry#connect#activate ~callback:ok_cb in + let _ = ok#connect#clicked ~callback:ok_cb in let cancel = GButton.button ~stock:`CANCEL ~packing:box#add () in let cancel_cb () = dialog#destroy () in - let _ = cancel#connect#clicked cancel_cb in + let _ = cancel#connect#clicked ~callback:cancel_cb in dialog#show () let coqtop_arguments = cb_on_current_term coqtop_arguments @@ -887,8 +878,8 @@ let alpha_items menu_name item_name l = | [] -> () | [s] -> mk_item s | s::_ as ll -> - let name = item_name^" "^(String.make 1 s.[0]) in - let label = "_@..." in label.[1] <- s.[0]; + let name = Printf.sprintf "%s %c" item_name s.[0] in + let label = Printf.sprintf "_%c..." s.[0] in item name ~label menu_name; List.iter mk_item ll in @@ -1103,8 +1094,8 @@ let build_ui () = menu templates_menu [ item "Templates" ~label:"Te_mplates"; - template_item ("Lemma new_lemma : .\nProof.\n\nSave.\n", 6,9, "J"); - template_item ("Theorem new_theorem : .\nProof.\n\nSave.\n", 8,11, "T"); + template_item ("Lemma new_lemma : .\nProof.\n\nQed.\n", 6,9, "J"); + template_item ("Theorem new_theorem : .\nProof.\n\nQed.\n", 8,11, "T"); template_item ("Definition ident := .\n", 11,5, "E"); template_item ("Inductive ident : :=\n | : .\n", 10,5, "I"); template_item ("Fixpoint ident (_ : _) {struct _} : _ :=\n.\n", 9,5, "F"); @@ -1115,15 +1106,15 @@ let build_ui () = ]; alpha_items templates_menu "Template" Coq_commands.commands; - let qitem s sc ?(dots = true) = - let query = if dots then s ^ "..." else s in + let qitem s sc = + let query = s ^ "..." in item s ~label:("_"^s) ~accel:(modifier_for_queries#get^sc) ~callback:(Query.query query) in menu queries_menu [ item "Queries" ~label:"_Queries"; - qitem "Search" "K" ~dots:false; + qitem "Search" "K"; qitem "Check" "C"; qitem "Print" "P"; qitem "About" "A"; @@ -1161,17 +1152,17 @@ let build_ui () = item "Help" ~label:"_Help"; item "Browse Coq Manual" ~label:"Browse Coq _Manual" ~callback:(fun _ -> - browse notebook#current_term.messages#add_string (doc_url ())); + browse notebook#current_term.messages#default_route#add_string (doc_url ())); item "Browse Coq Library" ~label:"Browse Coq _Library" ~callback:(fun _ -> - browse notebook#current_term.messages#add_string library_url#get); + browse notebook#current_term.messages#default_route#add_string library_url#get); item "Help for keyword" ~label:"Help for _keyword" ~stock:`HELP ~callback:(fun _ -> on_current_term (fun sn -> - browse_keyword sn.messages#add_string (get_current_word sn))); + browse_keyword sn.messages#default_route#add_string (get_current_word sn))); item "Help for μPG mode" ~label:"Help for μPG mode" ~callback:(fun _ -> on_current_term (fun sn -> - sn.messages#clear; - sn.messages#add_string (NanoPG.get_documentation ()))); + sn.messages#default_route#clear; + sn.messages#default_route#add_string (NanoPG.get_documentation ()))); item "About Coq" ~label:"_About" ~stock:`ABOUT ~callback:MiscMenu.about ]; @@ -1207,9 +1198,14 @@ let build_ui () = (* Emacs/PG mode *) NanoPG.init w notebook all_menus; - (* Reset on tab switch *) - let _ = notebook#connect#switch_page ~callback:(fun _ -> - if reset_on_tab_switch#get then Nav.restart ()) + (* On tab switch, reset, update location *) + let _ = notebook#connect#switch_page ~callback:(fun n -> + let _ = if reset_on_tab_switch#get then Nav.restart () in + try + let session = notebook#get_nth_term n in + let ins = session.buffer#get_iter_at_mark `INSERT in + Ideutils.display_location ins + with _ -> ()) in (* Vertical Separator between Scripts and Goals *) @@ -1274,8 +1270,8 @@ let build_ui () = if b then toolbar#misc#show () else toolbar#misc#hide () in stick show_toolbar toolbar refresh_toolbar; - let _ = source_style#connect#changed refresh_style in - let _ = source_language#connect#changed refresh_language in + let _ = source_style#connect#changed ~callback:refresh_style in + let _ = source_language#connect#changed ~callback:refresh_language in (* Color configuration *) Tags.Script.incomplete#set_property @@ -1311,25 +1307,6 @@ let main files = Minilib.log "End of Coqide.main" -(** {2 Geoproof } *) - -(** This function check every tenth of second if GeoProof has send - something on his private clipboard *) - -let check_for_geoproof_input () = - let cb_Dr = GData.clipboard (Gdk.Atom.intern "_GeoProof") in - let handler () = match cb_Dr#text with - |None -> true - |Some "Ack" -> true - |Some s -> - on_current_term (fun sn -> sn.buffer#insert (s ^ "\n")); - (* cb_Dr#clear does not work so i use : *) - cb_Dr#set_text "Ack"; - true - in - ignore (GMain.Timeout.add ~ms:100 ~callback:handler) - - (** {2 Argument parsing } *) (** By default, the coqtop we try to launch is exactly the current coqide @@ -1345,9 +1322,11 @@ let read_coqide_args argv = if coqtop = None then filter_coqtop (Some prog) project_files out args else (output_string stderr "Error: multiple -coqtop options"; exit 1) |"-f" :: file :: args -> + if project_files <> None then + (output_string stderr "Error: multiple -f options"; exit 1); let d = CUnix.canonical_path_name (Filename.dirname file) in - let p = Project_file.read_project_file file in - filter_coqtop coqtop ((d,p) :: project_files) out args + let p = CoqProject_file.read_project_file file in + filter_coqtop coqtop (Some (d,p)) out args |"-f" :: [] -> output_string stderr "Error: missing project file name"; exit 1 |"-coqtop" :: [] -> @@ -1358,17 +1337,17 @@ let read_coqide_args argv = Backtrace.record_backtrace true; filter_coqtop coqtop project_files ("-debug"::out) args |"-coqtop-flags" :: flags :: args-> - Flags.ideslave_coqtop_flags := Some flags; + Coq.ideslave_coqtop_flags := Some flags; filter_coqtop coqtop project_files out args |arg::args when out = [] && Minilib.is_prefix_of "-psn_" arg -> (* argument added by MacOS during .app launch *) filter_coqtop coqtop project_files out args |arg::args -> filter_coqtop coqtop project_files (arg::out) args - |[] -> (coqtop,List.rev project_files,List.rev out) + |[] -> (coqtop,project_files,List.rev out) in - let coqtop,project_files,argv = filter_coqtop None [] [] argv in + let coqtop,project_files,argv = filter_coqtop None None [] argv in Ideutils.custom_coqtop := coqtop; - custom_project_files := project_files; + custom_project_file := project_files; argv diff --git a/ide/coqide.mli b/ide/coqide.mli index 744b974f..03e85453 100644 --- a/ide/coqide.mli +++ b/ide/coqide.mli @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) (** * The CoqIde main module *) @@ -40,5 +42,3 @@ val set_signal_handlers : unit -> unit (** Emergency saving of opened files as "foo.v.crashcoqide", and exit (if the integer isn't 127). *) val crash_save : int -> unit - -val check_for_geoproof_input : unit -> unit diff --git a/ide/coqide_main.ml4 b/ide/coqide_main.ml4 index 534a3f17..3a92e1bc 100644 --- a/ide/coqide_main.ml4 +++ b/ide/coqide_main.ml4 @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) let _ = Coqide.set_signal_handlers () @@ -55,6 +57,8 @@ let os_specific_init () = () (** Win32 *) +IFDEF WIN32 THEN + (* On win32, we add the directory of coqide to the PATH at launch-time (this used to be done in a .bat script). *) @@ -86,7 +90,6 @@ let reroute_stdout_stderr () = (* We also provide specific kill and interrupt functions. *) -IFDEF WIN32 THEN external win32_kill : int -> unit = "win32_kill" external win32_interrupt : int -> unit = "win32_interrupt" let () = @@ -142,7 +145,6 @@ let () = Coq.check_connection args; Coqide.sup_args := args; Coqide.main files; - if !Coq_config.with_geoproof then Coqide.check_for_geoproof_input (); os_specific_init (); try GMain.main (); diff --git a/ide/coqide_main.mli b/ide/coqide_main.mli new file mode 100644 index 00000000..9db9ecd1 --- /dev/null +++ b/ide/coqide_main.mli @@ -0,0 +1,12 @@ +(************************************************************************) +(* * 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) *) +(************************************************************************) + +(* This empty file avoids a race condition that occurs when compiling a .ml file + that does not have a corresponding .mli file *) diff --git a/ide/coqide_ui.ml b/ide/coqide_ui.ml index 2ae18593..717c4000 100644 --- a/ide/coqide_ui.ml +++ b/ide/coqide_ui.ml @@ -28,148 +28,149 @@ let list_queries menu li = res_buf let init () = - let theui = Printf.sprintf "<ui> -<menubar name='CoqIde MenuBar'> - <menu action='File'> - <menuitem action='New' /> - <menuitem action='Open' /> - <menuitem action='Save' /> - <menuitem action='Save as' /> - <menuitem action='Save all' /> - <menuitem action='Revert all buffers' /> - <menuitem action='Close buffer' /> - <menuitem action='Print...' /> - <menu action='Export to'> - <menuitem action='Html' /> - <menuitem action='Latex' /> - <menuitem action='Dvi' /> - <menuitem action='Pdf' /> - <menuitem action='Ps' /> - </menu> - <menuitem action='Rehighlight' /> - %s - </menu> - <menu name='Edit' action='Edit'> - <menuitem action='Undo' /> - <menuitem action='Redo' /> - <separator /> - <menuitem action='Cut' /> - <menuitem action='Copy' /> - <menuitem action='Paste' /> - <separator /> - <menuitem action='Find' /> - <menuitem action='Find Next' /> - <menuitem action='Find Previous' /> - <menuitem action='Complete Word' /> - <separator /> - <menuitem action='External editor' /> - <separator /> - <menuitem name='Prefs' action='Preferences' /> - </menu> - <menu name='View' action='View'> - <menuitem action='Previous tab' /> - <menuitem action='Next tab' /> - <separator/> - <menuitem action='Zoom in' /> - <menuitem action='Zoom out' /> - <menuitem action='Zoom fit' /> - <separator/> - <menuitem action='Show Toolbar' /> - <menuitem action='Query Pane' /> - <separator/> - <menuitem action='Display implicit arguments' /> - <menuitem action='Display coercions' /> - <menuitem action='Display raw matching expressions' /> - <menuitem action='Display notations' /> - <menuitem action='Display all basic low-level contents' /> - <menuitem action='Display existential variable instances' /> - <menuitem action='Display universe levels' /> - <menuitem action='Display all low-level contents' /> - </menu> - <menu action='Navigation'> - <menuitem action='Forward' /> - <menuitem action='Backward' /> - <menuitem action='Go to' /> - <menuitem action='Start' /> - <menuitem action='End' /> - <menuitem action='Interrupt' /> - <menuitem action='Previous' /> - <menuitem action='Next' /> - </menu> - <menu action='Try Tactics'> - <menuitem action='auto' /> - <menuitem action='auto with *' /> - <menuitem action='eauto' /> - <menuitem action='eauto with *' /> - <menuitem action='intuition' /> - <menuitem action='omega' /> - <menuitem action='simpl' /> - <menuitem action='tauto' /> - <menuitem action='trivial' /> - <menuitem action='Wizard' /> - <separator /> - %s - </menu> - <menu action='Templates'> - <menuitem action='Lemma' /> - <menuitem action='Theorem' /> - <menuitem action='Definition' /> - <menuitem action='Inductive' /> - <menuitem action='Fixpoint' /> - <menuitem action='Scheme' /> - <menuitem action='match' /> - <separator /> - %s - </menu> - <menu action='Queries'> - <menuitem action='Search' /> - <menuitem action='Check' /> - <menuitem action='Print' /> - <menuitem action='About' /> - <menuitem action='Locate' /> - <menuitem action='Print Assumptions' /> - <separator /> - %s - </menu> - <menu name='Tools' action='Tools'> - <menuitem action='Comment' /> - <menuitem action='Uncomment' /> - <separator /> - <menuitem action='Coqtop arguments' /> - </menu> - <menu action='Compile'> - <menuitem action='Compile buffer' /> - <menuitem action='Make' /> - <menuitem action='Next error' /> - <menuitem action='Make makefile' /> - </menu> - <menu action='Windows'> - <menuitem action='Detach View' /> - </menu> - <menu name='Help' action='Help'> - <menuitem action='Browse Coq Manual' /> - <menuitem action='Browse Coq Library' /> - <menuitem action='Help for keyword' /> - <menuitem action='Help for μPG mode' /> - <separator /> - <menuitem name='Abt' action='About Coq' /> - </menu> -</menubar> -<toolbar name='CoqIde ToolBar'> - <toolitem action='Save' /> - <toolitem action='Close buffer' /> - <toolitem action='Forward' /> - <toolitem action='Backward' /> - <toolitem action='Go to' /> - <toolitem action='Start' /> - <toolitem action='End' /> - <toolitem action='Force' /> - <toolitem action='Interrupt' /> - <toolitem action='Previous' /> - <toolitem action='Next' /> - <toolitem action='Wizard' /> -</toolbar> -</ui>" + let theui = Printf.sprintf "<ui>\ +\n<menubar name='CoqIde MenuBar'>\ +\n <menu action='File'>\ +\n <menuitem action='New' />\ +\n <menuitem action='Open' />\ +\n <menuitem action='Save' />\ +\n <menuitem action='Save as' />\ +\n <menuitem action='Save all' />\ +\n <menuitem action='Revert all buffers' />\ +\n <menuitem action='Close buffer' />\ +\n <menuitem action='Print...' />\ +\n <menu action='Export to'>\ +\n <menuitem action='Html' />\ +\n <menuitem action='Latex' />\ +\n <menuitem action='Dvi' />\ +\n <menuitem action='Pdf' />\ +\n <menuitem action='Ps' />\ +\n </menu>\ +\n <menuitem action='Rehighlight' />\ +\n %s\ +\n </menu>\ +\n <menu name='Edit' action='Edit'>\ +\n <menuitem action='Undo' />\ +\n <menuitem action='Redo' />\ +\n <separator />\ +\n <menuitem action='Cut' />\ +\n <menuitem action='Copy' />\ +\n <menuitem action='Paste' />\ +\n <separator />\ +\n <menuitem action='Find' />\ +\n <menuitem action='Find Next' />\ +\n <menuitem action='Find Previous' />\ +\n <menuitem action='Complete Word' />\ +\n <separator />\ +\n <menuitem action='External editor' />\ +\n <separator />\ +\n <menuitem name='Prefs' action='Preferences' />\ +\n </menu>\ +\n <menu name='View' action='View'>\ +\n <menuitem action='Previous tab' />\ +\n <menuitem action='Next tab' />\ +\n <separator/>\ +\n <menuitem action='Zoom in' />\ +\n <menuitem action='Zoom out' />\ +\n <menuitem action='Zoom fit' />\ +\n <separator/>\ +\n <menuitem action='Show Toolbar' />\ +\n <menuitem action='Query Pane' />\ +\n <separator/>\ +\n <menuitem action='Display implicit arguments' />\ +\n <menuitem action='Display coercions' />\ +\n <menuitem action='Display raw matching expressions' />\ +\n <menuitem action='Display notations' />\ +\n <menuitem action='Display all basic low-level contents' />\ +\n <menuitem action='Display existential variable instances' />\ +\n <menuitem action='Display universe levels' />\ +\n <menuitem action='Display all low-level contents' />\ +\n <menuitem action='Display unfocused goals' />\ +\n </menu>\ +\n <menu action='Navigation'>\ +\n <menuitem action='Forward' />\ +\n <menuitem action='Backward' />\ +\n <menuitem action='Go to' />\ +\n <menuitem action='Start' />\ +\n <menuitem action='End' />\ +\n <menuitem action='Interrupt' />\ +\n <menuitem action='Previous' />\ +\n <menuitem action='Next' />\ +\n </menu>\ +\n <menu action='Try Tactics'>\ +\n <menuitem action='auto' />\ +\n <menuitem action='auto with *' />\ +\n <menuitem action='eauto' />\ +\n <menuitem action='eauto with *' />\ +\n <menuitem action='intuition' />\ +\n <menuitem action='omega' />\ +\n <menuitem action='simpl' />\ +\n <menuitem action='tauto' />\ +\n <menuitem action='trivial' />\ +\n <menuitem action='Wizard' />\ +\n <separator />\ +\n %s\ +\n </menu>\ +\n <menu action='Templates'>\ +\n <menuitem action='Lemma' />\ +\n <menuitem action='Theorem' />\ +\n <menuitem action='Definition' />\ +\n <menuitem action='Inductive' />\ +\n <menuitem action='Fixpoint' />\ +\n <menuitem action='Scheme' />\ +\n <menuitem action='match' />\ +\n <separator />\ +\n %s\ +\n </menu>\ +\n <menu action='Queries'>\ +\n <menuitem action='Search' />\ +\n <menuitem action='Check' />\ +\n <menuitem action='Print' />\ +\n <menuitem action='About' />\ +\n <menuitem action='Locate' />\ +\n <menuitem action='Print Assumptions' />\ +\n <separator />\ +\n %s\ +\n </menu>\ +\n <menu name='Tools' action='Tools'>\ +\n <menuitem action='Comment' />\ +\n <menuitem action='Uncomment' />\ +\n <separator />\ +\n <menuitem action='Coqtop arguments' />\ +\n </menu>\ +\n <menu action='Compile'>\ +\n <menuitem action='Compile buffer' />\ +\n <menuitem action='Make' />\ +\n <menuitem action='Next error' />\ +\n <menuitem action='Make makefile' />\ +\n </menu>\ +\n <menu action='Windows'>\ +\n <menuitem action='Detach View' />\ +\n </menu>\ +\n <menu name='Help' action='Help'>\ +\n <menuitem action='Browse Coq Manual' />\ +\n <menuitem action='Browse Coq Library' />\ +\n <menuitem action='Help for keyword' />\ +\n <menuitem action='Help for μPG mode' />\ +\n <separator />\ +\n <menuitem name='Abt' action='About Coq' />\ +\n </menu>\ +\n</menubar>\ +\n<toolbar name='CoqIde ToolBar'>\ +\n <toolitem action='Save' />\ +\n <toolitem action='Close buffer' />\ +\n <toolitem action='Forward' />\ +\n <toolitem action='Backward' />\ +\n <toolitem action='Go to' />\ +\n <toolitem action='Start' />\ +\n <toolitem action='End' />\ +\n <toolitem action='Force' />\ +\n <toolitem action='Interrupt' />\ +\n <toolitem action='Previous' />\ +\n <toolitem action='Next' />\ +\n <toolitem action='Wizard' />\ +\n</toolbar>\ +\n</ui>" (if Coq_config.gtk_platform <> `QUARTZ then "<menuitem action='Quit' />" else "") (Buffer.contents (list_items "Tactic" Coq_commands.tactics)) (Buffer.contents (list_items "Template" Coq_commands.commands)) diff --git a/ide/coqide_ui.mli b/ide/coqide_ui.mli new file mode 100644 index 00000000..afc5447a --- /dev/null +++ b/ide/coqide_ui.mli @@ -0,0 +1,12 @@ +(************************************************************************) +(* * 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) *) +(************************************************************************) + +val init : unit -> unit +val ui_m : GAction.ui_manager diff --git a/ide/coqidetop.mllib b/ide/coqidetop.mllib index ed1fa465..df988d8f 100644 --- a/ide/coqidetop.mllib +++ b/ide/coqidetop.mllib @@ -2,8 +2,7 @@ Xml_lexer Xml_parser Xml_printer Serialize -Richprinter +Richpp Xmlprotocol -Texmacspp Document Ide_slave diff --git a/ide/document.ml b/ide/document.ml index 62457fe5..0d3b36a7 100644 --- a/ide/document.ml +++ b/ide/document.ml @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2010 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) exception Empty diff --git a/ide/document.mli b/ide/document.mli index fb96cb6d..2f460e6d 100644 --- a/ide/document.mli +++ b/ide/document.mli @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2010 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) (* An 'a document is a structure to hold and manipulate list of sentences. @@ -102,7 +104,7 @@ val context : 'a document -> (id * 'a) list * (id * 'a) list (** debug print *) val print : - 'a document -> (bool -> id option -> 'a -> Pp.std_ppcmds) -> Pp.std_ppcmds + 'a document -> (bool -> id option -> 'a -> Pp.t) -> Pp.t (** Callbacks on documents *) diff --git a/ide/fileOps.ml b/ide/fileOps.ml index 7be1bdb9..7acd2c37 100644 --- a/ide/fileOps.ml +++ b/ide/fileOps.ml @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) open Ideutils diff --git a/ide/fileOps.mli b/ide/fileOps.mli index 9f0b75ac..9a1f0cb7 100644 --- a/ide/fileOps.mli +++ b/ide/fileOps.mli @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) val revert_timer : Ideutils.timer diff --git a/ide/gtk_parsing.ml b/ide/gtk_parsing.ml index f905053d..9f5c9924 100644 --- a/ide/gtk_parsing.ml +++ b/ide/gtk_parsing.ml @@ -1,17 +1,15 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) let underscore = Glib.Utf8.to_unichar "_" ~pos:(ref 0) -let arobase = Glib.Utf8.to_unichar "@" ~pos:(ref 0) let prime = Glib.Utf8.to_unichar "'" ~pos:(ref 0) -let bn = Glib.Utf8.to_unichar "\n" ~pos:(ref 0) -let space = Glib.Utf8.to_unichar " " ~pos:(ref 0) -let tab = Glib.Utf8.to_unichar "\t" ~pos:(ref 0) (* TODO: avoid num and prime at the head of a word *) @@ -30,17 +28,6 @@ let ends_word (it:GText.iter) = not (is_word_char c) ) - -let inside_word (it:GText.iter) = - let c = it#char in - not (starts_word it) && - not (ends_word it) && - is_word_char c - - -let is_on_word_limit (it:GText.iter) = inside_word it || ends_word it - - let find_word_start (it:GText.iter) = let rec step_to_start it = Minilib.log "Find word start"; @@ -72,100 +59,6 @@ let get_word_around (it:GText.iter) = let stop = find_word_end it in start,stop - -let rec complete_backward w (it:GText.iter) = - Minilib.log "Complete backward..."; - match it#backward_search w with - | None -> (Minilib.log "backward_search failed";None) - | Some (start,stop) -> - Minilib.log ("complete_backward got a match:"^(string_of_int start#offset)^(string_of_int stop#offset)); - if starts_word start then - let ne = find_word_end stop in - if ne#compare stop = 0 - then complete_backward w start - else Some (start,stop,ne) - else complete_backward w start - - -let rec complete_forward w (it:GText.iter) = - Minilib.log "Complete forward..."; - match it#forward_search w with - | None -> None - | Some (start,stop) -> - if starts_word start then - let ne = find_word_end stop in - if ne#compare stop = 0 then - complete_forward w stop - else Some (stop,stop,ne) - else complete_forward w stop - - -let find_comment_end (start:GText.iter) = - let rec find_nested_comment (search_start:GText.iter) (search_end:GText.iter) (comment_end:GText.iter) = - match (search_start#forward_search ~limit:search_end "(*"),(comment_end#forward_search "*)") with - | None,_ -> comment_end - | Some _, None -> raise Not_found - | Some (_,next_search_start),Some (next_search_end,next_comment_end) -> - find_nested_comment next_search_start next_search_end next_comment_end - in - match start#forward_search "*)" with - | None -> raise Not_found - | Some (search_end,comment_end) -> find_nested_comment start search_end comment_end - - -let rec find_string_end (start:GText.iter) = - let dblquote = int_of_char '"' in - let rec escaped_dblquote c = - (c#char = dblquote) && not (escaped_dblquote c#backward_char) - in - match start#forward_search "\"" with - | None -> raise Not_found - | Some (stop,next_start) -> - if escaped_dblquote stop#backward_char - then find_string_end next_start - else next_start - - -let rec find_next_sentence (from:GText.iter) = - match (from#forward_search ".") with - | None -> raise Not_found - | Some (non_vernac_search_end,next_sentence) -> - match from#forward_search ~limit:non_vernac_search_end "(*",from#forward_search ~limit:non_vernac_search_end "\"" with - | None,None -> - if Glib.Unichar.isspace next_sentence#char || next_sentence#compare next_sentence#forward_char == 0 - then next_sentence else find_next_sentence next_sentence - | None,Some (_,string_search_start) -> find_next_sentence (find_string_end string_search_start) - | Some (_,comment_search_start),None -> find_next_sentence (find_comment_end comment_search_start) - | Some (_,comment_search_start),Some (_,string_search_start) -> - find_next_sentence ( - if comment_search_start#compare string_search_start < 0 - then find_comment_end comment_search_start - else find_string_end string_search_start) - - -let find_nearest_forward (cursor:GText.iter) targets = - let fold_targets acc target = - match cursor#forward_search target,acc with - | Some (t_start,_),Some nearest when (t_start#compare nearest < 0) -> Some t_start - | Some (t_start,_),None -> Some t_start - | _ -> acc - in - match List.fold_left fold_targets None targets with - | None -> raise Not_found - | Some nearest -> nearest - - -let find_nearest_backward (cursor:GText.iter) targets = - let fold_targets acc target = - match cursor#backward_search target,acc with - | Some (t_start,_),Some nearest when (t_start#compare nearest > 0) -> Some t_start - | Some (t_start,_),None -> Some t_start - | _ -> acc - in - match List.fold_left fold_targets None targets with - | None -> raise Not_found - | Some nearest -> nearest - (** On double-click on a view, select the whole word. This is a workaround for a deficient word handling in TextView. *) let fix_double_click self = diff --git a/ide/gtk_parsing.mli b/ide/gtk_parsing.mli new file mode 100644 index 00000000..a9f3e122 --- /dev/null +++ b/ide/gtk_parsing.mli @@ -0,0 +1,28 @@ +(************************************************************************) +(* * 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) *) +(************************************************************************) + +val fix_double_click : + < buffer : < get_iter : [> `INSERT ] -> GText.iter; + move_mark : [> `INSERT | `SEL_BOUND ] -> + where:GText.iter -> unit; + .. >; + event : < connect : + < button_press : + callback:([> `TWO_BUTTON_PRESS ] Gdk.event -> + bool) -> + 'a; + .. >; + .. >; + .. > -> + unit +val starts_word : GText.iter -> bool +val ends_word : GText.iter -> bool +val find_word_start : GText.iter -> GText.iter +val find_word_end : GText.iter -> GText.iter diff --git a/ide/ide.mllib b/ide/ide.mllib index b2f32fcf..96ea8c41 100644 --- a/ide/ide.mllib +++ b/ide/ide.mllib @@ -1,12 +1,7 @@ Minilib -Okey -Config_file -Configwin_keys -Configwin_types Configwin_messages Configwin_ihm Configwin -Editable_cells Config_parser Tags Wg_Notebook @@ -19,6 +14,9 @@ Richprinter Xml_lexer Xml_parser Xml_printer +Serialize +Richpp +Topfmt Xmlprotocol Ideutils Coq @@ -28,15 +26,16 @@ Gtk_parsing Wg_Segment Wg_ProofView Wg_MessageView +Wg_RoutedMessageViews Wg_Detachable Wg_Find Wg_Completion Wg_ScriptView Coq_commands -Wg_Command FileOps Document CoqOps +Wg_Command Session Coqide_ui NanoPG diff --git a/ide/ide_slave.ml b/ide/ide_slave.ml index 5b07d3ec..6b7efc83 100644 --- a/ide/ide_slave.ml +++ b/ide/ide_slave.ml @@ -1,23 +1,27 @@ (************************************************************************) - -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) open Vernacexpr +open Vernacprop open CErrors open Util open Pp open Printer +module NamedDecl = Context.Named.Declaration +module CompactedDecl = Context.Compacted.Declaration + (** Ide_slave : an implementation of [Interface], i.e. mainly an interp function and a rewind function. This specialized loop is triggered - when the -ideslave option is passed to Coqtop. Currently CoqIDE is - the only one using this mode, but we try here to be as generic as - possible, so this may change in the future... *) + when the -ideslave option is passed to Coqtop. *) + (** Signal handling: we postpone ^C during input and output phases, but make it directly raise a Sys.Break during evaluation of the request. *) @@ -28,24 +32,6 @@ let init_signal_handler () = let f _ = if !catch_break then raise Sys.Break else Control.interrupt := true in Sys.set_signal Sys.sigint (Sys.Signal_handle f) - -(** Redirection of standard output to a printable buffer *) - -let init_stdout, read_stdout = - let out_buff = Buffer.create 100 in - let out_ft = Format.formatter_of_buffer out_buff in - let deep_out_ft = Format.formatter_of_buffer out_buff in - let _ = Pp_control.set_gp deep_out_ft Pp_control.deep_gp in - (fun () -> - flush_all (); - Pp_control.std_ft := out_ft; - Pp_control.err_ft := out_ft; - Pp_control.deep_ft := deep_out_ft; - ), - (fun () -> Format.pp_print_flush out_ft (); - let r = Buffer.contents out_buff in - Buffer.clear out_buff; r) - let pr_with_pid s = Printf.eprintf "[pid %d] %s\n%!" (Unix.getpid ()) s let pr_error s = pr_with_pid s @@ -67,73 +53,85 @@ let coqide_known_option table = List.mem table [ ["Printing";"All"]; ["Printing";"Records"]; ["Printing";"Existential";"Instances"]; - ["Printing";"Universes"]] - -let is_known_option cmd = match cmd with - | VernacSetOption (o,BoolValue true) - | VernacUnsetOption o -> coqide_known_option o - | _ -> false - -let is_debug cmd = match cmd with - | VernacSetOption (["Ltac";"Debug"], _) -> true - | _ -> false - -let is_query cmd = match cmd with - | VernacChdir None - | VernacMemOption _ - | VernacPrintOption _ - | VernacCheckMayEval _ - | VernacGlobalCheck _ - | VernacPrint _ - | VernacSearch _ - | VernacLocate _ -> true - | _ -> false + ["Printing";"Universes"]; + ["Printing";"Unfocused"]] -let is_undo cmd = match cmd with - | VernacUndo _ | VernacUndoTo _ -> true +let is_known_option cmd = match Vernacprop.under_control cmd with + | VernacSetOption (_, o, BoolValue true) + | VernacUnsetOption (_, o) -> coqide_known_option o | _ -> false -(** Check whether a command is forbidden by CoqIDE *) +(** Check whether a command is forbidden in the IDE *) -let coqide_cmd_checks (loc,ast) = - let user_error s = CErrors.user_err_loc (loc, "CoqIde", str s) in +let ide_cmd_checks ~id {CAst.loc;v=ast} = + let user_error s = CErrors.user_err ?loc ~hdr:"IDE" (str s) in + let warn msg = Feedback.(feedback ~id (Message (Warning, loc, strbrk msg))) in if is_debug ast then - user_error "Debug mode not available within CoqIDE"; + user_error "Debug mode not available in the IDE"; if is_known_option ast then - Feedback.msg_warning (strbrk"This will not work. Use CoqIDE view menu instead"); - if Vernac.is_navigation_vernac ast || is_undo ast then - Feedback.msg_warning (strbrk "Rather use CoqIDE navigation instead"); - if is_query ast then - Feedback.msg_warning (strbrk "Query commands should not be inserted in scripts") + warn "Set this option from the IDE menu instead"; + if is_navigation_vernac ast || is_undo ast then + warn "Use IDE navigation instead" (** Interpretation (cf. [Ide_intf.interp]) *) +let ide_doc = ref None +let get_doc () = Option.get !ide_doc +let set_doc doc = ide_doc := Some doc + let add ((s,eid),(sid,verbose)) = - let newid, rc = Stm.add ~ontop:sid verbose ~check:coqide_cmd_checks eid s in + let doc = get_doc () in + let pa = Pcoq.Gram.parsable (Stream.of_string s) in + let loc_ast = Stm.parse_sentence ~doc sid pa in + let doc, newid, rc = Stm.add ~doc ~ontop:sid verbose loc_ast in + set_doc doc; let rc = match rc with `NewTip -> CSig.Inl () | `Unfocus id -> CSig.Inr id in - newid, (rc, read_stdout ()) + ide_cmd_checks ~id:newid loc_ast; + (* TODO: the "" parameter is a leftover of the times the protocol + * used to include stderr/stdout output. + * + * Currently, we force all the output meant for the to go via the + * feedback mechanism, and we don't manipulate stderr/stdout, which + * are left to the client's discrection. The parameter is still there + * as not to break the core protocol for this minor change, but it should + * be removed in the next version of the protocol. + *) + newid, (rc, "") let edit_at id = - match Stm.edit_at id with - | `NewTip -> CSig.Inl () - | `Focus { Stm.start; stop; tip} -> CSig.Inr (start, (stop, tip)) - -let query (s,id) = Stm.query ~at:id s; read_stdout () + let doc = get_doc () in + match Stm.edit_at ~doc id with + | doc, `NewTip -> set_doc doc; CSig.Inl () + | doc, `Focus { Stm.start; stop; tip} -> set_doc doc; CSig.Inr (start, (stop, tip)) + +(* TODO: the "" parameter is a leftover of the times the protocol + * used to include stderr/stdout output. + * + * Currently, we force all the output meant for the to go via the + * feedback mechanism, and we don't manipulate stderr/stdout, which + * are left to the client's discrection. The parameter is still there + * as not to break the core protocol for this minor change, but it should + * be removed in the next version of the protocol. + *) +let query (route, (s,id)) = + let pa = Pcoq.Gram.parsable (Stream.of_string s) in + let doc = get_doc () in + Stm.query ~at:id ~doc ~route pa let annotate phrase = - let (loc, ast) = + let doc = get_doc () in + let {CAst.loc;v=ast} = let pa = Pcoq.Gram.parsable (Stream.of_string phrase) in - Vernac.parse_sentence (pa,None) + Stm.parse_sentence ~doc (Stm.get_current_state ~doc) pa in - let (_, xml) = - Richprinter.richpp_vernac ast - in - xml + (* XXX: Width should be a parameter of annotate... *) + Richpp.richpp_of_pp 78 (Ppvernac.pr_vernac ast) (** Goal display *) let hyp_next_tac sigma env decl = - let (id,_,ast) = Context.Named.Declaration.to_tuple decl in + let id = NamedDecl.get_id decl in + let ast = NamedDecl.get_type decl in let id_s = Names.Id.to_string id in let type_s = string_of_ppcmds (pr_ltype_env env sigma ast) in [ @@ -186,20 +184,14 @@ let process_goal sigma g = let min_env = Environ.reset_context env in let id = Goal.uid g in let ccl = - let norm_constr = Reductionops.nf_evar sigma (Goal.V82.concl sigma g) in - Richpp.richpp_of_pp (pr_goal_concl_style_env env sigma norm_constr) + pr_goal_concl_style_env env sigma (Goal.V82.concl sigma g) in let process_hyp d (env,l) = - let d = Context.NamedList.Declaration.map_constr (Reductionops.nf_evar sigma) d in - let d' = List.map (fun name -> let open Context.Named.Declaration in - match pi2 d with - | None -> LocalAssum (name, pi3 d) - | Some value -> LocalDef (name, value, pi3 d)) - (pi1 d) in + let d' = CompactedDecl.to_named_context d in (List.fold_right Environ.push_named d' env, - (Richpp.richpp_of_pp (pr_var_list_decl env sigma d)) :: l) in + (pr_compacted_decl env sigma d) :: l) in let (_env, hyps) = - Context.NamedList.fold process_hyp + Context.Compacted.fold process_hyp (Termops.compact_named_context (Environ.named_context env)) ~init:(min_env,[]) in { Interface.goal_hyp = List.rev hyps; Interface.goal_ccl = ccl; Interface.goal_id = id; } @@ -212,9 +204,8 @@ let export_pre_goals pgs = } let goals () = - Stm.finish (); - let s = read_stdout () in - if not (String.is_empty s) then Feedback.msg_info (str s); + let doc = get_doc () in + set_doc @@ Stm.finish ~doc; try let pfts = Proof_global.give_me_the_proof () in Some (export_pre_goals (Proof.map_structured_proof pfts process_goal)) @@ -222,12 +213,11 @@ let goals () = let evars () = try - Stm.finish (); - let s = read_stdout () in - if not (String.is_empty s) then Feedback.msg_info (str s); + let doc = get_doc () in + set_doc @@ Stm.finish ~doc; let pfts = Proof_global.give_me_the_proof () in - let { Evd.it = all_goals ; sigma = sigma } = Proof.V82.subgoals pfts in - let exl = Evar.Map.bindings (Evarutil.non_instantiated sigma) in + let all_goals, _, _, _, sigma = Proof.proof pfts in + let exl = Evar.Map.bindings (Evd.undefined_map sigma) in let map_evar ev = { Interface.evar_info = string_of_ppcmds (pr_evar sigma ev); } in let el = List.map map_evar exl in Some el @@ -236,7 +226,7 @@ let evars () = let hints () = try let pfts = Proof_global.give_me_the_proof () in - let { Evd.it = all_goals ; sigma = sigma } = Proof.V82.subgoals pfts in + let all_goals, _, _, _, sigma = Proof.proof pfts in match all_goals with | [] -> None | g :: _ -> @@ -250,14 +240,17 @@ let hints () = (** Other API calls *) +let wait () = + let doc = get_doc () in + set_doc (Stm.wait ~doc) + 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 not (String.is_empty s) then Feedback.msg_info (str s); + set_doc (Stm.finish ~doc:(get_doc ())); + if force then + set_doc (Stm.join ~doc:(get_doc ())); let path = let l = Names.DirPath.repr (Lib.cwd ()) in List.rev_map Names.Id.to_string l @@ -274,13 +267,13 @@ let status force = Interface.status_path = path; Interface.status_proofname = proof; Interface.status_allproofs = allproofs; - Interface.status_proofnum = Stm.current_proof_depth (); + Interface.status_proofnum = Stm.current_proof_depth ~doc:(get_doc ()); } let export_coq_object t = { Interface.coq_object_prefix = t.Search.coq_object_prefix; Interface.coq_object_qualid = t.Search.coq_object_qualid; - Interface.coq_object_object = t.Search.coq_object_object + Interface.coq_object_object = Pp.string_of_ppcmds (pr_lconstr_env (Global.env ()) Evd.empty t.Search.coq_object_object) } let pattern_of_string ?env s = @@ -290,17 +283,17 @@ let pattern_of_string ?env s = | Some e -> e in let constr = Pcoq.parse_string Pcoq.Constr.lconstr_pattern s in - let (_, pat) = Constrintern.intern_constr_pattern env constr in + let (_, pat) = Constrintern.intern_constr_pattern env Evd.empty constr in pat let dirpath_of_string_list s = let path = String.concat "." s in let m = Pcoq.parse_string Pcoq.Constr.global path in - let (_, qid) = Libnames.qualid_of_reference m in + let {CAst.v=qid} = Libnames.qualid_of_reference m in let id = try Nametab.full_name_module qid with Not_found -> - CErrors.errorlabstrm "Search.interface_search" + CErrors.user_err ~hdr:"Search.interface_search" (str "Module " ++ str path ++ str " not found.") in id @@ -330,7 +323,7 @@ let import_option_value = function | Interface.StringOptValue s -> Goptions.StringOptValue s let export_option_state s = { - Interface.opt_sync = s.Goptions.opt_sync; + Interface.opt_sync = true; Interface.opt_depr = s.Goptions.opt_depr; Interface.opt_name = s.Goptions.opt_name; Interface.opt_value = export_option_value s.Goptions.opt_value; @@ -347,7 +340,7 @@ let set_options options = | IntValue i -> Goptions.set_int_option_value name i | StringValue s -> Goptions.set_string_option_value name s | StringOptValue (Some s) -> Goptions.set_string_option_value name s - | StringOptValue None -> Goptions.unset_option_value_gen None name + | StringOptValue None -> Goptions.unset_option_value_gen name in List.iter iter options @@ -359,18 +352,15 @@ let about () = { } let handle_exn (e, info) = + let (e, info) = ExplainErr.process_vernac_interp_error (e, info) in let dummy = Stateid.dummy in let loc_of e = match Loc.get_loc e with - | Some loc when not (Loc.is_ghost loc) -> Some (Loc.unloc loc) - | _ -> None in - let mk_msg () = - let msg = read_stdout () in - let msg = str msg ++ fnl () ++ CErrors.print ~info e in - Richpp.richpp_of_pp msg - in + | Some loc -> Some (Loc.unloc loc) + | _ -> None in + let mk_msg () = CErrors.print ~info e in match e with - | CErrors.Drop -> dummy, None, Richpp.richpp_of_string "Drop is not allowed by coqide!" - | CErrors.Quit -> dummy, None, Richpp.richpp_of_string "Quit is not allowed by coqide!" + | CErrors.Drop -> dummy, None, Pp.str "Drop is not allowed by coqide!" + | CErrors.Quit -> dummy, None, Pp.str "Quit is not allowed by coqide!" | e -> match Stateid.get info with | Some (valid, _) -> valid, loc_of info, mk_msg () @@ -379,35 +369,24 @@ let handle_exn (e, info) = let init = let initialized = ref false in fun file -> - if !initialized then anomaly (str "Already initialized") + if !initialized then anomaly (str "Already initialized.") else begin + let init_sid = Stm.get_current_state ~doc:(get_doc ()) in initialized := true; match file with - | None -> Stm.get_current_state () + | None -> init_sid | Some file -> - let dir = Filename.dirname file in - let open Loadpath in let open CUnix in - let initial_id, _ = - if not (is_in_load_paths (physical_path_of_string dir)) then - Stm.add false ~ontop:(Stm.get_current_state ()) - 0 (Printf.sprintf "Add LoadPath \"%s\". " dir) - else Stm.get_current_state (), `NewTip in - Stm.set_compilation_hints file; - Stm.finish (); + let doc, initial_id, _ = + get_doc (), init_sid, `NewTip in + if Filename.check_suffix file ".v" then + Stm.set_compilation_hints file; + set_doc (Stm.finish ~doc); initial_id end -(* Retrocompatibility stuff *) +(* Retrocompatibility stuff, disabled since 8.7 *) let interp ((_raw, verbose), s) = - let vernac_parse s = - let pa = Pcoq.Gram.parsable (Stream.of_string s) in - Flags.with_option Flags.we_are_parsing (fun () -> - match Pcoq.Gram.entry_parse Pcoq.main_entry pa with - | None -> raise (Invalid_argument "vernac_parse") - | Some ast -> ast) - () in - Stm.interp verbose (vernac_parse s); - Stm.get_current_state (), CSig.Inl (read_stdout ()) + Stateid.dummy, CSig.Inr "The interp call has been disabled, please use Add." (** 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 @@ -415,25 +394,17 @@ let interp ((_raw, verbose), s) = let quit = ref false -(** Serializes the output of Stm.get_ast *) -let print_ast id = - match Stm.get_ast id with - | Some (expr, loc) -> begin - try Texmacspp.tmpp expr loc - with e -> Xml_datatype.PCData ("ERROR " ^ Printexc.to_string e) - end - | None -> Xml_datatype.PCData "ERROR" +(** Disabled *) +let print_ast id = Xml_datatype.PCData "ERROR" (** Grouping all call handlers together + error handling *) -let eval_call xml_oc log c = +let eval_call c = let interruptible f x = catch_break := true; Control.check_for_interrupt (); let r = f x in catch_break := false; - let out = read_stdout () in - if not (String.is_empty out) then log (str out); r in let handler = { @@ -451,6 +422,7 @@ let eval_call xml_oc log c = Interface.quit = (fun () -> quit := true); Interface.init = interruptible init; Interface.about = interruptible about; + Interface.wait = interruptible wait; Interface.interp = interruptible interp; Interface.handle_exn = handle_exn; Interface.stop_worker = Stm.stop_worker; @@ -471,16 +443,8 @@ let print_xml = try Xml_printer.print oc xml; Mutex.unlock m with e -> let e = CErrors.push e in Mutex.unlock m; iraise e - -let slave_logger xml_oc ?loc level message = - (* convert the message into XML *) - let msg = hov 0 message in - let () = pr_debug (Printf.sprintf "-> %S" (string_of_ppcmds msg)) in - let xml = Xmlprotocol.of_message level loc (Richpp.richpp_of_pp message) in - print_xml xml_oc xml - -let slave_feeder xml_oc msg = - let xml = Xmlprotocol.of_feedback msg in +let slave_feeder fmt xml_oc msg = + let xml = Xmlprotocol.(of_feedback fmt msg) in print_xml xml_oc xml (** The main loop *) @@ -489,30 +453,36 @@ let slave_feeder xml_oc msg = messages by [handle_exn] above. Otherwise, we die badly, without trying to answer malformed requests. *) -let loop () = +let msg_format = ref (fun () -> + let margin = Option.default 72 (Topfmt.get_margin ()) in + Xmlprotocol.Richpp margin + ) + +(* The loop ignores the command line arguments as the current model delegates + its handing to the toplevel container. *) +let loop _args ~state = + let open Vernac.State in + set_doc state.doc; init_signal_handler (); catch_break := false; - let in_ch, out_ch = Spawned.get_channels () in - let xml_oc = Xml_printer.make (Xml_printer.TChannel out_ch) in - let in_lb = Lexing.from_function (fun s len -> - CThread.thread_friendly_read in_ch s ~off:0 ~len) in - let xml_ic = Xml_parser.make (Xml_parser.SLexbuf in_lb) in + let in_ch, out_ch = Spawned.get_channels () in + let xml_oc = Xml_printer.make (Xml_printer.TChannel out_ch) in + let in_lb = Lexing.from_function (fun s len -> + CThread.thread_friendly_read in_ch s ~off:0 ~len) in + (* SEXP parser make *) + let xml_ic = Xml_parser.make (Xml_parser.SLexbuf in_lb) in let () = Xml_parser.check_eof xml_ic false in - Feedback.set_logger (slave_logger xml_oc); - Feedback.add_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; + ignore (Feedback.add_feeder (slave_feeder (!msg_format ()) xml_oc)); while not !quit do try let xml_query = Xml_parser.parse xml_ic in (* pr_with_pid (Xml_printer.to_string_fmt xml_query); *) let Xmlprotocol.Unknown q = Xmlprotocol.to_call xml_query in let () = pr_debug_call q in - let r = eval_call xml_oc (slave_logger xml_oc Feedback.Notice) q in + let r = eval_call q in let () = pr_debug_answer q r in (* pr_with_pid (Xml_printer.to_string_fmt (Xmlprotocol.of_answer q r)); *) - print_xml xml_oc (Xmlprotocol.of_answer q r); + print_xml xml_oc Xmlprotocol.(of_answer (!msg_format ()) q r); flush out_ch with | Xml_parser.Error (Xml_parser.Empty, _) -> @@ -534,16 +504,19 @@ let loop () = let rec parse = function | "--help-XML-protocol" :: rest -> Xmlprotocol.document Xml_printer.to_string_fmt; exit 0 + | "--xml_format=Ppcmds" :: rest -> + msg_format := (fun () -> Xmlprotocol.Ppcmds); parse rest | x :: rest -> x :: parse rest | [] -> [] -let () = Coqtop.toploop_init := (fun args -> - let args = parse args in - Flags.make_silent true; - init_stdout (); - CoqworkmgrApi.(init Flags.High); +let () = Coqtop.toploop_init := (fun coq_args extra_args -> + let args = parse extra_args in + Flags.quiet := true; + CoqworkmgrApi.(init High); args) let () = Coqtop.toploop_run := loop -let () = Usage.add_to_usage "coqidetop" " --help-XML-protocol print the documentation of the XML protocol used by CoqIDE\n" +let () = Usage.add_to_usage "coqidetop" +" --xml_format=Ppcmds serialize pretty printing messages using the std_ppcmds format\ +\n --help-XML-protocol print documentation of the Coq XML protocol\n" diff --git a/ide/ide_slave.mli b/ide/ide_slave.mli new file mode 100644 index 00000000..9db9ecd1 --- /dev/null +++ b/ide/ide_slave.mli @@ -0,0 +1,12 @@ +(************************************************************************) +(* * 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) *) +(************************************************************************) + +(* This empty file avoids a race condition that occurs when compiling a .ml file + that does not have a corresponding .mli file *) diff --git a/ide/ideutils.ml b/ide/ideutils.ml index 06a13273..bdb39e94 100644 --- a/ide/ideutils.ml +++ b/ide/ideutils.ml @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) @@ -35,17 +37,6 @@ let flash_info = let flash_context = status#new_context ~name:"Flash" in (fun ?(delay=5000) s -> flash_context#flash ~delay s) -let xml_to_string xml = - let open Xml_datatype in - let buf = Buffer.create 1024 in - let rec iter = function - | PCData s -> Buffer.add_string buf s - | Element (_, _, children) -> - List.iter iter children - in - let () = iter (Richpp.repr xml) in - Buffer.contents buf - let insert_with_tags (buf : #GText.buffer_skel) mark rmark tags text = (** FIXME: LablGTK2 does not export the C insert_with_tags function, so that it has to reimplement its own helper function. Unluckily, it relies on @@ -58,7 +49,7 @@ let insert_with_tags (buf : #GText.buffer_skel) mark rmark tags text = let () = buf#insert ~iter:(buf#get_iter_at_mark mark) text in let start = buf#get_iter_at_mark mark in let stop = buf#get_iter_at_mark rmark in - let iter tag = buf#apply_tag tag start stop in + let iter tag = buf#apply_tag tag ~start ~stop in List.iter iter tags let insert_xml ?(mark = `INSERT) ?(tags = []) (buf : #GText.buffer_skel) msg = @@ -75,11 +66,17 @@ let insert_xml ?(mark = `INSERT) ?(tags = []) (buf : #GText.buffer_skel) msg = let tags = try tag t :: tags with Not_found -> tags in List.iter (fun xml -> insert tags xml) children in - let () = try insert tags (Richpp.repr msg) with _ -> () in + let () = try insert tags msg with _ -> () in buf#delete_mark rmark let set_location = ref (function s -> failwith "not ready") +let display_location ins = + let line = ins#line + 1 in + let off = ins#line_offset + 1 in + let msg = Printf.sprintf "Line: %5d Char: %3d" line off in + !set_location msg + (** A utf8 char is either a single byte (ascii char, 0xxxxxxx) or multi-byte (with a leading byte 11xxxxxx and extra bytes 10xxxxxx) *) @@ -294,18 +291,20 @@ let coqtop_path () = match cmd_coqtop#get with | Some s -> s | None -> - let prog = String.copy Sys.executable_name in try - let pos = String.length prog - 6 in - let i = Str.search_backward (Str.regexp_string "coqide") prog pos + let old_prog = Sys.executable_name in + let pos = String.length old_prog - 6 in + let i = Str.search_backward (Str.regexp_string "coqide") old_prog pos in - String.blit "coqtop" 0 prog i 6; - if Sys.file_exists prog then prog + let new_prog = Bytes.of_string old_prog in + Bytes.blit_string "coqtop" 0 new_prog i 6; + let new_prog = Bytes.to_string new_prog in + if Sys.file_exists new_prog then new_prog else let in_macos_bundle = Filename.concat - (Filename.dirname prog) - (Filename.concat "../Resources/bin" (Filename.basename prog)) + (Filename.dirname new_prog) + (Filename.concat "../Resources/bin" (Filename.basename new_prog)) in if Sys.file_exists in_macos_bundle then in_macos_bundle else "coqtop" with Not_found -> "coqtop" @@ -325,7 +324,7 @@ let textview_width (view : #GText.view_skel) = let char_width = GPango.to_pixels metrics#approx_char_width in pixel_width / char_width -type logger = Feedback.level -> Richpp.richpp -> unit +type logger = Feedback.level -> Pp.t -> unit let default_logger level message = let level = match level with @@ -335,7 +334,7 @@ let default_logger level message = | Feedback.Warning -> `WARNING | Feedback.Error -> `ERROR in - Minilib.log ~level (xml_to_string message) + Minilib.log_pp ~level message (** {6 File operations} *) @@ -357,7 +356,7 @@ let stat f = let maxread = 4096 -let read_string = String.create maxread +let read_string = Bytes.create maxread let read_buffer = Buffer.create maxread (** Read the content of file [f] and add it to buffer [b]. @@ -368,7 +367,7 @@ let read_file name buf = let len = ref 0 in try while len := input ic read_string 0 maxread; !len > 0 do - Buffer.add_substring buf read_string 0 !len + Buffer.add_subbytes buf read_string 0 !len done; close_in ic with e -> close_in ic; raise e @@ -382,7 +381,7 @@ let io_read_all chan = Buffer.clear read_buffer; let read_once () = let len = Glib.Io.read_chars ~buf:read_string ~pos:0 ~len:maxread chan in - Buffer.add_substring read_buffer read_string 0 len + Buffer.add_subbytes read_buffer read_string 0 len in begin try while true do read_once () done @@ -430,7 +429,7 @@ let browse prerr url = let doc_url () = if doc_url#get = use_default_doc_url || doc_url#get = "" then - let addr = List.fold_left Filename.concat (Coq_config.docdir) + let addr = List.fold_left Filename.concat (Envars.docdir ()) ["html";"refman";"index.html"] in if Sys.file_exists addr then "file://"^addr else Coq_config.wwwrefman @@ -475,3 +474,14 @@ let browse_keyword prerr text = browse prerr (doc_url() ^ u) with Not_found -> prerr ("No documentation found for \""^text^"\".\n") +let rec is_valid (s : Pp.t) = match Pp.repr s with + | Pp.Ppcmd_empty + | Pp.Ppcmd_print_break _ + | Pp.Ppcmd_force_newline -> true + | Pp.Ppcmd_glue l -> List.for_all is_valid l + | Pp.Ppcmd_string s -> Glib.Utf8.validate s + | Pp.Ppcmd_box (_,s) + | Pp.Ppcmd_tag (_,s) -> is_valid s + | Pp.Ppcmd_comment s -> List.for_all Glib.Utf8.validate s +let validate s = + if is_valid s then s else Pp.str "This error massage can't be printed." diff --git a/ide/ideutils.mli b/ide/ideutils.mli index e32a4d9e..0031c59c 100644 --- a/ide/ideutils.mli +++ b/ide/ideutils.mli @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) val warn_image : unit -> GMisc.image @@ -52,12 +54,11 @@ val pop_info : unit -> unit val clear_info : unit -> unit val flash_info : ?delay:int -> string -> unit -val xml_to_string : Richpp.richpp -> string - val insert_xml : ?mark:GText.mark -> ?tags:GText.tag list -> #GText.buffer_skel -> Richpp.richpp -> unit val set_location : (string -> unit) ref +val display_location : GText.iter -> unit (* In win32, when a command-line is to be executed via cmd.exe (i.e. Sys.command, Unix.open_process, ...), it cannot contain several @@ -69,7 +70,7 @@ val requote : string -> string val textview_width : #GText.view_skel -> int (** Returns an approximate value of the character width of a textview *) -type logger = Feedback.level -> Richpp.richpp -> unit +type logger = Feedback.level -> Pp.t -> unit val default_logger : logger (** Default logger. It logs messages that the casual user should not see. *) @@ -98,3 +99,6 @@ val io_read_all : Glib.Io.channel -> string val run_command : (string -> unit) -> (Unix.process_status -> unit) -> string -> unit +(* Checks if an error message is printable, it not replaces it with + * a printable error *) +val validate : Pp.t -> Pp.t diff --git a/ide/interface.mli b/ide/interface.mli index 2a9b8b24..debbc830 100644 --- a/ide/interface.mli +++ b/ide/interface.mli @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) (** * Declarative part of the interface of CoqIde calls to Coq *) @@ -12,15 +14,14 @@ type raw = bool type verbose = bool -type richpp = Richpp.richpp (** The type of coqtop goals *) type goal = { goal_id : string; (** Unique goal identifier *) - goal_hyp : richpp list; + goal_hyp : Pp.t list; (** List of hypotheses *) - goal_ccl : richpp; + goal_ccl : Pp.t; (** Goal conclusion *) } @@ -112,14 +113,17 @@ type coq_info = { (** Calls result *) type location = (int * int) option (* start and end of the error *) -type state_id = Feedback.state_id -type edit_id = Feedback.edit_id +type state_id = Stateid.t +type route_id = Feedback.route_id + +(* Obsolete *) +type edit_id = int (* The fail case carries the current state_id of the prover, the GUI should probably retract to that point *) type 'a value = | Good of 'a - | Fail of (state_id * location * richpp) + | Fail of (state_id * location * Pp.t) type ('a, 'b) union = ('a, 'b) Util.union @@ -128,9 +132,13 @@ type ('a, 'b) union = ('a, 'b) Util.union (** [add ((s,eid),(sid,v))] adds the phrase [s] with edit id [eid] on top of the current edit position (that is asserted to be [sid]) verbosely if [v] is true. The response [(id,(rc,s)] is the new state - [id] assigned to the phrase, some output [s]. [rc] is [Inl] if the new + [id] assigned to the phrase. [rc] is [Inl] if the new state id is the tip of the edit point, or [Inr tip] if the new phrase - closes a focus and [tip] is the new edit tip *) + closes a focus and [tip] is the new edit tip + + [s] used to contain Coq's console output and has been deprecated + in favor of sending feedback, it will be removed in a future + version of the protocol. *) type add_sty = (string * edit_id) * (state_id * verbose) type add_rty = state_id * ((unit, state_id) union * string) @@ -139,21 +147,25 @@ type add_rty = state_id * ((unit, state_id) union * string) [Inr (start,(stop,tip))] if [id] is in a zone that can be focused. In that case the zone is delimited by [start] and [stop] while [tip] is the new document [tip]. Edits made by subsequent [add] are always - performend on top of [id]. *) + performed on top of [id]. *) type edit_at_sty = state_id type edit_at_rty = (unit, state_id * (state_id * state_id)) union -(** [query s id] executes [s] at state [id] and does not record any state - change but for the printings that are sent in response *) -type query_sty = string * state_id -type query_rty = string +(** [query s id] executes [s] at state [id]. + + query used to reply with the contents of Coq's console output, and + has been deprecated in favor of sending the query answers as + feedback. It will be removed in a future version of the protocol. +*) +type query_sty = route_id * (string * state_id) +type query_rty = unit (** Fetching the list of current goals. Return [None] if no proof is in progress, [Some gl] otherwise. *) type goals_sty = unit type goals_rty = goals option -(** Retrieve the list of unintantiated evars in the current proof. [None] if no +(** Retrieve the list of uninstantiated evars in the current proof. [None] if no proof is in progress. *) type evars_sty = unit type evars_rty = evar list option @@ -203,7 +215,7 @@ type about_sty = unit type about_rty = coq_info type handle_exn_sty = Exninfo.iexn -type handle_exn_rty = state_id * location * richpp +type handle_exn_rty = state_id * location * Pp.t (* Retrocompatibility stuff *) type interp_sty = (raw * verbose) * string @@ -219,6 +231,9 @@ type print_ast_rty = Xml_datatype.xml type annotate_sty = string type annotate_rty = Xml_datatype.xml +type wait_sty = unit +type wait_rty = unit + type handler = { add : add_sty -> add_rty; edit_at : edit_at_sty -> edit_at_rty; @@ -238,6 +253,8 @@ type handler = { handle_exn : handle_exn_sty -> handle_exn_rty; init : init_sty -> init_rty; quit : quit_sty -> quit_rty; + (* for internal use (fake_id) only, do not use *) + wait : wait_sty -> wait_rty; (* Retrocompatibility stuff *) interp : interp_sty -> interp_rty; } diff --git a/ide/macos_prehook.mli b/ide/macos_prehook.mli new file mode 100644 index 00000000..9db9ecd1 --- /dev/null +++ b/ide/macos_prehook.mli @@ -0,0 +1,12 @@ +(************************************************************************) +(* * 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) *) +(************************************************************************) + +(* This empty file avoids a race condition that occurs when compiling a .ml file + that does not have a corresponding .mli file *) diff --git a/ide/minilib.ml b/ide/minilib.ml index d11e8c56..39183e00 100644 --- a/ide/minilib.ml +++ b/ide/minilib.ml @@ -1,10 +1,12 @@ -(***********************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *) -(* \VV/ *************************************************************) -(* // * This file is distributed under the terms of the *) -(* * GNU Lesser General Public License Version 2.1 *) -(***********************************************************************) +(************************************************************************) +(* * 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) *) +(************************************************************************) let rec print_list print fmt = function | [] -> () @@ -20,7 +22,7 @@ type level = [ | `FATAL ] (** Some excerpt of Util and similar files to avoid loading the whole - module and its dependencies (and hence Compat and Camlp4) *) + module and its dependencies (and hence Compat and Camlp5) *) let debug = ref false @@ -30,7 +32,7 @@ let debug = ref false print in the response buffer. *) -let log ?(level = `DEBUG) msg = +let log_pp ?(level = `DEBUG) msg = let prefix = match level with | `DEBUG -> "DEBUG" | `INFO -> "INFO" @@ -40,10 +42,12 @@ let log ?(level = `DEBUG) msg = | `FATAL -> "FATAL" in if !debug then begin - try Printf.eprintf "[%s] %s\n%!" prefix msg + try Format.eprintf "[%s] @[%a@]\n%!" prefix Pp.pp_with msg with _ -> () end +let log ?level str = log_pp ?level (Pp.str str) + let coqify d = Filename.concat d "coq" let coqide_config_home () = @@ -52,12 +56,12 @@ let coqide_config_home () = let coqide_data_dirs () = coqify (Glib.get_user_data_dir ()) :: List.map coqify (Glib.get_system_data_dirs ()) - @ Option.List.cons Coq_config.datadir [] + @ [Envars.datadir ()] let coqide_config_dirs () = coqide_config_home () :: List.map coqify (Glib.get_system_config_dirs ()) - @ Option.List.cons Coq_config.configdir [] + @ [Envars.configdir ()] let is_prefix_of pre s = let i = ref 0 in diff --git a/ide/minilib.mli b/ide/minilib.mli index b7672c90..6cc36f5f 100644 --- a/ide/minilib.mli +++ b/ide/minilib.mli @@ -1,13 +1,15 @@ -(***********************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *) -(* \VV/ *************************************************************) -(* // * This file is distributed under the terms of the *) -(* * GNU Lesser General Public License Version 2.1 *) -(***********************************************************************) +(************************************************************************) +(* * 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) *) +(************************************************************************) (** Some excerpts of Util and similar files to avoid depending on them - and hence on Compat and Camlp4 *) + and hence on Compat and Camlp5 *) val print_list : (Format.formatter -> 'a -> unit) -> Format.formatter -> 'a list -> unit @@ -22,7 +24,8 @@ type level = [ (** debug printing *) val debug : bool ref -val log : ?level:level -> string -> unit +val log_pp : ?level:level -> Pp.t -> unit +val log : ?level:level -> string -> unit val coqide_config_home : unit -> string val coqide_config_dirs : unit -> string list diff --git a/ide/nanoPG.ml b/ide/nanoPG.ml index 93bdeb32..2be5dce4 100644 --- a/ide/nanoPG.ml +++ b/ide/nanoPG.ml @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) open Ideutils diff --git a/ide/nanoPG.mli b/ide/nanoPG.mli new file mode 100644 index 00000000..bc9b39d8 --- /dev/null +++ b/ide/nanoPG.mli @@ -0,0 +1,13 @@ +(************************************************************************) +(* * 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) *) +(************************************************************************) + +val get_documentation : unit -> string +val init : GWindow.window -> Session.session Wg_Notebook.typed_notebook -> + GAction.action_group list -> unit diff --git a/ide/preferences.ml b/ide/preferences.ml index f0fd45d7..11aaf6e8 100644 --- a/ide/preferences.ml +++ b/ide/preferences.ml @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) open Configwin @@ -73,8 +75,8 @@ end let stick (pref : 'a preference) (obj : #GObj.widget as 'obj) (cb : 'a -> unit) = let _ = cb pref#get in - let p_id = pref#connect#changed (fun v -> cb v) in - let _ = obj#misc#connect#destroy (fun () -> pref#connect#disconnect p_id) in + let p_id = pref#connect#changed ~callback:(fun v -> cb v) in + let _ = obj#misc#connect#destroy ~callback:(fun () -> pref#connect#disconnect p_id) in () (** Useful marshallers *) @@ -314,7 +316,7 @@ let attach_modifiers (pref : string preference) prefix = in GtkData.AccelMap.foreach change in - pref#connect#changed cb + pref#connect#changed ~callback:cb let modifier_for_navigation = new preference ~name:["modifier_for_navigation"] ~init:"<Control>" ~repr:Repr.(string) @@ -360,7 +362,7 @@ object ~name:["doc_url"] ~init:Coq_config.wwwrefman ~repr:Repr.(string) as super - method set v = + method! set v = if not (Flags.is_standard_doc_url v) && v <> use_default_doc_url && (* Extra hack to support links to last released doc version *) @@ -407,11 +409,15 @@ let opposite_tabs = let background_color = new preference ~name:["background_color"] ~init:"cornsilk" ~repr:Repr.(string) +let attach_tag (pref : string preference) (tag : GText.tag) f = + tag#set_property (f pref#get); + pref#connect#changed ~callback:(fun c -> tag#set_property (f c)) + let attach_bg (pref : string preference) (tag : GText.tag) = - pref#connect#changed (fun c -> tag#set_property (`BACKGROUND c)) + attach_tag pref tag (fun c -> `BACKGROUND c) let attach_fg (pref : string preference) (tag : GText.tag) = - pref#connect#changed (fun c -> tag#set_property (`FOREGROUND c)) + attach_tag pref tag (fun c -> `FOREGROUND c) let processing_color = new preference ~name:["processing_color"] ~init:"light blue" ~repr:Repr.(string) @@ -468,7 +474,7 @@ let create_tag name default = let iter table = let tag = GText.tag ~name () in table#add tag#as_tag; - ignore (pref#connect#changed (fun _ -> set_tag tag)); + ignore (pref#connect#changed ~callback:(fun _ -> set_tag tag)); set_tag tag; in List.iter iter [Tags.Script.table; Tags.Proof.table; Tags.Message.table]; @@ -601,8 +607,8 @@ object (self) box#pack italic#coerce; box#pack underline#coerce; let cb but obj = obj#set_sensitive (not but#active) in - let _ = fg_unset#connect#toggled (fun () -> cb fg_unset fg_color#misc) in - let _ = bg_unset#connect#toggled (fun () -> cb bg_unset bg_color#misc) in + let _ = fg_unset#connect#toggled ~callback:(fun () -> cb fg_unset fg_color#misc) in + let _ = bg_unset#connect#toggled ~callback:(fun () -> cb bg_unset bg_color#misc) in () end @@ -643,6 +649,10 @@ let pmodifiers ?(all = false) name p = modifiers name (str_to_mod_list p#get) +[@@@ocaml.warning "-3"] (* String.uppercase_ascii since 4.03.0 GPR#124 *) +let uppercase = String.uppercase +[@@@ocaml.warning "+3"] + let configure ?(apply=(fun () -> ())) () = let cmd_coqtop = string @@ -692,7 +702,7 @@ let configure ?(apply=(fun () -> ())) () = ~color:(Tags.color_of_string pref#get) ~packing:(table#attach ~left:1 ~top:i) () in - let _ = button#connect#color_set begin fun () -> + let _ = button#connect#color_set ~callback:begin fun () -> pref#set (Tags.string_of_color button#color) end in let reset _ = @@ -754,7 +764,7 @@ let configure ?(apply=(fun () -> ())) () = let button text (pref : bool preference) = let active = pref#get in let but = GButton.check_button ~label:text ~active ~packing:box#pack () in - ignore (but#connect#toggled (fun () -> pref#set but#active)) + ignore (but#connect#toggled ~callback:(fun () -> pref#set but#active)) in let () = button "Dynamic word wrap" dynamic_word_wrap in let () = button "Show line number" show_line_number in @@ -918,7 +928,7 @@ let configure ?(apply=(fun () -> ())) () = in let doc_url = let predefined = [ - "file://"^(List.fold_left Filename.concat (Coq_config.docdir) ["refman";"html"]); + "file://"^(List.fold_left Filename.concat (Envars.docdir ()) ["refman";"html"]); Coq_config.wwwrefman; use_default_doc_url ] in @@ -931,7 +941,7 @@ let configure ?(apply=(fun () -> ())) () = doc_url#get in let library_url = let predefined = [ - "file://"^(List.fold_left Filename.concat (Coq_config.docdir) ["stdlib";"html"]); + "file://"^(List.fold_left Filename.concat (Envars.docdir ()) ["stdlib";"html"]); Coq_config.wwwstdlib ] in combo @@ -969,7 +979,7 @@ let configure ?(apply=(fun () -> ())) () = let k = if Int.equal (CString.length k) 1 && Util.is_letter k.[0] then k else "" in - let k = CString.uppercase k in + let k = uppercase k in [q, k] in diff --git a/ide/preferences.mli b/ide/preferences.mli index 801869d1..ccf028ae 100644 --- a/ide/preferences.mli +++ b/ide/preferences.mli @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) val lang_manager : GSourceView2.source_language_manager diff --git a/ide/project_file.ml4 b/ide/project_file.ml4 deleted file mode 100644 index de0720e0..00000000 --- a/ide/project_file.ml4 +++ /dev/null @@ -1,202 +0,0 @@ -type target = - | ML of string (* ML file : foo.ml -> (ML "foo.ml") *) - | MLI of string (* MLI file : foo.mli -> (MLI "foo.mli") *) - | ML4 of string (* ML4 file : foo.ml4 -> (ML4 "foo.ml4") *) - | MLLIB of string (* MLLIB file : foo.mllib -> (MLLIB "foo.mllib") *) - | MLPACK of string (* MLLIB file : foo.mlpack -> (MLLIB "foo.mlpack") *) - | V of string (* V file : foo.v -> (V "foo") *) - | Arg of string - | Special of string * string * bool * string - (* file, dependencies, is_phony, command *) - | Subdir of string - | Def of string * string (* X=foo -> Def ("X","foo") *) - | MLInclude of string (* -I physicalpath *) - | Include of string * string (* -Q physicalpath logicalpath *) - | RInclude of string * string (* -R physicalpath logicalpath *) - -type install = - | NoInstall - | TraditionalInstall - | UserInstall - | UnspecInstall - -exception Parsing_error -let rec parse_string = parser - | [< '' ' | '\n' | '\t' >] -> "" - | [< 'c; s >] -> (String.make 1 c)^(parse_string s) - | [< >] -> "" -and parse_string2 = parser - | [< ''"' >] -> "" - | [< 'c; s >] -> (String.make 1 c)^(parse_string2 s) - | [< >] -> raise Parsing_error -and parse_skip_comment = parser - | [< ''\n'; s >] -> s - | [< 'c; s >] -> parse_skip_comment s - | [< >] -> [< >] -and parse_args = parser - | [< '' ' | '\n' | '\t'; s >] -> parse_args s - | [< ''#'; s >] -> parse_args (parse_skip_comment s) - | [< ''"'; str = parse_string2; s >] -> ("" ^ str) :: parse_args s - | [< 'c; str = parse_string; s >] -> ((String.make 1 c) ^ str) :: (parse_args s) - | [< >] -> [] - - -let parse f = - let c = open_in f in - let res = parse_args (Stream.of_channel c) in - close_in c; - res - -let rec process_cmd_line orig_dir ((project_file,makefile,install,opt) as opts) l = function - | [] -> opts, l - | ("-h"|"--help") :: _ -> - raise Parsing_error - | ("-no-opt"|"-byte") :: r -> - process_cmd_line orig_dir (project_file,makefile,install,false) l r - | ("-full"|"-opt") :: r -> - process_cmd_line orig_dir (project_file,makefile,install,true) l r - | "-impredicative-set" :: r -> - Feedback.msg_warning (Pp.str "Please now use \"-arg -impredicative-set\" instead of \"-impredicative-set\" alone to be more uniform."); - process_cmd_line orig_dir opts (Arg "-impredicative-set" :: l) r - | "-no-install" :: r -> - Feedback.msg_warning (Pp.(++) (Pp.str "Option -no-install is deprecated.") (Pp.(++) (Pp.spc ()) (Pp.str "Use \"-install none\" instead"))); - process_cmd_line orig_dir (project_file,makefile,NoInstall,opt) l r - | "-install" :: d :: r -> - if install <> UnspecInstall then Feedback.msg_warning (Pp.str "-install sets more than once."); - let install = - match d with - | "user" -> UserInstall - | "none" -> NoInstall - | "global" -> TraditionalInstall - | _ -> Feedback.msg_warning (Pp.(++) (Pp.str "invalid option '") (Pp.(++) (Pp.str d) (Pp.str "' passed to -install."))); - install - in - process_cmd_line orig_dir (project_file,makefile,install,opt) l r - | "-custom" :: com :: dependencies :: file :: r -> - Feedback.msg_warning (Pp.app - (Pp.str "Please now use \"-extra[-phony] result deps command\" instead of \"-custom command deps result\".") - (Pp.pr_arg Pp.str "It follows makefile target declaration order and has a clearer semantic.") - ); - process_cmd_line orig_dir opts (Special (file,dependencies,false,com) :: l) r - | "-extra" :: file :: dependencies :: com :: r -> - process_cmd_line orig_dir opts (Special (file,dependencies,false,com) :: l) r - | "-extra-phony" :: target :: dependencies :: com :: r -> - process_cmd_line orig_dir opts (Special (target,dependencies,true,com) :: l) r - | "-Q" :: d :: lp :: r -> - process_cmd_line orig_dir opts ((Include (CUnix.correct_path d orig_dir, lp)) :: l) r - | "-I" :: d :: r -> - process_cmd_line orig_dir opts ((MLInclude (CUnix.correct_path d orig_dir)) :: l) r - | "-R" :: p :: lp :: r -> - process_cmd_line orig_dir opts (RInclude (CUnix.correct_path p orig_dir,lp) :: l) r - | ("-Q"|"-R"|"-I"|"-custom"|"-extra"|"-extra-phony") :: _ -> - raise Parsing_error - | "-f" :: file :: r -> - let file = CUnix.remove_path_dot (CUnix.correct_path file orig_dir) in - let () = match project_file with - | None -> () - | Some _ -> Feedback.msg_warning (Pp.str - "Several features will not work with multiple project files.") - in - let (opts',l') = process_cmd_line (Filename.dirname file) (Some file,makefile,install,opt) l (parse file) in - process_cmd_line orig_dir opts' l' r - | ["-f"] -> - raise Parsing_error - | "-o" :: file :: r -> - begin try - let _ = String.index file '/' in - raise Parsing_error - with Not_found -> - let () = match makefile with - |None -> () - |Some f -> - Feedback.msg_warning (Pp.(++) (Pp.str "Only one output file is genererated. ") (Pp.(++) (Pp.str f) (Pp.str " will not be."))) - in process_cmd_line orig_dir (project_file,Some file,install,opt) l r - end - | v :: "=" :: def :: r -> - process_cmd_line orig_dir opts (Def (v,def) :: l) r - | "-arg" :: a :: r -> - process_cmd_line orig_dir opts (Arg a :: l) r - | f :: r -> - let f = CUnix.correct_path f orig_dir in - process_cmd_line orig_dir opts (( - if Filename.check_suffix f ".v" then V f - else if (Filename.check_suffix f ".ml") then ML f - else if (Filename.check_suffix f ".ml4") then ML4 f - else if (Filename.check_suffix f ".mli") then MLI f - else if (Filename.check_suffix f ".mllib") then MLLIB f - else if (Filename.check_suffix f ".mlpack") then MLPACK f - else Subdir f) :: l) r - -let process_cmd_line orig_dir opts l args = - let (opts, l) = process_cmd_line orig_dir opts l args in - opts, List.rev l - -let rec post_canonize f = - if Filename.basename f = Filename.current_dir_name - then let dir = Filename.dirname f in - if dir = Filename.current_dir_name then f else post_canonize dir - else f - -(* Return: ((v,(mli,ml4,ml,mllib,mlpack),special,subdir),(ml_inc,q_inc,r_inc),(args,defs)) *) -let split_arguments args = - List.fold_right - (fun a ((v,(mli,ml4,ml,mllib,mlpack as m),o,s as t), - (ml_inc,q_inc,r_inc as i),(args,defs as d)) -> - match a with - | V n -> - ((CUnix.remove_path_dot n::v,m,o,s),i,d) - | ML n -> - ((v,(mli,ml4,CUnix.remove_path_dot n::ml,mllib,mlpack),o,s),i,d) - | MLI n -> - ((v,(CUnix.remove_path_dot n::mli,ml4,ml,mllib,mlpack),o,s),i,d) - | ML4 n -> - ((v,(mli,CUnix.remove_path_dot n::ml4,ml,mllib,mlpack),o,s),i,d) - | MLLIB n -> - ((v,(mli,ml4,ml,CUnix.remove_path_dot n::mllib,mlpack),o,s),i,d) - | MLPACK n -> - ((v,(mli,ml4,ml,mllib,CUnix.remove_path_dot n::mlpack),o,s),i,d) - | Special (n,dep,is_phony,c) -> - ((v,m,(n,dep,is_phony,c)::o,s),i,d) - | Subdir n -> - ((v,m,o,n::s),i,d) - | MLInclude p -> - let ml_new = (CUnix.remove_path_dot (post_canonize p), - CUnix.canonical_path_name p) in - (t,(ml_new::ml_inc,q_inc,r_inc),d) - | Include (p,l) -> - let q_new = (CUnix.remove_path_dot (post_canonize p),l, - CUnix.canonical_path_name p) in - (t,(ml_inc,q_new::q_inc,r_inc),d) - | RInclude (p,l) -> - let r_new = (CUnix.remove_path_dot (post_canonize p),l, - CUnix.canonical_path_name p) in - (t,(ml_inc,q_inc,r_new::r_inc),d) - | Def (v,def) -> - (t,i,(args,(v,def)::defs)) - | Arg a -> - (t,i,(a::args,defs))) - args (([],([],[],[],[],[]),[],[]),([],[],[]),([],[])) - -let read_project_file f = - split_arguments - (snd (process_cmd_line (Filename.dirname f) (Some f, None, NoInstall, true) [] (parse f))) - -let args_from_project file project_files default_name = - let build_cmd_line ml_inc i_inc r_inc args = - List.fold_right (fun (_,i) o -> "-I" :: i :: o) ml_inc - (List.fold_right (fun (_,l,i) o -> "-Q" :: i :: l :: o) i_inc - (List.fold_right (fun (_,l,p) o -> "-R" :: p :: l :: o) r_inc - (List.fold_right (fun a o -> parse_args (Stream.of_string a) @ o) args []))) - in try - let (fname,(_,(ml_inc,i_inc,r_inc),(args,_))) = List.hd project_files in - fname, build_cmd_line ml_inc i_inc r_inc args - with Failure _ -> - let rec find_project_file dir = try - let fname = Filename.concat dir default_name in - let ((v_files,_,_,_),(ml_inc,i_inc,r_inc),(args,_)) = - read_project_file fname in - fname, build_cmd_line ml_inc i_inc r_inc args - with Sys_error s -> - let newdir = Filename.dirname dir in - if dir = newdir then "",[] else find_project_file newdir - in find_project_file (Filename.dirname file) diff --git a/ide/richpp.ml b/ide/richpp.ml new file mode 100644 index 00000000..19e9799c --- /dev/null +++ b/ide/richpp.ml @@ -0,0 +1,171 @@ +(************************************************************************) +(* * 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) *) +(************************************************************************) + +open Util +open Xml_datatype + +type 'annotation located = { + annotation : 'annotation option; + startpos : int; + endpos : int +} + +type 'a stack = +| Leaf +| Node of string * 'a located gxml list * int * 'a stack + +type 'a context = { + mutable stack : 'a stack; + (** Pending opened nodes *) + mutable offset : int; + (** Quantity of characters printed so far *) +} + +(** We use Format to introduce tags inside the pretty-printed document. + Each inserted tag is a fresh index that we keep in sync with the contents + of annotations. + + We build an XML tree on the fly, by plugging ourselves in Format tag + marking functions. As those functions are called when actually writing to + the device, the resulting tree is correct. +*) +let rich_pp width ppcmds = + + let context = { + stack = Leaf; + offset = 0; + } in + + let pp_buffer = Buffer.create 180 in + + let push_pcdata () = + (** Push the optional PCData on the above node *) + let len = Buffer.length pp_buffer in + if len = 0 then () + else match context.stack with + | Leaf -> assert false + | Node (node, child, pos, ctx) -> + let data = Buffer.contents pp_buffer in + let () = Buffer.clear pp_buffer in + let () = context.stack <- Node (node, PCData data :: child, pos, ctx) in + context.offset <- context.offset + len + in + + let open_xml_tag tag = + let () = push_pcdata () in + context.stack <- Node (tag, [], context.offset, context.stack) + in + + let close_xml_tag tag = + let () = push_pcdata () in + match context.stack with + | Leaf -> assert false + | Node (node, child, pos, ctx) -> + let () = assert (String.equal tag node) in + let annotation = { + annotation = Some tag; + startpos = pos; + endpos = context.offset; + } in + let xml = Element (node, annotation, List.rev child) in + match ctx with + | Leaf -> + (** Final node: we keep the result in a dummy context *) + context.stack <- Node ("", [xml], 0, Leaf) + | Node (node, child, pos, ctx) -> + context.stack <- Node (node, xml :: child, pos, ctx) + in + + let open Format in + + let ft = formatter_of_buffer pp_buffer in + + let tag_functions = { + mark_open_tag = (fun tag -> let () = open_xml_tag tag in ""); + mark_close_tag = (fun tag -> let () = close_xml_tag tag in ""); + print_open_tag = ignore; + print_close_tag = ignore; + } in + + pp_set_formatter_tag_functions ft tag_functions; + pp_set_mark_tags ft true; + + (* Setting the formatter *) + pp_set_margin ft width; + let m = max (64 * width / 100) (width-30) in + pp_set_max_indent ft m; + pp_set_max_boxes ft 50 ; + pp_set_ellipsis_text ft "..."; + + (** The whole output must be a valid document. To that + end, we nest the document inside <pp> tags. *) + pp_open_box ft 0; + pp_open_tag ft "pp"; + Pp.(pp_with ft ppcmds); + pp_close_tag ft (); + pp_close_box ft (); + + (** Get the resulting XML tree. *) + let () = pp_print_flush ft () in + let () = assert (Buffer.length pp_buffer = 0) in + match context.stack with + | Node ("", [xml], 0, Leaf) -> xml + | _ -> assert false + + +let annotations_positions xml = + let rec node accu = function + | Element (_, { annotation = Some annotation; startpos; endpos }, cs) -> + children ((annotation, (startpos, endpos)) :: accu) cs + | Element (_, _, cs) -> + children accu cs + | _ -> + accu + and children accu cs = + List.fold_left node accu cs + in + node [] xml + +let xml_of_rich_pp tag_of_annotation attributes_of_annotation xml = + let rec node = function + | Element (index, { annotation; startpos; endpos }, cs) -> + let attributes = + [ "startpos", string_of_int startpos; + "endpos", string_of_int endpos + ] + @ (match annotation with + | None -> [] + | Some annotation -> attributes_of_annotation annotation + ) + in + let tag = + match annotation with + | None -> index + | Some annotation -> tag_of_annotation annotation + in + Element (tag, attributes, List.map node cs) + | PCData s -> + PCData s + in + node xml + +type richpp = xml + +let richpp_of_pp width pp = + let rec drop = function + | PCData s -> [PCData s] + | Element (_, annotation, cs) -> + let cs = List.concat (List.map drop cs) in + match annotation.annotation with + | None -> cs + | Some s -> [Element (s, [], cs)] + in + let xml = rich_pp width pp in + Element ("_", [], drop xml) diff --git a/ide/richpp.mli b/ide/richpp.mli new file mode 100644 index 00000000..31fc7b56 --- /dev/null +++ b/ide/richpp.mli @@ -0,0 +1,53 @@ +(************************************************************************) +(* * 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) *) +(************************************************************************) + +(** This module offers semi-structured pretty-printing. *) + +(** Each annotation of the semi-structured document refers to the + substring it annotates. *) +type 'annotation located = { + annotation : 'annotation option; + startpos : int; + endpos : int +} + +(* XXX: The width parameter should be moved to a `formatter_property` + record shared with Topfmt *) + +(** [rich_pp width ppcmds] returns the interpretation + of [ppcmds] as a semi-structured document + that represents (located) annotations of this string. + The [get_annotations] function is used to convert tags into the desired + annotation. [width] sets the printing witdh of the formatter. *) +val rich_pp : int -> Pp.t -> Pp.pp_tag located Xml_datatype.gxml + +(** [annotations_positions ssdoc] returns a list associating each + annotations with its position in the string from which [ssdoc] is + built. *) +val annotations_positions : + 'annotation located Xml_datatype.gxml -> + ('annotation * (int * int)) list + +(** [xml_of_rich_pp ssdoc] returns an XML representation of the + semi-structured document [ssdoc]. *) +val xml_of_rich_pp : + ('annotation -> string) -> + ('annotation -> (string * string) list) -> + 'annotation located Xml_datatype.gxml -> + Xml_datatype.xml + +(** {5 Enriched text} *) + +type richpp = Xml_datatype.xml + +(** Type of text with style annotations *) + +val richpp_of_pp : int -> Pp.t -> richpp +(** Extract style information from formatted text *) diff --git a/ide/richprinter.ml b/ide/richprinter.ml deleted file mode 100644 index 5f39f36e..00000000 --- a/ide/richprinter.ml +++ /dev/null @@ -1,24 +0,0 @@ -open Richpp - -module RichppConstr = Ppconstr.Richpp -module RichppVernac = Ppvernac.Richpp -module RichppTactic = Pptactic.Richpp - -type rich_pp = - Ppannotation.t Richpp.located Xml_datatype.gxml - * Xml_datatype.xml - -let get_annotations obj = Pp.Tag.prj obj Ppannotation.tag - -let make_richpp pr ast = - let rich_pp = - rich_pp get_annotations (pr ast) - in - let xml = Ppannotation.( - xml_of_rich_pp tag_of_annotation attributes_of_annotation rich_pp - ) - in - (rich_pp, xml) - -let richpp_vernac = make_richpp RichppVernac.pr_vernac -let richpp_constr = make_richpp RichppConstr.pr_constr_expr diff --git a/ide/richprinter.mli b/ide/richprinter.mli deleted file mode 100644 index c9e84e3e..00000000 --- a/ide/richprinter.mli +++ /dev/null @@ -1,36 +0,0 @@ -(************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) -(* \VV/ **************************************************************) -(* // * This file is distributed under the terms of the *) -(* * GNU Lesser General Public License Version 2.1 *) -(************************************************************************) - -(** This module provides an entry point to "rich" pretty-printers that - produce pretty-printing as done by {!Printer} but with additional - annotations represented as a semi-structured document. - - To understand what are these annotations and how they are represented - as standard XML attributes, please refer to {!Ppannotation}. - - In addition to these annotations, each node of the semi-structured - document contains a [startpos] and an [endpos] attribute that - relate this node to the raw pretty-printing. - Please refer to {!Richpp} for more details. *) - -(** A rich pretty-print is composed of: *) -type rich_pp = - - (** - a generalized semi-structured document whose attributes are - annotations ; *) - Ppannotation.t Richpp.located Xml_datatype.gxml - - (** - an XML document, representing annotations as usual textual - XML attributes. *) - * Xml_datatype.xml - -(** [richpp_vernac phrase] produces a rich pretty-printing of [phrase]. *) -val richpp_vernac : Vernacexpr.vernac_expr -> rich_pp - -(** [richpp_constr constr] produces a rich pretty-printing of [constr]. *) -val richpp_constr : Constrexpr.constr_expr -> rich_pp diff --git a/ide/sentence.ml b/ide/sentence.ml index e332682d..2f7820a7 100644 --- a/ide/sentence.ml +++ b/ide/sentence.ml @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) (** {1 Sentences in coqide buffers } *) diff --git a/ide/sentence.mli b/ide/sentence.mli index feb3c0ac..75c815c5 100644 --- a/ide/sentence.mli +++ b/ide/sentence.mli @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) (** Retag the ends of sentences around an inserted zone *) diff --git a/ide/serialize.ml b/ide/serialize.ml index 7b568501..86074d44 100644 --- a/ide/serialize.ml +++ b/ide/serialize.ml @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) open Xml_datatype diff --git a/ide/serialize.mli b/ide/serialize.mli index bf9e184e..af082f25 100644 --- a/ide/serialize.mli +++ b/ide/serialize.mli @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) open Xml_datatype diff --git a/ide/session.ml b/ide/session.ml index fc6340d2..be2bfe06 100644 --- a/ide/session.ml +++ b/ide/session.ml @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) open Preferences @@ -31,7 +33,7 @@ type session = { buffer : GText.buffer; script : Wg_ScriptView.script_view; proof : Wg_ProofView.proof_view; - messages : Wg_MessageView.message_view; + messages : Wg_RoutedMessageViews.message_views_router; segment : Wg_Segment.segment; fileops : FileOps.ops; coqops : CoqOps.ops; @@ -209,10 +211,7 @@ let set_buffer_handlers let mark_set_cb it m = debug_edit_zone (); let ins = get_insert () in - let line = ins#line + 1 in - let off = ins#line_offset + 1 in - let msg = Printf.sprintf "Line: %5d Char: %3d" line off in - let () = !Ideutils.set_location msg in + let () = Ideutils.display_location ins in match GtkText.Mark.get_name m with | Some "insert" -> () | Some s -> Minilib.log (s^" moved") @@ -249,8 +248,8 @@ let make_table_widget ?sort cd cb = let () = data#set_headers_visible true in let () = data#set_headers_clickable true in let refresh clr = data#misc#modify_base [`NORMAL, `NAME clr] in - let _ = background_color#connect#changed refresh in - let _ = data#misc#connect#realize (fun () -> refresh background_color#get) in + let _ = background_color#connect#changed ~callback:refresh in + let _ = data#misc#connect#realize ~callback:(fun () -> refresh background_color#get) in let mk_rend c = GTree.cell_renderer_text [], ["text",c] in let cols = List.map2 (fun (_,c) (_,n,v) -> @@ -308,8 +307,8 @@ let create_errpage (script : Wg_ScriptView.script_view) : errpage = !callback errs; List.iter (fun (lno, msg) -> access (fun columns store -> let line = store#append () in - store#set line (find_int_col "Line" columns) lno; - store#set line (find_string_col "Error message" columns) msg)) + store#set ~row:line ~column:(find_int_col "Line" columns) lno; + store#set ~row:line ~column:(find_string_col "Error message" columns) msg)) errs end method on_update ~callback:cb = callback := cb @@ -348,8 +347,8 @@ let create_jobpage coqtop coqops : jobpage = else false) else let line = store#append () in - store#set line column id; - store#set line (find_string_col "Job name" columns) job)) + store#set ~row:line ~column id; + store#set ~row:line ~column:(find_string_col "Job name" columns) job)) jobs end method on_update ~callback:cb = callback := cb @@ -367,7 +366,7 @@ let create_proof () = let create_messages () = let messages = Wg_MessageView.message_view () in let _ = messages#misc#set_can_focus true in - messages + Wg_RoutedMessageViews.message_views ~route_0:messages let dummy_control : control = object @@ -386,12 +385,12 @@ let create file coqtop_args = let proof = create_proof () in let messages = create_messages () in let segment = new Wg_Segment.segment () in - let command = new Wg_Command.command_window basename coqtop in let finder = new Wg_Find.finder basename (script :> GText.view) in let fops = new FileOps.fileops (buffer :> GText.buffer) file reset in let _ = fops#update_stats in let cops = new CoqOps.coqops script proof messages segment coqtop (fun () -> fops#filename) in + let command = new Wg_Command.command_window basename coqtop cops messages in let errpage = create_errpage script in let jobpage = create_jobpage coqtop cops in let _ = set_buffer_handlers (buffer :> GText.buffer) script cops coqtop in @@ -512,12 +511,12 @@ let build_layout (sn:session) = sn.command#pack_in (session_paned#pack2 ~shrink:false ~resize:false); script_scroll#add sn.script#coerce; proof_scroll#add sn.proof#coerce; - let detach, _ = add_msg_page 0 sn.tab_label#text "Messages" sn.messages#coerce in + let detach, _ = add_msg_page 0 sn.tab_label#text "Messages" sn.messages#default_route#coerce in let _, label = add_msg_page 1 sn.tab_label#text "Errors" sn.errpage#coerce in let _, _ = add_msg_page 2 sn.tab_label#text "Jobs" sn.jobpage#coerce in (** When a message is received, focus on the message pane *) let _ = - sn.messages#connect#pushed ~callback:(fun _ _ -> + sn.messages#default_route#connect#pushed ~callback:(fun _ _ -> let num = message_frame#page_num detach#coerce in if 0 <= num then message_frame#goto_page num ) diff --git a/ide/session.mli b/ide/session.mli index 028a1f9d..bb381690 100644 --- a/ide/session.mli +++ b/ide/session.mli @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) (** A session is a script buffer + proof + messages, @@ -29,7 +31,7 @@ type session = { buffer : GText.buffer; script : Wg_ScriptView.script_view; proof : Wg_ProofView.proof_view; - messages : Wg_MessageView.message_view; + messages : Wg_RoutedMessageViews.message_views_router; segment : Wg_Segment.segment; fileops : FileOps.ops; coqops : CoqOps.ops; diff --git a/ide/tags.ml b/ide/tags.ml index e4510e7a..60195e8a 100644 --- a/ide/tags.ml +++ b/ide/tags.ml @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) @@ -15,33 +17,22 @@ let make_tag (tt:GText.tag_table) ~name prop = module Script = struct + (* More recently defined tags have highest priority in case of overlapping *) let table = GText.tag_table () - let comment = make_tag table ~name:"comment" [] - let error = make_tag table ~name:"error" [`UNDERLINE `SINGLE] let warning = make_tag table ~name:"warning" [`UNDERLINE `SINGLE; `FOREGROUND "blue"] + let error = make_tag table ~name:"error" [`UNDERLINE `SINGLE] let error_bg = make_tag table ~name:"error_bg" [] let to_process = make_tag table ~name:"to_process" [] let processed = make_tag table ~name:"processed" [] - let incomplete = make_tag table ~name:"incomplete" [ - `BACKGROUND_STIPPLE_SET true; - ] + let incomplete = make_tag table ~name:"incomplete" [`BACKGROUND_STIPPLE_SET true] let unjustified = make_tag table ~name:"unjustified" [`BACKGROUND "gold"] - let found = make_tag table ~name:"found" [`BACKGROUND "blue"; `FOREGROUND "white"] - let sentence = make_tag table ~name:"sentence" [] let tooltip = make_tag table ~name:"tooltip" [] (* debug:`BACKGROUND "blue" *) - let ephemere = [error; warning; error_bg; tooltip; processed; to_process; incomplete; unjustified] - - let all = - comment :: found :: sentence :: ephemere - - let edit_zone = - let t = make_tag table ~name:"edit_zone" [`UNDERLINE `SINGLE] in - t#set_priority (List.length all); - t - let all = edit_zone :: all - + let comment = make_tag table ~name:"comment" [] + let sentence = make_tag table ~name:"sentence" [] + let edit_zone = make_tag table ~name:"edit_zone" [`UNDERLINE `SINGLE] (* for debugging *) + let all = edit_zone :: comment :: sentence :: ephemere end module Proof = struct diff --git a/ide/tags.mli b/ide/tags.mli index 02e15a5a..3194f879 100644 --- a/ide/tags.mli +++ b/ide/tags.mli @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) module Script : @@ -17,7 +19,6 @@ sig val processed : GText.tag val incomplete : GText.tag val unjustified : GText.tag - val found : GText.tag val sentence : GText.tag val tooltip : GText.tag val edit_zone : GText.tag (* for debugging *) diff --git a/ide/texmacspp.ml b/ide/texmacspp.ml deleted file mode 100644 index 680da7f5..00000000 --- a/ide/texmacspp.ml +++ /dev/null @@ -1,768 +0,0 @@ -(************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) -(* \VV/ **************************************************************) -(* // * This file is distributed under the terms of the *) -(* * GNU Lesser General Public License Version 2.1 *) -(************************************************************************) - -open Xml_datatype -open Vernacexpr -open Constrexpr -open Names -open Misctypes -open Bigint -open Decl_kinds -open Extend -open Libnames - -let unlock loc = - let start, stop = Loc.unloc loc in - (string_of_int start, string_of_int stop) - -let xmlWithLoc loc ename attr xml = - let start, stop = unlock loc in - Element(ename, [ "begin", start; "end", stop ] @ attr, xml) - -let get_fst_attr_in_xml_list attr xml_list = - let attrs_list = - List.map (function - | Element (_, attrs, _) -> (List.filter (fun (a,_) -> a = attr) attrs) - | _ -> []) - xml_list in - match List.flatten attrs_list with - | [] -> (attr, "") - | l -> (List.hd l) - -let backstep_loc xmllist = - let start_att = get_fst_attr_in_xml_list "begin" xmllist in - let stop_att = get_fst_attr_in_xml_list "end" (List.rev xmllist) in - [start_att ; stop_att] - -let compare_begin_att xml1 xml2 = - let att1 = get_fst_attr_in_xml_list "begin" [xml1] in - let att2 = get_fst_attr_in_xml_list "begin" [xml2] in - match att1, att2 with - | (_, s1), (_, s2) when s1 == "" || s2 == "" -> 0 - | (_, s1), (_, s2) when int_of_string s1 > int_of_string s2 -> 1 - | (_, s1), (_, s2) when int_of_string s1 < int_of_string s2 -> -1 - | _ -> 0 - -let xmlBeginSection loc name = xmlWithLoc loc "beginsection" ["name", name] [] - -let xmlEndSegment loc name = xmlWithLoc loc "endsegment" ["name", name] [] - -let xmlThm typ name loc xml = - xmlWithLoc loc "theorem" ["type", typ; "name", name] xml - -let xmlDef typ name loc xml = - xmlWithLoc loc "definition" ["type", typ; "name", name] xml - -let xmlNotation attr name loc xml = - xmlWithLoc loc "notation" (("name", name) :: attr) xml - -let xmlReservedNotation attr name loc = - xmlWithLoc loc "reservednotation" (("name", name) :: attr) [] - -let xmlCst name ?(attr=[]) loc = - xmlWithLoc loc "constant" (("name", name) :: attr) [] - -let xmlOperator name ?(attr=[]) ?(pprules=[]) loc = - xmlWithLoc loc "operator" - (("name", name) :: List.map (fun (a,b) -> "format"^a,b) pprules @ attr) [] - -let xmlApply loc ?(attr=[]) xml = xmlWithLoc loc "apply" attr xml - -let xmlToken loc ?(attr=[]) xml = xmlWithLoc loc "token" attr xml - -let xmlTyped xml = Element("typed", (backstep_loc xml), xml) - -let xmlReturn ?(attr=[]) xml = Element("return", attr, xml) - -let xmlCase xml = Element("case", [], xml) - -let xmlScrutinee ?(attr=[]) xml = Element("scrutinee", attr, xml) - -let xmlWith xml = Element("with", [], xml) - -let xmlAssign id xml = Element("assign", ["target",string_of_id id], [xml]) - -let xmlInductive kind loc xml = xmlWithLoc loc "inductive" ["kind",kind] xml - -let xmlCoFixpoint xml = Element("cofixpoint", [], xml) - -let xmlFixpoint xml = Element("fixpoint", [], xml) - -let xmlCheck loc xml = xmlWithLoc loc "check" [] xml - -let xmlAssumption kind loc xml = xmlWithLoc loc "assumption" ["kind",kind] xml - -let xmlComment loc xml = xmlWithLoc loc "comment" [] xml - -let xmlCanonicalStructure attr loc = xmlWithLoc loc "canonicalstructure" attr [] - -let xmlQed ?(attr=[]) loc = xmlWithLoc loc "qed" attr [] - -let xmlPatvar id loc = xmlWithLoc loc "patvar" ["id", id] [] - -let xmlReference ref = - let name = Libnames.string_of_reference ref in - let i, j = Loc.unloc (Libnames.loc_of_reference ref) in - let b, e = string_of_int i, string_of_int j in - Element("reference",["name", name; "begin", b; "end", e] ,[]) - -let xmlRequire loc ?(attr=[]) xml = xmlWithLoc loc "require" attr xml -let xmlImport loc ?(attr=[]) xml = xmlWithLoc loc "import" attr xml - -let xmlAddLoadPath loc ?(attr=[]) xml = xmlWithLoc loc "addloadpath" attr xml -let xmlRemoveLoadPath loc ?(attr=[]) = xmlWithLoc loc "removeloadpath" attr -let xmlAddMLPath loc ?(attr=[]) = xmlWithLoc loc "addmlpath" attr - -let xmlExtend loc xml = xmlWithLoc loc "extend" [] xml - -let xmlScope loc action ?(attr=[]) name xml = - xmlWithLoc loc "scope" (["name",name;"action",action] @ attr) xml - -let xmlProofMode loc name = xmlWithLoc loc "proofmode" ["name",name] [] - -let xmlProof loc xml = xmlWithLoc loc "proof" [] xml - -let xmlRawTactic name rtac = - Element("rawtactic", ["name",name], - [PCData (Pp.string_of_ppcmds (Pptactic.pr_raw_tactic rtac))]) - -let xmlSectionSubsetDescr name ssd = - Element("sectionsubsetdescr",["name",name], - [PCData (Proof_using.to_string ssd)]) - -let xmlDeclareMLModule loc s = - xmlWithLoc loc "declarexmlmodule" [] - (List.map (fun x -> Element("path",["value",x],[])) s) - -(* tactics *) -let xmlLtac loc xml = xmlWithLoc loc "ltac" [] xml - -(* toplevel commands *) -let xmlGallina loc xml = xmlWithLoc loc "gallina" [] xml - -let xmlTODO loc x = - xmlWithLoc loc "todo" [] [PCData (Pp.string_of_ppcmds (Ppvernac.pr_vernac x))] - -let string_of_name n = - match n with - | Anonymous -> "_" - | Name id -> Id.to_string id - -let string_of_glob_sort s = - match s with - | GProp -> "Prop" - | GSet -> "Set" - | GType _ -> "Type" - -let string_of_cast_sort c = - match c with - | CastConv _ -> "CastConv" - | CastVM _ -> "CastVM" - | CastNative _ -> "CastNative" - | CastCoerce -> "CastCoerce" - -let string_of_case_style s = - match s with - | LetStyle -> "Let" - | IfStyle -> "If" - | LetPatternStyle -> "LetPattern" - | MatchStyle -> "Match" - | RegularStyle -> "Regular" - -let attribute_of_syntax_modifier sm = -match sm with - | SetItemLevel (sl, NumLevel n) -> - List.map (fun s -> ("itemlevel", s)) sl @ ["level", string_of_int n] - | SetItemLevel (sl, NextLevel) -> - List.map (fun s -> ("itemlevel", s)) sl @ ["level", "next"] - | SetLevel i -> ["level", string_of_int i] - | SetAssoc a -> - begin match a with - | NonA -> ["",""] - | RightA -> ["associativity", "right"] - | LeftA -> ["associativity", "left"] - end - | SetEntryType (s, _) -> ["entrytype", s] - | SetOnlyPrinting -> ["onlyprinting", ""] - | SetOnlyParsing -> ["onlyparsing", ""] - | SetCompatVersion v -> ["compat", Flags.pr_version v] - | SetFormat (system, (loc, s)) -> - let start, stop = unlock loc in - ["format-"^system, s; "begin", start; "end", stop] - -let string_of_assumption_kind l a many = - match l, a, many with - | (Discharge, Logical, true) -> "Hypotheses" - | (Discharge, Logical, false) -> "Hypothesis" - | (Discharge, Definitional, true) -> "Variables" - | (Discharge, Definitional, false) -> "Variable" - | (Global, Logical, true) -> "Axioms" - | (Global, Logical, false) -> "Axiom" - | (Global, Definitional, true) -> "Parameters" - | (Global, Definitional, false) -> "Parameter" - | (Local, Logical, true) -> "Local Axioms" - | (Local, Logical, false) -> "Local Axiom" - | (Local, Definitional, true) -> "Local Parameters" - | (Local, Definitional, false) -> "Local Parameter" - | (Global, Conjectural, _) -> "Conjecture" - | ((Discharge | Local), Conjectural, _) -> assert false - -let rec pp_bindlist bl = - let tlist = - List.flatten - (List.map - (fun (loc_names, _, e) -> - let names = - (List.map - (fun (loc, name) -> - xmlCst (string_of_name name) loc) loc_names) in - match e with - | CHole _ -> names - | _ -> names @ [pp_expr e]) - bl) in - match tlist with - | [e] -> e - | l -> xmlTyped l -and pp_decl_notation ((_, s), ce, sc) = (* don't know what it is for now *) - Element ("decl_notation", ["name", s], [pp_expr ce]) -and pp_local_binder lb = (* don't know what it is for now *) - match lb with - | LocalRawDef ((_, nam), ce) -> - let attrs = ["name", string_of_name nam] in - pp_expr ~attr:attrs ce - | LocalRawAssum (namll, _, ce) -> - let ppl = - List.map (fun (loc, nam) -> (xmlCst (string_of_name nam) loc)) namll in - xmlTyped (ppl @ [pp_expr ce]) - | LocalPattern _ -> - assert false -and pp_local_decl_expr lde = (* don't know what it is for now *) - match lde with - | AssumExpr (_, ce) -> pp_expr ce - | DefExpr (_, ce, _) -> pp_expr ce -and pp_inductive_expr ((_, ((l, id),_)), lbl, ceo, _, cl_or_rdexpr) = - (* inductive_expr *) - let b,e = Loc.unloc l in - let location = ["begin", string_of_int b; "end", string_of_int e] in - [Element ("lident", ["name", Id.to_string id] @ location, [])] @ (* inductive name *) - begin match cl_or_rdexpr with - | Constructors coel -> List.map (fun (_, (_, ce)) -> pp_expr ce) coel - | RecordDecl (_, ldewwwl) -> - List.map (fun (((_, x), _), _) -> pp_local_decl_expr x) ldewwwl - end @ - begin match ceo with (* don't know what it is for now *) - | Some ce -> [pp_expr ce] - | None -> [] - end @ - (List.map pp_local_binder lbl) -and pp_recursion_order_expr optid roe = (* don't know what it is for now *) - let attrs = - match optid with - | None -> [] - | Some (loc, id) -> - let start, stop = unlock loc in - ["begin", start; "end", stop ; "name", Id.to_string id] in - let kind, expr = - match roe with - | CStructRec -> "struct", [] - | CWfRec e -> "rec", [pp_expr e] - | CMeasureRec (e, None) -> "mesrec", [pp_expr e] - | CMeasureRec (e, Some rel) -> "mesrec", [pp_expr e] @ [pp_expr rel] in - Element ("recursion_order", ["kind", kind] @ attrs, expr) -and pp_fixpoint_expr (((loc, id), pl), (optid, roe), lbl, ce, ceo) = - (* fixpoint_expr *) - let start, stop = unlock loc in - let id = Id.to_string id in - [Element ("lident", ["begin", start; "end", stop ; "name", id], [])] @ - (* fixpoint name *) - [pp_recursion_order_expr optid roe] @ - (List.map pp_local_binder lbl) @ - [pp_expr ce] @ - begin match ceo with (* don't know what it is for now *) - | Some ce -> [pp_expr ce] - | None -> [] - end -and pp_cofixpoint_expr (((loc, id), pl), lbl, ce, ceo) = (* cofixpoint_expr *) - (* Nota: it is like fixpoint_expr without (optid, roe) - * so could be merged if there is no more differences *) - let start, stop = unlock loc in - let id = Id.to_string id in - [Element ("lident", ["begin", start; "end", stop ; "name", id], [])] @ - (* cofixpoint name *) - (List.map pp_local_binder lbl) @ - [pp_expr ce] @ - begin match ceo with (* don't know what it is for now *) - | Some ce -> [pp_expr ce] - | None -> [] - end -and pp_lident (loc, id) = xmlCst (Id.to_string id) loc -and pp_simple_binder (idl, ce) = List.map pp_lident idl @ [pp_expr ce] -and pp_cases_pattern_expr cpe = - match cpe with - | CPatAlias (loc, cpe, id) -> - xmlApply loc - (xmlOperator "alias" ~attr:["name", string_of_id id] loc :: - [pp_cases_pattern_expr cpe]) - | CPatCstr (loc, ref, None, cpel2) -> - xmlApply loc - (xmlOperator "reference" - ~attr:["name", Libnames.string_of_reference ref] loc :: - [Element ("impargs", [], []); - Element ("args", [], (List.map pp_cases_pattern_expr cpel2))]) - | CPatCstr (loc, ref, Some cpel1, cpel2) -> - xmlApply loc - (xmlOperator "reference" - ~attr:["name", Libnames.string_of_reference ref] loc :: - [Element ("impargs", [], (List.map pp_cases_pattern_expr cpel1)); - Element ("args", [], (List.map pp_cases_pattern_expr cpel2))]) - | CPatAtom (loc, optr) -> - let attrs = match optr with - | None -> [] - | Some r -> ["name", Libnames.string_of_reference r] in - xmlApply loc (xmlOperator "atom" ~attr:attrs loc :: []) - | CPatOr (loc, cpel) -> - xmlApply loc (xmlOperator "or" loc :: List.map pp_cases_pattern_expr cpel) - | CPatNotation (loc, n, (subst_constr, subst_rec), cpel) -> - xmlApply loc - (xmlOperator "notation" loc :: - [xmlOperator n loc; - Element ("subst", [], - [Element ("subterms", [], - List.map pp_cases_pattern_expr subst_constr); - Element ("recsubterms", [], - List.map - (fun (cpel) -> - Element ("recsubterm", [], - List.map pp_cases_pattern_expr cpel)) - subst_rec)]); - Element ("args", [], (List.map pp_cases_pattern_expr cpel))]) - | CPatPrim (loc, tok) -> pp_token loc tok - | CPatRecord (loc, rcl) -> - xmlApply loc - (xmlOperator "record" loc :: - List.map (fun (r, cpe) -> - Element ("field", - ["reference", Libnames.string_of_reference r], - [pp_cases_pattern_expr cpe])) - rcl) - | CPatDelimiters (loc, delim, cpe) -> - xmlApply loc - (xmlOperator "delimiter" ~attr:["name", delim] loc :: - [pp_cases_pattern_expr cpe]) - | CPatCast _ -> assert false -and pp_case_expr (e, name, pat) = - match name, pat with - | None, None -> xmlScrutinee [pp_expr e] - | Some (loc, name), None -> - let start, stop= unlock loc in - xmlScrutinee ~attr:["name", string_of_name name; - "begin", start; "end", stop] [pp_expr e] - | Some (loc, name), Some p -> - let start, stop= unlock loc in - xmlScrutinee ~attr:["name", string_of_name name; - "begin", start; "end", stop] - [Element ("in", [], [pp_cases_pattern_expr p]) ; pp_expr e] - | None, Some p -> - xmlScrutinee [Element ("in", [], [pp_cases_pattern_expr p]) ; pp_expr e] -and pp_branch_expr_list bel = - xmlWith - (List.map - (fun (_, cpel, e) -> - let ppcepl = - List.map pp_cases_pattern_expr (List.flatten (List.map snd cpel)) in - let ppe = [pp_expr e] in - xmlCase (ppcepl @ ppe)) - bel) -and pp_token loc tok = - let tokstr = - match tok with - | String s -> PCData s - | Numeral n -> PCData (to_string n) in - xmlToken loc [tokstr] -and pp_local_binder_list lbl = - let l = (List.map pp_local_binder lbl) in - Element ("recurse", (backstep_loc l), l) -and pp_const_expr_list cel = - let l = List.map pp_expr cel in - Element ("recurse", (backstep_loc l), l) -and pp_expr ?(attr=[]) e = - match e with - | CRef (r, _) -> - xmlCst ~attr - (Libnames.string_of_reference r) (Libnames.loc_of_reference r) - | CProdN (loc, bl, e) -> - xmlApply loc - (xmlOperator "forall" loc :: [pp_bindlist bl] @ [pp_expr e]) - | CApp (loc, (_, hd), args) -> - xmlApply ~attr loc (pp_expr hd :: List.map (fun (e,_) -> pp_expr e) args) - | CAppExpl (loc, (_, r, _), args) -> - xmlApply ~attr loc - (xmlCst (Libnames.string_of_reference r) - (Libnames.loc_of_reference r) :: List.map pp_expr args) - | CNotation (loc, notation, ([],[],[])) -> - xmlOperator notation loc - | CNotation (loc, notation, (args, cell, lbll)) -> - let fmts = Notation.find_notation_extra_printing_rules notation in - let oper = xmlOperator notation loc ~pprules:fmts in - let cels = List.map pp_const_expr_list cell in - let lbls = List.map pp_local_binder_list lbll in - let args = List.map pp_expr args in - xmlApply loc (oper :: (List.sort compare_begin_att (args @ cels @ lbls))) - | CSort(loc, s) -> - xmlOperator (string_of_glob_sort s) loc - | CDelimiters (loc, scope, ce) -> - xmlApply loc (xmlOperator "delimiter" ~attr:["name", scope] loc :: - [pp_expr ce]) - | CPrim (loc, tok) -> pp_token loc tok - | CGeneralization (loc, kind, _, e) -> - let kind= match kind with - | Explicit -> "explicit" - | Implicit -> "implicit" in - xmlApply loc - (xmlOperator "generalization" ~attr:["kind", kind] loc :: [pp_expr e]) - | CCast (loc, e, tc) -> - begin match tc with - | CastConv t | CastVM t |CastNative t -> - xmlApply loc - (xmlOperator ":" loc ~attr:["kind", (string_of_cast_sort tc)] :: - [pp_expr e; pp_expr t]) - | CastCoerce -> - xmlApply loc - (xmlOperator ":" loc ~attr:["kind", "CastCoerce"] :: - [pp_expr e]) - end - | CEvar (loc, ek, cel) -> - let ppcel = List.map (fun (id,e) -> xmlAssign id (pp_expr e)) cel in - xmlApply loc - (xmlOperator "evar" loc ~attr:["id", string_of_id ek] :: - ppcel) - | CPatVar (loc, id) -> xmlPatvar (string_of_id id) loc - | CHole (loc, _, _, _) -> xmlCst ~attr "_" loc - | CIf (loc, test, (_, ret), th, el) -> - let return = match ret with - | None -> [] - | Some r -> [xmlReturn [pp_expr r]] in - xmlApply loc - (xmlOperator "if" loc :: - return @ [pp_expr th] @ [pp_expr el]) - | CLetTuple (loc, names, (_, ret), value, body) -> - let return = match ret with - | None -> [] - | Some r -> [xmlReturn [pp_expr r]] in - xmlApply loc - (xmlOperator "lettuple" loc :: - return @ - (List.map (fun (loc, var) -> xmlCst (string_of_name var) loc) names) @ - [pp_expr value; pp_expr body]) - | CCases (loc, sty, ret, cel, bel) -> - let return = match ret with - | None -> [] - | Some r -> [xmlReturn [pp_expr r]] in - xmlApply loc - (xmlOperator "match" loc ~attr:["style", (string_of_case_style sty)] :: - (return @ - [Element ("scrutinees", [], List.map pp_case_expr cel)] @ - [pp_branch_expr_list bel])) - | CRecord (_, _) -> assert false - | CLetIn (loc, (varloc, var), value, body) -> - xmlApply loc - (xmlOperator "let" loc :: - [xmlCst (string_of_name var) varloc; pp_expr value; pp_expr body]) - | CLambdaN (loc, bl, e) -> - xmlApply loc - (xmlOperator "lambda" loc :: [pp_bindlist bl] @ [pp_expr e]) - | CCoFix (_, _, _) -> assert false - | CFix (loc, lid, fel) -> - xmlApply loc - (xmlOperator "fix" loc :: - List.flatten (List.map - (fun (a,b,cl,c,d) -> pp_fixpoint_expr ((a,None),b,cl,c,Some d)) - fel)) - -let pp_comment (c) = - match c with - | CommentConstr e -> [pp_expr e] - | CommentString s -> [Element ("string", [], [PCData s])] - | CommentInt i -> [PCData (string_of_int i)] - -let rec tmpp v loc = - match v with - (* Control *) - | VernacLoad (verbose,f) -> - xmlWithLoc loc "load" ["verbose",string_of_bool verbose;"file",f] [] - | VernacTime (loc,e) -> - xmlApply loc (Element("time",[],[]) :: - [tmpp e loc]) - | VernacRedirect (s, (loc,e)) -> - xmlApply loc (Element("redirect",["path", s],[]) :: - [tmpp e loc]) - | VernacTimeout (s,e) -> - xmlApply loc (Element("timeout",["val",string_of_int s],[]) :: - [tmpp e loc]) - | VernacFail e -> xmlApply loc (Element("fail",[],[]) :: [tmpp e loc]) - | VernacError _ -> xmlWithLoc loc "error" [] [] - - (* Syntax *) - | VernacSyntaxExtension (_, ((_, name), sml)) -> - let attrs = List.flatten (List.map attribute_of_syntax_modifier sml) in - xmlReservedNotation attrs name loc - - | VernacOpenCloseScope (_,(true,name)) -> xmlScope loc "open" name [] - | VernacOpenCloseScope (_,(false,name)) -> xmlScope loc "close" name [] - | VernacDelimiters (name,Some tag) -> - xmlScope loc "delimit" name ~attr:["delimiter",tag] [] - | VernacDelimiters (name,None) -> - xmlScope loc "undelimit" name ~attr:[] [] - | VernacInfix (_,((_,name),sml),ce,sn) -> - let attrs = List.flatten (List.map attribute_of_syntax_modifier sml) in - let sc_attr = - match sn with - | Some scope -> ["scope", scope] - | None -> [] in - xmlNotation (sc_attr @ attrs) name loc [pp_expr ce] - | VernacNotation (_, ce, (lstr, sml), sn) -> - let name = snd lstr in - let attrs = List.flatten (List.map attribute_of_syntax_modifier sml) in - let sc_attr = - match sn with - | Some scope -> ["scope", scope] - | None -> [] in - xmlNotation (sc_attr @ attrs) name loc [pp_expr ce] - | VernacBindScope _ as x -> xmlTODO loc x - | VernacNotationAddFormat _ as x -> xmlTODO loc x - | VernacUniverse _ - | VernacConstraint _ - | VernacPolymorphic (_, _) as x -> xmlTODO loc x - (* Gallina *) - | VernacDefinition (ldk, ((_,id),_), de) -> - let l, dk = - match ldk with - | Some l, dk -> (l, dk) - | None, dk -> (Global, dk) in (* Like in ppvernac.ml, l 585 *) - let e = - match de with - | ProveBody (_, ce) -> ce - | DefineBody (_, Some _, ce, None) -> ce - | DefineBody (_, None , ce, None) -> ce - | DefineBody (_, Some _, ce, Some _) -> ce - | DefineBody (_, None , ce, Some _) -> ce in - let str_dk = Kindops.string_of_definition_kind (l, false, dk) in - let str_id = Id.to_string id in - (xmlDef str_dk str_id loc [pp_expr e]) - | VernacStartTheoremProof (tk, [ Some ((_,id),_), ([], statement, None) ], b) -> - let str_tk = Kindops.string_of_theorem_kind tk in - let str_id = Id.to_string id in - (xmlThm str_tk str_id loc [pp_expr statement]) - | VernacStartTheoremProof _ as x -> xmlTODO loc x - | VernacEndProof pe -> - begin - match pe with - | Admitted -> xmlQed loc - | Proved (_, Some ((_, id), Some tk)) -> - let nam = Id.to_string id in - let typ = Kindops.string_of_theorem_kind tk in - xmlQed ~attr:["name", nam; "type", typ] loc - | Proved (_, Some ((_, id), None)) -> - let nam = Id.to_string id in - xmlQed ~attr:["name", nam] loc - | Proved _ -> xmlQed loc - end - | VernacExactProof _ as x -> xmlTODO loc x - | VernacAssumption ((l, a), _, sbwcl) -> - let binders = List.map (fun (_, (id, c)) -> (List.map fst id, c)) sbwcl in - let many = - List.length (List.flatten (List.map fst binders)) > 1 in - let exprs = - List.flatten (List.map pp_simple_binder binders) in - let l = match l with Some x -> x | None -> Decl_kinds.Global in - let kind = string_of_assumption_kind l a many in - xmlAssumption kind loc exprs - | VernacInductive (_, _, iednll) -> - let kind = - let (_, _, _, k, _),_ = List.hd iednll in - begin - match k with - | Record -> "Record" - | Structure -> "Structure" - | Inductive_kw -> "Inductive" - | CoInductive -> "CoInductive" - | Class _ -> "Class" - | Variant -> "Variant" - end in - let exprs = - List.flatten (* should probably not be flattened *) - (List.map - (fun (ie, dnl) -> (pp_inductive_expr ie) @ - (List.map pp_decl_notation dnl)) iednll) in - xmlInductive kind loc exprs - | VernacFixpoint (_, fednll) -> - let exprs = - List.flatten (* should probably not be flattened *) - (List.map - (fun (fe, dnl) -> (pp_fixpoint_expr fe) @ - (List.map pp_decl_notation dnl)) fednll) in - xmlFixpoint exprs - | VernacCoFixpoint (_, cfednll) -> - (* Nota: it is like VernacFixpoint without so could be merged *) - let exprs = - List.flatten (* should probably not be flattened *) - (List.map - (fun (cfe, dnl) -> (pp_cofixpoint_expr cfe) @ - (List.map pp_decl_notation dnl)) cfednll) in - xmlCoFixpoint exprs - | VernacScheme _ as x -> xmlTODO loc x - | VernacCombinedScheme _ as x -> xmlTODO loc x - - (* Gallina extensions *) - | VernacBeginSection (_, id) -> xmlBeginSection loc (Id.to_string id) - | VernacEndSegment (_, id) -> xmlEndSegment loc (Id.to_string id) - | VernacNameSectionHypSet _ as x -> xmlTODO loc x - | VernacRequire (from, import, l) -> - let import = match import with - | None -> [] - | Some true -> ["export","true"] - | Some false -> ["import","true"] - in - let from = match from with - | None -> [] - | Some r -> ["from", Libnames.string_of_reference r] - in - xmlRequire loc ~attr:(from @ import) (List.map (fun ref -> - xmlReference ref) l) - | VernacImport (true,l) -> - xmlImport loc ~attr:["export","true"] (List.map (fun ref -> - xmlReference ref) l) - | VernacImport (false,l) -> - xmlImport loc (List.map (fun ref -> - xmlReference ref) l) - | VernacCanonical r -> - let attr = - match r with - | AN (Qualid (_, q)) -> ["qualid", string_of_qualid q] - | AN (Ident (_, id)) -> ["id", Id.to_string id] - | ByNotation (_, s, _) -> ["notation", s] in - xmlCanonicalStructure attr loc - | VernacCoercion _ as x -> xmlTODO loc x - | VernacIdentityCoercion _ as x -> xmlTODO loc x - - (* Type classes *) - | VernacInstance _ as x -> xmlTODO loc x - - | VernacContext _ as x -> xmlTODO loc x - - | VernacDeclareInstances _ as x -> xmlTODO loc x - - | VernacDeclareClass _ as x -> xmlTODO loc x - - (* Modules and Module Types *) - | VernacDeclareModule _ as x -> xmlTODO loc x - | VernacDefineModule _ as x -> xmlTODO loc x - | VernacDeclareModuleType _ as x -> xmlTODO loc x - | VernacInclude _ as x -> xmlTODO loc x - - (* Solving *) - - | (VernacSolveExistential _) as x -> - xmlLtac loc [PCData (Pp.string_of_ppcmds (Ppvernac.pr_vernac x))] - - (* Auxiliary file and library management *) - | VernacAddLoadPath (recf,name,None) -> - xmlAddLoadPath loc ~attr:["rec",string_of_bool recf;"path",name] [] - | VernacAddLoadPath (recf,name,Some dp) -> - xmlAddLoadPath loc ~attr:["rec",string_of_bool recf;"path",name] - [PCData (Names.DirPath.to_string dp)] - | VernacRemoveLoadPath name -> xmlRemoveLoadPath loc ~attr:["path",name] [] - | VernacAddMLPath (recf,name) -> - xmlAddMLPath loc ~attr:["rec",string_of_bool recf;"path",name] [] - | VernacDeclareMLModule sl -> xmlDeclareMLModule loc sl - | VernacChdir _ as x -> xmlTODO loc x - - (* State management *) - | VernacWriteState _ as x -> xmlTODO loc x - | VernacRestoreState _ as x -> xmlTODO loc x - - (* Resetting *) - | VernacResetName _ as x -> xmlTODO loc x - | VernacResetInitial as x -> xmlTODO loc x - | VernacBack _ as x -> xmlTODO loc x - | VernacBackTo _ -> PCData "VernacBackTo" - - (* Commands *) - | VernacCreateHintDb _ as x -> xmlTODO loc x - | VernacRemoveHints _ as x -> xmlTODO loc x - | VernacHints _ as x -> xmlTODO loc x - | VernacSyntacticDefinition ((_, name), (idl, ce), _, _) -> - let name = Id.to_string name in - let attrs = List.map (fun id -> ("id", Id.to_string id)) idl in - xmlNotation attrs name loc [pp_expr ce] - | VernacDeclareImplicits _ as x -> xmlTODO loc x - | VernacArguments _ as x -> xmlTODO loc x - | VernacArgumentsScope _ as x -> xmlTODO loc x - | VernacReserve _ as x -> xmlTODO loc x - | VernacGeneralizable _ as x -> xmlTODO loc x - | VernacSetOpacity _ as x -> xmlTODO loc x - | VernacSetStrategy _ as x -> xmlTODO loc x - | VernacUnsetOption _ as x -> xmlTODO loc x - | VernacSetOption _ as x -> xmlTODO loc x - | VernacSetAppendOption _ as x -> xmlTODO loc x - | VernacAddOption _ as x -> xmlTODO loc x - | VernacRemoveOption _ as x -> xmlTODO loc x - | VernacMemOption _ as x -> xmlTODO loc x - | VernacPrintOption _ as x -> xmlTODO loc x - | VernacCheckMayEval (_,_,e) -> xmlCheck loc [pp_expr e] - | VernacGlobalCheck _ as x -> xmlTODO loc x - | VernacDeclareReduction _ as x -> xmlTODO loc x - | VernacPrint _ as x -> xmlTODO loc x - | VernacSearch _ as x -> xmlTODO loc x - | VernacLocate _ as x -> xmlTODO loc x - | VernacRegister _ as x -> xmlTODO loc x - | VernacComments (cl) -> - xmlComment loc (List.flatten (List.map pp_comment cl)) - - (* Stm backdoor *) - | VernacStm _ as x -> xmlTODO loc x - - (* Proof management *) - | VernacGoal _ as x -> xmlTODO loc x - | VernacAbort _ as x -> xmlTODO loc x - | VernacAbortAll -> PCData "VernacAbortAll" - | VernacRestart as x -> xmlTODO loc x - | VernacUndo _ as x -> xmlTODO loc x - | VernacUndoTo _ as x -> xmlTODO loc x - | VernacBacktrack _ as x -> xmlTODO loc x - | VernacFocus _ as x -> xmlTODO loc x - | VernacUnfocus as x -> xmlTODO loc x - | VernacUnfocused as x -> xmlTODO loc x - | VernacBullet _ as x -> xmlTODO loc x - | VernacSubproof _ as x -> xmlTODO loc x - | VernacEndSubproof as x -> xmlTODO loc x - | VernacShow _ as x -> xmlTODO loc x - | VernacCheckGuard as x -> xmlTODO loc x - | VernacProof (tac,using) -> - let tac = Option.map (xmlRawTactic "closingtactic") tac in - let using = Option.map (xmlSectionSubsetDescr "using") using in - xmlProof loc (Option.List.(cons tac (cons using []))) - | VernacProofMode name -> xmlProofMode loc name - - (* Toplevel control *) - | VernacToplevelControl _ as x -> xmlTODO loc x - - (* For extension *) - | VernacExtend _ as x -> - xmlExtend loc [PCData (Pp.string_of_ppcmds (Ppvernac.pr_vernac x))] - - (* Flags *) - | VernacProgram e -> xmlApply loc (Element("program",[],[]) :: [tmpp e loc]) - | VernacLocal (b,e) -> - xmlApply loc (Element("local",["flag",string_of_bool b],[]) :: - [tmpp e loc]) - -let tmpp v loc = - match tmpp v loc with - | Element("ltac",_,_) as x -> x - | xml -> xmlGallina loc [xml] diff --git a/ide/texmacspp.mli b/ide/texmacspp.mli deleted file mode 100644 index 858847fb..00000000 --- a/ide/texmacspp.mli +++ /dev/null @@ -1,12 +0,0 @@ -(************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) -(* \VV/ **************************************************************) -(* // * This file is distributed under the terms of the *) -(* * GNU Lesser General Public License Version 2.1 *) -(************************************************************************) - -open Xml_datatype -open Vernacexpr - -val tmpp : vernac_expr -> Loc.t -> xml diff --git a/ide/utf8_convert.mli b/ide/utf8_convert.mli new file mode 100644 index 00000000..9b3db5fd --- /dev/null +++ b/ide/utf8_convert.mli @@ -0,0 +1,11 @@ +(************************************************************************) +(* * 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) *) +(************************************************************************) + +val f : string -> string diff --git a/ide/utf8_convert.mll b/ide/utf8_convert.mll index 5cc8cbc0..6e36ae1c 100644 --- a/ide/utf8_convert.mll +++ b/ide/utf8_convert.mll @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) { diff --git a/ide/utils/config_file.ml b/ide/utils/config_file.ml deleted file mode 100644 index 4d0aabeb..00000000 --- a/ide/utils/config_file.ml +++ /dev/null @@ -1,640 +0,0 @@ -(*********************************************************************************) -(* Cameleon *) -(* *) -(* Copyright (C) 2005 Institut National de Recherche en Informatique et *) -(* en Automatique. All rights reserved. *) -(* *) -(* This program is free software; you can redistribute it and/or modify *) -(* it under the terms of the GNU Library General Public License as *) -(* published by the Free Software Foundation; either version 2 of the *) -(* License, or any later version. *) -(* *) -(* This program is distributed in the hope that it will be useful, *) -(* but WITHOUT ANY WARRANTY; without even the implied warranty of *) -(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) -(* GNU Library General Public License for more details. *) -(* *) -(* You should have received a copy of the GNU Library General Public *) -(* License along with this program; if not, write to the Free Software *) -(* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA *) -(* 02111-1307 USA *) -(* *) -(* Contact: Maxence.Guesdon@inria.fr *) -(* *) -(*********************************************************************************) - -(* TODO *) -(* section comments *) -(* better obsoletes: no "{}", line cuts *) - -(* possible improvements: *) -(* use lex/yacc instead of genlex to be more robust, efficient, allow arrays and other types, read comments. *) -(* description and help, level (beginner/advanced/...) for each cp *) -(* find an option from its name and group *) -(* class hooks *) -(* get the sections of a group / of a file *) -(* read file format from inifiles and ConfigParser *) - - -(* Read the mli before reading this file! *) - - -(* ******************************************************************************** *) -(* ******************************** misc utilities ******************************** *) -(* ******************************************************************************** *) -(* This code is intended to be usable without any dependencies. *) - -(* pipeline style, see for instance Raw.of_channel. *) -let (|>) x f = f x - -(* as List.assoc, but applies f to the element matching [key] and returns the list -where this element has been replaced by the result of f. *) -let rec list_assoc_remove key f = function - | [] -> raise Not_found - | (key',value) as elt :: tail -> - if key <> key' - then elt :: list_assoc_remove key f tail - else match f value with - | None -> tail - | Some a -> (key',a) :: tail - -(* reminiscent of String.concat. Same as [Queue.iter f1 queue] - but calls [f2 ()] between each calls to f1. - Does not call f2 before the first call nor after the last call to f2. - Could be more efficient with a richer module interface of Queue. -*) -let queue_iter_between f1 f2 queue = -(* let f flag elt = if flag then f2 (); (f1 elt:unit); true in *) - let f flag elt = if flag then f2 (); f1 elt; true in - ignore (Queue.fold f false queue) - -let list_iter_between f1 f2 = function - [] -> () - | a::[] -> f1 a - | a::tail -> f1 a; List.iter (fun elt -> (f2 ():unit); f1 elt) tail -(* | a::tail -> f1 a; List.iter (fun elt -> f2 (); f1 elt) tail *) -(* !! types ??? *) - -(* to ensure that strings will be parsed correctly by Genlex. -It's more comfortable not to have quotes around the string, but sometimes it's necessary. *) -exception Unsafe_string -let safe_string s = - if s = "" - then "\"\"" - else if ( - try match s.[0] with - | 'a'..'z' | 'A'..'Z' -> - for i = 1 to String.length s - 1 do - match s.[i] with - 'a'..'z' | 'A'..'Z' | '_' | '0'..'9' -> () - | _ -> raise Unsafe_string - done; - false - | _ -> - try - string_of_int (int_of_string s) <> s || - string_of_float (float_of_string s) <> s - with Failure "int_of_string" | Failure "float_of_string" -> true - with Unsafe_string -> true) - then Printf.sprintf "\"%s\"" (String.escaped s) - else s - - -(* ******************************************************************************** *) -(* ************************************* core ************************************* *) -(* ******************************************************************************** *) - -module Raw = struct - type cp = - | String of string - | Int of int - | Float of float - | List of cp list - | Tuple of cp list - | Section of (string * cp) list - -(* code generated by -camlp4 pa_o.cmo pa_op.cmo pr_o.cmo -- -o config_file_parser.ml -impl config_file_parser.ml4 -Unreadable on purpose, edit the file config_file_parser.ml4 rather than editing this (huge) lines. Then manually copy-paste here the content of config_file_parser.ml. -Could be one day rewritten with ocamllex/yacc to be more robust, efficient, allow arrays, read comments...*) - module Parse = struct - let lexer = Genlex.make_lexer ["="; "{"; "}"; "["; "]"; ";"; "("; ")"; ","] - let rec file l (strm__ : _ Stream.t) = match try Some (ident strm__) with Stream.Failure -> None with Some id -> begin match Stream.peek strm__ with Some (Genlex.Kwd "=") -> Stream.junk strm__; let v = try value strm__ with Stream.Failure -> raise (Stream.Error "") in begin try file ((id, v) :: l) strm__ with Stream.Failure -> raise (Stream.Error "") end | _ -> raise (Stream.Error "") end | _ -> List.rev l - and value (strm__ : _ Stream.t) = match Stream.peek strm__ with Some (Genlex.Kwd "{") -> Stream.junk strm__; let v = try file [] strm__ with Stream.Failure -> raise (Stream.Error "") in begin match Stream.peek strm__ with Some (Genlex.Kwd "}") -> Stream.junk strm__; Section v | _ -> raise (Stream.Error "") end | Some (Genlex.Ident s) -> Stream.junk strm__; String s | Some (Genlex.String s) -> Stream.junk strm__; String s | Some (Genlex.Int i) -> Stream.junk strm__; Int i | Some (Genlex.Float f) -> Stream.junk strm__; Float f | Some (Genlex.Char c) -> Stream.junk strm__; String (String.make 1 c) | Some (Genlex.Kwd "[") -> Stream.junk strm__; let v = try list [] strm__ with Stream.Failure -> raise (Stream.Error "") in List v | Some (Genlex.Kwd "(") -> Stream.junk strm__; let v = try list [] strm__ with Stream.Failure -> raise (Stream.Error "") in Tuple v | _ -> raise Stream.Failure - and ident (strm__ : _ Stream.t) = match Stream.peek strm__ with Some (Genlex.Ident s) -> Stream.junk strm__; s | Some (Genlex.String s) -> Stream.junk strm__; s | _ -> raise Stream.Failure - and list l (strm__ : _ Stream.t) = match Stream.peek strm__ with Some (Genlex.Kwd ";") -> Stream.junk strm__; begin try list l strm__ with Stream.Failure -> raise (Stream.Error "") end | Some (Genlex.Kwd ",") -> Stream.junk strm__; begin try list l strm__ with Stream.Failure -> raise (Stream.Error "") end | _ -> match try Some (value strm__) with Stream.Failure -> None with Some v -> begin try list (v :: l) strm__ with Stream.Failure -> raise (Stream.Error "") end | _ -> match Stream.peek strm__ with Some (Genlex.Kwd "]") -> Stream.junk strm__; List.rev l | Some (Genlex.Kwd ")") -> Stream.junk strm__; List.rev l | _ -> raise Stream.Failure - end - - open Format - (* formating convention: the caller has to open the box, close it and flush the output *) - (* remarks on Format: - set_margin forces a call to set_max_indent - sprintf et bprintf are flushed at each call*) - - (* pretty print a Raw.cp *) - let rec save formatter = function - | String s -> fprintf formatter "%s" (safe_string s) (* How can I cut lines and *) - | Int i -> fprintf formatter "%d" i (* print backslashes just before the \n? *) - | Float f -> fprintf formatter "%g" f - | List l -> - fprintf formatter "[@[<b0>"; - list_iter_between - (fun v -> fprintf formatter "@[<b2>"; save formatter v; fprintf formatter "@]") - (fun () -> fprintf formatter ";@ ") - l; - fprintf formatter "@]]" - | Tuple l -> - fprintf formatter "(@[<b0>"; - list_iter_between - (fun v -> fprintf formatter "@[<b2>"; save formatter v; fprintf formatter "@]") - (fun () -> fprintf formatter ",@ ") - l; - fprintf formatter "@])" - | Section l -> - fprintf formatter "{@;<0 2>@[<hv0>"; - list_iter_between - (fun (name,value) -> - fprintf formatter "@[<hov2>%s =@ @[<b2>" name; - save formatter value; - fprintf formatter "@]@]";) - (fun () -> fprintf formatter "@;<2 0>") - l; - fprintf formatter "@]}" - -(* let to_string r = save str_formatter r; flush_str_formatter () *) - let to_channel out_channel r = - let f = formatter_of_out_channel out_channel in - fprintf f "@[<b2>"; save f r; fprintf f "@]@?" - - let of_string s = s |> Stream.of_string |> Parse.lexer |> Parse.value - - let of_channel in_channel = - let result = in_channel |> Stream.of_channel |> Parse.lexer |> Parse.file [] in - close_in in_channel; - result -end - -(* print the given string in a way compatible with Format. - Truncate the lines when needed, indent the newlines.*) -let print_help formatter = - String.iter (function - | ' ' -> Format.pp_print_space formatter () - | '\n' -> Format.pp_force_newline formatter () - | c -> Format.pp_print_char formatter c) - -type 'a wrappers = { - to_raw : 'a -> Raw.cp; - of_raw : Raw.cp -> 'a} - -class type ['a] cp = object -(* method private to_raw = wrappers.to_raw *) -(* method private of_raw = wrappers.of_raw *) -(* method private set_string s = s |> Raw.of_string |> self#of_raw |> self#set *) - method add_hook : ('a -> 'a -> unit) -> unit - method get : 'a - method get_default : 'a - method set : 'a -> unit - method reset : unit - - method get_formatted : Format.formatter -> unit - method get_default_formatted : Format.formatter -> unit - method get_help_formatted : Format.formatter -> unit - - method get_name : string list - method get_short_name : string option - method set_short_name : string -> unit - method get_help : string - method get_spec : Arg.spec - - method set_raw : Raw.cp -> unit -end - -type groupable_cp = < - get_name : string list; - get_short_name : string option; - get_help : string; - - get_formatted : Format.formatter -> unit; - get_default_formatted : Format.formatter -> unit; - get_help_formatted : Format.formatter -> unit; - get_spec : Arg.spec; - - reset : unit; - set_raw : Raw.cp -> unit; > - -exception Double_name -exception Missing_cp of groupable_cp -exception Wrong_type of (out_channel -> unit) - -(* Two exceptions to stop the iteration on queues. *) -exception Found -exception Found_cp of groupable_cp - -(* The data structure to store the cps. -It's a tree, each node is a section, and a queue of sons with their name. -Each leaf contains a cp. *) -type 'a nametree = - | Immediate of 'a - | Subsection of ((string * 'a nametree) Queue.t) - (* this Queue must be nonempty for group.read.choose *) - -class group = object (self) - val mutable cps = Queue.create () (* hold all the added cps, in a nametree. *) - - method add : 'a. 'a cp -> unit = fun original_cp -> - let cp = (original_cp :> groupable_cp) in - (* function called when we reach the end of the list cp#get_name. *) - let add_immediate name cp queue = - Queue.iter (fun (name',_) -> if name = name' then raise Double_name) queue; - Queue.push (name, Immediate cp) queue in - (* adds the cp with name [first_name::last_name] in section [section]. *) - let rec add_in_section section first_name last_name cp queue = - let sub_add = match last_name with (* what to do once we have find the correct section *) - | [] -> add_immediate first_name - | middle_name :: last_name -> add_in_section first_name middle_name last_name in - try - Queue.iter - (function - | name, Subsection subsection when name = section -> - sub_add cp subsection; raise Found - | _ -> ()) - queue; - let sub_queue = Queue.create () in - sub_add cp sub_queue; - Queue.push (section, Subsection sub_queue) queue - with Found -> () in - (match cp#get_name with - | [] -> failwith "empty name" - | first_name :: [] -> add_immediate first_name cp cps - | first_name :: middle_name :: last_name -> - add_in_section first_name middle_name last_name cp cps) - - method write ?(with_help=true) filename = - let out_channel = open_out filename in - let formatter = Format.formatter_of_out_channel out_channel in - let print = Format.fprintf formatter in - print "@[<v>"; - let rec save_queue formatter = - queue_iter_between - (fun (name,nametree) -> save_nametree name nametree) - (Format.pp_print_cut formatter) - and save_nametree name = function - | Immediate cp -> - if with_help && cp#get_help <> "" then - (print "@[<hov3>(* "; cp#get_help_formatted formatter; - print "@ *)@]@,"); - Format.fprintf formatter "@[<hov2>%s =@ @[<b2>" (safe_string name); - cp#get_formatted formatter; - print "@]@]" - | Subsection queue -> - Format.fprintf formatter "%s = {@;<0 2>@[<v>" (safe_string name); - save_queue formatter queue; - print "@]@,}" in - save_queue formatter cps; - print "@]@."; close_out out_channel - - method read ?obsoletes ?(no_default=false) - ?(on_type_error = fun groupable_cp raw_cp output filename in_channel -> - close_in in_channel; - Printf.eprintf - "Type error while loading configuration parameter %s from file %s.\n%!" - (String.concat "." groupable_cp#get_name) filename; - output stderr; - exit 1) - filename = - (* [filename] is created if it doesn't exist. In this case there is no need to read it. *) - match Sys.file_exists filename with false -> self#write filename | true -> - let in_channel = open_in filename in - (* what to do when a cp is missing: *) - let missing cp default = if no_default then raise (Missing_cp cp) else default in - (* returns a cp contained in the nametree queue, which must be nonempty *) - let choose queue = - let rec iter q = Queue.iter (function - | _, Immediate cp -> raise (Found_cp cp) - | _, Subsection q -> iter q) q in - try iter queue; failwith "choose" with Found_cp cp -> cp in - (* [set_and_remove raw_cps nametree] sets the cp of [nametree] to their value - defined in [raw_cps] and returns the remaining raw_cps. *) - let set_cp cp value = - try cp#set_raw value - with Wrong_type output -> on_type_error cp value output filename in_channel in - let rec set_and_remove raw_cps = function - | name, Immediate cp -> - (try list_assoc_remove name (fun value -> set_cp cp value; None) raw_cps - with Not_found -> missing cp raw_cps) - | name, Subsection queue -> - (try list_assoc_remove name - (function - | Raw.Section l -> - (match remainings l queue with - | [] -> None - | l -> Some (Raw.Section l)) - | r -> missing (choose queue) (Some r)) - raw_cps - with Not_found -> missing (choose queue) raw_cps) - and remainings raw_cps queue = Queue.fold set_and_remove raw_cps queue in - let remainings = remainings (Raw.of_channel in_channel) cps in - (* Handling of cps defined in filename but not belonging to self. *) - if remainings <> [] then match obsoletes with - | Some filename -> - let out_channel = - open_out filename in -(* open_out_gen [Open_wronly; Open_creat; Open_append; Open_text] 0o666 filename in *) - let formatter = Format.formatter_of_out_channel out_channel in - Format.fprintf formatter "@[<v>"; - Raw.save formatter (Raw.Section remainings); - Format.fprintf formatter "@]@."; - close_out out_channel - | None -> () - - method command_line_args ~section_separator = - let print = Format.fprintf Format.str_formatter in (* shortcut *) - let result = ref [] in let push x = result := x :: !result in - let rec iter = function - | _, Immediate cp -> - let key = "-" ^ String.concat section_separator cp#get_name in - let spec = cp#get_spec in - let doc = ( - print "@[<hv5>"; - Format.pp_print_as Format.str_formatter (String.length key +3) ""; - if cp#get_help <> "" - then (print "@,@[<b2>"; cp#get_help_formatted Format.str_formatter; print "@]@ ") - else print "@,"; - print "@[<hv>@[current:@;<1 2>@[<hov1>"; cp#get_formatted Format.str_formatter; - print "@]@],@ @[default:@;<1 2>@[<b2>"; cp#get_default_formatted Format.str_formatter; - print "@]@]@]@]"; - Format.flush_str_formatter ()) in - (match cp#get_short_name with - | None -> () - | Some short_name -> push ("-" ^ short_name,spec,"")); - push (key,spec,doc) - | _, Subsection queue -> Queue.iter iter queue in - Queue.iter iter cps; - List.rev !result -end - - -(* Given wrappers for the type 'a, cp_custom_type defines a class 'a cp. *) -class ['a] cp_custom_type wrappers - ?group:(group:group option) name ?short_name default help = -object (self) - method private to_raw = wrappers.to_raw - method private of_raw = wrappers.of_raw - - val mutable value = default - (* output *) - method get = value - method get_default = default - method get_formatted formatter = self#get |> self#to_raw |> Raw.save formatter - method get_default_formatted formatter = self#get_default |> self#to_raw |> Raw.save formatter - (* input *) - method set v = let v' = value in value <- v; self#exec_hooks v' v - method set_raw v = self#of_raw v |> self#set - method private set_string s = s |> Raw.of_string |> self#of_raw |> self#set - method reset = self#set self#get_default - - (* name *) - val mutable shortname = short_name - method get_name = name - method get_short_name = shortname - method set_short_name s = shortname <- Some s - - (* help *) - method get_help = help - method get_help_formatted formatter = print_help formatter self#get_help - method get_spec = Arg.String self#set_string - - (* hooks *) - val mutable hooks = [] - method add_hook f = hooks <- (f:'a->'a->unit) :: hooks - method private exec_hooks v' v = List.iter (fun f -> f v' v) hooks - - initializer match group with Some g -> g#add (self :> 'a cp) | None -> () -end - - -(* ******************************************************************************** *) -(* ****************************** predefined classes ****************************** *) -(* ******************************************************************************** *) - -let int_wrappers = { - to_raw = (fun v -> Raw.Int v); - of_raw = function - | Raw.Int v -> v - | r -> raise (Wrong_type (fun outchan -> Printf.fprintf outchan - "Raw.Int expected, got %a\n%!" Raw.to_channel r))} -class int_cp ?group name ?short_name default help = object (self) - inherit [int] cp_custom_type int_wrappers ?group name ?short_name default help - method get_spec = Arg.Int self#set -end - -let float_wrappers = { - to_raw = (fun v -> Raw.Float v); - of_raw = function - | Raw.Float v -> v - | Raw.Int v -> float v - | r -> raise (Wrong_type (fun outchan -> Printf.fprintf outchan - "Raw.Float expected, got %a\n%!" Raw.to_channel r)) -} -class float_cp ?group name ?short_name default help = object (self) - inherit [float] cp_custom_type float_wrappers ?group name ?short_name default help - method get_spec = Arg.Float self#set -end - -(* The Pervasives version is too restrictive *) -let bool_of_string s = - match String.lowercase s with - | "false" | "no" | "n" | "0" -> false (* "0" and "1" aren't used. *) - | "true" | "yes" | "y" | "1" -> true - | r -> raise (Wrong_type (fun outchan -> Printf.fprintf outchan - "Raw.Bool expected, got %s\n%!" r)) -let bool_wrappers = { - to_raw = (fun v -> Raw.String (string_of_bool v)); - of_raw = function - | Raw.String v -> bool_of_string v - | Raw.Int v -> v <> 0 - | r -> raise (Wrong_type (fun outchan -> Printf.fprintf outchan - "Raw.Bool expected, got %a\n%!" Raw.to_channel r)) -} -class bool_cp ?group name ?short_name default help = object (self) - inherit [bool] cp_custom_type bool_wrappers ?group name ?short_name default help - method get_spec = Arg.Bool self#set -end - -let string_wrappers = { - to_raw = (fun v -> Raw.String v); - of_raw = function - | Raw.String v -> v - | Raw.Int v -> string_of_int v - | Raw.Float v -> string_of_float v - | r -> raise (Wrong_type (fun outchan -> Printf.fprintf outchan - "Raw.String expected, got %a\n%!" Raw.to_channel r)) -} -class string_cp ?group name ?short_name default help = object (self) - inherit [string] cp_custom_type string_wrappers ?group name ?short_name default help - method private of_string s = s - method get_spec = Arg.String self#set -end - -let list_wrappers wrappers = { - to_raw = (fun l -> Raw.List (List.map wrappers.to_raw l)); - of_raw = function - | Raw.List l -> List.map wrappers.of_raw l - | r -> raise (Wrong_type (fun outchan -> Printf.fprintf outchan - "Raw.List expected, got %a\n%!" Raw.to_channel r)) -} -class ['a] list_cp wrappers = ['a list] cp_custom_type (list_wrappers wrappers) - -let option_wrappers wrappers = { - to_raw = (function - | Some v -> wrappers.to_raw v - | None -> Raw.String ""); - of_raw = function - | Raw.String s as v -> ( - if s = "" || s = "None" then None - else if String.length s >= 5 && String.sub s 0 5 = "Some " - then Some (wrappers.of_raw (Raw.String (String.sub s 5 (String.length s -5)))) - else Some (wrappers.of_raw v)) - | r -> Some (wrappers.of_raw r)} -class ['a] option_cp wrappers = ['a option] cp_custom_type (option_wrappers wrappers) - -let enumeration_wrappers enum = - let switched = List.map (fun (string,cons) -> cons,string) enum in - {to_raw = (fun v -> Raw.String (List.assq v switched)); - of_raw = function - | Raw.String s -> - (try List.assoc s enum - with Not_found -> failwith (Printf.sprintf "%s isn't a known constructor" s)) - | r -> raise (Wrong_type (fun outchan -> Printf.fprintf outchan - "Raw enumeration expected, got %a\n%!" Raw.to_channel r)) -} -class ['a] enumeration_cp enum ?group name ?short_name default help = object (self) - inherit ['a] cp_custom_type (enumeration_wrappers enum) - ?group name ?short_name default help - method get_spec = Arg.Symbol (List.map fst enum, (fun s -> self#set (List.assoc s enum))) -end - -let tuple2_wrappers wrapa wrapb = { - to_raw = (fun (a,b) -> Raw.Tuple [wrapa.to_raw a; wrapb.to_raw b]); - of_raw = function - | Raw.Tuple [a;b] -> wrapa.of_raw a, wrapb.of_raw b - | r -> raise (Wrong_type (fun outchan -> Printf.fprintf outchan - "Raw.Tuple 2 expected, got %a\n%!" Raw.to_channel r)) -} -class ['a, 'b] tuple2_cp wrapa wrapb = ['a*'b] cp_custom_type (tuple2_wrappers wrapa wrapb) - -let tuple3_wrappers wrapa wrapb wrapc = { - to_raw = (fun (a,b,c) -> Raw.Tuple[wrapa.to_raw a; wrapb.to_raw b; wrapc.to_raw c]); - of_raw = function - | Raw.Tuple [a;b;c] -> wrapa.of_raw a, wrapb.of_raw b, wrapc.of_raw c - | r -> raise (Wrong_type (fun outchan -> Printf.fprintf outchan - "Raw.Tuple 3 expected, got %a\n%!" Raw.to_channel r)) -} -class ['a,'b,'c] tuple3_cp wrapa wrapb wrapc = - ['a*'b*'c] cp_custom_type (tuple3_wrappers wrapa wrapb wrapc) - -let tuple4_wrappers wrapa wrapb wrapc wrapd = { - to_raw=(fun (a,b,c,d)->Raw.Tuple[wrapa.to_raw a;wrapb.to_raw b;wrapc.to_raw c;wrapd.to_raw d]); - of_raw = function - | Raw.Tuple [a;b;c;d] -> wrapa.of_raw a, wrapb.of_raw b, wrapc.of_raw c, wrapd.of_raw d - | r -> raise (Wrong_type (fun outchan -> Printf.fprintf outchan - "Raw.Tuple 4 expected, got %a\n%!" Raw.to_channel r)) -} -class ['a,'b,'c,'d] tuple4_cp wrapa wrapb wrapc wrapd = - ['a*'b*'c*'d] cp_custom_type (tuple4_wrappers wrapa wrapb wrapc wrapd) - -class string2_cp = [string,string] tuple2_cp string_wrappers string_wrappers -(* class color_cp = string_cp *) -class font_cp = string_cp -class filename_cp = string_cp - - -(* ******************************************************************************** *) -(******************** Backward compatibility with module Flags.****************** *) -(* ******************************************************************************** *) - -type 'a option_class = 'a wrappers -type 'a option_record = 'a cp -type options_file = {mutable filename:string; group:group} - -let create_options_file filename = {filename = filename; group = new group} -let set_options_file options_file filename = options_file.filename <- filename -let load {filename=f; group = g} = g#read f -let append {group=g} filename = g#read filename -let save {filename=f; group = g} = g#write ~with_help:false f -let save_with_help {filename=f; group = g} = g#write ~with_help:true f -let define_option {group=group} name help option_class default = - (new cp_custom_type option_class ~group name default help) -let option_hook cp f = cp#add_hook (fun _ _ -> f ()) - -let string_option = string_wrappers -let color_option = string_wrappers -let font_option = string_wrappers -let int_option = int_wrappers -let bool_option = bool_wrappers -let float_option = float_wrappers -let string2_option = tuple2_wrappers string_wrappers string_wrappers - -let option_option = option_wrappers -let list_option = list_wrappers -let sum_option = enumeration_wrappers -let tuple2_option (a,b) = tuple2_wrappers a b -let tuple3_option (a,b,c) = tuple3_wrappers a b c -let tuple4_option (a,b,c,d) = tuple4_wrappers a b c d - -let ( !! ) cp = cp#get -let ( =:= ) cp value = cp#set value - -let shortname cp = String.concat ":" cp#get_name -let get_help cp = cp#get_help - -type option_value = - Module of option_module -| StringValue of string -| IntValue of int -| FloatValue of float -| List of option_value list -| SmallList of option_value list -and option_module = (string * option_value) list - -let rec value_to_raw = function - | Module a -> Raw.Section (List.map (fun (name,value) -> name, value_to_raw value) a) - | StringValue a -> Raw.String a - | IntValue a -> Raw.Int a - | FloatValue a -> Raw.Float a - | List a -> Raw.List (List.map value_to_raw a) - | SmallList a -> Raw.Tuple (List.map value_to_raw a) -let rec raw_to_value = function - | Raw.String a -> StringValue a - | Raw.Int a -> IntValue a - | Raw.Float a -> FloatValue a - | Raw.List a -> List (List.map raw_to_value a) - | Raw.Tuple a -> SmallList (List.map raw_to_value a) - | Raw.Section a -> Module (List.map (fun (name,value) -> name, raw_to_value value) a) - -let define_option_class _ of_option_value to_option_value = - {to_raw = (fun a -> a |> to_option_value |> value_to_raw); - of_raw = (fun a -> a |> raw_to_value |> of_option_value)} - -let to_value {to_raw = to_raw} a = a |> to_raw |> raw_to_value -let from_value {of_raw = of_raw} a = a |> value_to_raw |> of_raw - -let of_value_w wrappers a = a |> value_to_raw |> wrappers.of_raw -let to_value_w wrappers a = a |> wrappers.to_raw |> raw_to_value -(* fancy indentation when finishing this stub code, not good style :-) *) -let value_to_string : option_value -> string = of_value_w string_option -let string_to_value = to_value_w string_option -let value_to_int = of_value_w int_option -let int_to_value = to_value_w int_option -let value_to_bool = of_value_w bool_option -let bool_to_value = to_value_w bool_option -let value_to_float = of_value_w float_option -let float_to_value = to_value_w float_option -let value_to_string2 = of_value_w string2_option -let string2_to_value = to_value_w string2_option -let value_to_list of_value = - let wrapper = define_option_class "" of_value (fun _ -> failwith "value_to_list") in - of_value_w (list_option wrapper) -let list_to_value to_value = - let wrapper = define_option_class "" (fun _ -> failwith "value_to_list") to_value in - to_value_w (list_option wrapper) diff --git a/ide/utils/config_file.mli b/ide/utils/config_file.mli deleted file mode 100644 index 22328e7f..00000000 --- a/ide/utils/config_file.mli +++ /dev/null @@ -1,352 +0,0 @@ -(*********************************************************************************) -(* Cameleon *) -(* *) -(* Copyright (C) 2005 Institut National de Recherche en Informatique et *) -(* en Automatique. All rights reserved. *) -(* *) -(* This program is free software; you can redistribute it and/or modify *) -(* it under the terms of the GNU Library General Public License as *) -(* published by the Free Software Foundation; either version 2 of the *) -(* License, or any later version. *) -(* *) -(* This program is distributed in the hope that it will be useful, *) -(* but WITHOUT ANY WARRANTY; without even the implied warranty of *) -(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) -(* GNU Library General Public License for more details. *) -(* *) -(* You should have received a copy of the GNU Library General Public *) -(* License along with this program; if not, write to the Free Software *) -(* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA *) -(* 02111-1307 USA *) -(* *) -(* Contact: Maxence.Guesdon@inria.fr *) -(* *) -(*********************************************************************************) - -(** - This module implements a mechanism to handle configuration files. - A configuration file is defined as a set of [variable = value] lines, - where value can be - a simple string (types int, string, bool...), - a list of values between brackets (lists) or parentheses (tuples), - or a set of [variable = value] lines between braces. - The configuration file is automatically loaded and saved, - and configuration parameters are manipulated inside the program as easily as references. - - Object implementation by Jean-Baptiste Rouquier. -*) - -(** {1:lowlevelinterface Low level interface} *) -(** Skip this section on a first reading... *) - -(** The type of cp freshly parsed from configuration file, -not yet wrapped in their proper type. *) -module Raw : sig - type cp = - | String of string (** base types, reproducing the tokens of Genlex *) - | Int of int - | Float of float - | List of cp list (** compound types *) - | Tuple of cp list - | Section of (string * cp) list - - (** A parser. *) - val of_string : string -> cp - - (** Used to print the values into a log file for instance. *) - val to_channel : out_channel -> cp -> unit -end - -(** A type used to specialize polymorphics classes and define new classes. - {!Config_file.predefinedwrappers} are provided. - *) -type 'a wrappers = { to_raw : 'a -> Raw.cp; of_raw : Raw.cp -> 'a; } - -(** An exception raised by {!Config_file.cp.set_raw} - when the argument doesn't have a suitable {!Config_file.Raw.cp} type. - The function explains the problem and flush the output.*) -exception Wrong_type of (out_channel -> unit) - -(* (\** {2 Miscellaneous functions} *\) *) - -(* val bool_of_string : string -> bool *) - -(** {1 High level interface} *) -(** {2 The two main classes} *) - -(** A Configuration Parameter, in short cp, ie - a value we can store in and read from a configuration file. *) -class type ['a] cp = object - (** {1 Accessing methods} *) - - method get : 'a - method set : 'a -> unit - method get_default : 'a - method get_help : string - method get_name : string list - - (** Resets to the default value. *) - method reset : unit - - (** {1 Miscellaneous} *) - - (** All the hooks are executed each time the method set is called, - just after setting the new value.*) - method add_hook : ('a -> 'a -> unit) -> unit - - (** Used to generate command line arguments in {!Config_file.group.command_line_args} *) - method set_short_name : string -> unit - - (** [None] if no optional short_name was provided during object creation - and [set_short_name] was never called.*) - method get_short_name : string option - - (** {1 Methods for internal use} *) - - method get_formatted : Format.formatter -> unit - method get_default_formatted : Format.formatter -> unit - method get_help_formatted : Format.formatter -> unit - - method get_spec : Arg.spec - method set_raw : Raw.cp -> unit -end - -(** Unification over all possible ['a cp]: - contains the main methods of ['a cp] except the methods using the type ['a]. - A [group] manipulates only [groupable_cp] for homogeneity. *) -type groupable_cp = < - get_name : string list; - get_short_name : string option; - get_help : string; - - get_formatted : Format.formatter -> unit; - get_default_formatted : Format.formatter -> unit; - get_help_formatted : Format.formatter -> unit; - get_spec : Arg.spec; - - reset : unit; - set_raw : Raw.cp -> unit; > - -(** Raised in case a name is already used. - See {!Config_file.group.add} *) -exception Double_name - -(** An exception possibly raised if we want to check that - every cp is defined in a configuration file. - See {!Config_file.group.read}. -*) -exception Missing_cp of groupable_cp - -(** A group of cps, that can be loaded and saved, -or used to generate command line arguments. - -The basic usage is to have only one group and one configuration file, -but this mechanism allows having more, -for instance having another smaller group for the options to pass on the command line. -*) -class group : object - (** Adds a cp to the group. - Note that the type ['a] must be lost - to allow cps of different types to belong to the same group. - @raise Double_name if [cp#get_name] is already used. *) -(* method add : 'a cp -> 'a cp *) - method add : 'a cp -> unit - - (**[write filename] saves all the cps into the configuration file [filename].*) - method write : ?with_help:bool -> string -> unit - - (** [read filename] reads [filename] - and stores the values it specifies into the cps belonging to this group. - The file is created (and not read) if it doesn't exists. - In the default behaviour, no warning is issued - if not all cps are updated or if some values of [filename] aren't used. - - If [obsoletes] is specified, - then prints in this file all the values that are - in [filename] but not in this group. - Those cps are likely to be erroneous or obsolete. - Opens this file only if there is something to write in it. - - If [no_default] is [true], then raises [Missing_cp foo] if - the cp [foo] isn't defined in [filename] but belongs to this group. - - [on_type_error groupable_cp value output filename in_channel] - is called if the file doesn't give suitable value - (string instead of int for instance, or a string not belonging to the expected enumeration) - for the cp [groupable_cp]. - [value] is the value read from the file, - [output] is the argument of {!Config_file.Wrong_type}, - [filename] is the same argument as the one given to read, - and [in_channel] refers to [filename] to allow a function to close it if needed. - Default behaviour is to print an error message and call [exit 1]. -*) - method read : ?obsoletes:string -> ?no_default:bool -> - ?on_type_error : (groupable_cp -> Raw.cp -> (out_channel -> unit) -> - string -> in_channel -> unit) -> - string -> unit - - (** Interface with module Arg. - @param section_separator the string used to concatenate the name of a cp, - to get the command line option name. - ["-"] is a good default. - @return a list that can be used with [Arg.parse] and [Arg.usage].*) - method command_line_args : section_separator:string -> (string * Arg.spec * string) list - end - -(** {2 Predefined cp classes} *) - -(** The last three non-optional arguments are always - [name] (of type string list), [default_value] and [help] (of type string). - - [name] is the path to the cp: [["section";"subsection"; ...; "foo"]]. - It can consists of a single element but must not be empty. - - [short_name] will be added a "-" and used in - {!Config_file.group.command_line_args}. - - [group], if provided, adds the freshly defined option to it - (something like [initializer group#add self]). - - [help] needs not contain newlines, it will be automatically truncated where needed. - It is mandatory but can be [""]. -*) - -class int_cp : ?group:group -> string list -> ?short_name:string -> int -> string -> [int] cp -class float_cp : ?group:group -> string list -> ?short_name:string -> float -> string -> [float] cp -class bool_cp : ?group:group -> string list -> ?short_name:string -> bool -> string -> [bool] cp -class string_cp : ?group:group -> string list -> ?short_name:string -> string -> string -> [string] cp -class ['a] list_cp : 'a wrappers -> ?group:group -> string list -> ?short_name:string -> 'a list -> string -> ['a list] cp -class ['a] option_cp : 'a wrappers -> ?group:group -> string list -> ?short_name:string -> 'a option -> string -> ['a option] cp -class ['a] enumeration_cp : (string * 'a) list -> ?group:group -> string list -> ?short_name:string -> 'a -> string -> ['a] cp -class ['a, 'b] tuple2_cp : 'a wrappers -> 'b wrappers -> ?group:group -> string list -> ?short_name:string -> 'a * 'b -> string -> ['a * 'b] cp -class ['a, 'b, 'c] tuple3_cp : 'a wrappers -> 'b wrappers -> 'c wrappers -> ?group:group -> string list -> ?short_name:string -> 'a * 'b * 'c -> string -> ['a * 'b * 'c] cp -class ['a, 'b, 'c, 'd] tuple4_cp : 'a wrappers -> 'b wrappers -> 'c wrappers -> 'd wrappers -> ?group:group -> string list -> ?short_name:string -> 'a * 'b * 'c * 'd -> string -> ['a * 'b * 'c * 'd] cp -class string2_cp : ?group:group -> string list -> ?short_name:string -> string * string -> string -> [string, string] tuple2_cp -(* class color_cp : ?group:group -> string list -> ?short_name:string -> string -> string -> string_cp *) -class font_cp : ?group:group -> string list -> ?short_name:string -> string -> string -> string_cp -class filename_cp : ?group:group -> string list -> ?short_name:string -> string -> string -> string_cp - -(** {2:predefinedwrappers Predefined wrappers} *) - -val int_wrappers : int wrappers -val float_wrappers : float wrappers -val bool_wrappers : bool wrappers -val string_wrappers : string wrappers -val list_wrappers : 'a wrappers -> 'a list wrappers -val option_wrappers : 'a wrappers -> 'a option wrappers - -(** If you have a [type suit = Spades | Hearts | Diamond | Clubs], then -{[enumeration_wrappers ["spades",Spades; "hearts",Hearts; "diamond",Diamond; "clubs",Clubs]]} -will allow you to use cp of this type. -For sum types with not only constant constructors, -you will need to define your own cp class. *) -val enumeration_wrappers : (string * 'a) list -> 'a wrappers -val tuple2_wrappers : 'a wrappers -> 'b wrappers -> ('a * 'b) wrappers -val tuple3_wrappers : 'a wrappers -> 'b wrappers -> 'c wrappers -> ('a * 'b * 'c) wrappers -val tuple4_wrappers : 'a wrappers -> 'b wrappers -> 'c wrappers -> 'd wrappers -> ('a * 'b * 'c * 'd) wrappers - -(** {2 Defining new cp classes} *) - -(** To define a new cp class, you just have to provide an implementation for the wrappers -between your type [foo] and the type [Raw.cp]. -Once you have your wrappers [w], write -{[class foo_cp = [foo] cp_custom_type w]} - -For further details, have a look at the commented .ml file, -section "predefined cp classes". -*) -class ['a] cp_custom_type : 'a wrappers -> - ?group:group -> string list -> ?short_name:string -> 'a -> string -> ['a] cp - - -(** {1 Backward compatibility} - -Deprecated. - -All the functions from the module Options are available, except: - -- [prune_file]: use [group#write ?obsoletes:"foo.ml"]. -- [smalllist_to_value], [smalllist_option]: use lists or tuples. -- [get_class]. -- [class_hook]: hooks are local to a cp. - If you want hooks global to a class, - define a new class that inherit from {!Config_file.cp_custom_type}. -- [set_simple_option], [get_simple_option], [simple_options], [simple_args]: - use {!Config_file.group.write}. -- [set_option_hook]: use {!Config_file.cp.add_hook}. -- [set_string_wrappers]: define a new class with {!Config_file.cp_custom_type}. - -The old configurations files are readable by this module. -*) - - - - - -(**/**) -type 'a option_class -type 'a option_record -type options_file - -val create_options_file : string -> options_file -val set_options_file : options_file -> string -> unit -val load : options_file -> unit -val append : options_file -> string -> unit -val save : options_file -> unit -val save_with_help : options_file -> unit -(* val define_option : options_file -> *) -(* string list -> string -> 'a option_class -> 'a -> 'a option_record *) -val option_hook : 'a option_record -> (unit -> unit) -> unit - -val string_option : string option_class -val color_option : string option_class -val font_option : string option_class -val int_option : int option_class -val bool_option : bool option_class -val float_option : float option_class -val string2_option : (string * string) option_class - -val option_option : 'a option_class -> 'a option option_class -val list_option : 'a option_class -> 'a list option_class -val sum_option : (string * 'a) list -> 'a option_class -val tuple2_option : - 'a option_class * 'b option_class -> ('a * 'b) option_class -val tuple3_option : 'a option_class * 'b option_class * 'c option_class -> - ('a * 'b * 'c) option_class -val tuple4_option : - 'a option_class * 'b option_class * 'c option_class * 'd option_class -> - ('a * 'b * 'c * 'd) option_class - -val ( !! ) : 'a option_record -> 'a -val ( =:= ) : 'a option_record -> 'a -> unit -val shortname : 'a option_record -> string -val get_help : 'a option_record -> string - -type option_value = - Module of option_module -| StringValue of string -| IntValue of int -| FloatValue of float -| List of option_value list -| SmallList of option_value list -and option_module = (string * option_value) list - -val define_option_class : - string -> (option_value -> 'a) -> ('a -> option_value) -> 'a option_class - -val to_value : 'a option_class -> 'a -> option_value -val from_value : 'a option_class -> option_value -> 'a - -val value_to_string : option_value -> string -val string_to_value : string -> option_value -val value_to_int : option_value -> int -val int_to_value : int -> option_value -val bool_of_string : string -> bool -val value_to_bool : option_value -> bool -val bool_to_value : bool -> option_value -val value_to_float : option_value -> float -val float_to_value : float -> option_value -val value_to_string2 : option_value -> string * string -val string2_to_value : string * string -> option_value -val value_to_list : (option_value -> 'a) -> option_value -> 'a list -val list_to_value : ('a -> option_value) -> 'a list -> option_value diff --git a/ide/utils/configwin.ml b/ide/utils/configwin.ml index 4606ef29..69e8b647 100644 --- a/ide/utils/configwin.ml +++ b/ide/utils/configwin.ml @@ -36,44 +36,16 @@ type return_button = | Return_ok | Return_cancel -let string_to_key = Configwin_types.string_to_key -let key_to_string = Configwin_types.key_to_string -let key_cp_wrapper = Configwin_types.key_cp_wrapper -class key_cp = Configwin_types.key_cp - - let string = Configwin_ihm.string -let text = Configwin_ihm.text let strings = Configwin_ihm.strings let list = Configwin_ihm.list let bool = Configwin_ihm.bool -let filename = Configwin_ihm.filename -let filenames = Configwin_ihm.filenames -let color = Configwin_ihm.color -let font = Configwin_ihm.font let combo = Configwin_ihm.combo let custom = Configwin_ihm.custom -let date = Configwin_ihm.date -let hotkey = Configwin_ihm.hotkey let modifiers = Configwin_ihm.modifiers -let html = Configwin_ihm.html let edit ?(apply=(fun () -> ())) title ?width ?height conf_struct_list = Configwin_ihm.edit ~with_apply: true ~apply title ?width ?height conf_struct_list - -let get = Configwin_ihm.edit ~with_apply: false ~apply: (fun () -> ()) - -let simple_edit - ?(apply=(fun () -> ())) - title ?width ?height - param_list = Configwin_ihm.simple_edit ~with_apply: true ~apply title ?width ?height param_list - -let simple_get = Configwin_ihm.simple_edit - ~with_apply: false ~apply: (fun () -> ()) - -let box = Configwin_ihm.box - -let tabbed_box = Configwin_ihm.tabbed_box diff --git a/ide/utils/configwin.mli b/ide/utils/configwin.mli index c5fbf39a..7616e471 100644 --- a/ide/utils/configwin.mli +++ b/ide/utils/configwin.mli @@ -50,22 +50,6 @@ type return_button = button or the window manager but never clicked on the apply button.*) - -(** {2 The key option class (to use with the {!Config_file} library)} *) - -val string_to_key : string -> Gdk.Tags.modifier list * int - -val key_to_string : Gdk.Tags.modifier list * int -> string - -val key_cp_wrapper : (Gdk.Tags.modifier list * int) Config_file.wrappers - -class key_cp : - ?group:Config_file.group -> - string list -> - ?short_name:string -> - Gdk.Tags.modifier list * int -> - string -> [Gdk.Tags.modifier list * int] Config_file.cp_custom_type - (** {2 Functions to create parameters} *) (** [string label value] creates a string parameter. @@ -136,24 +120,6 @@ val list : ?editable: bool -> ?help: string -> 'a list -> parameter_kind -(** [color label value] creates a color parameter. - @param editable indicate if the value is editable (default is [true]). - @param expand indicate if the entry widget must expand or not (default is [true]). - @param help an optional help message. - @param f the function called to apply the value (default function does nothing). -*) -val color : ?editable: bool -> ?expand: bool -> ?help: string -> - ?f: (string -> unit) -> string -> string -> parameter_kind - -(** [font label value] creates a font parameter. - @param editable indicate if the value is editable (default is [true]). - @param expand indicate if the entry widget must expand or not (default is [true]). - @param help an optional help message. - @param f the function called to apply the value (default function does nothing). -*) -val font : ?editable: bool -> ?expand: bool -> ?help: string -> - ?f: (string -> unit) -> string -> string -> parameter_kind - (** [combo label choices value] creates a combo parameter. @param editable indicate if the value is editable (default is [true]). @param expand indicate if the entry widget must expand or not (default is [true]). @@ -169,69 +135,6 @@ val combo : ?editable: bool -> ?expand: bool -> ?help: string -> ?new_allowed: bool -> ?blank_allowed: bool -> string -> string list -> string -> parameter_kind -(** [text label value] creates a text parameter. - @param editable indicate if the value is editable (default is [true]). - @param expand indicate if the box for the text must expand or not (default is [true]). - @param help an optional help message. - @param f the function called to apply the value (default function does nothing). -*) -val text : ?editable: bool -> ?expand: bool -> ?help: string -> - ?f: (string -> unit) -> string -> string -> parameter_kind - -(** Same as {!Configwin.text} but html bindings are available - in the text widget. Use the [configwin_html_config] utility - to edit your bindings. -*) -val html : ?editable: bool -> ?expand: bool -> ?help: string -> - ?f: (string -> unit) -> string -> string -> parameter_kind - -(** [filename label value] creates a filename parameter. - @param editable indicate if the value is editable (default is [true]). - @param expand indicate if the entry widget must expand or not (default is [true]). - @param help an optional help message. - @param f the function called to apply the value (default function does nothing). -*) -val filename : ?editable: bool -> ?expand: bool -> ?help: string -> - ?f: (string -> unit) -> string -> string -> parameter_kind - -(** [filenames label value] creates a filename list parameter. - @param editable indicate if the value is editable (default is [true]). - @param help an optional help message. - @param f the function called to apply the value (default function does nothing). - @param eq the comparison function, used not to have doubles in list. Default - is [Pervasives.(=)]. If you want to allow doubles in the list, give a function - always returning false. -*) -val filenames : ?editable: bool -> ?help: string -> - ?f: (string list -> unit) -> - ?eq: (string -> string -> bool) -> - string -> string list -> parameter_kind - -(** [date label value] creates a date parameter. - @param editable indicate if the value is editable (default is [true]). - @param expand indicate if the entry widget must expand or not (default is [true]). - @param help an optional help message. - @param f the function called to apply the value (default function does nothing). - @param f_string the function used to display the date as a string. The parameter - is a tupe [(day,month,year)], where [month] is between [0] and [11]. The default - function creates the string [year/month/day]. -*) -val date : ?editable: bool -> ?expand: bool -> ?help: string -> - ?f: ((int * int * int) -> unit) -> - ?f_string: ((int * int * int -> string)) -> - string -> (int * int * int) -> parameter_kind - -(** [hotkey label value] creates a hot key parameter. - A hot key is defined by a list of modifiers and a key code. - @param editable indicate if the value is editable (default is [true]). - @param expand indicate if the entry widget must expand or not (default is [true]). - @param help an optional help message. - @param f the function called to apply the value (default function does nothing). -*) -val hotkey : ?editable: bool -> ?expand: bool -> ?help: string -> - ?f: ((Gdk.Tags.modifier list * int) -> unit) -> - string -> (Gdk.Tags.modifier list * int) -> parameter_kind - val modifiers : ?editable: bool -> ?expand: bool -> ?help: string -> ?allow:(Gdk.Tags.modifier list) -> ?f: (Gdk.Tags.modifier list -> unit) -> @@ -259,46 +162,3 @@ val edit : ?height:int -> configuration_structure list -> return_button - -(** This function takes a configuration structure and creates a window used - to get the various parameters from the user. It is the same window as edit but - there is no apply button.*) -val get : - string -> - ?width:int -> - ?height:int -> - configuration_structure list -> - return_button - -(** This function takes a list of parameter specifications and - creates a window to configure the various parameters. - @param apply this function is called when the apply button is clicked, after - giving new values to parameters.*) -val simple_edit : - ?apply: (unit -> unit) -> - string -> - ?width:int -> - ?height:int -> - parameter_kind list -> return_button - -(** This function takes a list of parameter specifications and - creates a window to configure the various parameters, - without Apply button.*) -val simple_get : - string -> - ?width:int -> - ?height:int -> - parameter_kind list -> return_button - -(** Create a [GPack.box] with the list of given parameters, - Return the box and the function to call to apply new values to parameters. -*) -val box : parameter_kind list -> GData.tooltips -> GPack.box * (unit -> unit) - -(** Create a [GPack.box] with the list of given configuration structure list, - and the given list of buttons (defined by their label and callback). - Before calling the callback of a button, the [apply] function - of each parameter is called. -*) -val tabbed_box : configuration_structure list -> - (string * (unit -> unit)) list -> GData.tooltips -> GPack.box diff --git a/ide/utils/configwin_ihm.ml b/ide/utils/configwin_ihm.ml index c1062a9d..d16efa60 100644 --- a/ide/utils/configwin_ihm.ml +++ b/ide/utils/configwin_ihm.ml @@ -27,7 +27,25 @@ open Configwin_types -module O = Config_file +let modifiers_to_string m = + let rec iter m s = + match m with + [] -> s + | c :: m -> + iter m (( + match c with + `CONTROL -> "<ctrl>" + | `SHIFT -> "<shft>" + | `LOCK -> "<lock>" + | `MOD1 -> "<alt>" + | `MOD2 -> "<mod2>" + | `MOD3 -> "<mod3>" + | `MOD4 -> "<mod4>" + | `MOD5 -> "<mod5>" + | _ -> raise Not_found + ) ^ s) + in + iter m "" class type widget = object @@ -35,112 +53,9 @@ class type widget = method apply : unit -> unit end -let file_html_config = Filename.concat Configwin_messages.home ".configwin_html" - let debug = false let dbg s = if debug then Minilib.log s else () -(** Return the config group for the html config file, - and the option for bindings. *) -let html_config_file_and_option () = - let ini = new O.group in - let bindings = new O.list_cp - Configwin_types.htmlbinding_cp_wrapper - ~group: ini - ["bindings"] - ~short_name: "bd" - [ { html_key = Configwin_types.string_to_key "A-b" ; - html_begin = "<b>"; - html_end = "</b>" ; - } ; - { html_key = Configwin_types.string_to_key "A-i" ; - html_begin = "<i>"; - html_end = "</i>" ; - } - ] - "" - in - ini#read file_html_config ; - (ini, bindings) - -(** This variable contains the last directory where the user selected a file.*) -let last_dir = ref "";; - -(** This function allows the user to select a file and returns the - selected file name. An optional function allows changing the - behaviour of the ok button. - A VOIR : mutli-selection ? *) -let select_files ?dir - ?(fok : (string -> unit) option) - the_title = - let files = ref ([] : string list) in - let fs = GWindow.file_selection ~modal:true - ~title: the_title () in - (* we set the previous directory, if no directory is given *) - ( - match dir with - None -> - if !last_dir <> "" then - let _ = fs#set_filename !last_dir in - () - else - () - | Some dir -> - let _ = fs#set_filename !last_dir in - () - ); - - let _ = fs # connect#destroy ~callback: GMain.Main.quit in - let _ = fs # ok_button # connect#clicked ~callback: - (match fok with - None -> - (fun () -> files := [fs#filename] ; fs#destroy ()) - | Some f -> - (fun () -> f fs#filename) - ) - in - let _ = fs # cancel_button # connect#clicked ~callback:fs#destroy in - fs # show (); - GMain.Main.main (); - match !files with - | [] -> - [] - | [""] -> - [] - | l -> - (* we keep the directory in last_dir *) - last_dir := Filename.dirname (List.hd l); - l -;; - -(** Make the user select a date. *) -let select_date title (day,mon,year) = - let v_opt = ref None in - let window = GWindow.dialog ~modal:true ~title () in - let hbox = GPack.hbox ~border_width:10 ~packing:window#vbox#add () in - let cal = GMisc.calendar ~packing: (hbox#pack ~expand: true) () in - cal#select_month ~month: mon ~year: year ; - cal#select_day day; - let bbox = window#action_area in - - let bok = GButton.button ~label: Configwin_messages.mOk - ~packing:(bbox#pack ~expand:true ~padding:4) () - in - let bcancel = GButton.button ~label: Configwin_messages.mCancel - ~packing:(bbox#pack ~expand:true ~padding:4) () - in - ignore (bok#connect#clicked ~callback: - (fun () -> v_opt := Some (cal#date); window#destroy ())); - ignore(bcancel#connect#clicked ~callback: window#destroy); - - bok#grab_default (); - ignore(window#connect#destroy ~callback: GMain.Main.quit); - window#set_position `CENTER; - window#show (); - GMain.Main.main (); - !v_opt - - (** This class builds a frame with a clist and two buttons : one to add items and one to remove the selected items. The class takes in parameter a function used to add items and @@ -460,164 +375,6 @@ class custom_param_box param (tt:GData.tooltips) = method apply = param.custom_f_apply () end -(** This class is used to build a box for a color parameter.*) -class color_param_box param (tt:GData.tooltips) = - let _ = dbg "color_param_box" in - let v = ref param.color_value in - let hbox = GPack.hbox () in - let wb = GButton.button ~label: param.color_label - ~packing: (hbox#pack ~expand: false ~padding: 2) () - in - let w_test = GMisc.arrow - ~kind: `RIGHT - ~shadow: `OUT - ~width: 20 - ~height: 20 - ~packing: (hbox#pack ~expand: false ~padding: 2 ) - () - in - let we = GEdit.entry - ~editable: param.color_editable - ~packing: (hbox#pack ~expand: param.color_expand ~padding: 2) - () - in - let _ = - match param.color_help with - None -> () - | Some help -> - tt#set_tip ~text: help ~privat: help wb#coerce - in - let set_color s = - let style = w_test#misc#style#copy in - ( - try style#set_fg [ (`NORMAL, `NAME s) ; ] - with _ -> () - ); - w_test#misc#set_style style; - in - let _ = set_color !v in - let _ = we#set_text !v in - let f_sel () = - let dialog = GWindow.color_selection_dialog - ~title: param.color_label - ~modal: true - ~show: true - () - in - let wb_ok = dialog#ok_button in - let wb_cancel = dialog#cancel_button in - let _ = dialog#connect#destroy ~callback:GMain.Main.quit in - let _ = wb_ok#connect#clicked - ~callback:(fun () -> -(* let color = dialog#colorsel#color in - let r = (Gdk.Color.red color) in - let g = (Gdk.Color.green color)in - let b = (Gdk.Color.blue color) in - let s = Printf.sprintf "#%4X%4X%4X" r g b in - let _ = - for i = 1 to (String.length s) - 1 do - if s.[i] = ' ' then s.[i] <- '0' - done - in - we#set_text s ; *) - dialog#destroy () - ) - in - let _ = wb_cancel#connect#clicked ~callback:dialog#destroy in - GMain.Main.main () - in - let _ = - if param.color_editable then ignore (wb#connect#clicked ~callback:f_sel) - in - - object (self) - (** This method returns the main box ready to be packed. *) - method box = hbox#coerce - (** This method applies the new value of the parameter. *) - method apply = - let new_value = we#text in - if new_value <> param.color_value then - let _ = param.color_f_apply new_value in - param.color_value <- new_value - else - () - - initializer - ignore (we#connect#changed ~callback:(fun () -> set_color we#text)); - - end ;; - -(** This class is used to build a box for a font parameter.*) -class font_param_box param (tt:GData.tooltips) = - let _ = dbg "font_param_box" in - let v = ref param.font_value in - let hbox = GPack.hbox () in - let wb = GButton.button ~label: param.font_label - ~packing: (hbox#pack ~expand: false ~padding: 2) () - in - let we = GEdit.entry - ~editable: false - ~packing: (hbox#pack ~expand: param.font_expand ~padding: 2) - () - in - let _ = - match param.font_help with - None -> () - | Some help -> - tt#set_tip ~text: help ~privat: help wb#coerce - in - let set_entry_font font_opt = - match font_opt with - None -> () - | Some s -> - let style = we#misc#style#copy in - ( - try - let font = Gdk.Font.load_fontset s in - style#set_font font - with _ -> () - ); - we#misc#set_style style - in - let _ = set_entry_font (Some !v) in - let _ = we#set_text !v in - let f_sel () = - let dialog = GWindow.font_selection_dialog - ~title: param.font_label - ~modal: true - ~show: true - () - in - dialog#selection#set_font_name !v; - let wb_ok = dialog#ok_button in - let wb_cancel = dialog#cancel_button in - let _ = dialog#connect#destroy ~callback:GMain.Main.quit in - let _ = wb_ok#connect#clicked - ~callback:(fun () -> - let font = dialog#selection#font_name in - we#set_text font ; - set_entry_font (Some font); - dialog#destroy () - ) - in - let _ = wb_cancel#connect#clicked ~callback:dialog#destroy in - GMain.Main.main () - in - let _ = if param.font_editable then ignore (wb#connect#clicked ~callback:f_sel) in - - object (self) - (** This method returns the main box ready to be packed. *) - method box = hbox#coerce - (** This method applies the new value of the parameter. *) - method apply = - let new_value = we#text in - if new_value <> param.font_value then - let _ = param.font_f_apply new_value in - param.font_value <- new_value - else - () - end ;; - (** This class is used to build a box for a text parameter.*) class text_param_box param (tt:GData.tooltips) = let _ = dbg "text_param_box" in @@ -654,7 +411,7 @@ class text_param_box param (tt:GData.tooltips) = let v = param.string_of_string (buffer#get_text ()) in if v <> param.string_value then ( - dbg "apply new value !"; + dbg "apply new value!"; let _ = param.string_f_apply v in param.string_value <- v ) @@ -662,35 +419,6 @@ class text_param_box param (tt:GData.tooltips) = () end ;; -(** This class is used to build a box a html parameter. *) -class html_param_box param (tt:GData.tooltips) = - let _ = dbg "html_param_box" in - object (self) - inherit text_param_box param tt - - method private exec html_start html_end () = - let (i1,i2) = wview#buffer#selection_bounds in - let s = i1#get_text ~stop: i2 in - match s with - "" -> - wview#buffer#insert (html_start^html_end) - | _ -> - ignore (wview#buffer#insert ~iter: i2 html_end); - ignore (wview#buffer#insert ~iter: i1 html_start); - wview#buffer#place_cursor ~where: i2 - - initializer - dbg "html_param_box:initializer"; - let (_,html_bindings) = html_config_file_and_option () in - dbg "html_param_box:connecting key press events"; - let add_shortcut hb = - let (mods, k) = hb.html_key in - Okey.add wview ~mods k (self#exec hb.html_begin hb.html_end) - in - List.iter add_shortcut html_bindings#get; - dbg "html_param_box:end" - end - (** This class is used to build a box for a boolean parameter.*) class bool_param_box param (tt:GData.tooltips) = let _ = dbg "bool_param_box" in @@ -719,105 +447,6 @@ class bool_param_box param (tt:GData.tooltips) = () end ;; -(** This class is used to build a box for a file name parameter.*) -class filename_param_box param (tt:GData.tooltips) = - let _ = dbg "filename_param_box" in - let hbox = GPack.hbox () in - let wb = GButton.button ~label: param.string_label - ~packing: (hbox#pack ~expand: false ~padding: 2) () - in - let we = GEdit.entry - ~editable: param.string_editable - ~packing: (hbox#pack ~expand: param.string_expand ~padding: 2) - () - in - let _ = - match param.string_help with - None -> () - | Some help -> - tt#set_tip ~text: help ~privat: help wb#coerce - in - let _ = we#set_text (param.string_to_string param.string_value) in - - let f_click () = - match select_files param.string_label with - [] -> - () - | f :: _ -> - we#set_text f - in - let _ = - if param.string_editable then - let _ = wb#connect#clicked ~callback:f_click in - () - else - () - in - - object (self) - (** This method returns the main box ready to be packed. *) - method box = hbox#coerce - (** This method applies the new value of the parameter. *) - method apply = - let new_value = param.string_of_string we#text in - if new_value <> param.string_value then - let _ = param.string_f_apply new_value in - param.string_value <- new_value - else - () - end ;; - -(** This class is used to build a box for a hot key parameter.*) -class hotkey_param_box param (tt:GData.tooltips) = - let _ = dbg "hotkey_param_box" in - let hbox = GPack.hbox () in - let wev = GBin.event_box ~packing: (hbox#pack ~expand: false ~padding: 2) () in - let _wl = GMisc.label ~text: param.hk_label ~packing: wev#add () in - let we = GEdit.entry - ~editable: false - ~packing: (hbox#pack ~expand: param.hk_expand ~padding: 2) - () - in - let value = ref param.hk_value in - let _ = - match param.hk_help with - None -> () - | Some help -> - tt#set_tip ~text: help ~privat: help wev#coerce - in - let _ = we#set_text (Configwin_types.key_to_string param.hk_value) in - let mods_we_dont_care = [`MOD2 ; `MOD3 ; `MOD4 ; `MOD5 ; `LOCK] in - let capture ev = - let key = GdkEvent.Key.keyval ev in - let modifiers = GdkEvent.Key.state ev in - let mods = List.filter - (fun m -> not (List.mem m mods_we_dont_care)) - modifiers - in - value := (mods, key); - we#set_text (Glib.Convert.locale_to_utf8 (Configwin_types.key_to_string !value)); - false - in - let _ = - if param.hk_editable then - ignore (we#event#connect#key_press ~callback:capture) - else - () - in - - object (self) - (** This method returns the main box ready to be packed. *) - method box = hbox#coerce - (** This method applies the new value of the parameter. *) - method apply = - let new_value = !value in - if new_value <> param.hk_value then - let _ = param.hk_f_apply new_value in - param.hk_value <- new_value - else - () - end ;; - class modifiers_param_box param = let hbox = GPack.hbox () in let wev = GBin.event_box ~packing: (hbox#pack ~expand:true ~fill:true ~padding: 2) () in @@ -825,7 +454,7 @@ class modifiers_param_box param = let value = ref param.md_value in let _ = List.map (fun modifier -> let but = GButton.toggle_button - ~label:(Configwin_types.modifiers_to_string [modifier]) + ~label:(modifiers_to_string [modifier]) ~active:(List.mem modifier param.md_value) ~packing:(hbox#pack ~expand:false) () in ignore (but#connect#toggled @@ -854,55 +483,6 @@ class modifiers_param_box param = () end ;; -(** This class is used to build a box for a date parameter.*) -class date_param_box param (tt:GData.tooltips) = - let _ = dbg "date_param_box" in - let v = ref param.date_value in - let hbox = GPack.hbox () in - let wb = GButton.button ~label: param.date_label - ~packing: (hbox#pack ~expand: false ~padding: 2) () - in - let we = GEdit.entry - ~editable: false - ~packing: (hbox#pack ~expand: param.date_expand ~padding: 2) - () - in - - let _ = - match param.date_help with - None -> () - | Some help -> - tt#set_tip ~text: help ~privat: help wb#coerce - in - - let _ = we#set_text (param.date_f_string param.date_value) in - let f_click () = - match select_date param.date_label !v with - None -> () - | Some (y,m,d) -> - v := (d,m,y) ; - we#set_text (param.date_f_string (d,m,y)) - in - let _ = - if param.date_editable then - let _ = wb#connect#clicked ~callback:f_click in - () - else - () - in - - object (self) - (** This method returns the main box ready to be packed. *) - method box = hbox#coerce - (** This method applies the new value of the parameter. *) - method apply = - if !v <> param.date_value then - let _ = param.date_f_apply !v in - param.date_value <- !v - else - () - end ;; - (** This class is used to build a box for a parameter whose values are a list.*) class ['a] list_param_box (param : 'a list_param) (tt:GData.tooltips) = let _ = dbg "list_param_box" in @@ -975,10 +555,6 @@ class configuration_box (tt : GData.tooltips) conf_struct = let box = new bool_param_box p tt in let _ = main_box#pack ~expand: false ~padding: 2 box#box in box - | Filename_param p -> - let box = new filename_param_box p tt in - let _ = main_box#pack ~expand: false ~padding: 2 box#box in - box | List_param f -> let box = f tt in let _ = main_box#pack ~expand: true ~padding: 2 box#box in @@ -987,30 +563,10 @@ class configuration_box (tt : GData.tooltips) conf_struct = let box = new custom_param_box p tt in let _ = main_box#pack ~expand: p.custom_expand ~padding: 2 box#box in box - | Color_param p -> - let box = new color_param_box p tt in - let _ = main_box#pack ~expand: false ~padding: 2 box#box in - box - | Font_param p -> - let box = new font_param_box p tt in - let _ = main_box#pack ~expand: false ~padding: 2 box#box in - box - | Date_param p -> - let box = new date_param_box p tt in - let _ = main_box#pack ~expand: false ~padding: 2 box#box in - box - | Hotkey_param p -> - let box = new hotkey_param_box p tt in - let _ = main_box#pack ~expand: false ~padding: 2 box#box in - box | Modifiers_param p -> let box = new modifiers_param_box p in let _ = main_box#pack ~expand: false ~padding: 2 box#box in box - | Html_param p -> - let box = new html_param_box p tt in - let _ = main_box#pack ~expand: p.string_expand ~padding: 2 box#box in - box in let set_icon iter = function @@ -1102,36 +658,6 @@ class configuration_box (tt : GData.tooltips) conf_struct = end -(** Create a vbox with the list of given configuration structure list, - and the given list of buttons (defined by their label and callback). - Before calling the callback of a button, the [apply] function - of each parameter is called. -*) -let tabbed_box conf_struct_list buttons tooltips = - let param_box = - new configuration_box tooltips conf_struct_list - in - let f_apply () = param_box#apply - in - let hbox_buttons = GPack.hbox ~packing: (param_box#box#pack ~expand: false ~padding: 4) () in - let rec iter_buttons ?(grab=false) = function - [] -> - () - | (label, callb) :: q -> - let b = GButton.button ~label: label - ~packing:(hbox_buttons#pack ~expand:true ~fill: true ~padding:4) () - in - ignore (b#connect#clicked ~callback: - (fun () -> f_apply (); callb ())); - (* If it's the first button then give it the focus *) - if grab then b#grab_default (); - - iter_buttons q - in - iter_buttons ~grab: true buttons; - - param_box#box - (** This function takes a configuration structure list and creates a window to configure the various parameters. *) let edit ?(with_apply=true) @@ -1174,110 +700,6 @@ let edit ?(with_apply=true) in iter Return_cancel -(** Create a vbox with the list of given parameters. *) -let box param_list tt = - let main_box = GPack.vbox () in - let f parameter = - match parameter with - String_param p -> - let box = new string_param_box p tt in - let _ = main_box#pack ~expand: false ~padding: 2 box#box in - box - | Combo_param p -> - let box = new combo_param_box p tt in - let _ = main_box#pack ~expand: false ~padding: 2 box#box in - box - | Text_param p -> - let box = new text_param_box p tt in - let _ = main_box#pack ~expand: p.string_expand ~padding: 2 box#box in - box - | Bool_param p -> - let box = new bool_param_box p tt in - let _ = main_box#pack ~expand: false ~padding: 2 box#box in - box - | Filename_param p -> - let box = new filename_param_box p tt in - let _ = main_box#pack ~expand: false ~padding: 2 box#box in - box - | List_param f -> - let box = f tt in - let _ = main_box#pack ~expand: true ~padding: 2 box#box in - box - | Custom_param p -> - let box = new custom_param_box p tt in - let _ = main_box#pack ~expand: p.custom_expand ~padding: 2 box#box in - box - | Color_param p -> - let box = new color_param_box p tt in - let _ = main_box#pack ~expand: false ~padding: 2 box#box in - box - | Font_param p -> - let box = new font_param_box p tt in - let _ = main_box#pack ~expand: false ~padding: 2 box#box in - box - | Date_param p -> - let box = new date_param_box p tt in - let _ = main_box#pack ~expand: false ~padding: 2 box#box in - box - | Hotkey_param p -> - let box = new hotkey_param_box p tt in - let _ = main_box#pack ~expand: false ~padding: 2 box#box in - box - | Modifiers_param p -> - let box = new modifiers_param_box p in - let _ = main_box#pack ~expand: false ~padding: 2 box#box in - box - | Html_param p -> - let box = new html_param_box p tt in - let _ = main_box#pack ~expand: p.string_expand ~padding: 2 box#box in - box - in - let list_param_box = List.map f param_list in - let f_apply () = - List.iter (fun param_box -> param_box#apply) list_param_box - in - (main_box, f_apply) - -(** This function takes a list of parameter specifications and - creates a window to configure the various parameters.*) -let simple_edit ?(with_apply=true) - ?(apply=(fun () -> ())) - title ?width ?height - param_list = - let dialog = GWindow.dialog - ~modal: true ~title: title - ?height ?width - () - in - let tooltips = GData.tooltips () in - if with_apply then - dialog#add_button Configwin_messages.mApply `APPLY; - - dialog#add_button Configwin_messages.mOk `OK; - dialog#add_button Configwin_messages.mCancel `CANCEL; - - let (box, f_apply) = box param_list tooltips in - dialog#vbox#pack ~expand: true ~fill: true box#coerce; - - let destroy () = - tooltips#destroy () ; - dialog#destroy (); - in - let rec iter rep = - try - match dialog#run () with - | `APPLY -> f_apply (); apply (); iter Return_apply - | `OK -> f_apply () ; destroy () ; Return_ok - | _ -> destroy (); rep - with - Failure s -> - GToolbox.message_box ~title:"Error" s; iter rep - | e -> - GToolbox.message_box ~title:"Error" (Printexc.to_string e); iter rep - in - iter Return_cancel - - let edit_string l s = match GToolbox.input_string ~title: l ~text: s Configwin_messages.mValue with None -> s @@ -1342,30 +764,6 @@ let strings ?(editable=true) ?help ?(add=(fun () -> [])) label v = list ~editable ?help ~f ~eq ~edit: (edit_string label) ~add label (fun s -> [s]) v -(** Create a color param. *) -let color ?(editable=true) ?(expand=true) ?help ?(f=(fun _ -> ())) label v = - Color_param - { - color_label = label ; - color_help = help ; - color_value = v ; - color_editable = editable ; - color_f_apply = f ; - color_expand = expand ; - } - -(** Create a font param. *) -let font ?(editable=true) ?(expand=true) ?help ?(f=(fun _ -> ())) label v = - Font_param - { - font_label = label ; - font_help = help ; - font_value = v ; - font_editable = editable ; - font_f_apply = f ; - font_expand = expand ; - } - (** Create a combo param. *) let combo ?(editable=true) ?(expand=true) ?help ?(f=(fun _ -> ())) ?(new_allowed=false) @@ -1383,82 +781,6 @@ let combo ?(editable=true) ?(expand=true) ?help ?(f=(fun _ -> ())) combo_expand = expand ; } -(** Create a text param. *) -let text ?(editable=true) ?(expand=true) ?help ?(f=(fun _ -> ())) label v = - Text_param - { - string_label = label ; - string_help = help ; - string_value = v ; - string_editable = editable ; - string_f_apply = f ; - string_expand = expand ; - string_to_string = (fun x -> x) ; - string_of_string = (fun x -> x) ; - } - -(** Create a html param. *) -let html ?(editable=true) ?(expand=true) ?help ?(f=(fun _ -> ())) label v = - Html_param - { - string_label = label ; - string_help = help ; - string_value = v ; - string_editable = editable ; - string_f_apply = f ; - string_expand = expand ; - string_to_string = (fun x -> x) ; - string_of_string = (fun x -> x) ; - } - -(** Create a filename param. *) -let filename ?(editable=true) ?(expand=true)?help ?(f=(fun _ -> ())) label v = - Filename_param - { - string_label = label ; - string_help = help ; - string_value = v ; - string_editable = editable ; - string_f_apply = f ; - string_expand = expand ; - string_to_string = (fun x -> x) ; - string_of_string = (fun x -> x) ; - } - -(** Create a filenames param.*) -let filenames ?(editable=true) ?help ?(f=(fun _ -> ())) - ?(eq=Pervasives.(=)) - label v = - let add () = select_files label in - list ~editable ?help ~f ~eq ~add label (fun s -> [Glib.Convert.locale_to_utf8 s]) v - -(** Create a date param. *) -let date ?(editable=true) ?(expand=true) ?help ?(f=(fun _ -> ())) - ?(f_string=(fun(d,m,y)-> Printf.sprintf "%d/%d/%d" y (m+1) d)) - label v = - Date_param - { - date_label = label ; - date_help = help ; - date_value = v ; - date_editable = editable ; - date_f_string = f_string ; - date_f_apply = f ; - date_expand = expand ; - } - -(** Create a hot key param. *) -let hotkey ?(editable=true) ?(expand=true) ?help ?(f=(fun _ -> ())) label v = - Hotkey_param - { - hk_label = label ; - hk_help = help ; - hk_value = v ; - hk_editable = editable ; - hk_f_apply = f ; - hk_expand = expand ; - } - let modifiers ?(editable=true) ?(expand=true) diff --git a/ide/utils/configwin_ihm.mli b/ide/utils/configwin_ihm.mli new file mode 100644 index 00000000..c867ad91 --- /dev/null +++ b/ide/utils/configwin_ihm.mli @@ -0,0 +1,66 @@ +(*********************************************************************************) +(* Cameleon *) +(* *) +(* Copyright (C) 2005 Institut National de Recherche en Informatique et *) +(* en Automatique. All rights reserved. *) +(* *) +(* This program is free software; you can redistribute it and/or modify *) +(* it under the terms of the GNU Library General Public License as *) +(* published by the Free Software Foundation; either version 2 of the *) +(* License, or any later version. *) +(* *) +(* This program is distributed in the hope that it will be useful, *) +(* but WITHOUT ANY WARRANTY; without even the implied warranty of *) +(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) +(* GNU Library General Public License for more details. *) +(* *) +(* You should have received a copy of the GNU Library General Public *) +(* License along with this program; if not, write to the Free Software *) +(* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA *) +(* 02111-1307 USA *) +(* *) +(* Contact: Maxence.Guesdon@inria.fr *) +(* *) +(*********************************************************************************) + +open Configwin_types + +val string : ?editable: bool -> ?expand: bool -> ?help: string -> + ?f: (string -> unit) -> string -> string -> parameter_kind +val bool : ?editable: bool -> ?help: string -> + ?f: (bool -> unit) -> string -> bool -> parameter_kind +val strings : ?editable: bool -> ?help: string -> + ?f: (string list -> unit) -> + ?eq: (string -> string -> bool) -> + ?add: (unit -> string list) -> + string -> string list -> parameter_kind +val list : ?editable: bool -> ?help: string -> + ?f: ('a list -> unit) -> + ?eq: ('a -> 'a -> bool) -> + ?edit: ('a -> 'a) -> + ?add: (unit -> 'a list) -> + ?titles: string list -> + ?color: ('a -> string option) -> + string -> + ('a -> string list) -> + 'a list -> + parameter_kind +val combo : ?editable: bool -> ?expand: bool -> ?help: string -> + ?f: (string -> unit) -> + ?new_allowed: bool -> ?blank_allowed: bool -> + string -> string list -> string -> parameter_kind + +val modifiers : ?editable: bool -> ?expand: bool -> ?help: string -> + ?allow:(Gdk.Tags.modifier list) -> + ?f: (Gdk.Tags.modifier list -> unit) -> + string -> Gdk.Tags.modifier list -> parameter_kind +val custom : ?label: string -> GPack.box -> (unit -> unit) -> bool -> parameter_kind + +val edit : + ?with_apply:bool -> + ?apply:(unit -> unit) -> + string -> + ?width:int -> + ?height:int -> + configuration_structure list -> + return_button diff --git a/ide/utils/configwin_keys.ml b/ide/utils/configwin_keys.ml deleted file mode 100644 index e9b19da6..00000000 --- a/ide/utils/configwin_keys.ml +++ /dev/null @@ -1,4176 +0,0 @@ -(*********************************************************************************) -(* Cameleon *) -(* *) -(* Copyright (C) 2005 Institut National de Recherche en Informatique et *) -(* en Automatique. All rights reserved. *) -(* *) -(* This program is free software; you can redistribute it and/or modify *) -(* it under the terms of the GNU Library General Public License as *) -(* published by the Free Software Foundation; either version 2 of the *) -(* License, or any later version. *) -(* *) -(* This program is distributed in the hope that it will be useful, *) -(* but WITHOUT ANY WARRANTY; without even the implied warranty of *) -(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) -(* GNU Library General Public License for more details. *) -(* *) -(* You should have received a copy of the GNU Library General Public *) -(* License along with this program; if not, write to the Free Software *) -(* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA *) -(* 02111-1307 USA *) -(* *) -(* Contact: Maxence.Guesdon@inria.fr *) -(* *) -(*********************************************************************************) - -(** Key codes - - Ce fichier provient de X11/keysymdef.h - les noms des symboles deviennent : XK_ -> xk_ - - Thanks to Fabrice Le Fessant. -*) - -let xk_VoidSymbol = 0xFFFFFF (** void symbol *) - - -(** TTY Functions, cleverly chosen to map to ascii, for convenience of - programming, but could have been arbitrary (at the cost of lookup - tables in client code. -*) - -let xk_BackSpace = 0xFF08 (** back space, back char *) -let xk_Tab = 0xFF09 -let xk_Linefeed = 0xFF0A (** Linefeed, LF *) -let xk_Clear = 0xFF0B -let xk_Return = 0xFF0D (** Return, enter *) -let xk_Pause = 0xFF13 (** Pause, hold *) -let xk_Scroll_Lock = 0xFF14 -let xk_Sys_Req = 0xFF15 -let xk_Escape = 0xFF1B -let xk_Delete = 0xFFFF (** Delete, rubout *) - - - -(** International & multi-key character composition *) - -let xk_Multi_key = 0xFF20 (** Multi-key character compose *) - -(** Japanese keyboard support *) - -let xk_Kanji = 0xFF21 (** Kanji, Kanji convert *) -let xk_Muhenkan = 0xFF22 (** Cancel Conversion *) -let xk_Henkan_Mode = 0xFF23 (** Start/Stop Conversion *) -let xk_Henkan = 0xFF23 (** Alias for Henkan_Mode *) -let xk_Romaji = 0xFF24 (** to Romaji *) -let xk_Hiragana = 0xFF25 (** to Hiragana *) -let xk_Katakana = 0xFF26 (** to Katakana *) -let xk_Hiragana_Katakana = 0xFF27 (** Hiragana/Katakana toggle *) -let xk_Zenkaku = 0xFF28 (** to Zenkaku *) -let xk_Hankaku = 0xFF29 (** to Hankaku *) -let xk_Zenkaku_Hankaku = 0xFF2A (** Zenkaku/Hankaku toggle *) -let xk_Touroku = 0xFF2B (** Add to Dictionary *) -let xk_Massyo = 0xFF2C (** Delete from Dictionary *) -let xk_Kana_Lock = 0xFF2D (** Kana Lock *) -let xk_Kana_Shift = 0xFF2E (** Kana Shift *) -let xk_Eisu_Shift = 0xFF2F (** Alphanumeric Shift *) -let xk_Eisu_toggle = 0xFF30 (** Alphanumeric toggle *) - -(** = 0xFF31 thru = 0xFF3F are under xk_KOREAN *) - -(** Cursor control & motion *) - -let xk_Home = 0xFF50 -let xk_Left = 0xFF51 (** Move left, left arrow *) -let xk_Up = 0xFF52 (** Move up, up arrow *) -let xk_Right = 0xFF53 (** Move right, right arrow *) -let xk_Down = 0xFF54 (** Move down, down arrow *) -let xk_Prior = 0xFF55 (** Prior, previous *) -let xk_Page_Up = 0xFF55 -let xk_Next = 0xFF56 (** Next *) -let xk_Page_Down = 0xFF56 -let xk_End = 0xFF57 (** EOL *) -let xk_Begin = 0xFF58 (** BOL *) - - -(** Misc Functions *) - -let xk_Select = 0xFF60 (** Select, mark *) -let xk_Print = 0xFF61 -let xk_Execute = 0xFF62 (** Execute, run, do *) -let xk_Insert = 0xFF63 (** Insert, insert here *) -let xk_Undo = 0xFF65 (** Undo, oops *) -let xk_Redo = 0xFF66 (** redo, again *) -let xk_Menu = 0xFF67 -let xk_Find = 0xFF68 (** Find, search *) -let xk_Cancel = 0xFF69 (** Cancel, stop, abort, exit *) -let xk_Help = 0xFF6A (** Help *) -let xk_Break = 0xFF6B -let xk_Mode_switch = 0xFF7E (** Character set switch *) -let xk_script_switch = 0xFF7E (** Alias for mode_switch *) -let xk_Num_Lock = 0xFF7F - -(** Keypad Functions, keypad numbers cleverly chosen to map to ascii *) - -let xk_KP_Space = 0xFF80 (** space *) -let xk_KP_Tab = 0xFF89 -let xk_KP_Enter = 0xFF8D (** enter *) -let xk_KP_F1 = 0xFF91 (** PF1, KP_A, ... *) -let xk_KP_F2 = 0xFF92 -let xk_KP_F3 = 0xFF93 -let xk_KP_F4 = 0xFF94 -let xk_KP_Home = 0xFF95 -let xk_KP_Left = 0xFF96 -let xk_KP_Up = 0xFF97 -let xk_KP_Right = 0xFF98 -let xk_KP_Down = 0xFF99 -let xk_KP_Prior = 0xFF9A -let xk_KP_Page_Up = 0xFF9A -let xk_KP_Next = 0xFF9B -let xk_KP_Page_Down = 0xFF9B -let xk_KP_End = 0xFF9C -let xk_KP_Begin = 0xFF9D -let xk_KP_Insert = 0xFF9E -let xk_KP_Delete = 0xFF9F -let xk_KP_Equal = 0xFFBD (** equals *) -let xk_KP_Multiply = 0xFFAA -let xk_KP_Add = 0xFFAB -let xk_KP_Separator = 0xFFAC (** separator, often comma *) -let xk_KP_Subtract = 0xFFAD -let xk_KP_Decimal = 0xFFAE -let xk_KP_Divide = 0xFFAF - -let xk_KP_0 = 0xFFB0 -let xk_KP_1 = 0xFFB1 -let xk_KP_2 = 0xFFB2 -let xk_KP_3 = 0xFFB3 -let xk_KP_4 = 0xFFB4 -let xk_KP_5 = 0xFFB5 -let xk_KP_6 = 0xFFB6 -let xk_KP_7 = 0xFFB7 -let xk_KP_8 = 0xFFB8 -let xk_KP_9 = 0xFFB9 - - - -(* - * Auxiliary Functions; note the duplicate definitions for left and right - * function keys; Sun keyboards and a few other manufactures have such - * function key groups on the left and/or right sides of the keyboard. - * We've not found a keyboard with more than 35 function keys total. - *) - -let xk_F1 = 0xFFBE -let xk_F2 = 0xFFBF -let xk_F3 = 0xFFC0 -let xk_F4 = 0xFFC1 -let xk_F5 = 0xFFC2 -let xk_F6 = 0xFFC3 -let xk_F7 = 0xFFC4 -let xk_F8 = 0xFFC5 -let xk_F9 = 0xFFC6 -let xk_F10 = 0xFFC7 -let xk_F11 = 0xFFC8 -let xk_L1 = 0xFFC8 -let xk_F12 = 0xFFC9 -let xk_L2 = 0xFFC9 -let xk_F13 = 0xFFCA -let xk_L3 = 0xFFCA -let xk_F14 = 0xFFCB -let xk_L4 = 0xFFCB -let xk_F15 = 0xFFCC -let xk_L5 = 0xFFCC -let xk_F16 = 0xFFCD -let xk_L6 = 0xFFCD -let xk_F17 = 0xFFCE -let xk_L7 = 0xFFCE -let xk_F18 = 0xFFCF -let xk_L8 = 0xFFCF -let xk_F19 = 0xFFD0 -let xk_L9 = 0xFFD0 -let xk_F20 = 0xFFD1 -let xk_L10 = 0xFFD1 -let xk_F21 = 0xFFD2 -let xk_R1 = 0xFFD2 -let xk_F22 = 0xFFD3 -let xk_R2 = 0xFFD3 -let xk_F23 = 0xFFD4 -let xk_R3 = 0xFFD4 -let xk_F24 = 0xFFD5 -let xk_R4 = 0xFFD5 -let xk_F25 = 0xFFD6 -let xk_R5 = 0xFFD6 -let xk_F26 = 0xFFD7 -let xk_R6 = 0xFFD7 -let xk_F27 = 0xFFD8 -let xk_R7 = 0xFFD8 -let xk_F28 = 0xFFD9 -let xk_R8 = 0xFFD9 -let xk_F29 = 0xFFDA -let xk_R9 = 0xFFDA -let xk_F30 = 0xFFDB -let xk_R10 = 0xFFDB -let xk_F31 = 0xFFDC -let xk_R11 = 0xFFDC -let xk_F32 = 0xFFDD -let xk_R12 = 0xFFDD -let xk_F33 = 0xFFDE -let xk_R13 = 0xFFDE -let xk_F34 = 0xFFDF -let xk_R14 = 0xFFDF -let xk_F35 = 0xFFE0 -let xk_R15 = 0xFFE0 - -(** Modifiers *) - -let xk_Shift_L = 0xFFE1 (** Left shift *) -let xk_Shift_R = 0xFFE2 (** Right shift *) -let xk_Control_L = 0xFFE3 (** Left control *) -let xk_Control_R = 0xFFE4 (** Right control *) -let xk_Caps_Lock = 0xFFE5 (** Caps lock *) -let xk_Shift_Lock = 0xFFE6 (** Shift lock *) - -let xk_Meta_L = 0xFFE7 (** Left meta *) -let xk_Meta_R = 0xFFE8 (** Right meta *) -let xk_Alt_L = 0xFFE9 (** Left alt *) -let xk_Alt_R = 0xFFEA (** Right alt *) -let xk_Super_L = 0xFFEB (** Left super *) -let xk_Super_R = 0xFFEC (** Right super *) -let xk_Hyper_L = 0xFFED (** Left hyper *) -let xk_Hyper_R = 0xFFEE (** Right hyper *) - - -(* - * ISO 9995 Function and Modifier Keys - * Byte 3 = = 0xFE - *) - - -let xk_ISO_Lock = 0xFE01 -let xk_ISO_Level2_Latch = 0xFE02 -let xk_ISO_Level3_Shift = 0xFE03 -let xk_ISO_Level3_Latch = 0xFE04 -let xk_ISO_Level3_Lock = 0xFE05 -let xk_ISO_Group_Shift = 0xFF7E (** Alias for mode_switch *) -let xk_ISO_Group_Latch = 0xFE06 -let xk_ISO_Group_Lock = 0xFE07 -let xk_ISO_Next_Group = 0xFE08 -let xk_ISO_Next_Group_Lock = 0xFE09 -let xk_ISO_Prev_Group = 0xFE0A -let xk_ISO_Prev_Group_Lock = 0xFE0B -let xk_ISO_First_Group = 0xFE0C -let xk_ISO_First_Group_Lock = 0xFE0D -let xk_ISO_Last_Group = 0xFE0E -let xk_ISO_Last_Group_Lock = 0xFE0F - -let xk_ISO_Left_Tab = 0xFE20 -let xk_ISO_Move_Line_Up = 0xFE21 -let xk_ISO_Move_Line_Down = 0xFE22 -let xk_ISO_Partial_Line_Up = 0xFE23 -let xk_ISO_Partial_Line_Down = 0xFE24 -let xk_ISO_Partial_Space_Left = 0xFE25 -let xk_ISO_Partial_Space_Right = 0xFE26 -let xk_ISO_Set_Margin_Left = 0xFE27 -let xk_ISO_Set_Margin_Right = 0xFE28 -let xk_ISO_Release_Margin_Left = 0xFE29 -let xk_ISO_Release_Margin_Right = 0xFE2A -let xk_ISO_Release_Both_Margins = 0xFE2B -let xk_ISO_Fast_Cursor_Left = 0xFE2C -let xk_ISO_Fast_Cursor_Right = 0xFE2D -let xk_ISO_Fast_Cursor_Up = 0xFE2E -let xk_ISO_Fast_Cursor_Down = 0xFE2F -let xk_ISO_Continuous_Underline = 0xFE30 -let xk_ISO_Discontinuous_Underline = 0xFE31 -let xk_ISO_Emphasize = 0xFE32 -let xk_ISO_Center_Object = 0xFE33 -let xk_ISO_Enter = 0xFE34 - -let xk_dead_grave = 0xFE50 -let xk_dead_acute = 0xFE51 -let xk_dead_circumflex = 0xFE52 -let xk_dead_tilde = 0xFE53 -let xk_dead_macron = 0xFE54 -let xk_dead_breve = 0xFE55 -let xk_dead_abovedot = 0xFE56 -let xk_dead_diaeresis = 0xFE57 -let xk_dead_abovering = 0xFE58 -let xk_dead_doubleacute = 0xFE59 -let xk_dead_caron = 0xFE5A -let xk_dead_cedilla = 0xFE5B -let xk_dead_ogonek = 0xFE5C -let xk_dead_iota = 0xFE5D -let xk_dead_voiced_sound = 0xFE5E -let xk_dead_semivoiced_sound = 0xFE5F -let xk_dead_belowdot = 0xFE60 - -let xk_First_Virtual_Screen = 0xFED0 -let xk_Prev_Virtual_Screen = 0xFED1 -let xk_Next_Virtual_Screen = 0xFED2 -let xk_Last_Virtual_Screen = 0xFED4 -let xk_Terminate_Server = 0xFED5 - -let xk_AccessX_Enable = 0xFE70 -let xk_AccessX_Feedback_Enable = 0xFE71 -let xk_RepeatKeys_Enable = 0xFE72 -let xk_SlowKeys_Enable = 0xFE73 -let xk_BounceKeys_Enable = 0xFE74 -let xk_StickyKeys_Enable = 0xFE75 -let xk_MouseKeys_Enable = 0xFE76 -let xk_MouseKeys_Accel_Enable = 0xFE77 -let xk_Overlay1_Enable = 0xFE78 -let xk_Overlay2_Enable = 0xFE79 -let xk_AudibleBell_Enable = 0xFE7A - -let xk_Pointer_Left = 0xFEE0 -let xk_Pointer_Right = 0xFEE1 -let xk_Pointer_Up = 0xFEE2 -let xk_Pointer_Down = 0xFEE3 -let xk_Pointer_UpLeft = 0xFEE4 -let xk_Pointer_UpRight = 0xFEE5 -let xk_Pointer_DownLeft = 0xFEE6 -let xk_Pointer_DownRight = 0xFEE7 -let xk_Pointer_Button_Dflt = 0xFEE8 -let xk_Pointer_Button1 = 0xFEE9 -let xk_Pointer_Button2 = 0xFEEA -let xk_Pointer_Button3 = 0xFEEB -let xk_Pointer_Button4 = 0xFEEC -let xk_Pointer_Button5 = 0xFEED -let xk_Pointer_DblClick_Dflt = 0xFEEE -let xk_Pointer_DblClick1 = 0xFEEF -let xk_Pointer_DblClick2 = 0xFEF0 -let xk_Pointer_DblClick3 = 0xFEF1 -let xk_Pointer_DblClick4 = 0xFEF2 -let xk_Pointer_DblClick5 = 0xFEF3 -let xk_Pointer_Drag_Dflt = 0xFEF4 -let xk_Pointer_Drag1 = 0xFEF5 -let xk_Pointer_Drag2 = 0xFEF6 -let xk_Pointer_Drag3 = 0xFEF7 -let xk_Pointer_Drag4 = 0xFEF8 -let xk_Pointer_Drag5 = 0xFEFD - -let xk_Pointer_EnableKeys = 0xFEF9 -let xk_Pointer_Accelerate = 0xFEFA -let xk_Pointer_DfltBtnNext = 0xFEFB -let xk_Pointer_DfltBtnPrev = 0xFEFC - - - -(* - * 3270 Terminal Keys - * Byte 3 = = 0xFD - *) - - -let xk_3270_Duplicate = 0xFD01 -let xk_3270_FieldMark = 0xFD02 -let xk_3270_Right2 = 0xFD03 -let xk_3270_Left2 = 0xFD04 -let xk_3270_BackTab = 0xFD05 -let xk_3270_EraseEOF = 0xFD06 -let xk_3270_EraseInput = 0xFD07 -let xk_3270_Reset = 0xFD08 -let xk_3270_Quit = 0xFD09 -let xk_3270_PA1 = 0xFD0A -let xk_3270_PA2 = 0xFD0B -let xk_3270_PA3 = 0xFD0C -let xk_3270_Test = 0xFD0D -let xk_3270_Attn = 0xFD0E -let xk_3270_CursorBlink = 0xFD0F -let xk_3270_AltCursor = 0xFD10 -let xk_3270_KeyClick = 0xFD11 -let xk_3270_Jump = 0xFD12 -let xk_3270_Ident = 0xFD13 -let xk_3270_Rule = 0xFD14 -let xk_3270_Copy = 0xFD15 -let xk_3270_Play = 0xFD16 -let xk_3270_Setup = 0xFD17 -let xk_3270_Record = 0xFD18 -let xk_3270_ChangeScreen = 0xFD19 -let xk_3270_DeleteWord = 0xFD1A -let xk_3270_ExSelect = 0xFD1B -let xk_3270_CursorSelect = 0xFD1C -let xk_3270_PrintScreen = 0xFD1D -let xk_3270_Enter = 0xFD1E - - -(* - * Latin 1 - * Byte 3 = 0 - *) - -let xk_space = 0x020 -let xk_exclam = 0x021 -let xk_quotedbl = 0x022 -let xk_numbersign = 0x023 -let xk_dollar = 0x024 -let xk_percent = 0x025 -let xk_ampersand = 0x026 -let xk_apostrophe = 0x027 -let xk_quoteright = 0x027 (** deprecated *) -let xk_parenleft = 0x028 -let xk_parenright = 0x029 -let xk_asterisk = 0x02a -let xk_plus = 0x02b -let xk_comma = 0x02c -let xk_minus = 0x02d -let xk_period = 0x02e -let xk_slash = 0x02f -let xk_0 = 0x030 -let xk_1 = 0x031 -let xk_2 = 0x032 -let xk_3 = 0x033 -let xk_4 = 0x034 -let xk_5 = 0x035 -let xk_6 = 0x036 -let xk_7 = 0x037 -let xk_8 = 0x038 -let xk_9 = 0x039 -let xk_colon = 0x03a -let xk_semicolon = 0x03b -let xk_less = 0x03c -let xk_equal = 0x03d -let xk_greater = 0x03e -let xk_question = 0x03f -let xk_at = 0x040 -let xk_A = 0x041 -let xk_B = 0x042 -let xk_C = 0x043 -let xk_D = 0x044 -let xk_E = 0x045 -let xk_F = 0x046 -let xk_G = 0x047 -let xk_H = 0x048 -let xk_I = 0x049 -let xk_J = 0x04a -let xk_K = 0x04b -let xk_L = 0x04c -let xk_M = 0x04d -let xk_N = 0x04e -let xk_O = 0x04f -let xk_P = 0x050 -let xk_Q = 0x051 -let xk_R = 0x052 -let xk_S = 0x053 -let xk_T = 0x054 -let xk_U = 0x055 -let xk_V = 0x056 -let xk_W = 0x057 -let xk_X = 0x058 -let xk_Y = 0x059 -let xk_Z = 0x05a -let xk_bracketleft = 0x05b -let xk_backslash = 0x05c -let xk_bracketright = 0x05d -let xk_asciicircum = 0x05e -let xk_underscore = 0x05f -let xk_grave = 0x060 -let xk_quoteleft = 0x060 (** deprecated *) -let xk_a = 0x061 -let xk_b = 0x062 -let xk_c = 0x063 -let xk_d = 0x064 -let xk_e = 0x065 -let xk_f = 0x066 -let xk_g = 0x067 -let xk_h = 0x068 -let xk_i = 0x069 -let xk_j = 0x06a -let xk_k = 0x06b -let xk_l = 0x06c -let xk_m = 0x06d -let xk_n = 0x06e -let xk_o = 0x06f -let xk_p = 0x070 -let xk_q = 0x071 -let xk_r = 0x072 -let xk_s = 0x073 -let xk_t = 0x074 -let xk_u = 0x075 -let xk_v = 0x076 -let xk_w = 0x077 -let xk_x = 0x078 -let xk_y = 0x079 -let xk_z = 0x07a -let xk_braceleft = 0x07b -let xk_bar = 0x07c -let xk_braceright = 0x07d -let xk_asciitilde = 0x07e - -let xk_nobreakspace = 0x0a0 -let xk_exclamdown = 0x0a1 -let xk_cent = 0x0a2 -let xk_sterling = 0x0a3 -let xk_currency = 0x0a4 -let xk_yen = 0x0a5 -let xk_brokenbar = 0x0a6 -let xk_section = 0x0a7 -let xk_diaeresis = 0x0a8 -let xk_copyright = 0x0a9 -let xk_ordfeminine = 0x0aa -let xk_guillemotleft = 0x0ab (** left angle quotation mark *) -let xk_notsign = 0x0ac -let xk_hyphen = 0x0ad -let xk_registered = 0x0ae -let xk_macron = 0x0af -let xk_degree = 0x0b0 -let xk_plusminus = 0x0b1 -let xk_twosuperior = 0x0b2 -let xk_threesuperior = 0x0b3 -let xk_acute = 0x0b4 -let xk_mu = 0x0b5 -let xk_paragraph = 0x0b6 -let xk_periodcentered = 0x0b7 -let xk_cedilla = 0x0b8 -let xk_onesuperior = 0x0b9 -let xk_masculine = 0x0ba -let xk_guillemotright = 0x0bb (** right angle quotation mark *) -let xk_onequarter = 0x0bc -let xk_onehalf = 0x0bd -let xk_threequarters = 0x0be -let xk_questiondown = 0x0bf -let xk_Agrave = 0x0c0 -let xk_Aacute = 0x0c1 -let xk_Acircumflex = 0x0c2 -let xk_Atilde = 0x0c3 -let xk_Adiaeresis = 0x0c4 -let xk_Aring = 0x0c5 -let xk_AE = 0x0c6 -let xk_Ccedilla = 0x0c7 -let xk_Egrave = 0x0c8 -let xk_Eacute = 0x0c9 -let xk_Ecircumflex = 0x0ca -let xk_Ediaeresis = 0x0cb -let xk_Igrave = 0x0cc -let xk_Iacute = 0x0cd -let xk_Icircumflex = 0x0ce -let xk_Idiaeresis = 0x0cf -let xk_ETH = 0x0d0 -let xk_Eth = 0x0d0 (** deprecated *) -let xk_Ntilde = 0x0d1 -let xk_Ograve = 0x0d2 -let xk_Oacute = 0x0d3 -let xk_Ocircumflex = 0x0d4 -let xk_Otilde = 0x0d5 -let xk_Odiaeresis = 0x0d6 -let xk_multiply = 0x0d7 -let xk_Ooblique = 0x0d8 -let xk_Ugrave = 0x0d9 -let xk_Uacute = 0x0da -let xk_Ucircumflex = 0x0db -let xk_Udiaeresis = 0x0dc -let xk_Yacute = 0x0dd -let xk_THORN = 0x0de -let xk_Thorn = 0x0de (** deprecated *) -let xk_ssharp = 0x0df -let xk_agrave = 0x0e0 -let xk_aacute = 0x0e1 -let xk_acircumflex = 0x0e2 -let xk_atilde = 0x0e3 -let xk_adiaeresis = 0x0e4 -let xk_aring = 0x0e5 -let xk_ae = 0x0e6 -let xk_ccedilla = 0x0e7 -let xk_egrave = 0x0e8 -let xk_eacute = 0x0e9 -let xk_ecircumflex = 0x0ea -let xk_ediaeresis = 0x0eb -let xk_igrave = 0x0ec -let xk_iacute = 0x0ed -let xk_icircumflex = 0x0ee -let xk_idiaeresis = 0x0ef -let xk_eth = 0x0f0 -let xk_ntilde = 0x0f1 -let xk_ograve = 0x0f2 -let xk_oacute = 0x0f3 -let xk_ocircumflex = 0x0f4 -let xk_otilde = 0x0f5 -let xk_odiaeresis = 0x0f6 -let xk_division = 0x0f7 -let xk_oslash = 0x0f8 -let xk_ugrave = 0x0f9 -let xk_uacute = 0x0fa -let xk_ucircumflex = 0x0fb -let xk_udiaeresis = 0x0fc -let xk_yacute = 0x0fd -let xk_thorn = 0x0fe -let xk_ydiaeresis = 0x0ff - - -(* - * Latin 2 - * Byte 3 = 1 - *) - - -let xk_Aogonek = 0x1a1 -let xk_breve = 0x1a2 -let xk_Lstroke = 0x1a3 -let xk_Lcaron = 0x1a5 -let xk_Sacute = 0x1a6 -let xk_Scaron = 0x1a9 -let xk_Scedilla = 0x1aa -let xk_Tcaron = 0x1ab -let xk_Zacute = 0x1ac -let xk_Zcaron = 0x1ae -let xk_Zabovedot = 0x1af -let xk_aogonek = 0x1b1 -let xk_ogonek = 0x1b2 -let xk_lstroke = 0x1b3 -let xk_lcaron = 0x1b5 -let xk_sacute = 0x1b6 -let xk_caron = 0x1b7 -let xk_scaron = 0x1b9 -let xk_scedilla = 0x1ba -let xk_tcaron = 0x1bb -let xk_zacute = 0x1bc -let xk_doubleacute = 0x1bd -let xk_zcaron = 0x1be -let xk_zabovedot = 0x1bf -let xk_Racute = 0x1c0 -let xk_Abreve = 0x1c3 -let xk_Lacute = 0x1c5 -let xk_Cacute = 0x1c6 -let xk_Ccaron = 0x1c8 -let xk_Eogonek = 0x1ca -let xk_Ecaron = 0x1cc -let xk_Dcaron = 0x1cf -let xk_Dstroke = 0x1d0 -let xk_Nacute = 0x1d1 -let xk_Ncaron = 0x1d2 -let xk_Odoubleacute = 0x1d5 -let xk_Rcaron = 0x1d8 -let xk_Uring = 0x1d9 -let xk_Udoubleacute = 0x1db -let xk_Tcedilla = 0x1de -let xk_racute = 0x1e0 -let xk_abreve = 0x1e3 -let xk_lacute = 0x1e5 -let xk_cacute = 0x1e6 -let xk_ccaron = 0x1e8 -let xk_eogonek = 0x1ea -let xk_ecaron = 0x1ec -let xk_dcaron = 0x1ef -let xk_dstroke = 0x1f0 -let xk_nacute = 0x1f1 -let xk_ncaron = 0x1f2 -let xk_odoubleacute = 0x1f5 -let xk_udoubleacute = 0x1fb -let xk_rcaron = 0x1f8 -let xk_uring = 0x1f9 -let xk_tcedilla = 0x1fe -let xk_abovedot = 0x1ff - - -(* - * Latin 3 - * Byte 3 = 2 - *) - - -let xk_Hstroke = 0x2a1 -let xk_Hcircumflex = 0x2a6 -let xk_Iabovedot = 0x2a9 -let xk_Gbreve = 0x2ab -let xk_Jcircumflex = 0x2ac -let xk_hstroke = 0x2b1 -let xk_hcircumflex = 0x2b6 -let xk_idotless = 0x2b9 -let xk_gbreve = 0x2bb -let xk_jcircumflex = 0x2bc -let xk_Cabovedot = 0x2c5 -let xk_Ccircumflex = 0x2c6 -let xk_Gabovedot = 0x2d5 -let xk_Gcircumflex = 0x2d8 -let xk_Ubreve = 0x2dd -let xk_Scircumflex = 0x2de -let xk_cabovedot = 0x2e5 -let xk_ccircumflex = 0x2e6 -let xk_gabovedot = 0x2f5 -let xk_gcircumflex = 0x2f8 -let xk_ubreve = 0x2fd -let xk_scircumflex = 0x2fe - - - -(* - * Latin 4 - * Byte 3 = 3 - *) - - -let xk_kra = 0x3a2 -let xk_kappa = 0x3a2 (** deprecated *) -let xk_Rcedilla = 0x3a3 -let xk_Itilde = 0x3a5 -let xk_Lcedilla = 0x3a6 -let xk_Emacron = 0x3aa -let xk_Gcedilla = 0x3ab -let xk_Tslash = 0x3ac -let xk_rcedilla = 0x3b3 -let xk_itilde = 0x3b5 -let xk_lcedilla = 0x3b6 -let xk_emacron = 0x3ba -let xk_gcedilla = 0x3bb -let xk_tslash = 0x3bc -let xk_ENG = 0x3bd -let xk_eng = 0x3bf -let xk_Amacron = 0x3c0 -let xk_Iogonek = 0x3c7 -let xk_Eabovedot = 0x3cc -let xk_Imacron = 0x3cf -let xk_Ncedilla = 0x3d1 -let xk_Omacron = 0x3d2 -let xk_Kcedilla = 0x3d3 -let xk_Uogonek = 0x3d9 -let xk_Utilde = 0x3dd -let xk_Umacron = 0x3de -let xk_amacron = 0x3e0 -let xk_iogonek = 0x3e7 -let xk_eabovedot = 0x3ec -let xk_imacron = 0x3ef -let xk_ncedilla = 0x3f1 -let xk_omacron = 0x3f2 -let xk_kcedilla = 0x3f3 -let xk_uogonek = 0x3f9 -let xk_utilde = 0x3fd -let xk_umacron = 0x3fe - - -(* - * Katakana - * Byte 3 = 4 - *) - - -let xk_overline = 0x47e -let xk_kana_fullstop = 0x4a1 -let xk_kana_openingbracket = 0x4a2 -let xk_kana_closingbracket = 0x4a3 -let xk_kana_comma = 0x4a4 -let xk_kana_conjunctive = 0x4a5 -let xk_kana_middledot = 0x4a5 (** deprecated *) -let xk_kana_WO = 0x4a6 -let xk_kana_a = 0x4a7 -let xk_kana_i = 0x4a8 -let xk_kana_u = 0x4a9 -let xk_kana_e = 0x4aa -let xk_kana_o = 0x4ab -let xk_kana_ya = 0x4ac -let xk_kana_yu = 0x4ad -let xk_kana_yo = 0x4ae -let xk_kana_tsu = 0x4af -let xk_kana_tu = 0x4af (** deprecated *) -let xk_prolongedsound = 0x4b0 -let xk_kana_A = 0x4b1 -let xk_kana_I = 0x4b2 -let xk_kana_U = 0x4b3 -let xk_kana_E = 0x4b4 -let xk_kana_O = 0x4b5 -let xk_kana_KA = 0x4b6 -let xk_kana_KI = 0x4b7 -let xk_kana_KU = 0x4b8 -let xk_kana_KE = 0x4b9 -let xk_kana_KO = 0x4ba -let xk_kana_SA = 0x4bb -let xk_kana_SHI = 0x4bc -let xk_kana_SU = 0x4bd -let xk_kana_SE = 0x4be -let xk_kana_SO = 0x4bf -let xk_kana_TA = 0x4c0 -let xk_kana_CHI = 0x4c1 -let xk_kana_TI = 0x4c1 (** deprecated *) -let xk_kana_TSU = 0x4c2 -let xk_kana_TU = 0x4c2 (** deprecated *) -let xk_kana_TE = 0x4c3 -let xk_kana_TO = 0x4c4 -let xk_kana_NA = 0x4c5 -let xk_kana_NI = 0x4c6 -let xk_kana_NU = 0x4c7 -let xk_kana_NE = 0x4c8 -let xk_kana_NO = 0x4c9 -let xk_kana_HA = 0x4ca -let xk_kana_HI = 0x4cb -let xk_kana_FU = 0x4cc -let xk_kana_HU = 0x4cc (** deprecated *) -let xk_kana_HE = 0x4cd -let xk_kana_HO = 0x4ce -let xk_kana_MA = 0x4cf -let xk_kana_MI = 0x4d0 -let xk_kana_MU = 0x4d1 -let xk_kana_ME = 0x4d2 -let xk_kana_MO = 0x4d3 -let xk_kana_YA = 0x4d4 -let xk_kana_YU = 0x4d5 -let xk_kana_YO = 0x4d6 -let xk_kana_RA = 0x4d7 -let xk_kana_RI = 0x4d8 -let xk_kana_RU = 0x4d9 -let xk_kana_RE = 0x4da -let xk_kana_RO = 0x4db -let xk_kana_WA = 0x4dc -let xk_kana_N = 0x4dd -let xk_voicedsound = 0x4de -let xk_semivoicedsound = 0x4df -let xk_kana_switch = 0xFF7E (** Alias for mode_switch *) - - -(* - * Arabic - * Byte 3 = 5 - *) - - -let xk_Arabic_comma = 0x5ac -let xk_Arabic_semicolon = 0x5bb -let xk_Arabic_question_mark = 0x5bf -let xk_Arabic_hamza = 0x5c1 -let xk_Arabic_maddaonalef = 0x5c2 -let xk_Arabic_hamzaonalef = 0x5c3 -let xk_Arabic_hamzaonwaw = 0x5c4 -let xk_Arabic_hamzaunderalef = 0x5c5 -let xk_Arabic_hamzaonyeh = 0x5c6 -let xk_Arabic_alef = 0x5c7 -let xk_Arabic_beh = 0x5c8 -let xk_Arabic_tehmarbuta = 0x5c9 -let xk_Arabic_teh = 0x5ca -let xk_Arabic_theh = 0x5cb -let xk_Arabic_jeem = 0x5cc -let xk_Arabic_hah = 0x5cd -let xk_Arabic_khah = 0x5ce -let xk_Arabic_dal = 0x5cf -let xk_Arabic_thal = 0x5d0 -let xk_Arabic_ra = 0x5d1 -let xk_Arabic_zain = 0x5d2 -let xk_Arabic_seen = 0x5d3 -let xk_Arabic_sheen = 0x5d4 -let xk_Arabic_sad = 0x5d5 -let xk_Arabic_dad = 0x5d6 -let xk_Arabic_tah = 0x5d7 -let xk_Arabic_zah = 0x5d8 -let xk_Arabic_ain = 0x5d9 -let xk_Arabic_ghain = 0x5da -let xk_Arabic_tatweel = 0x5e0 -let xk_Arabic_feh = 0x5e1 -let xk_Arabic_qaf = 0x5e2 -let xk_Arabic_kaf = 0x5e3 -let xk_Arabic_lam = 0x5e4 -let xk_Arabic_meem = 0x5e5 -let xk_Arabic_noon = 0x5e6 -let xk_Arabic_ha = 0x5e7 -let xk_Arabic_heh = 0x5e7 (** deprecated *) -let xk_Arabic_waw = 0x5e8 -let xk_Arabic_alefmaksura = 0x5e9 -let xk_Arabic_yeh = 0x5ea -let xk_Arabic_fathatan = 0x5eb -let xk_Arabic_dammatan = 0x5ec -let xk_Arabic_kasratan = 0x5ed -let xk_Arabic_fatha = 0x5ee -let xk_Arabic_damma = 0x5ef -let xk_Arabic_kasra = 0x5f0 -let xk_Arabic_shadda = 0x5f1 -let xk_Arabic_sukun = 0x5f2 -let xk_Arabic_switch = 0xFF7E (** Alias for mode_switch *) - - -(* - * Cyrillic - * Byte 3 = 6 - *) - -let xk_Serbian_dje = 0x6a1 -let xk_Macedonia_gje = 0x6a2 -let xk_Cyrillic_io = 0x6a3 -let xk_Ukrainian_ie = 0x6a4 -let xk_Ukranian_je = 0x6a4 (** deprecated *) -let xk_Macedonia_dse = 0x6a5 -let xk_Ukrainian_i = 0x6a6 -let xk_Ukranian_i = 0x6a6 (** deprecated *) -let xk_Ukrainian_yi = 0x6a7 -let xk_Ukranian_yi = 0x6a7 (** deprecated *) -let xk_Cyrillic_je = 0x6a8 -let xk_Serbian_je = 0x6a8 (** deprecated *) -let xk_Cyrillic_lje = 0x6a9 -let xk_Serbian_lje = 0x6a9 (** deprecated *) -let xk_Cyrillic_nje = 0x6aa -let xk_Serbian_nje = 0x6aa (** deprecated *) -let xk_Serbian_tshe = 0x6ab -let xk_Macedonia_kje = 0x6ac -let xk_Byelorussian_shortu = 0x6ae -let xk_Cyrillic_dzhe = 0x6af -let xk_Serbian_dze = 0x6af (** deprecated *) -let xk_numerosign = 0x6b0 -let xk_Serbian_DJE = 0x6b1 -let xk_Macedonia_GJE = 0x6b2 -let xk_Cyrillic_IO = 0x6b3 -let xk_Ukrainian_IE = 0x6b4 -let xk_Ukranian_JE = 0x6b4 (** deprecated *) -let xk_Macedonia_DSE = 0x6b5 -let xk_Ukrainian_I = 0x6b6 -let xk_Ukranian_I = 0x6b6 (** deprecated *) -let xk_Ukrainian_YI = 0x6b7 -let xk_Ukranian_YI = 0x6b7 (** deprecated *) -let xk_Cyrillic_JE = 0x6b8 -let xk_Serbian_JE = 0x6b8 (** deprecated *) -let xk_Cyrillic_LJE = 0x6b9 -let xk_Serbian_LJE = 0x6b9 (** deprecated *) -let xk_Cyrillic_NJE = 0x6ba -let xk_Serbian_NJE = 0x6ba (** deprecated *) -let xk_Serbian_TSHE = 0x6bb -let xk_Macedonia_KJE = 0x6bc -let xk_Byelorussian_SHORTU = 0x6be -let xk_Cyrillic_DZHE = 0x6bf -let xk_Serbian_DZE = 0x6bf (** deprecated *) -let xk_Cyrillic_yu = 0x6c0 -let xk_Cyrillic_a = 0x6c1 -let xk_Cyrillic_be = 0x6c2 -let xk_Cyrillic_tse = 0x6c3 -let xk_Cyrillic_de = 0x6c4 -let xk_Cyrillic_ie = 0x6c5 -let xk_Cyrillic_ef = 0x6c6 -let xk_Cyrillic_ghe = 0x6c7 -let xk_Cyrillic_ha = 0x6c8 -let xk_Cyrillic_i = 0x6c9 -let xk_Cyrillic_shorti = 0x6ca -let xk_Cyrillic_ka = 0x6cb -let xk_Cyrillic_el = 0x6cc -let xk_Cyrillic_em = 0x6cd -let xk_Cyrillic_en = 0x6ce -let xk_Cyrillic_o = 0x6cf -let xk_Cyrillic_pe = 0x6d0 -let xk_Cyrillic_ya = 0x6d1 -let xk_Cyrillic_er = 0x6d2 -let xk_Cyrillic_es = 0x6d3 -let xk_Cyrillic_te = 0x6d4 -let xk_Cyrillic_u = 0x6d5 -let xk_Cyrillic_zhe = 0x6d6 -let xk_Cyrillic_ve = 0x6d7 -let xk_Cyrillic_softsign = 0x6d8 -let xk_Cyrillic_yeru = 0x6d9 -let xk_Cyrillic_ze = 0x6da -let xk_Cyrillic_sha = 0x6db -let xk_Cyrillic_e = 0x6dc -let xk_Cyrillic_shcha = 0x6dd -let xk_Cyrillic_che = 0x6de -let xk_Cyrillic_hardsign = 0x6df -let xk_Cyrillic_YU = 0x6e0 -let xk_Cyrillic_A = 0x6e1 -let xk_Cyrillic_BE = 0x6e2 -let xk_Cyrillic_TSE = 0x6e3 -let xk_Cyrillic_DE = 0x6e4 -let xk_Cyrillic_IE = 0x6e5 -let xk_Cyrillic_EF = 0x6e6 -let xk_Cyrillic_GHE = 0x6e7 -let xk_Cyrillic_HA = 0x6e8 -let xk_Cyrillic_I = 0x6e9 -let xk_Cyrillic_SHORTI = 0x6ea -let xk_Cyrillic_KA = 0x6eb -let xk_Cyrillic_EL = 0x6ec -let xk_Cyrillic_EM = 0x6ed -let xk_Cyrillic_EN = 0x6ee -let xk_Cyrillic_O = 0x6ef -let xk_Cyrillic_PE = 0x6f0 -let xk_Cyrillic_YA = 0x6f1 -let xk_Cyrillic_ER = 0x6f2 -let xk_Cyrillic_ES = 0x6f3 -let xk_Cyrillic_TE = 0x6f4 -let xk_Cyrillic_U = 0x6f5 -let xk_Cyrillic_ZHE = 0x6f6 -let xk_Cyrillic_VE = 0x6f7 -let xk_Cyrillic_SOFTSIGN = 0x6f8 -let xk_Cyrillic_YERU = 0x6f9 -let xk_Cyrillic_ZE = 0x6fa -let xk_Cyrillic_SHA = 0x6fb -let xk_Cyrillic_E = 0x6fc -let xk_Cyrillic_SHCHA = 0x6fd -let xk_Cyrillic_CHE = 0x6fe -let xk_Cyrillic_HARDSIGN = 0x6ff - - -(* - * Greek - * Byte 3 = 7 - *) - - -let xk_Greek_ALPHAaccent = 0x7a1 -let xk_Greek_EPSILONaccent = 0x7a2 -let xk_Greek_ETAaccent = 0x7a3 -let xk_Greek_IOTAaccent = 0x7a4 -let xk_Greek_IOTAdiaeresis = 0x7a5 -let xk_Greek_OMICRONaccent = 0x7a7 -let xk_Greek_UPSILONaccent = 0x7a8 -let xk_Greek_UPSILONdieresis = 0x7a9 -let xk_Greek_OMEGAaccent = 0x7ab -let xk_Greek_accentdieresis = 0x7ae -let xk_Greek_horizbar = 0x7af -let xk_Greek_alphaaccent = 0x7b1 -let xk_Greek_epsilonaccent = 0x7b2 -let xk_Greek_etaaccent = 0x7b3 -let xk_Greek_iotaaccent = 0x7b4 -let xk_Greek_iotadieresis = 0x7b5 -let xk_Greek_iotaaccentdieresis = 0x7b6 -let xk_Greek_omicronaccent = 0x7b7 -let xk_Greek_upsilonaccent = 0x7b8 -let xk_Greek_upsilondieresis = 0x7b9 -let xk_Greek_upsilonaccentdieresis = 0x7ba -let xk_Greek_omegaaccent = 0x7bb -let xk_Greek_ALPHA = 0x7c1 -let xk_Greek_BETA = 0x7c2 -let xk_Greek_GAMMA = 0x7c3 -let xk_Greek_DELTA = 0x7c4 -let xk_Greek_EPSILON = 0x7c5 -let xk_Greek_ZETA = 0x7c6 -let xk_Greek_ETA = 0x7c7 -let xk_Greek_THETA = 0x7c8 -let xk_Greek_IOTA = 0x7c9 -let xk_Greek_KAPPA = 0x7ca -let xk_Greek_LAMDA = 0x7cb -let xk_Greek_LAMBDA = 0x7cb -let xk_Greek_MU = 0x7cc -let xk_Greek_NU = 0x7cd -let xk_Greek_XI = 0x7ce -let xk_Greek_OMICRON = 0x7cf -let xk_Greek_PI = 0x7d0 -let xk_Greek_RHO = 0x7d1 -let xk_Greek_SIGMA = 0x7d2 -let xk_Greek_TAU = 0x7d4 -let xk_Greek_UPSILON = 0x7d5 -let xk_Greek_PHI = 0x7d6 -let xk_Greek_CHI = 0x7d7 -let xk_Greek_PSI = 0x7d8 -let xk_Greek_OMEGA = 0x7d9 -let xk_Greek_alpha = 0x7e1 -let xk_Greek_beta = 0x7e2 -let xk_Greek_gamma = 0x7e3 -let xk_Greek_delta = 0x7e4 -let xk_Greek_epsilon = 0x7e5 -let xk_Greek_zeta = 0x7e6 -let xk_Greek_eta = 0x7e7 -let xk_Greek_theta = 0x7e8 -let xk_Greek_iota = 0x7e9 -let xk_Greek_kappa = 0x7ea -let xk_Greek_lamda = 0x7eb -let xk_Greek_lambda = 0x7eb -let xk_Greek_mu = 0x7ec -let xk_Greek_nu = 0x7ed -let xk_Greek_xi = 0x7ee -let xk_Greek_omicron = 0x7ef -let xk_Greek_pi = 0x7f0 -let xk_Greek_rho = 0x7f1 -let xk_Greek_sigma = 0x7f2 -let xk_Greek_finalsmallsigma = 0x7f3 -let xk_Greek_tau = 0x7f4 -let xk_Greek_upsilon = 0x7f5 -let xk_Greek_phi = 0x7f6 -let xk_Greek_chi = 0x7f7 -let xk_Greek_psi = 0x7f8 -let xk_Greek_omega = 0x7f9 -let xk_Greek_switch = 0xFF7E (** Alias for mode_switch *) - - -(* - * Technical - * Byte 3 = 8 - *) - - -let xk_leftradical = 0x8a1 -let xk_topleftradical = 0x8a2 -let xk_horizconnector = 0x8a3 -let xk_topintegral = 0x8a4 -let xk_botintegral = 0x8a5 -let xk_vertconnector = 0x8a6 -let xk_topleftsqbracket = 0x8a7 -let xk_botleftsqbracket = 0x8a8 -let xk_toprightsqbracket = 0x8a9 -let xk_botrightsqbracket = 0x8aa -let xk_topleftparens = 0x8ab -let xk_botleftparens = 0x8ac -let xk_toprightparens = 0x8ad -let xk_botrightparens = 0x8ae -let xk_leftmiddlecurlybrace = 0x8af -let xk_rightmiddlecurlybrace = 0x8b0 -let xk_topleftsummation = 0x8b1 -let xk_botleftsummation = 0x8b2 -let xk_topvertsummationconnector = 0x8b3 -let xk_botvertsummationconnector = 0x8b4 -let xk_toprightsummation = 0x8b5 -let xk_botrightsummation = 0x8b6 -let xk_rightmiddlesummation = 0x8b7 -let xk_lessthanequal = 0x8bc -let xk_notequal = 0x8bd -let xk_greaterthanequal = 0x8be -let xk_integral = 0x8bf -let xk_therefore = 0x8c0 -let xk_variation = 0x8c1 -let xk_infinity = 0x8c2 -let xk_nabla = 0x8c5 -let xk_approximate = 0x8c8 -let xk_similarequal = 0x8c9 -let xk_ifonlyif = 0x8cd -let xk_implies = 0x8ce -let xk_identical = 0x8cf -let xk_radical = 0x8d6 -let xk_includedin = 0x8da -let xk_includes = 0x8db -let xk_intersection = 0x8dc -let xk_union = 0x8dd -let xk_logicaland = 0x8de -let xk_logicalor = 0x8df -let xk_partialderivative = 0x8ef -let xk_function = 0x8f6 -let xk_leftarrow = 0x8fb -let xk_uparrow = 0x8fc -let xk_rightarrow = 0x8fd -let xk_downarrow = 0x8fe - - -(* - * Special - * Byte 3 = 9 - *) - - -let xk_blank = 0x9df -let xk_soliddiamond = 0x9e0 -let xk_checkerboard = 0x9e1 -let xk_ht = 0x9e2 -let xk_ff = 0x9e3 -let xk_cr = 0x9e4 -let xk_lf = 0x9e5 -let xk_nl = 0x9e8 -let xk_vt = 0x9e9 -let xk_lowrightcorner = 0x9ea -let xk_uprightcorner = 0x9eb -let xk_upleftcorner = 0x9ec -let xk_lowleftcorner = 0x9ed -let xk_crossinglines = 0x9ee -let xk_horizlinescan1 = 0x9ef -let xk_horizlinescan3 = 0x9f0 -let xk_horizlinescan5 = 0x9f1 -let xk_horizlinescan7 = 0x9f2 -let xk_horizlinescan9 = 0x9f3 -let xk_leftt = 0x9f4 -let xk_rightt = 0x9f5 -let xk_bott = 0x9f6 -let xk_topt = 0x9f7 -let xk_vertbar = 0x9f8 - - -(* - * Publishing - * Byte 3 = a - *) - - -let xk_emspace = 0xaa1 -let xk_enspace = 0xaa2 -let xk_em3space = 0xaa3 -let xk_em4space = 0xaa4 -let xk_digitspace = 0xaa5 -let xk_punctspace = 0xaa6 -let xk_thinspace = 0xaa7 -let xk_hairspace = 0xaa8 -let xk_emdash = 0xaa9 -let xk_endash = 0xaaa -let xk_signifblank = 0xaac -let xk_ellipsis = 0xaae -let xk_doubbaselinedot = 0xaaf -let xk_onethird = 0xab0 -let xk_twothirds = 0xab1 -let xk_onefifth = 0xab2 -let xk_twofifths = 0xab3 -let xk_threefifths = 0xab4 -let xk_fourfifths = 0xab5 -let xk_onesixth = 0xab6 -let xk_fivesixths = 0xab7 -let xk_careof = 0xab8 -let xk_figdash = 0xabb -let xk_leftanglebracket = 0xabc -let xk_decimalpoint = 0xabd -let xk_rightanglebracket = 0xabe -let xk_marker = 0xabf -let xk_oneeighth = 0xac3 -let xk_threeeighths = 0xac4 -let xk_fiveeighths = 0xac5 -let xk_seveneighths = 0xac6 -let xk_trademark = 0xac9 -let xk_signaturemark = 0xaca -let xk_trademarkincircle = 0xacb -let xk_leftopentriangle = 0xacc -let xk_rightopentriangle = 0xacd -let xk_emopencircle = 0xace -let xk_emopenrectangle = 0xacf -let xk_leftsinglequotemark = 0xad0 -let xk_rightsinglequotemark = 0xad1 -let xk_leftdoublequotemark = 0xad2 -let xk_rightdoublequotemark = 0xad3 -let xk_prescription = 0xad4 -let xk_minutes = 0xad6 -let xk_seconds = 0xad7 -let xk_latincross = 0xad9 -let xk_hexagram = 0xada -let xk_filledrectbullet = 0xadb -let xk_filledlefttribullet = 0xadc -let xk_filledrighttribullet = 0xadd -let xk_emfilledcircle = 0xade -let xk_emfilledrect = 0xadf -let xk_enopencircbullet = 0xae0 -let xk_enopensquarebullet = 0xae1 -let xk_openrectbullet = 0xae2 -let xk_opentribulletup = 0xae3 -let xk_opentribulletdown = 0xae4 -let xk_openstar = 0xae5 -let xk_enfilledcircbullet = 0xae6 -let xk_enfilledsqbullet = 0xae7 -let xk_filledtribulletup = 0xae8 -let xk_filledtribulletdown = 0xae9 -let xk_leftpointer = 0xaea -let xk_rightpointer = 0xaeb -let xk_club = 0xaec -let xk_diamond = 0xaed -let xk_heart = 0xaee -let xk_maltesecross = 0xaf0 -let xk_dagger = 0xaf1 -let xk_doubledagger = 0xaf2 -let xk_checkmark = 0xaf3 -let xk_ballotcross = 0xaf4 -let xk_musicalsharp = 0xaf5 -let xk_musicalflat = 0xaf6 -let xk_malesymbol = 0xaf7 -let xk_femalesymbol = 0xaf8 -let xk_telephone = 0xaf9 -let xk_telephonerecorder = 0xafa -let xk_phonographcopyright = 0xafb -let xk_caret = 0xafc -let xk_singlelowquotemark = 0xafd -let xk_doublelowquotemark = 0xafe -let xk_cursor = 0xaff - - -(* - * APL - * Byte 3 = b - *) - - -let xk_leftcaret = 0xba3 -let xk_rightcaret = 0xba6 -let xk_downcaret = 0xba8 -let xk_upcaret = 0xba9 -let xk_overbar = 0xbc0 -let xk_downtack = 0xbc2 -let xk_upshoe = 0xbc3 -let xk_downstile = 0xbc4 -let xk_underbar = 0xbc6 -let xk_jot = 0xbca -let xk_quad = 0xbcc -let xk_uptack = 0xbce -let xk_circle = 0xbcf -let xk_upstile = 0xbd3 -let xk_downshoe = 0xbd6 -let xk_rightshoe = 0xbd8 -let xk_leftshoe = 0xbda -let xk_lefttack = 0xbdc -let xk_righttack = 0xbfc - - -(* - * Hebrew - * Byte 3 = c - *) - - -let xk_hebrew_doublelowline = 0xcdf -let xk_hebrew_aleph = 0xce0 -let xk_hebrew_bet = 0xce1 -let xk_hebrew_beth = 0xce1 (** deprecated *) -let xk_hebrew_gimel = 0xce2 -let xk_hebrew_gimmel = 0xce2 (** deprecated *) -let xk_hebrew_dalet = 0xce3 -let xk_hebrew_daleth = 0xce3 (** deprecated *) -let xk_hebrew_he = 0xce4 -let xk_hebrew_waw = 0xce5 -let xk_hebrew_zain = 0xce6 -let xk_hebrew_zayin = 0xce6 (** deprecated *) -let xk_hebrew_chet = 0xce7 -let xk_hebrew_het = 0xce7 (** deprecated *) -let xk_hebrew_tet = 0xce8 -let xk_hebrew_teth = 0xce8 (** deprecated *) -let xk_hebrew_yod = 0xce9 -let xk_hebrew_finalkaph = 0xcea -let xk_hebrew_kaph = 0xceb -let xk_hebrew_lamed = 0xcec -let xk_hebrew_finalmem = 0xced -let xk_hebrew_mem = 0xcee -let xk_hebrew_finalnun = 0xcef -let xk_hebrew_nun = 0xcf0 -let xk_hebrew_samech = 0xcf1 -let xk_hebrew_samekh = 0xcf1 (** deprecated *) -let xk_hebrew_ayin = 0xcf2 -let xk_hebrew_finalpe = 0xcf3 -let xk_hebrew_pe = 0xcf4 -let xk_hebrew_finalzade = 0xcf5 -let xk_hebrew_finalzadi = 0xcf5 (** deprecated *) -let xk_hebrew_zade = 0xcf6 -let xk_hebrew_zadi = 0xcf6 (** deprecated *) -let xk_hebrew_qoph = 0xcf7 -let xk_hebrew_kuf = 0xcf7 (** deprecated *) -let xk_hebrew_resh = 0xcf8 -let xk_hebrew_shin = 0xcf9 -let xk_hebrew_taw = 0xcfa -let xk_hebrew_taf = 0xcfa (** deprecated *) -let xk_Hebrew_switch = 0xFF7E (** Alias for mode_switch *) - - -(* - * Thai - * Byte 3 = d - *) - - -let xk_Thai_kokai = 0xda1 -let xk_Thai_khokhai = 0xda2 -let xk_Thai_khokhuat = 0xda3 -let xk_Thai_khokhwai = 0xda4 -let xk_Thai_khokhon = 0xda5 -let xk_Thai_khorakhang = 0xda6 -let xk_Thai_ngongu = 0xda7 -let xk_Thai_chochan = 0xda8 -let xk_Thai_choching = 0xda9 -let xk_Thai_chochang = 0xdaa -let xk_Thai_soso = 0xdab -let xk_Thai_chochoe = 0xdac -let xk_Thai_yoying = 0xdad -let xk_Thai_dochada = 0xdae -let xk_Thai_topatak = 0xdaf -let xk_Thai_thothan = 0xdb0 -let xk_Thai_thonangmontho = 0xdb1 -let xk_Thai_thophuthao = 0xdb2 -let xk_Thai_nonen = 0xdb3 -let xk_Thai_dodek = 0xdb4 -let xk_Thai_totao = 0xdb5 -let xk_Thai_thothung = 0xdb6 -let xk_Thai_thothahan = 0xdb7 -let xk_Thai_thothong = 0xdb8 -let xk_Thai_nonu = 0xdb9 -let xk_Thai_bobaimai = 0xdba -let xk_Thai_popla = 0xdbb -let xk_Thai_phophung = 0xdbc -let xk_Thai_fofa = 0xdbd -let xk_Thai_phophan = 0xdbe -let xk_Thai_fofan = 0xdbf -let xk_Thai_phosamphao = 0xdc0 -let xk_Thai_moma = 0xdc1 -let xk_Thai_yoyak = 0xdc2 -let xk_Thai_rorua = 0xdc3 -let xk_Thai_ru = 0xdc4 -let xk_Thai_loling = 0xdc5 -let xk_Thai_lu = 0xdc6 -let xk_Thai_wowaen = 0xdc7 -let xk_Thai_sosala = 0xdc8 -let xk_Thai_sorusi = 0xdc9 -let xk_Thai_sosua = 0xdca -let xk_Thai_hohip = 0xdcb -let xk_Thai_lochula = 0xdcc -let xk_Thai_oang = 0xdcd -let xk_Thai_honokhuk = 0xdce -let xk_Thai_paiyannoi = 0xdcf -let xk_Thai_saraa = 0xdd0 -let xk_Thai_maihanakat = 0xdd1 -let xk_Thai_saraaa = 0xdd2 -let xk_Thai_saraam = 0xdd3 -let xk_Thai_sarai = 0xdd4 -let xk_Thai_saraii = 0xdd5 -let xk_Thai_saraue = 0xdd6 -let xk_Thai_sarauee = 0xdd7 -let xk_Thai_sarau = 0xdd8 -let xk_Thai_sarauu = 0xdd9 -let xk_Thai_phinthu = 0xdda -let xk_Thai_maihanakat_maitho = 0xdde -let xk_Thai_baht = 0xddf -let xk_Thai_sarae = 0xde0 -let xk_Thai_saraae = 0xde1 -let xk_Thai_sarao = 0xde2 -let xk_Thai_saraaimaimuan = 0xde3 -let xk_Thai_saraaimaimalai = 0xde4 -let xk_Thai_lakkhangyao = 0xde5 -let xk_Thai_maiyamok = 0xde6 -let xk_Thai_maitaikhu = 0xde7 -let xk_Thai_maiek = 0xde8 -let xk_Thai_maitho = 0xde9 -let xk_Thai_maitri = 0xdea -let xk_Thai_maichattawa = 0xdeb -let xk_Thai_thanthakhat = 0xdec -let xk_Thai_nikhahit = 0xded -let xk_Thai_leksun = 0xdf0 -let xk_Thai_leknung = 0xdf1 -let xk_Thai_leksong = 0xdf2 -let xk_Thai_leksam = 0xdf3 -let xk_Thai_leksi = 0xdf4 -let xk_Thai_lekha = 0xdf5 -let xk_Thai_lekhok = 0xdf6 -let xk_Thai_lekchet = 0xdf7 -let xk_Thai_lekpaet = 0xdf8 -let xk_Thai_lekkao = 0xdf9 - - -(* - * Korean - * Byte 3 = e - *) - - - -let xk_Hangul = 0xff31 (** Hangul start/stop(toggle) *) -let xk_Hangul_Start = 0xff32 (** Hangul start *) -let xk_Hangul_End = 0xff33 (** Hangul end, English start *) -let xk_Hangul_Hanja = 0xff34 (** Start Hangul->Hanja Conversion *) -let xk_Hangul_Jamo = 0xff35 (** Hangul Jamo mode *) -let xk_Hangul_Romaja = 0xff36 (** Hangul Romaja mode *) -let xk_Hangul_Codeinput = 0xff37 (** Hangul code input mode *) -let xk_Hangul_Jeonja = 0xff38 (** Jeonja mode *) -let xk_Hangul_Banja = 0xff39 (** Banja mode *) -let xk_Hangul_PreHanja = 0xff3a (** Pre Hanja conversion *) -let xk_Hangul_PostHanja = 0xff3b (** Post Hanja conversion *) -let xk_Hangul_SingleCandidate = 0xff3c (** Single candidate *) -let xk_Hangul_MultipleCandidate = 0xff3d (** Multiple candidate *) -let xk_Hangul_PreviousCandidate = 0xff3e (** Previous candidate *) -let xk_Hangul_Special = 0xff3f (** Special symbols *) -let xk_Hangul_switch = 0xFF7E (** Alias for mode_switch *) - -(** Hangul Consonant Characters *) -let xk_Hangul_Kiyeog = 0xea1 -let xk_Hangul_SsangKiyeog = 0xea2 -let xk_Hangul_KiyeogSios = 0xea3 -let xk_Hangul_Nieun = 0xea4 -let xk_Hangul_NieunJieuj = 0xea5 -let xk_Hangul_NieunHieuh = 0xea6 -let xk_Hangul_Dikeud = 0xea7 -let xk_Hangul_SsangDikeud = 0xea8 -let xk_Hangul_Rieul = 0xea9 -let xk_Hangul_RieulKiyeog = 0xeaa -let xk_Hangul_RieulMieum = 0xeab -let xk_Hangul_RieulPieub = 0xeac -let xk_Hangul_RieulSios = 0xead -let xk_Hangul_RieulTieut = 0xeae -let xk_Hangul_RieulPhieuf = 0xeaf -let xk_Hangul_RieulHieuh = 0xeb0 -let xk_Hangul_Mieum = 0xeb1 -let xk_Hangul_Pieub = 0xeb2 -let xk_Hangul_SsangPieub = 0xeb3 -let xk_Hangul_PieubSios = 0xeb4 -let xk_Hangul_Sios = 0xeb5 -let xk_Hangul_SsangSios = 0xeb6 -let xk_Hangul_Ieung = 0xeb7 -let xk_Hangul_Jieuj = 0xeb8 -let xk_Hangul_SsangJieuj = 0xeb9 -let xk_Hangul_Cieuc = 0xeba -let xk_Hangul_Khieuq = 0xebb -let xk_Hangul_Tieut = 0xebc -let xk_Hangul_Phieuf = 0xebd -let xk_Hangul_Hieuh = 0xebe - -(** Hangul Vowel Characters *) -let xk_Hangul_A = 0xebf -let xk_Hangul_AE = 0xec0 -let xk_Hangul_YA = 0xec1 -let xk_Hangul_YAE = 0xec2 -let xk_Hangul_EO = 0xec3 -let xk_Hangul_E = 0xec4 -let xk_Hangul_YEO = 0xec5 -let xk_Hangul_YE = 0xec6 -let xk_Hangul_O = 0xec7 -let xk_Hangul_WA = 0xec8 -let xk_Hangul_WAE = 0xec9 -let xk_Hangul_OE = 0xeca -let xk_Hangul_YO = 0xecb -let xk_Hangul_U = 0xecc -let xk_Hangul_WEO = 0xecd -let xk_Hangul_WE = 0xece -let xk_Hangul_WI = 0xecf -let xk_Hangul_YU = 0xed0 -let xk_Hangul_EU = 0xed1 -let xk_Hangul_YI = 0xed2 -let xk_Hangul_I = 0xed3 - -(** Hangul syllable-final (JongSeong) Characters *) -let xk_Hangul_J_Kiyeog = 0xed4 -let xk_Hangul_J_SsangKiyeog = 0xed5 -let xk_Hangul_J_KiyeogSios = 0xed6 -let xk_Hangul_J_Nieun = 0xed7 -let xk_Hangul_J_NieunJieuj = 0xed8 -let xk_Hangul_J_NieunHieuh = 0xed9 -let xk_Hangul_J_Dikeud = 0xeda -let xk_Hangul_J_Rieul = 0xedb -let xk_Hangul_J_RieulKiyeog = 0xedc -let xk_Hangul_J_RieulMieum = 0xedd -let xk_Hangul_J_RieulPieub = 0xede -let xk_Hangul_J_RieulSios = 0xedf -let xk_Hangul_J_RieulTieut = 0xee0 -let xk_Hangul_J_RieulPhieuf = 0xee1 -let xk_Hangul_J_RieulHieuh = 0xee2 -let xk_Hangul_J_Mieum = 0xee3 -let xk_Hangul_J_Pieub = 0xee4 -let xk_Hangul_J_PieubSios = 0xee5 -let xk_Hangul_J_Sios = 0xee6 -let xk_Hangul_J_SsangSios = 0xee7 -let xk_Hangul_J_Ieung = 0xee8 -let xk_Hangul_J_Jieuj = 0xee9 -let xk_Hangul_J_Cieuc = 0xeea -let xk_Hangul_J_Khieuq = 0xeeb -let xk_Hangul_J_Tieut = 0xeec -let xk_Hangul_J_Phieuf = 0xeed -let xk_Hangul_J_Hieuh = 0xeee - -(** Ancient Hangul Consonant Characters *) -let xk_Hangul_RieulYeorinHieuh = 0xeef -let xk_Hangul_SunkyeongeumMieum = 0xef0 -let xk_Hangul_SunkyeongeumPieub = 0xef1 -let xk_Hangul_PanSios = 0xef2 -let xk_Hangul_KkogjiDalrinIeung = 0xef3 -let xk_Hangul_SunkyeongeumPhieuf = 0xef4 -let xk_Hangul_YeorinHieuh = 0xef5 - -(** Ancient Hangul Vowel Characters *) -let xk_Hangul_AraeA = 0xef6 -let xk_Hangul_AraeAE = 0xef7 - -(** Ancient Hangul syllable-final (JongSeong) Characters *) -let xk_Hangul_J_PanSios = 0xef8 -let xk_Hangul_J_KkogjiDalrinIeung = 0xef9 -let xk_Hangul_J_YeorinHieuh = 0xefa - -(** Korean currency symbol *) -let xk_Korean_Won = 0xeff - - - -let name_to_keysym = [ -"VoidSymbol",0xFFFFFF; -"BackSpace",0xFF08; -"Tab",0xFF09; -"Linefeed",0xFF0A; -"Clear",0xFF0B; -"Return",0xFF0D; -"Pause",0xFF13; -"Scroll_Lock",0xFF14; -"Sys_Req",0xFF15; -"Escape",0xFF1B; -"Delete",0xFFFF; -"Multi_key",0xFF20; -"Kanji",0xFF21; -"Muhenkan",0xFF22; -"Henkan_Mode",0xFF23; -"Henkan",0xFF23; -"Romaji",0xFF24; -"Hiragana",0xFF25; -"Katakana",0xFF26; -"Hiragana_Katakana",0xFF27; -"Zenkaku",0xFF28; -"Hankaku",0xFF29; -"Zenkaku_Hankaku",0xFF2A; -"Touroku",0xFF2B; -"Massyo",0xFF2C; -"Kana_Lock",0xFF2D; -"Kana_Shift",0xFF2E; -"Eisu_Shift",0xFF2F; -"Eisu_toggle",0xFF30; -"Home",0xFF50; -"Left",0xFF51; -"Up",0xFF52; -"Right",0xFF53; -"Down",0xFF54; -"Prior",0xFF55; -"Page_Up",0xFF55; -"Next",0xFF56; -"Page_Down",0xFF56; -"End",0xFF57; -"Begin",0xFF58; -"Select",0xFF60; -"Print",0xFF61; -"Execute",0xFF62; -"Insert",0xFF63; -"Undo",0xFF65; -"Redo",0xFF66; -"Menu",0xFF67; -"Find",0xFF68; -"Cancel",0xFF69; -"Help",0xFF6A; -"Break",0xFF6B; -"Mode_switch",0xFF7E; -"script_switch",0xFF7E; -"Num_Lock",0xFF7F; -"KP_Space",0xFF80; -"KP_Tab",0xFF89; -"KP_Enter",0xFF8D; -"KP_F1",0xFF91; -"KP_F2",0xFF92; -"KP_F3",0xFF93; -"KP_F4",0xFF94; -"KP_Home",0xFF95; -"KP_Left",0xFF96; -"KP_Up",0xFF97; -"KP_Right",0xFF98; -"KP_Down",0xFF99; -"KP_Prior",0xFF9A; -"KP_Page_Up",0xFF9A; -"KP_Next",0xFF9B; -"KP_Page_Down",0xFF9B; -"KP_End",0xFF9C; -"KP_Begin",0xFF9D; -"KP_Insert",0xFF9E; -"KP_Delete",0xFF9F; -"KP_Equal",0xFFBD; -"KP_Multiply",0xFFAA; -"KP_Add",0xFFAB; -"KP_Separator",0xFFAC; -"KP_Subtract",0xFFAD; -"KP_Decimal",0xFFAE; -"KP_Divide",0xFFAF; -"KP_0",0xFFB0; -"KP_1",0xFFB1; -"KP_2",0xFFB2; -"KP_3",0xFFB3; -"KP_4",0xFFB4; -"KP_5",0xFFB5; -"KP_6",0xFFB6; -"KP_7",0xFFB7; -"KP_8",0xFFB8; -"KP_9",0xFFB9; -"F1",0xFFBE; -"F2",0xFFBF; -"F3",0xFFC0; -"F4",0xFFC1; -"F5",0xFFC2; -"F6",0xFFC3; -"F7",0xFFC4; -"F8",0xFFC5; -"F9",0xFFC6; -"F10",0xFFC7; -"F11",0xFFC8; -"L1",0xFFC8; -"F12",0xFFC9; -"L2",0xFFC9; -"F13",0xFFCA; -"L3",0xFFCA; -"F14",0xFFCB; -"L4",0xFFCB; -"F15",0xFFCC; -"L5",0xFFCC; -"F16",0xFFCD; -"L6",0xFFCD; -"F17",0xFFCE; -"L7",0xFFCE; -"F18",0xFFCF; -"L8",0xFFCF; -"F19",0xFFD0; -"L9",0xFFD0; -"F20",0xFFD1; -"L10",0xFFD1; -"F21",0xFFD2; -"R1",0xFFD2; -"F22",0xFFD3; -"R2",0xFFD3; -"F23",0xFFD4; -"R3",0xFFD4; -"F24",0xFFD5; -"R4",0xFFD5; -"F25",0xFFD6; -"R5",0xFFD6; -"F26",0xFFD7; -"R6",0xFFD7; -"F27",0xFFD8; -"R7",0xFFD8; -"F28",0xFFD9; -"R8",0xFFD9; -"F29",0xFFDA; -"R9",0xFFDA; -"F30",0xFFDB; -"R10",0xFFDB; -"F31",0xFFDC; -"R11",0xFFDC; -"F32",0xFFDD; -"R12",0xFFDD; -"F33",0xFFDE; -"R13",0xFFDE; -"F34",0xFFDF; -"R14",0xFFDF; -"F35",0xFFE0; -"R15",0xFFE0; -"Shift_L",0xFFE1; -"Shift_R",0xFFE2; -"Control_L",0xFFE3; -"Control_R",0xFFE4; -"Caps_Lock",0xFFE5; -"Shift_Lock",0xFFE6; -"Meta_L",0xFFE7; -"Meta_R",0xFFE8; -"Alt_L",0xFFE9; -"Alt_R",0xFFEA; -"Super_L",0xFFEB; -"Super_R",0xFFEC; -"Hyper_L",0xFFED; -"Hyper_R",0xFFEE; -"ISO_Lock",0xFE01; -"ISO_Level2_Latch",0xFE02; -"ISO_Level3_Shift",0xFE03; -"ISO_Level3_Latch",0xFE04; -"ISO_Level3_Lock",0xFE05; -"ISO_Group_Shift",0xFF7E; -"ISO_Group_Latch",0xFE06; -"ISO_Group_Lock",0xFE07; -"ISO_Next_Group",0xFE08; -"ISO_Next_Group_Lock",0xFE09; -"ISO_Prev_Group",0xFE0A; -"ISO_Prev_Group_Lock",0xFE0B; -"ISO_First_Group",0xFE0C; -"ISO_First_Group_Lock",0xFE0D; -"ISO_Last_Group",0xFE0E; -"ISO_Last_Group_Lock",0xFE0F; -"ISO_Left_Tab",0xFE20; -"ISO_Move_Line_Up",0xFE21; -"ISO_Move_Line_Down",0xFE22; -"ISO_Partial_Line_Up",0xFE23; -"ISO_Partial_Line_Down",0xFE24; -"ISO_Partial_Space_Left",0xFE25; -"ISO_Partial_Space_Right",0xFE26; -"ISO_Set_Margin_Left",0xFE27; -"ISO_Set_Margin_Right",0xFE28; -"ISO_Release_Margin_Left",0xFE29; -"ISO_Release_Margin_Right",0xFE2A; -"ISO_Release_Both_Margins",0xFE2B; -"ISO_Fast_Cursor_Left",0xFE2C; -"ISO_Fast_Cursor_Right",0xFE2D; -"ISO_Fast_Cursor_Up",0xFE2E; -"ISO_Fast_Cursor_Down",0xFE2F; -"ISO_Continuous_Underline",0xFE30; -"ISO_Discontinuous_Underline",0xFE31; -"ISO_Emphasize",0xFE32; -"ISO_Center_Object",0xFE33; -"ISO_Enter",0xFE34; -"dead_grave",0xFE50; -"dead_acute",0xFE51; -"dead_circumflex",0xFE52; -"dead_tilde",0xFE53; -"dead_macron",0xFE54; -"dead_breve",0xFE55; -"dead_abovedot",0xFE56; -"dead_diaeresis",0xFE57; -"dead_abovering",0xFE58; -"dead_doubleacute",0xFE59; -"dead_caron",0xFE5A; -"dead_cedilla",0xFE5B; -"dead_ogonek",0xFE5C; -"dead_iota",0xFE5D; -"dead_voiced_sound",0xFE5E; -"dead_semivoiced_sound",0xFE5F; -"dead_belowdot",0xFE60; -"First_Virtual_Screen",0xFED0; -"Prev_Virtual_Screen",0xFED1; -"Next_Virtual_Screen",0xFED2; -"Last_Virtual_Screen",0xFED4; -"Terminate_Server",0xFED5; -"AccessX_Enable",0xFE70; -"AccessX_Feedback_Enable",0xFE71; -"RepeatKeys_Enable",0xFE72; -"SlowKeys_Enable",0xFE73; -"BounceKeys_Enable",0xFE74; -"StickyKeys_Enable",0xFE75; -"MouseKeys_Enable",0xFE76; -"MouseKeys_Accel_Enable",0xFE77; -"Overlay1_Enable",0xFE78; -"Overlay2_Enable",0xFE79; -"AudibleBell_Enable",0xFE7A; -"Pointer_Left",0xFEE0; -"Pointer_Right",0xFEE1; -"Pointer_Up",0xFEE2; -"Pointer_Down",0xFEE3; -"Pointer_UpLeft",0xFEE4; -"Pointer_UpRight",0xFEE5; -"Pointer_DownLeft",0xFEE6; -"Pointer_DownRight",0xFEE7; -"Pointer_Button_Dflt",0xFEE8; -"Pointer_Button1",0xFEE9; -"Pointer_Button2",0xFEEA; -"Pointer_Button3",0xFEEB; -"Pointer_Button4",0xFEEC; -"Pointer_Button5",0xFEED; -"Pointer_DblClick_Dflt",0xFEEE; -"Pointer_DblClick1",0xFEEF; -"Pointer_DblClick2",0xFEF0; -"Pointer_DblClick3",0xFEF1; -"Pointer_DblClick4",0xFEF2; -"Pointer_DblClick5",0xFEF3; -"Pointer_Drag_Dflt",0xFEF4; -"Pointer_Drag1",0xFEF5; -"Pointer_Drag2",0xFEF6; -"Pointer_Drag3",0xFEF7; -"Pointer_Drag4",0xFEF8; -"Pointer_Drag5",0xFEFD; -"Pointer_EnableKeys",0xFEF9; -"Pointer_Accelerate",0xFEFA; -"Pointer_DfltBtnNext",0xFEFB; -"Pointer_DfltBtnPrev",0xFEFC; -"3270_Duplicate",0xFD01; -"3270_FieldMark",0xFD02; -"3270_Right2",0xFD03; -"3270_Left2",0xFD04; -"3270_BackTab",0xFD05; -"3270_EraseEOF",0xFD06; -"3270_EraseInput",0xFD07; -"3270_Reset",0xFD08; -"3270_Quit",0xFD09; -"3270_PA1",0xFD0A; -"3270_PA2",0xFD0B; -"3270_PA3",0xFD0C; -"3270_Test",0xFD0D; -"3270_Attn",0xFD0E; -"3270_CursorBlink",0xFD0F; -"3270_AltCursor",0xFD10; -"3270_KeyClick",0xFD11; -"3270_Jump",0xFD12; -"3270_Ident",0xFD13; -"3270_Rule",0xFD14; -"3270_Copy",0xFD15; -"3270_Play",0xFD16; -"3270_Setup",0xFD17; -"3270_Record",0xFD18; -"3270_ChangeScreen",0xFD19; -"3270_DeleteWord",0xFD1A; -"3270_ExSelect",0xFD1B; -"3270_CursorSelect",0xFD1C; -"3270_PrintScreen",0xFD1D; -"3270_Enter",0xFD1E; -"space",0x020; -"exclam",0x021; -"quotedbl",0x022; -"numbersign",0x023; -"dollar",0x024; -"percent",0x025; -"ampersand",0x026; -"apostrophe",0x027; -"quoteright",0x027; -"parenleft",0x028; -"parenright",0x029; -"asterisk",0x02a; -"plus",0x02b; -"comma",0x02c; -"minus",0x02d; -"period",0x02e; -"slash",0x02f; -"0",0x030; -"1",0x031; -"2",0x032; -"3",0x033; -"4",0x034; -"5",0x035; -"6",0x036; -"7",0x037; -"8",0x038; -"9",0x039; -"colon",0x03a; -"semicolon",0x03b; -"less",0x03c; -"equal",0x03d; -"greater",0x03e; -"question",0x03f; -"at",0x040; -"A",0x041; -"B",0x042; -"C",0x043; -"D",0x044; -"E",0x045; -"F",0x046; -"G",0x047; -"H",0x048; -"I",0x049; -"J",0x04a; -"K",0x04b; -"L",0x04c; -"M",0x04d; -"N",0x04e; -"O",0x04f; -"P",0x050; -"Q",0x051; -"R",0x052; -"S",0x053; -"T",0x054; -"U",0x055; -"V",0x056; -"W",0x057; -"X",0x058; -"Y",0x059; -"Z",0x05a; -"bracketleft",0x05b; -"backslash",0x05c; -"bracketright",0x05d; -"asciicircum",0x05e; -"underscore",0x05f; -"grave",0x060; -"quoteleft",0x060; -"a",0x061; -"b",0x062; -"c",0x063; -"d",0x064; -"e",0x065; -"f",0x066; -"g",0x067; -"h",0x068; -"i",0x069; -"j",0x06a; -"k",0x06b; -"l",0x06c; -"m",0x06d; -"n",0x06e; -"o",0x06f; -"p",0x070; -"q",0x071; -"r",0x072; -"s",0x073; -"t",0x074; -"u",0x075; -"v",0x076; -"w",0x077; -"x",0x078; -"y",0x079; -"z",0x07a; -"braceleft",0x07b; -"bar",0x07c; -"braceright",0x07d; -"asciitilde",0x07e; -"nobreakspace",0x0a0; -"exclamdown",0x0a1; -"cent",0x0a2; -"sterling",0x0a3; -"currency",0x0a4; -"yen",0x0a5; -"brokenbar",0x0a6; -"section",0x0a7; -"diaeresis",0x0a8; -"copyright",0x0a9; -"ordfeminine",0x0aa; -"guillemotleft",0x0ab; -"notsign",0x0ac; -"hyphen",0x0ad; -"registered",0x0ae; -"macron",0x0af; -"degree",0x0b0; -"plusminus",0x0b1; -"twosuperior",0x0b2; -"threesuperior",0x0b3; -"acute",0x0b4; -"mu",0x0b5; -"paragraph",0x0b6; -"periodcentered",0x0b7; -"cedilla",0x0b8; -"onesuperior",0x0b9; -"masculine",0x0ba; -"guillemotright",0x0bb; -"onequarter",0x0bc; -"onehalf",0x0bd; -"threequarters",0x0be; -"questiondown",0x0bf; -"Agrave",0x0c0; -"Aacute",0x0c1; -"Acircumflex",0x0c2; -"Atilde",0x0c3; -"Adiaeresis",0x0c4; -"Aring",0x0c5; -"AE",0x0c6; -"Ccedilla",0x0c7; -"Egrave",0x0c8; -"Eacute",0x0c9; -"Ecircumflex",0x0ca; -"Ediaeresis",0x0cb; -"Igrave",0x0cc; -"Iacute",0x0cd; -"Icircumflex",0x0ce; -"Idiaeresis",0x0cf; -"ETH",0x0d0; -"Eth",0x0d0; -"Ntilde",0x0d1; -"Ograve",0x0d2; -"Oacute",0x0d3; -"Ocircumflex",0x0d4; -"Otilde",0x0d5; -"Odiaeresis",0x0d6; -"multiply",0x0d7; -"Ooblique",0x0d8; -"Ugrave",0x0d9; -"Uacute",0x0da; -"Ucircumflex",0x0db; -"Udiaeresis",0x0dc; -"Yacute",0x0dd; -"THORN",0x0de; -"Thorn",0x0de; -"ssharp",0x0df; -"agrave",0x0e0; -"aacute",0x0e1; -"acircumflex",0x0e2; -"atilde",0x0e3; -"adiaeresis",0x0e4; -"aring",0x0e5; -"ae",0x0e6; -"ccedilla",0x0e7; -"egrave",0x0e8; -"eacute",0x0e9; -"ecircumflex",0x0ea; -"ediaeresis",0x0eb; -"igrave",0x0ec; -"iacute",0x0ed; -"icircumflex",0x0ee; -"idiaeresis",0x0ef; -"eth",0x0f0; -"ntilde",0x0f1; -"ograve",0x0f2; -"oacute",0x0f3; -"ocircumflex",0x0f4; -"otilde",0x0f5; -"odiaeresis",0x0f6; -"division",0x0f7; -"oslash",0x0f8; -"ugrave",0x0f9; -"uacute",0x0fa; -"ucircumflex",0x0fb; -"udiaeresis",0x0fc; -"yacute",0x0fd; -"thorn",0x0fe; -"ydiaeresis",0x0ff; -"Aogonek",0x1a1; -"breve",0x1a2; -"Lstroke",0x1a3; -"Lcaron",0x1a5; -"Sacute",0x1a6; -"Scaron",0x1a9; -"Scedilla",0x1aa; -"Tcaron",0x1ab; -"Zacute",0x1ac; -"Zcaron",0x1ae; -"Zabovedot",0x1af; -"aogonek",0x1b1; -"ogonek",0x1b2; -"lstroke",0x1b3; -"lcaron",0x1b5; -"sacute",0x1b6; -"caron",0x1b7; -"scaron",0x1b9; -"scedilla",0x1ba; -"tcaron",0x1bb; -"zacute",0x1bc; -"doubleacute",0x1bd; -"zcaron",0x1be; -"zabovedot",0x1bf; -"Racute",0x1c0; -"Abreve",0x1c3; -"Lacute",0x1c5; -"Cacute",0x1c6; -"Ccaron",0x1c8; -"Eogonek",0x1ca; -"Ecaron",0x1cc; -"Dcaron",0x1cf; -"Dstroke",0x1d0; -"Nacute",0x1d1; -"Ncaron",0x1d2; -"Odoubleacute",0x1d5; -"Rcaron",0x1d8; -"Uring",0x1d9; -"Udoubleacute",0x1db; -"Tcedilla",0x1de; -"racute",0x1e0; -"abreve",0x1e3; -"lacute",0x1e5; -"cacute",0x1e6; -"ccaron",0x1e8; -"eogonek",0x1ea; -"ecaron",0x1ec; -"dcaron",0x1ef; -"dstroke",0x1f0; -"nacute",0x1f1; -"ncaron",0x1f2; -"odoubleacute",0x1f5; -"udoubleacute",0x1fb; -"rcaron",0x1f8; -"uring",0x1f9; -"tcedilla",0x1fe; -"abovedot",0x1ff; -"Hstroke",0x2a1; -"Hcircumflex",0x2a6; -"Iabovedot",0x2a9; -"Gbreve",0x2ab; -"Jcircumflex",0x2ac; -"hstroke",0x2b1; -"hcircumflex",0x2b6; -"idotless",0x2b9; -"gbreve",0x2bb; -"jcircumflex",0x2bc; -"Cabovedot",0x2c5; -"Ccircumflex",0x2c6; -"Gabovedot",0x2d5; -"Gcircumflex",0x2d8; -"Ubreve",0x2dd; -"Scircumflex",0x2de; -"cabovedot",0x2e5; -"ccircumflex",0x2e6; -"gabovedot",0x2f5; -"gcircumflex",0x2f8; -"ubreve",0x2fd; -"scircumflex",0x2fe; -"kra",0x3a2; -"kappa",0x3a2; -"Rcedilla",0x3a3; -"Itilde",0x3a5; -"Lcedilla",0x3a6; -"Emacron",0x3aa; -"Gcedilla",0x3ab; -"Tslash",0x3ac; -"rcedilla",0x3b3; -"itilde",0x3b5; -"lcedilla",0x3b6; -"emacron",0x3ba; -"gcedilla",0x3bb; -"tslash",0x3bc; -"ENG",0x3bd; -"eng",0x3bf; -"Amacron",0x3c0; -"Iogonek",0x3c7; -"Eabovedot",0x3cc; -"Imacron",0x3cf; -"Ncedilla",0x3d1; -"Omacron",0x3d2; -"Kcedilla",0x3d3; -"Uogonek",0x3d9; -"Utilde",0x3dd; -"Umacron",0x3de; -"amacron",0x3e0; -"iogonek",0x3e7; -"eabovedot",0x3ec; -"imacron",0x3ef; -"ncedilla",0x3f1; -"omacron",0x3f2; -"kcedilla",0x3f3; -"uogonek",0x3f9; -"utilde",0x3fd; -"umacron",0x3fe; -"overline",0x47e; -"kana_fullstop",0x4a1; -"kana_openingbracket",0x4a2; -"kana_closingbracket",0x4a3; -"kana_comma",0x4a4; -"kana_conjunctive",0x4a5; -"kana_middledot",0x4a5; -"kana_WO",0x4a6; -"kana_a",0x4a7; -"kana_i",0x4a8; -"kana_u",0x4a9; -"kana_e",0x4aa; -"kana_o",0x4ab; -"kana_ya",0x4ac; -"kana_yu",0x4ad; -"kana_yo",0x4ae; -"kana_tsu",0x4af; -"kana_tu",0x4af; -"prolongedsound",0x4b0; -"kana_A",0x4b1; -"kana_I",0x4b2; -"kana_U",0x4b3; -"kana_E",0x4b4; -"kana_O",0x4b5; -"kana_KA",0x4b6; -"kana_KI",0x4b7; -"kana_KU",0x4b8; -"kana_KE",0x4b9; -"kana_KO",0x4ba; -"kana_SA",0x4bb; -"kana_SHI",0x4bc; -"kana_SU",0x4bd; -"kana_SE",0x4be; -"kana_SO",0x4bf; -"kana_TA",0x4c0; -"kana_CHI",0x4c1; -"kana_TI",0x4c1; -"kana_TSU",0x4c2; -"kana_TU",0x4c2; -"kana_TE",0x4c3; -"kana_TO",0x4c4; -"kana_NA",0x4c5; -"kana_NI",0x4c6; -"kana_NU",0x4c7; -"kana_NE",0x4c8; -"kana_NO",0x4c9; -"kana_HA",0x4ca; -"kana_HI",0x4cb; -"kana_FU",0x4cc; -"kana_HU",0x4cc; -"kana_HE",0x4cd; -"kana_HO",0x4ce; -"kana_MA",0x4cf; -"kana_MI",0x4d0; -"kana_MU",0x4d1; -"kana_ME",0x4d2; -"kana_MO",0x4d3; -"kana_YA",0x4d4; -"kana_YU",0x4d5; -"kana_YO",0x4d6; -"kana_RA",0x4d7; -"kana_RI",0x4d8; -"kana_RU",0x4d9; -"kana_RE",0x4da; -"kana_RO",0x4db; -"kana_WA",0x4dc; -"kana_N",0x4dd; -"voicedsound",0x4de; -"semivoicedsound",0x4df; -"kana_switch",0xFF7E; -"Arabic_comma",0x5ac; -"Arabic_semicolon",0x5bb; -"Arabic_question_mark",0x5bf; -"Arabic_hamza",0x5c1; -"Arabic_maddaonalef",0x5c2; -"Arabic_hamzaonalef",0x5c3; -"Arabic_hamzaonwaw",0x5c4; -"Arabic_hamzaunderalef",0x5c5; -"Arabic_hamzaonyeh",0x5c6; -"Arabic_alef",0x5c7; -"Arabic_beh",0x5c8; -"Arabic_tehmarbuta",0x5c9; -"Arabic_teh",0x5ca; -"Arabic_theh",0x5cb; -"Arabic_jeem",0x5cc; -"Arabic_hah",0x5cd; -"Arabic_khah",0x5ce; -"Arabic_dal",0x5cf; -"Arabic_thal",0x5d0; -"Arabic_ra",0x5d1; -"Arabic_zain",0x5d2; -"Arabic_seen",0x5d3; -"Arabic_sheen",0x5d4; -"Arabic_sad",0x5d5; -"Arabic_dad",0x5d6; -"Arabic_tah",0x5d7; -"Arabic_zah",0x5d8; -"Arabic_ain",0x5d9; -"Arabic_ghain",0x5da; -"Arabic_tatweel",0x5e0; -"Arabic_feh",0x5e1; -"Arabic_qaf",0x5e2; -"Arabic_kaf",0x5e3; -"Arabic_lam",0x5e4; -"Arabic_meem",0x5e5; -"Arabic_noon",0x5e6; -"Arabic_ha",0x5e7; -"Arabic_heh",0x5e7; -"Arabic_waw",0x5e8; -"Arabic_alefmaksura",0x5e9; -"Arabic_yeh",0x5ea; -"Arabic_fathatan",0x5eb; -"Arabic_dammatan",0x5ec; -"Arabic_kasratan",0x5ed; -"Arabic_fatha",0x5ee; -"Arabic_damma",0x5ef; -"Arabic_kasra",0x5f0; -"Arabic_shadda",0x5f1; -"Arabic_sukun",0x5f2; -"Arabic_switch",0xFF7E; -"Serbian_dje",0x6a1; -"Macedonia_gje",0x6a2; -"Cyrillic_io",0x6a3; -"Ukrainian_ie",0x6a4; -"Ukranian_je",0x6a4; -"Macedonia_dse",0x6a5; -"Ukrainian_i",0x6a6; -"Ukranian_i",0x6a6; -"Ukrainian_yi",0x6a7; -"Ukranian_yi",0x6a7; -"Cyrillic_je",0x6a8; -"Serbian_je",0x6a8; -"Cyrillic_lje",0x6a9; -"Serbian_lje",0x6a9; -"Cyrillic_nje",0x6aa; -"Serbian_nje",0x6aa; -"Serbian_tshe",0x6ab; -"Macedonia_kje",0x6ac; -"Byelorussian_shortu",0x6ae; -"Cyrillic_dzhe",0x6af; -"Serbian_dze",0x6af; -"numerosign",0x6b0; -"Serbian_DJE",0x6b1; -"Macedonia_GJE",0x6b2; -"Cyrillic_IO",0x6b3; -"Ukrainian_IE",0x6b4; -"Ukranian_JE",0x6b4; -"Macedonia_DSE",0x6b5; -"Ukrainian_I",0x6b6; -"Ukranian_I",0x6b6; -"Ukrainian_YI",0x6b7; -"Ukranian_YI",0x6b7; -"Cyrillic_JE",0x6b8; -"Serbian_JE",0x6b8; -"Cyrillic_LJE",0x6b9; -"Serbian_LJE",0x6b9; -"Cyrillic_NJE",0x6ba; -"Serbian_NJE",0x6ba; -"Serbian_TSHE",0x6bb; -"Macedonia_KJE",0x6bc; -"Byelorussian_SHORTU",0x6be; -"Cyrillic_DZHE",0x6bf; -"Serbian_DZE",0x6bf; -"Cyrillic_yu",0x6c0; -"Cyrillic_a",0x6c1; -"Cyrillic_be",0x6c2; -"Cyrillic_tse",0x6c3; -"Cyrillic_de",0x6c4; -"Cyrillic_ie",0x6c5; -"Cyrillic_ef",0x6c6; -"Cyrillic_ghe",0x6c7; -"Cyrillic_ha",0x6c8; -"Cyrillic_i",0x6c9; -"Cyrillic_shorti",0x6ca; -"Cyrillic_ka",0x6cb; -"Cyrillic_el",0x6cc; -"Cyrillic_em",0x6cd; -"Cyrillic_en",0x6ce; -"Cyrillic_o",0x6cf; -"Cyrillic_pe",0x6d0; -"Cyrillic_ya",0x6d1; -"Cyrillic_er",0x6d2; -"Cyrillic_es",0x6d3; -"Cyrillic_te",0x6d4; -"Cyrillic_u",0x6d5; -"Cyrillic_zhe",0x6d6; -"Cyrillic_ve",0x6d7; -"Cyrillic_softsign",0x6d8; -"Cyrillic_yeru",0x6d9; -"Cyrillic_ze",0x6da; -"Cyrillic_sha",0x6db; -"Cyrillic_e",0x6dc; -"Cyrillic_shcha",0x6dd; -"Cyrillic_che",0x6de; -"Cyrillic_hardsign",0x6df; -"Cyrillic_YU",0x6e0; -"Cyrillic_A",0x6e1; -"Cyrillic_BE",0x6e2; -"Cyrillic_TSE",0x6e3; -"Cyrillic_DE",0x6e4; -"Cyrillic_IE",0x6e5; -"Cyrillic_EF",0x6e6; -"Cyrillic_GHE",0x6e7; -"Cyrillic_HA",0x6e8; -"Cyrillic_I",0x6e9; -"Cyrillic_SHORTI",0x6ea; -"Cyrillic_KA",0x6eb; -"Cyrillic_EL",0x6ec; -"Cyrillic_EM",0x6ed; -"Cyrillic_EN",0x6ee; -"Cyrillic_O",0x6ef; -"Cyrillic_PE",0x6f0; -"Cyrillic_YA",0x6f1; -"Cyrillic_ER",0x6f2; -"Cyrillic_ES",0x6f3; -"Cyrillic_TE",0x6f4; -"Cyrillic_U",0x6f5; -"Cyrillic_ZHE",0x6f6; -"Cyrillic_VE",0x6f7; -"Cyrillic_SOFTSIGN",0x6f8; -"Cyrillic_YERU",0x6f9; -"Cyrillic_ZE",0x6fa; -"Cyrillic_SHA",0x6fb; -"Cyrillic_E",0x6fc; -"Cyrillic_SHCHA",0x6fd; -"Cyrillic_CHE",0x6fe; -"Cyrillic_HARDSIGN",0x6ff; -"Greek_ALPHAaccent",0x7a1; -"Greek_EPSILONaccent",0x7a2; -"Greek_ETAaccent",0x7a3; -"Greek_IOTAaccent",0x7a4; -"Greek_IOTAdiaeresis",0x7a5; -"Greek_OMICRONaccent",0x7a7; -"Greek_UPSILONaccent",0x7a8; -"Greek_UPSILONdieresis",0x7a9; -"Greek_OMEGAaccent",0x7ab; -"Greek_accentdieresis",0x7ae; -"Greek_horizbar",0x7af; -"Greek_alphaaccent",0x7b1; -"Greek_epsilonaccent",0x7b2; -"Greek_etaaccent",0x7b3; -"Greek_iotaaccent",0x7b4; -"Greek_iotadieresis",0x7b5; -"Greek_iotaaccentdieresis",0x7b6; -"Greek_omicronaccent",0x7b7; -"Greek_upsilonaccent",0x7b8; -"Greek_upsilondieresis",0x7b9; -"Greek_upsilonaccentdieresis",0x7ba; -"Greek_omegaaccent",0x7bb; -"Greek_ALPHA",0x7c1; -"Greek_BETA",0x7c2; -"Greek_GAMMA",0x7c3; -"Greek_DELTA",0x7c4; -"Greek_EPSILON",0x7c5; -"Greek_ZETA",0x7c6; -"Greek_ETA",0x7c7; -"Greek_THETA",0x7c8; -"Greek_IOTA",0x7c9; -"Greek_KAPPA",0x7ca; -"Greek_LAMDA",0x7cb; -"Greek_LAMBDA",0x7cb; -"Greek_MU",0x7cc; -"Greek_NU",0x7cd; -"Greek_XI",0x7ce; -"Greek_OMICRON",0x7cf; -"Greek_PI",0x7d0; -"Greek_RHO",0x7d1; -"Greek_SIGMA",0x7d2; -"Greek_TAU",0x7d4; -"Greek_UPSILON",0x7d5; -"Greek_PHI",0x7d6; -"Greek_CHI",0x7d7; -"Greek_PSI",0x7d8; -"Greek_OMEGA",0x7d9; -"Greek_alpha",0x7e1; -"Greek_beta",0x7e2; -"Greek_gamma",0x7e3; -"Greek_delta",0x7e4; -"Greek_epsilon",0x7e5; -"Greek_zeta",0x7e6; -"Greek_eta",0x7e7; -"Greek_theta",0x7e8; -"Greek_iota",0x7e9; -"Greek_kappa",0x7ea; -"Greek_lamda",0x7eb; -"Greek_lambda",0x7eb; -"Greek_mu",0x7ec; -"Greek_nu",0x7ed; -"Greek_xi",0x7ee; -"Greek_omicron",0x7ef; -"Greek_pi",0x7f0; -"Greek_rho",0x7f1; -"Greek_sigma",0x7f2; -"Greek_finalsmallsigma",0x7f3; -"Greek_tau",0x7f4; -"Greek_upsilon",0x7f5; -"Greek_phi",0x7f6; -"Greek_chi",0x7f7; -"Greek_psi",0x7f8; -"Greek_omega",0x7f9; -"Greek_switch",0xFF7E; -"leftradical",0x8a1; -"topleftradical",0x8a2; -"horizconnector",0x8a3; -"topintegral",0x8a4; -"botintegral",0x8a5; -"vertconnector",0x8a6; -"topleftsqbracket",0x8a7; -"botleftsqbracket",0x8a8; -"toprightsqbracket",0x8a9; -"botrightsqbracket",0x8aa; -"topleftparens",0x8ab; -"botleftparens",0x8ac; -"toprightparens",0x8ad; -"botrightparens",0x8ae; -"leftmiddlecurlybrace",0x8af; -"rightmiddlecurlybrace",0x8b0; -"topleftsummation",0x8b1; -"botleftsummation",0x8b2; -"topvertsummationconnector",0x8b3; -"botvertsummationconnector",0x8b4; -"toprightsummation",0x8b5; -"botrightsummation",0x8b6; -"rightmiddlesummation",0x8b7; -"lessthanequal",0x8bc; -"notequal",0x8bd; -"greaterthanequal",0x8be; -"integral",0x8bf; -"therefore",0x8c0; -"variation",0x8c1; -"infinity",0x8c2; -"nabla",0x8c5; -"approximate",0x8c8; -"similarequal",0x8c9; -"ifonlyif",0x8cd; -"implies",0x8ce; -"identical",0x8cf; -"radical",0x8d6; -"includedin",0x8da; -"includes",0x8db; -"intersection",0x8dc; -"union",0x8dd; -"logicaland",0x8de; -"logicalor",0x8df; -"partialderivative",0x8ef; -"function",0x8f6; -"leftarrow",0x8fb; -"uparrow",0x8fc; -"rightarrow",0x8fd; -"downarrow",0x8fe; -"blank",0x9df; -"soliddiamond",0x9e0; -"checkerboard",0x9e1; -"ht",0x9e2; -"ff",0x9e3; -"cr",0x9e4; -"lf",0x9e5; -"nl",0x9e8; -"vt",0x9e9; -"lowrightcorner",0x9ea; -"uprightcorner",0x9eb; -"upleftcorner",0x9ec; -"lowleftcorner",0x9ed; -"crossinglines",0x9ee; -"horizlinescan1",0x9ef; -"horizlinescan3",0x9f0; -"horizlinescan5",0x9f1; -"horizlinescan7",0x9f2; -"horizlinescan9",0x9f3; -"leftt",0x9f4; -"rightt",0x9f5; -"bott",0x9f6; -"topt",0x9f7; -"vertbar",0x9f8; -"emspace",0xaa1; -"enspace",0xaa2; -"em3space",0xaa3; -"em4space",0xaa4; -"digitspace",0xaa5; -"punctspace",0xaa6; -"thinspace",0xaa7; -"hairspace",0xaa8; -"emdash",0xaa9; -"endash",0xaaa; -"signifblank",0xaac; -"ellipsis",0xaae; -"doubbaselinedot",0xaaf; -"onethird",0xab0; -"twothirds",0xab1; -"onefifth",0xab2; -"twofifths",0xab3; -"threefifths",0xab4; -"fourfifths",0xab5; -"onesixth",0xab6; -"fivesixths",0xab7; -"careof",0xab8; -"figdash",0xabb; -"leftanglebracket",0xabc; -"decimalpoint",0xabd; -"rightanglebracket",0xabe; -"marker",0xabf; -"oneeighth",0xac3; -"threeeighths",0xac4; -"fiveeighths",0xac5; -"seveneighths",0xac6; -"trademark",0xac9; -"signaturemark",0xaca; -"trademarkincircle",0xacb; -"leftopentriangle",0xacc; -"rightopentriangle",0xacd; -"emopencircle",0xace; -"emopenrectangle",0xacf; -"leftsinglequotemark",0xad0; -"rightsinglequotemark",0xad1; -"leftdoublequotemark",0xad2; -"rightdoublequotemark",0xad3; -"prescription",0xad4; -"minutes",0xad6; -"seconds",0xad7; -"latincross",0xad9; -"hexagram",0xada; -"filledrectbullet",0xadb; -"filledlefttribullet",0xadc; -"filledrighttribullet",0xadd; -"emfilledcircle",0xade; -"emfilledrect",0xadf; -"enopencircbullet",0xae0; -"enopensquarebullet",0xae1; -"openrectbullet",0xae2; -"opentribulletup",0xae3; -"opentribulletdown",0xae4; -"openstar",0xae5; -"enfilledcircbullet",0xae6; -"enfilledsqbullet",0xae7; -"filledtribulletup",0xae8; -"filledtribulletdown",0xae9; -"leftpointer",0xaea; -"rightpointer",0xaeb; -"club",0xaec; -"diamond",0xaed; -"heart",0xaee; -"maltesecross",0xaf0; -"dagger",0xaf1; -"doubledagger",0xaf2; -"checkmark",0xaf3; -"ballotcross",0xaf4; -"musicalsharp",0xaf5; -"musicalflat",0xaf6; -"malesymbol",0xaf7; -"femalesymbol",0xaf8; -"telephone",0xaf9; -"telephonerecorder",0xafa; -"phonographcopyright",0xafb; -"caret",0xafc; -"singlelowquotemark",0xafd; -"doublelowquotemark",0xafe; -"cursor",0xaff; -"leftcaret",0xba3; -"rightcaret",0xba6; -"downcaret",0xba8; -"upcaret",0xba9; -"overbar",0xbc0; -"downtack",0xbc2; -"upshoe",0xbc3; -"downstile",0xbc4; -"underbar",0xbc6; -"jot",0xbca; -"quad",0xbcc; -"uptack",0xbce; -"circle",0xbcf; -"upstile",0xbd3; -"downshoe",0xbd6; -"rightshoe",0xbd8; -"leftshoe",0xbda; -"lefttack",0xbdc; -"righttack",0xbfc; -"hebrew_doublelowline",0xcdf; -"hebrew_aleph",0xce0; -"hebrew_bet",0xce1; -"hebrew_beth",0xce1; -"hebrew_gimel",0xce2; -"hebrew_gimmel",0xce2; -"hebrew_dalet",0xce3; -"hebrew_daleth",0xce3; -"hebrew_he",0xce4; -"hebrew_waw",0xce5; -"hebrew_zain",0xce6; -"hebrew_zayin",0xce6; -"hebrew_chet",0xce7; -"hebrew_het",0xce7; -"hebrew_tet",0xce8; -"hebrew_teth",0xce8; -"hebrew_yod",0xce9; -"hebrew_finalkaph",0xcea; -"hebrew_kaph",0xceb; -"hebrew_lamed",0xcec; -"hebrew_finalmem",0xced; -"hebrew_mem",0xcee; -"hebrew_finalnun",0xcef; -"hebrew_nun",0xcf0; -"hebrew_samech",0xcf1; -"hebrew_samekh",0xcf1; -"hebrew_ayin",0xcf2; -"hebrew_finalpe",0xcf3; -"hebrew_pe",0xcf4; -"hebrew_finalzade",0xcf5; -"hebrew_finalzadi",0xcf5; -"hebrew_zade",0xcf6; -"hebrew_zadi",0xcf6; -"hebrew_qoph",0xcf7; -"hebrew_kuf",0xcf7; -"hebrew_resh",0xcf8; -"hebrew_shin",0xcf9; -"hebrew_taw",0xcfa; -"hebrew_taf",0xcfa; -"Hebrew_switch",0xFF7E; -"Thai_kokai",0xda1; -"Thai_khokhai",0xda2; -"Thai_khokhuat",0xda3; -"Thai_khokhwai",0xda4; -"Thai_khokhon",0xda5; -"Thai_khorakhang",0xda6; -"Thai_ngongu",0xda7; -"Thai_chochan",0xda8; -"Thai_choching",0xda9; -"Thai_chochang",0xdaa; -"Thai_soso",0xdab; -"Thai_chochoe",0xdac; -"Thai_yoying",0xdad; -"Thai_dochada",0xdae; -"Thai_topatak",0xdaf; -"Thai_thothan",0xdb0; -"Thai_thonangmontho",0xdb1; -"Thai_thophuthao",0xdb2; -"Thai_nonen",0xdb3; -"Thai_dodek",0xdb4; -"Thai_totao",0xdb5; -"Thai_thothung",0xdb6; -"Thai_thothahan",0xdb7; -"Thai_thothong",0xdb8; -"Thai_nonu",0xdb9; -"Thai_bobaimai",0xdba; -"Thai_popla",0xdbb; -"Thai_phophung",0xdbc; -"Thai_fofa",0xdbd; -"Thai_phophan",0xdbe; -"Thai_fofan",0xdbf; -"Thai_phosamphao",0xdc0; -"Thai_moma",0xdc1; -"Thai_yoyak",0xdc2; -"Thai_rorua",0xdc3; -"Thai_ru",0xdc4; -"Thai_loling",0xdc5; -"Thai_lu",0xdc6; -"Thai_wowaen",0xdc7; -"Thai_sosala",0xdc8; -"Thai_sorusi",0xdc9; -"Thai_sosua",0xdca; -"Thai_hohip",0xdcb; -"Thai_lochula",0xdcc; -"Thai_oang",0xdcd; -"Thai_honokhuk",0xdce; -"Thai_paiyannoi",0xdcf; -"Thai_saraa",0xdd0; -"Thai_maihanakat",0xdd1; -"Thai_saraaa",0xdd2; -"Thai_saraam",0xdd3; -"Thai_sarai",0xdd4; -"Thai_saraii",0xdd5; -"Thai_saraue",0xdd6; -"Thai_sarauee",0xdd7; -"Thai_sarau",0xdd8; -"Thai_sarauu",0xdd9; -"Thai_phinthu",0xdda; -"Thai_maihanakat_maitho",0xdde; -"Thai_baht",0xddf; -"Thai_sarae",0xde0; -"Thai_saraae",0xde1; -"Thai_sarao",0xde2; -"Thai_saraaimaimuan",0xde3; -"Thai_saraaimaimalai",0xde4; -"Thai_lakkhangyao",0xde5; -"Thai_maiyamok",0xde6; -"Thai_maitaikhu",0xde7; -"Thai_maiek",0xde8; -"Thai_maitho",0xde9; -"Thai_maitri",0xdea; -"Thai_maichattawa",0xdeb; -"Thai_thanthakhat",0xdec; -"Thai_nikhahit",0xded; -"Thai_leksun",0xdf0; -"Thai_leknung",0xdf1; -"Thai_leksong",0xdf2; -"Thai_leksam",0xdf3; -"Thai_leksi",0xdf4; -"Thai_lekha",0xdf5; -"Thai_lekhok",0xdf6; -"Thai_lekchet",0xdf7; -"Thai_lekpaet",0xdf8; -"Thai_lekkao",0xdf9; -"Hangul",0xff31; -"Hangul_Start",0xff32; -"Hangul_End",0xff33; -"Hangul_Hanja",0xff34; -"Hangul_Jamo",0xff35; -"Hangul_Romaja",0xff36; -"Hangul_Codeinput",0xff37; -"Hangul_Jeonja",0xff38; -"Hangul_Banja",0xff39; -"Hangul_PreHanja",0xff3a; -"Hangul_PostHanja",0xff3b; -"Hangul_SingleCandidate",0xff3c; -"Hangul_MultipleCandidate",0xff3d; -"Hangul_PreviousCandidate",0xff3e; -"Hangul_Special",0xff3f; -"Hangul_switch",0xFF7E; -"Hangul_Kiyeog",0xea1; -"Hangul_SsangKiyeog",0xea2; -"Hangul_KiyeogSios",0xea3; -"Hangul_Nieun",0xea4; -"Hangul_NieunJieuj",0xea5; -"Hangul_NieunHieuh",0xea6; -"Hangul_Dikeud",0xea7; -"Hangul_SsangDikeud",0xea8; -"Hangul_Rieul",0xea9; -"Hangul_RieulKiyeog",0xeaa; -"Hangul_RieulMieum",0xeab; -"Hangul_RieulPieub",0xeac; -"Hangul_RieulSios",0xead; -"Hangul_RieulTieut",0xeae; -"Hangul_RieulPhieuf",0xeaf; -"Hangul_RieulHieuh",0xeb0; -"Hangul_Mieum",0xeb1; -"Hangul_Pieub",0xeb2; -"Hangul_SsangPieub",0xeb3; -"Hangul_PieubSios",0xeb4; -"Hangul_Sios",0xeb5; -"Hangul_SsangSios",0xeb6; -"Hangul_Ieung",0xeb7; -"Hangul_Jieuj",0xeb8; -"Hangul_SsangJieuj",0xeb9; -"Hangul_Cieuc",0xeba; -"Hangul_Khieuq",0xebb; -"Hangul_Tieut",0xebc; -"Hangul_Phieuf",0xebd; -"Hangul_Hieuh",0xebe; -"Hangul_A",0xebf; -"Hangul_AE",0xec0; -"Hangul_YA",0xec1; -"Hangul_YAE",0xec2; -"Hangul_EO",0xec3; -"Hangul_E",0xec4; -"Hangul_YEO",0xec5; -"Hangul_YE",0xec6; -"Hangul_O",0xec7; -"Hangul_WA",0xec8; -"Hangul_WAE",0xec9; -"Hangul_OE",0xeca; -"Hangul_YO",0xecb; -"Hangul_U",0xecc; -"Hangul_WEO",0xecd; -"Hangul_WE",0xece; -"Hangul_WI",0xecf; -"Hangul_YU",0xed0; -"Hangul_EU",0xed1; -"Hangul_YI",0xed2; -"Hangul_I",0xed3; -"Hangul_J_Kiyeog",0xed4; -"Hangul_J_SsangKiyeog",0xed5; -"Hangul_J_KiyeogSios",0xed6; -"Hangul_J_Nieun",0xed7; -"Hangul_J_NieunJieuj",0xed8; -"Hangul_J_NieunHieuh",0xed9; -"Hangul_J_Dikeud",0xeda; -"Hangul_J_Rieul",0xedb; -"Hangul_J_RieulKiyeog",0xedc; -"Hangul_J_RieulMieum",0xedd; -"Hangul_J_RieulPieub",0xede; -"Hangul_J_RieulSios",0xedf; -"Hangul_J_RieulTieut",0xee0; -"Hangul_J_RieulPhieuf",0xee1; -"Hangul_J_RieulHieuh",0xee2; -"Hangul_J_Mieum",0xee3; -"Hangul_J_Pieub",0xee4; -"Hangul_J_PieubSios",0xee5; -"Hangul_J_Sios",0xee6; -"Hangul_J_SsangSios",0xee7; -"Hangul_J_Ieung",0xee8; -"Hangul_J_Jieuj",0xee9; -"Hangul_J_Cieuc",0xeea; -"Hangul_J_Khieuq",0xeeb; -"Hangul_J_Tieut",0xeec; -"Hangul_J_Phieuf",0xeed; -"Hangul_J_Hieuh",0xeee; -"Hangul_RieulYeorinHieuh",0xeef; -"Hangul_SunkyeongeumMieum",0xef0; -"Hangul_SunkyeongeumPieub",0xef1; -"Hangul_PanSios",0xef2; -"Hangul_KkogjiDalrinIeung",0xef3; -"Hangul_SunkyeongeumPhieuf",0xef4; -"Hangul_YeorinHieuh",0xef5; -"Hangul_AraeA",0xef6; -"Hangul_AraeAE",0xef7; -"Hangul_J_PanSios",0xef8; -"Hangul_J_KkogjiDalrinIeung",0xef9; -"Hangul_J_YeorinHieuh",0xefa; -"Korean_Won",0xeff; -] -let keysym_to_name = [ -0xFFFFFF,"VoidSymbol"; -0xFF08,"BackSpace"; -0xFF09,"Tab"; -0xFF0A,"Linefeed"; -0xFF0B,"Clear"; -0xFF0D,"Return"; -0xFF13,"Pause"; -0xFF14,"Scroll_Lock"; -0xFF15,"Sys_Req"; -0xFF1B,"Escape"; -0xFFFF,"Delete"; -0xFF20,"Multi_key"; -0xFF21,"Kanji"; -0xFF22,"Muhenkan"; -0xFF23,"Henkan_Mode"; -0xFF23,"Henkan"; -0xFF24,"Romaji"; -0xFF25,"Hiragana"; -0xFF26,"Katakana"; -0xFF27,"Hiragana_Katakana"; -0xFF28,"Zenkaku"; -0xFF29,"Hankaku"; -0xFF2A,"Zenkaku_Hankaku"; -0xFF2B,"Touroku"; -0xFF2C,"Massyo"; -0xFF2D,"Kana_Lock"; -0xFF2E,"Kana_Shift"; -0xFF2F,"Eisu_Shift"; -0xFF30,"Eisu_toggle"; -0xFF50,"Home"; -0xFF51,"Left"; -0xFF52,"Up"; -0xFF53,"Right"; -0xFF54,"Down"; -0xFF55,"Prior"; -0xFF55,"Page_Up"; -0xFF56,"Next"; -0xFF56,"Page_Down"; -0xFF57,"End"; -0xFF58,"Begin"; -0xFF60,"Select"; -0xFF61,"Print"; -0xFF62,"Execute"; -0xFF63,"Insert"; -0xFF65,"Undo"; -0xFF66,"Redo"; -0xFF67,"Menu"; -0xFF68,"Find"; -0xFF69,"Cancel"; -0xFF6A,"Help"; -0xFF6B,"Break"; -0xFF7E,"Mode_switch"; -0xFF7E,"script_switch"; -0xFF7F,"Num_Lock"; -0xFF80,"KP_Space"; -0xFF89,"KP_Tab"; -0xFF8D,"KP_Enter"; -0xFF91,"KP_F1"; -0xFF92,"KP_F2"; -0xFF93,"KP_F3"; -0xFF94,"KP_F4"; -0xFF95,"KP_Home"; -0xFF96,"KP_Left"; -0xFF97,"KP_Up"; -0xFF98,"KP_Right"; -0xFF99,"KP_Down"; -0xFF9A,"KP_Prior"; -0xFF9A,"KP_Page_Up"; -0xFF9B,"KP_Next"; -0xFF9B,"KP_Page_Down"; -0xFF9C,"KP_End"; -0xFF9D,"KP_Begin"; -0xFF9E,"KP_Insert"; -0xFF9F,"KP_Delete"; -0xFFBD,"KP_Equal"; -0xFFAA,"KP_Multiply"; -0xFFAB,"KP_Add"; -0xFFAC,"KP_Separator"; -0xFFAD,"KP_Subtract"; -0xFFAE,"KP_Decimal"; -0xFFAF,"KP_Divide"; -0xFFB0,"KP_0"; -0xFFB1,"KP_1"; -0xFFB2,"KP_2"; -0xFFB3,"KP_3"; -0xFFB4,"KP_4"; -0xFFB5,"KP_5"; -0xFFB6,"KP_6"; -0xFFB7,"KP_7"; -0xFFB8,"KP_8"; -0xFFB9,"KP_9"; -0xFFBE,"F1"; -0xFFBF,"F2"; -0xFFC0,"F3"; -0xFFC1,"F4"; -0xFFC2,"F5"; -0xFFC3,"F6"; -0xFFC4,"F7"; -0xFFC5,"F8"; -0xFFC6,"F9"; -0xFFC7,"F10"; -0xFFC8,"F11"; -0xFFC8,"L1"; -0xFFC9,"F12"; -0xFFC9,"L2"; -0xFFCA,"F13"; -0xFFCA,"L3"; -0xFFCB,"F14"; -0xFFCB,"L4"; -0xFFCC,"F15"; -0xFFCC,"L5"; -0xFFCD,"F16"; -0xFFCD,"L6"; -0xFFCE,"F17"; -0xFFCE,"L7"; -0xFFCF,"F18"; -0xFFCF,"L8"; -0xFFD0,"F19"; -0xFFD0,"L9"; -0xFFD1,"F20"; -0xFFD1,"L10"; -0xFFD2,"F21"; -0xFFD2,"R1"; -0xFFD3,"F22"; -0xFFD3,"R2"; -0xFFD4,"F23"; -0xFFD4,"R3"; -0xFFD5,"F24"; -0xFFD5,"R4"; -0xFFD6,"F25"; -0xFFD6,"R5"; -0xFFD7,"F26"; -0xFFD7,"R6"; -0xFFD8,"F27"; -0xFFD8,"R7"; -0xFFD9,"F28"; -0xFFD9,"R8"; -0xFFDA,"F29"; -0xFFDA,"R9"; -0xFFDB,"F30"; -0xFFDB,"R10"; -0xFFDC,"F31"; -0xFFDC,"R11"; -0xFFDD,"F32"; -0xFFDD,"R12"; -0xFFDE,"F33"; -0xFFDE,"R13"; -0xFFDF,"F34"; -0xFFDF,"R14"; -0xFFE0,"F35"; -0xFFE0,"R15"; -0xFFE1,"Shift_L"; -0xFFE2,"Shift_R"; -0xFFE3,"Control_L"; -0xFFE4,"Control_R"; -0xFFE5,"Caps_Lock"; -0xFFE6,"Shift_Lock"; -0xFFE7,"Meta_L"; -0xFFE8,"Meta_R"; -0xFFE9,"Alt_L"; -0xFFEA,"Alt_R"; -0xFFEB,"Super_L"; -0xFFEC,"Super_R"; -0xFFED,"Hyper_L"; -0xFFEE,"Hyper_R"; -0xFE01,"ISO_Lock"; -0xFE02,"ISO_Level2_Latch"; -0xFE03,"ISO_Level3_Shift"; -0xFE04,"ISO_Level3_Latch"; -0xFE05,"ISO_Level3_Lock"; -0xFF7E,"ISO_Group_Shift"; -0xFE06,"ISO_Group_Latch"; -0xFE07,"ISO_Group_Lock"; -0xFE08,"ISO_Next_Group"; -0xFE09,"ISO_Next_Group_Lock"; -0xFE0A,"ISO_Prev_Group"; -0xFE0B,"ISO_Prev_Group_Lock"; -0xFE0C,"ISO_First_Group"; -0xFE0D,"ISO_First_Group_Lock"; -0xFE0E,"ISO_Last_Group"; -0xFE0F,"ISO_Last_Group_Lock"; -0xFE20,"ISO_Left_Tab"; -0xFE21,"ISO_Move_Line_Up"; -0xFE22,"ISO_Move_Line_Down"; -0xFE23,"ISO_Partial_Line_Up"; -0xFE24,"ISO_Partial_Line_Down"; -0xFE25,"ISO_Partial_Space_Left"; -0xFE26,"ISO_Partial_Space_Right"; -0xFE27,"ISO_Set_Margin_Left"; -0xFE28,"ISO_Set_Margin_Right"; -0xFE29,"ISO_Release_Margin_Left"; -0xFE2A,"ISO_Release_Margin_Right"; -0xFE2B,"ISO_Release_Both_Margins"; -0xFE2C,"ISO_Fast_Cursor_Left"; -0xFE2D,"ISO_Fast_Cursor_Right"; -0xFE2E,"ISO_Fast_Cursor_Up"; -0xFE2F,"ISO_Fast_Cursor_Down"; -0xFE30,"ISO_Continuous_Underline"; -0xFE31,"ISO_Discontinuous_Underline"; -0xFE32,"ISO_Emphasize"; -0xFE33,"ISO_Center_Object"; -0xFE34,"ISO_Enter"; -0xFE50,"dead_grave"; -0xFE51,"dead_acute"; -0xFE52,"dead_circumflex"; -0xFE53,"dead_tilde"; -0xFE54,"dead_macron"; -0xFE55,"dead_breve"; -0xFE56,"dead_abovedot"; -0xFE57,"dead_diaeresis"; -0xFE58,"dead_abovering"; -0xFE59,"dead_doubleacute"; -0xFE5A,"dead_caron"; -0xFE5B,"dead_cedilla"; -0xFE5C,"dead_ogonek"; -0xFE5D,"dead_iota"; -0xFE5E,"dead_voiced_sound"; -0xFE5F,"dead_semivoiced_sound"; -0xFE60,"dead_belowdot"; -0xFED0,"First_Virtual_Screen"; -0xFED1,"Prev_Virtual_Screen"; -0xFED2,"Next_Virtual_Screen"; -0xFED4,"Last_Virtual_Screen"; -0xFED5,"Terminate_Server"; -0xFE70,"AccessX_Enable"; -0xFE71,"AccessX_Feedback_Enable"; -0xFE72,"RepeatKeys_Enable"; -0xFE73,"SlowKeys_Enable"; -0xFE74,"BounceKeys_Enable"; -0xFE75,"StickyKeys_Enable"; -0xFE76,"MouseKeys_Enable"; -0xFE77,"MouseKeys_Accel_Enable"; -0xFE78,"Overlay1_Enable"; -0xFE79,"Overlay2_Enable"; -0xFE7A,"AudibleBell_Enable"; -0xFEE0,"Pointer_Left"; -0xFEE1,"Pointer_Right"; -0xFEE2,"Pointer_Up"; -0xFEE3,"Pointer_Down"; -0xFEE4,"Pointer_UpLeft"; -0xFEE5,"Pointer_UpRight"; -0xFEE6,"Pointer_DownLeft"; -0xFEE7,"Pointer_DownRight"; -0xFEE8,"Pointer_Button_Dflt"; -0xFEE9,"Pointer_Button1"; -0xFEEA,"Pointer_Button2"; -0xFEEB,"Pointer_Button3"; -0xFEEC,"Pointer_Button4"; -0xFEED,"Pointer_Button5"; -0xFEEE,"Pointer_DblClick_Dflt"; -0xFEEF,"Pointer_DblClick1"; -0xFEF0,"Pointer_DblClick2"; -0xFEF1,"Pointer_DblClick3"; -0xFEF2,"Pointer_DblClick4"; -0xFEF3,"Pointer_DblClick5"; -0xFEF4,"Pointer_Drag_Dflt"; -0xFEF5,"Pointer_Drag1"; -0xFEF6,"Pointer_Drag2"; -0xFEF7,"Pointer_Drag3"; -0xFEF8,"Pointer_Drag4"; -0xFEFD,"Pointer_Drag5"; -0xFEF9,"Pointer_EnableKeys"; -0xFEFA,"Pointer_Accelerate"; -0xFEFB,"Pointer_DfltBtnNext"; -0xFEFC,"Pointer_DfltBtnPrev"; -0xFD01,"3270_Duplicate"; -0xFD02,"3270_FieldMark"; -0xFD03,"3270_Right2"; -0xFD04,"3270_Left2"; -0xFD05,"3270_BackTab"; -0xFD06,"3270_EraseEOF"; -0xFD07,"3270_EraseInput"; -0xFD08,"3270_Reset"; -0xFD09,"3270_Quit"; -0xFD0A,"3270_PA1"; -0xFD0B,"3270_PA2"; -0xFD0C,"3270_PA3"; -0xFD0D,"3270_Test"; -0xFD0E,"3270_Attn"; -0xFD0F,"3270_CursorBlink"; -0xFD10,"3270_AltCursor"; -0xFD11,"3270_KeyClick"; -0xFD12,"3270_Jump"; -0xFD13,"3270_Ident"; -0xFD14,"3270_Rule"; -0xFD15,"3270_Copy"; -0xFD16,"3270_Play"; -0xFD17,"3270_Setup"; -0xFD18,"3270_Record"; -0xFD19,"3270_ChangeScreen"; -0xFD1A,"3270_DeleteWord"; -0xFD1B,"3270_ExSelect"; -0xFD1C,"3270_CursorSelect"; -0xFD1D,"3270_PrintScreen"; -0xFD1E,"3270_Enter"; -0x020,"space"; -0x021,"exclam"; -0x022,"quotedbl"; -0x023,"numbersign"; -0x024,"dollar"; -0x025,"percent"; -0x026,"ampersand"; -0x027,"apostrophe"; -0x027,"quoteright"; -0x028,"parenleft"; -0x029,"parenright"; -0x02a,"asterisk"; -0x02b,"plus"; -0x02c,"comma"; -0x02d,"minus"; -0x02e,"period"; -0x02f,"slash"; -0x030,"0"; -0x031,"1"; -0x032,"2"; -0x033,"3"; -0x034,"4"; -0x035,"5"; -0x036,"6"; -0x037,"7"; -0x038,"8"; -0x039,"9"; -0x03a,"colon"; -0x03b,"semicolon"; -0x03c,"less"; -0x03d,"equal"; -0x03e,"greater"; -0x03f,"question"; -0x040,"at"; -0x041,"A"; -0x042,"B"; -0x043,"C"; -0x044,"D"; -0x045,"E"; -0x046,"F"; -0x047,"G"; -0x048,"H"; -0x049,"I"; -0x04a,"J"; -0x04b,"K"; -0x04c,"L"; -0x04d,"M"; -0x04e,"N"; -0x04f,"O"; -0x050,"P"; -0x051,"Q"; -0x052,"R"; -0x053,"S"; -0x054,"T"; -0x055,"U"; -0x056,"V"; -0x057,"W"; -0x058,"X"; -0x059,"Y"; -0x05a,"Z"; -0x05b,"bracketleft"; -0x05c,"backslash"; -0x05d,"bracketright"; -0x05e,"asciicircum"; -0x05f,"underscore"; -0x060,"grave"; -0x060,"quoteleft"; -0x061,"a"; -0x062,"b"; -0x063,"c"; -0x064,"d"; -0x065,"e"; -0x066,"f"; -0x067,"g"; -0x068,"h"; -0x069,"i"; -0x06a,"j"; -0x06b,"k"; -0x06c,"l"; -0x06d,"m"; -0x06e,"n"; -0x06f,"o"; -0x070,"p"; -0x071,"q"; -0x072,"r"; -0x073,"s"; -0x074,"t"; -0x075,"u"; -0x076,"v"; -0x077,"w"; -0x078,"x"; -0x079,"y"; -0x07a,"z"; -0x07b,"braceleft"; -0x07c,"bar"; -0x07d,"braceright"; -0x07e,"asciitilde"; -0x0a0,"nobreakspace"; -0x0a1,"exclamdown"; -0x0a2,"cent"; -0x0a3,"sterling"; -0x0a4,"currency"; -0x0a5,"yen"; -0x0a6,"brokenbar"; -0x0a7,"section"; -0x0a8,"diaeresis"; -0x0a9,"copyright"; -0x0aa,"ordfeminine"; -0x0ab,"guillemotleft"; -0x0ac,"notsign"; -0x0ad,"hyphen"; -0x0ae,"registered"; -0x0af,"macron"; -0x0b0,"degree"; -0x0b1,"plusminus"; -0x0b2,"twosuperior"; -0x0b3,"threesuperior"; -0x0b4,"acute"; -0x0b5,"mu"; -0x0b6,"paragraph"; -0x0b7,"periodcentered"; -0x0b8,"cedilla"; -0x0b9,"onesuperior"; -0x0ba,"masculine"; -0x0bb,"guillemotright"; -0x0bc,"onequarter"; -0x0bd,"onehalf"; -0x0be,"threequarters"; -0x0bf,"questiondown"; -0x0c0,"Agrave"; -0x0c1,"Aacute"; -0x0c2,"Acircumflex"; -0x0c3,"Atilde"; -0x0c4,"Adiaeresis"; -0x0c5,"Aring"; -0x0c6,"AE"; -0x0c7,"Ccedilla"; -0x0c8,"Egrave"; -0x0c9,"Eacute"; -0x0ca,"Ecircumflex"; -0x0cb,"Ediaeresis"; -0x0cc,"Igrave"; -0x0cd,"Iacute"; -0x0ce,"Icircumflex"; -0x0cf,"Idiaeresis"; -0x0d0,"ETH"; -0x0d0,"Eth"; -0x0d1,"Ntilde"; -0x0d2,"Ograve"; -0x0d3,"Oacute"; -0x0d4,"Ocircumflex"; -0x0d5,"Otilde"; -0x0d6,"Odiaeresis"; -0x0d7,"multiply"; -0x0d8,"Ooblique"; -0x0d9,"Ugrave"; -0x0da,"Uacute"; -0x0db,"Ucircumflex"; -0x0dc,"Udiaeresis"; -0x0dd,"Yacute"; -0x0de,"THORN"; -0x0de,"Thorn"; -0x0df,"ssharp"; -0x0e0,"agrave"; -0x0e1,"aacute"; -0x0e2,"acircumflex"; -0x0e3,"atilde"; -0x0e4,"adiaeresis"; -0x0e5,"aring"; -0x0e6,"ae"; -0x0e7,"ccedilla"; -0x0e8,"egrave"; -0x0e9,"eacute"; -0x0ea,"ecircumflex"; -0x0eb,"ediaeresis"; -0x0ec,"igrave"; -0x0ed,"iacute"; -0x0ee,"icircumflex"; -0x0ef,"idiaeresis"; -0x0f0,"eth"; -0x0f1,"ntilde"; -0x0f2,"ograve"; -0x0f3,"oacute"; -0x0f4,"ocircumflex"; -0x0f5,"otilde"; -0x0f6,"odiaeresis"; -0x0f7,"division"; -0x0f8,"oslash"; -0x0f9,"ugrave"; -0x0fa,"uacute"; -0x0fb,"ucircumflex"; -0x0fc,"udiaeresis"; -0x0fd,"yacute"; -0x0fe,"thorn"; -0x0ff,"ydiaeresis"; -0x1a1,"Aogonek"; -0x1a2,"breve"; -0x1a3,"Lstroke"; -0x1a5,"Lcaron"; -0x1a6,"Sacute"; -0x1a9,"Scaron"; -0x1aa,"Scedilla"; -0x1ab,"Tcaron"; -0x1ac,"Zacute"; -0x1ae,"Zcaron"; -0x1af,"Zabovedot"; -0x1b1,"aogonek"; -0x1b2,"ogonek"; -0x1b3,"lstroke"; -0x1b5,"lcaron"; -0x1b6,"sacute"; -0x1b7,"caron"; -0x1b9,"scaron"; -0x1ba,"scedilla"; -0x1bb,"tcaron"; -0x1bc,"zacute"; -0x1bd,"doubleacute"; -0x1be,"zcaron"; -0x1bf,"zabovedot"; -0x1c0,"Racute"; -0x1c3,"Abreve"; -0x1c5,"Lacute"; -0x1c6,"Cacute"; -0x1c8,"Ccaron"; -0x1ca,"Eogonek"; -0x1cc,"Ecaron"; -0x1cf,"Dcaron"; -0x1d0,"Dstroke"; -0x1d1,"Nacute"; -0x1d2,"Ncaron"; -0x1d5,"Odoubleacute"; -0x1d8,"Rcaron"; -0x1d9,"Uring"; -0x1db,"Udoubleacute"; -0x1de,"Tcedilla"; -0x1e0,"racute"; -0x1e3,"abreve"; -0x1e5,"lacute"; -0x1e6,"cacute"; -0x1e8,"ccaron"; -0x1ea,"eogonek"; -0x1ec,"ecaron"; -0x1ef,"dcaron"; -0x1f0,"dstroke"; -0x1f1,"nacute"; -0x1f2,"ncaron"; -0x1f5,"odoubleacute"; -0x1fb,"udoubleacute"; -0x1f8,"rcaron"; -0x1f9,"uring"; -0x1fe,"tcedilla"; -0x1ff,"abovedot"; -0x2a1,"Hstroke"; -0x2a6,"Hcircumflex"; -0x2a9,"Iabovedot"; -0x2ab,"Gbreve"; -0x2ac,"Jcircumflex"; -0x2b1,"hstroke"; -0x2b6,"hcircumflex"; -0x2b9,"idotless"; -0x2bb,"gbreve"; -0x2bc,"jcircumflex"; -0x2c5,"Cabovedot"; -0x2c6,"Ccircumflex"; -0x2d5,"Gabovedot"; -0x2d8,"Gcircumflex"; -0x2dd,"Ubreve"; -0x2de,"Scircumflex"; -0x2e5,"cabovedot"; -0x2e6,"ccircumflex"; -0x2f5,"gabovedot"; -0x2f8,"gcircumflex"; -0x2fd,"ubreve"; -0x2fe,"scircumflex"; -0x3a2,"kra"; -0x3a2,"kappa"; -0x3a3,"Rcedilla"; -0x3a5,"Itilde"; -0x3a6,"Lcedilla"; -0x3aa,"Emacron"; -0x3ab,"Gcedilla"; -0x3ac,"Tslash"; -0x3b3,"rcedilla"; -0x3b5,"itilde"; -0x3b6,"lcedilla"; -0x3ba,"emacron"; -0x3bb,"gcedilla"; -0x3bc,"tslash"; -0x3bd,"ENG"; -0x3bf,"eng"; -0x3c0,"Amacron"; -0x3c7,"Iogonek"; -0x3cc,"Eabovedot"; -0x3cf,"Imacron"; -0x3d1,"Ncedilla"; -0x3d2,"Omacron"; -0x3d3,"Kcedilla"; -0x3d9,"Uogonek"; -0x3dd,"Utilde"; -0x3de,"Umacron"; -0x3e0,"amacron"; -0x3e7,"iogonek"; -0x3ec,"eabovedot"; -0x3ef,"imacron"; -0x3f1,"ncedilla"; -0x3f2,"omacron"; -0x3f3,"kcedilla"; -0x3f9,"uogonek"; -0x3fd,"utilde"; -0x3fe,"umacron"; -0x47e,"overline"; -0x4a1,"kana_fullstop"; -0x4a2,"kana_openingbracket"; -0x4a3,"kana_closingbracket"; -0x4a4,"kana_comma"; -0x4a5,"kana_conjunctive"; -0x4a5,"kana_middledot"; -0x4a6,"kana_WO"; -0x4a7,"kana_a"; -0x4a8,"kana_i"; -0x4a9,"kana_u"; -0x4aa,"kana_e"; -0x4ab,"kana_o"; -0x4ac,"kana_ya"; -0x4ad,"kana_yu"; -0x4ae,"kana_yo"; -0x4af,"kana_tsu"; -0x4af,"kana_tu"; -0x4b0,"prolongedsound"; -0x4b1,"kana_A"; -0x4b2,"kana_I"; -0x4b3,"kana_U"; -0x4b4,"kana_E"; -0x4b5,"kana_O"; -0x4b6,"kana_KA"; -0x4b7,"kana_KI"; -0x4b8,"kana_KU"; -0x4b9,"kana_KE"; -0x4ba,"kana_KO"; -0x4bb,"kana_SA"; -0x4bc,"kana_SHI"; -0x4bd,"kana_SU"; -0x4be,"kana_SE"; -0x4bf,"kana_SO"; -0x4c0,"kana_TA"; -0x4c1,"kana_CHI"; -0x4c1,"kana_TI"; -0x4c2,"kana_TSU"; -0x4c2,"kana_TU"; -0x4c3,"kana_TE"; -0x4c4,"kana_TO"; -0x4c5,"kana_NA"; -0x4c6,"kana_NI"; -0x4c7,"kana_NU"; -0x4c8,"kana_NE"; -0x4c9,"kana_NO"; -0x4ca,"kana_HA"; -0x4cb,"kana_HI"; -0x4cc,"kana_FU"; -0x4cc,"kana_HU"; -0x4cd,"kana_HE"; -0x4ce,"kana_HO"; -0x4cf,"kana_MA"; -0x4d0,"kana_MI"; -0x4d1,"kana_MU"; -0x4d2,"kana_ME"; -0x4d3,"kana_MO"; -0x4d4,"kana_YA"; -0x4d5,"kana_YU"; -0x4d6,"kana_YO"; -0x4d7,"kana_RA"; -0x4d8,"kana_RI"; -0x4d9,"kana_RU"; -0x4da,"kana_RE"; -0x4db,"kana_RO"; -0x4dc,"kana_WA"; -0x4dd,"kana_N"; -0x4de,"voicedsound"; -0x4df,"semivoicedsound"; -0xFF7E,"kana_switch"; -0x5ac,"Arabic_comma"; -0x5bb,"Arabic_semicolon"; -0x5bf,"Arabic_question_mark"; -0x5c1,"Arabic_hamza"; -0x5c2,"Arabic_maddaonalef"; -0x5c3,"Arabic_hamzaonalef"; -0x5c4,"Arabic_hamzaonwaw"; -0x5c5,"Arabic_hamzaunderalef"; -0x5c6,"Arabic_hamzaonyeh"; -0x5c7,"Arabic_alef"; -0x5c8,"Arabic_beh"; -0x5c9,"Arabic_tehmarbuta"; -0x5ca,"Arabic_teh"; -0x5cb,"Arabic_theh"; -0x5cc,"Arabic_jeem"; -0x5cd,"Arabic_hah"; -0x5ce,"Arabic_khah"; -0x5cf,"Arabic_dal"; -0x5d0,"Arabic_thal"; -0x5d1,"Arabic_ra"; -0x5d2,"Arabic_zain"; -0x5d3,"Arabic_seen"; -0x5d4,"Arabic_sheen"; -0x5d5,"Arabic_sad"; -0x5d6,"Arabic_dad"; -0x5d7,"Arabic_tah"; -0x5d8,"Arabic_zah"; -0x5d9,"Arabic_ain"; -0x5da,"Arabic_ghain"; -0x5e0,"Arabic_tatweel"; -0x5e1,"Arabic_feh"; -0x5e2,"Arabic_qaf"; -0x5e3,"Arabic_kaf"; -0x5e4,"Arabic_lam"; -0x5e5,"Arabic_meem"; -0x5e6,"Arabic_noon"; -0x5e7,"Arabic_ha"; -0x5e7,"Arabic_heh"; -0x5e8,"Arabic_waw"; -0x5e9,"Arabic_alefmaksura"; -0x5ea,"Arabic_yeh"; -0x5eb,"Arabic_fathatan"; -0x5ec,"Arabic_dammatan"; -0x5ed,"Arabic_kasratan"; -0x5ee,"Arabic_fatha"; -0x5ef,"Arabic_damma"; -0x5f0,"Arabic_kasra"; -0x5f1,"Arabic_shadda"; -0x5f2,"Arabic_sukun"; -0xFF7E,"Arabic_switch"; -0x6a1,"Serbian_dje"; -0x6a2,"Macedonia_gje"; -0x6a3,"Cyrillic_io"; -0x6a4,"Ukrainian_ie"; -0x6a4,"Ukranian_je"; -0x6a5,"Macedonia_dse"; -0x6a6,"Ukrainian_i"; -0x6a6,"Ukranian_i"; -0x6a7,"Ukrainian_yi"; -0x6a7,"Ukranian_yi"; -0x6a8,"Cyrillic_je"; -0x6a8,"Serbian_je"; -0x6a9,"Cyrillic_lje"; -0x6a9,"Serbian_lje"; -0x6aa,"Cyrillic_nje"; -0x6aa,"Serbian_nje"; -0x6ab,"Serbian_tshe"; -0x6ac,"Macedonia_kje"; -0x6ae,"Byelorussian_shortu"; -0x6af,"Cyrillic_dzhe"; -0x6af,"Serbian_dze"; -0x6b0,"numerosign"; -0x6b1,"Serbian_DJE"; -0x6b2,"Macedonia_GJE"; -0x6b3,"Cyrillic_IO"; -0x6b4,"Ukrainian_IE"; -0x6b4,"Ukranian_JE"; -0x6b5,"Macedonia_DSE"; -0x6b6,"Ukrainian_I"; -0x6b6,"Ukranian_I"; -0x6b7,"Ukrainian_YI"; -0x6b7,"Ukranian_YI"; -0x6b8,"Cyrillic_JE"; -0x6b8,"Serbian_JE"; -0x6b9,"Cyrillic_LJE"; -0x6b9,"Serbian_LJE"; -0x6ba,"Cyrillic_NJE"; -0x6ba,"Serbian_NJE"; -0x6bb,"Serbian_TSHE"; -0x6bc,"Macedonia_KJE"; -0x6be,"Byelorussian_SHORTU"; -0x6bf,"Cyrillic_DZHE"; -0x6bf,"Serbian_DZE"; -0x6c0,"Cyrillic_yu"; -0x6c1,"Cyrillic_a"; -0x6c2,"Cyrillic_be"; -0x6c3,"Cyrillic_tse"; -0x6c4,"Cyrillic_de"; -0x6c5,"Cyrillic_ie"; -0x6c6,"Cyrillic_ef"; -0x6c7,"Cyrillic_ghe"; -0x6c8,"Cyrillic_ha"; -0x6c9,"Cyrillic_i"; -0x6ca,"Cyrillic_shorti"; -0x6cb,"Cyrillic_ka"; -0x6cc,"Cyrillic_el"; -0x6cd,"Cyrillic_em"; -0x6ce,"Cyrillic_en"; -0x6cf,"Cyrillic_o"; -0x6d0,"Cyrillic_pe"; -0x6d1,"Cyrillic_ya"; -0x6d2,"Cyrillic_er"; -0x6d3,"Cyrillic_es"; -0x6d4,"Cyrillic_te"; -0x6d5,"Cyrillic_u"; -0x6d6,"Cyrillic_zhe"; -0x6d7,"Cyrillic_ve"; -0x6d8,"Cyrillic_softsign"; -0x6d9,"Cyrillic_yeru"; -0x6da,"Cyrillic_ze"; -0x6db,"Cyrillic_sha"; -0x6dc,"Cyrillic_e"; -0x6dd,"Cyrillic_shcha"; -0x6de,"Cyrillic_che"; -0x6df,"Cyrillic_hardsign"; -0x6e0,"Cyrillic_YU"; -0x6e1,"Cyrillic_A"; -0x6e2,"Cyrillic_BE"; -0x6e3,"Cyrillic_TSE"; -0x6e4,"Cyrillic_DE"; -0x6e5,"Cyrillic_IE"; -0x6e6,"Cyrillic_EF"; -0x6e7,"Cyrillic_GHE"; -0x6e8,"Cyrillic_HA"; -0x6e9,"Cyrillic_I"; -0x6ea,"Cyrillic_SHORTI"; -0x6eb,"Cyrillic_KA"; -0x6ec,"Cyrillic_EL"; -0x6ed,"Cyrillic_EM"; -0x6ee,"Cyrillic_EN"; -0x6ef,"Cyrillic_O"; -0x6f0,"Cyrillic_PE"; -0x6f1,"Cyrillic_YA"; -0x6f2,"Cyrillic_ER"; -0x6f3,"Cyrillic_ES"; -0x6f4,"Cyrillic_TE"; -0x6f5,"Cyrillic_U"; -0x6f6,"Cyrillic_ZHE"; -0x6f7,"Cyrillic_VE"; -0x6f8,"Cyrillic_SOFTSIGN"; -0x6f9,"Cyrillic_YERU"; -0x6fa,"Cyrillic_ZE"; -0x6fb,"Cyrillic_SHA"; -0x6fc,"Cyrillic_E"; -0x6fd,"Cyrillic_SHCHA"; -0x6fe,"Cyrillic_CHE"; -0x6ff,"Cyrillic_HARDSIGN"; -0x7a1,"Greek_ALPHAaccent"; -0x7a2,"Greek_EPSILONaccent"; -0x7a3,"Greek_ETAaccent"; -0x7a4,"Greek_IOTAaccent"; -0x7a5,"Greek_IOTAdiaeresis"; -0x7a7,"Greek_OMICRONaccent"; -0x7a8,"Greek_UPSILONaccent"; -0x7a9,"Greek_UPSILONdieresis"; -0x7ab,"Greek_OMEGAaccent"; -0x7ae,"Greek_accentdieresis"; -0x7af,"Greek_horizbar"; -0x7b1,"Greek_alphaaccent"; -0x7b2,"Greek_epsilonaccent"; -0x7b3,"Greek_etaaccent"; -0x7b4,"Greek_iotaaccent"; -0x7b5,"Greek_iotadieresis"; -0x7b6,"Greek_iotaaccentdieresis"; -0x7b7,"Greek_omicronaccent"; -0x7b8,"Greek_upsilonaccent"; -0x7b9,"Greek_upsilondieresis"; -0x7ba,"Greek_upsilonaccentdieresis"; -0x7bb,"Greek_omegaaccent"; -0x7c1,"Greek_ALPHA"; -0x7c2,"Greek_BETA"; -0x7c3,"Greek_GAMMA"; -0x7c4,"Greek_DELTA"; -0x7c5,"Greek_EPSILON"; -0x7c6,"Greek_ZETA"; -0x7c7,"Greek_ETA"; -0x7c8,"Greek_THETA"; -0x7c9,"Greek_IOTA"; -0x7ca,"Greek_KAPPA"; -0x7cb,"Greek_LAMDA"; -0x7cb,"Greek_LAMBDA"; -0x7cc,"Greek_MU"; -0x7cd,"Greek_NU"; -0x7ce,"Greek_XI"; -0x7cf,"Greek_OMICRON"; -0x7d0,"Greek_PI"; -0x7d1,"Greek_RHO"; -0x7d2,"Greek_SIGMA"; -0x7d4,"Greek_TAU"; -0x7d5,"Greek_UPSILON"; -0x7d6,"Greek_PHI"; -0x7d7,"Greek_CHI"; -0x7d8,"Greek_PSI"; -0x7d9,"Greek_OMEGA"; -0x7e1,"Greek_alpha"; -0x7e2,"Greek_beta"; -0x7e3,"Greek_gamma"; -0x7e4,"Greek_delta"; -0x7e5,"Greek_epsilon"; -0x7e6,"Greek_zeta"; -0x7e7,"Greek_eta"; -0x7e8,"Greek_theta"; -0x7e9,"Greek_iota"; -0x7ea,"Greek_kappa"; -0x7eb,"Greek_lamda"; -0x7eb,"Greek_lambda"; -0x7ec,"Greek_mu"; -0x7ed,"Greek_nu"; -0x7ee,"Greek_xi"; -0x7ef,"Greek_omicron"; -0x7f0,"Greek_pi"; -0x7f1,"Greek_rho"; -0x7f2,"Greek_sigma"; -0x7f3,"Greek_finalsmallsigma"; -0x7f4,"Greek_tau"; -0x7f5,"Greek_upsilon"; -0x7f6,"Greek_phi"; -0x7f7,"Greek_chi"; -0x7f8,"Greek_psi"; -0x7f9,"Greek_omega"; -0xFF7E,"Greek_switch"; -0x8a1,"leftradical"; -0x8a2,"topleftradical"; -0x8a3,"horizconnector"; -0x8a4,"topintegral"; -0x8a5,"botintegral"; -0x8a6,"vertconnector"; -0x8a7,"topleftsqbracket"; -0x8a8,"botleftsqbracket"; -0x8a9,"toprightsqbracket"; -0x8aa,"botrightsqbracket"; -0x8ab,"topleftparens"; -0x8ac,"botleftparens"; -0x8ad,"toprightparens"; -0x8ae,"botrightparens"; -0x8af,"leftmiddlecurlybrace"; -0x8b0,"rightmiddlecurlybrace"; -0x8b1,"topleftsummation"; -0x8b2,"botleftsummation"; -0x8b3,"topvertsummationconnector"; -0x8b4,"botvertsummationconnector"; -0x8b5,"toprightsummation"; -0x8b6,"botrightsummation"; -0x8b7,"rightmiddlesummation"; -0x8bc,"lessthanequal"; -0x8bd,"notequal"; -0x8be,"greaterthanequal"; -0x8bf,"integral"; -0x8c0,"therefore"; -0x8c1,"variation"; -0x8c2,"infinity"; -0x8c5,"nabla"; -0x8c8,"approximate"; -0x8c9,"similarequal"; -0x8cd,"ifonlyif"; -0x8ce,"implies"; -0x8cf,"identical"; -0x8d6,"radical"; -0x8da,"includedin"; -0x8db,"includes"; -0x8dc,"intersection"; -0x8dd,"union"; -0x8de,"logicaland"; -0x8df,"logicalor"; -0x8ef,"partialderivative"; -0x8f6,"function"; -0x8fb,"leftarrow"; -0x8fc,"uparrow"; -0x8fd,"rightarrow"; -0x8fe,"downarrow"; -0x9df,"blank"; -0x9e0,"soliddiamond"; -0x9e1,"checkerboard"; -0x9e2,"ht"; -0x9e3,"ff"; -0x9e4,"cr"; -0x9e5,"lf"; -0x9e8,"nl"; -0x9e9,"vt"; -0x9ea,"lowrightcorner"; -0x9eb,"uprightcorner"; -0x9ec,"upleftcorner"; -0x9ed,"lowleftcorner"; -0x9ee,"crossinglines"; -0x9ef,"horizlinescan1"; -0x9f0,"horizlinescan3"; -0x9f1,"horizlinescan5"; -0x9f2,"horizlinescan7"; -0x9f3,"horizlinescan9"; -0x9f4,"leftt"; -0x9f5,"rightt"; -0x9f6,"bott"; -0x9f7,"topt"; -0x9f8,"vertbar"; -0xaa1,"emspace"; -0xaa2,"enspace"; -0xaa3,"em3space"; -0xaa4,"em4space"; -0xaa5,"digitspace"; -0xaa6,"punctspace"; -0xaa7,"thinspace"; -0xaa8,"hairspace"; -0xaa9,"emdash"; -0xaaa,"endash"; -0xaac,"signifblank"; -0xaae,"ellipsis"; -0xaaf,"doubbaselinedot"; -0xab0,"onethird"; -0xab1,"twothirds"; -0xab2,"onefifth"; -0xab3,"twofifths"; -0xab4,"threefifths"; -0xab5,"fourfifths"; -0xab6,"onesixth"; -0xab7,"fivesixths"; -0xab8,"careof"; -0xabb,"figdash"; -0xabc,"leftanglebracket"; -0xabd,"decimalpoint"; -0xabe,"rightanglebracket"; -0xabf,"marker"; -0xac3,"oneeighth"; -0xac4,"threeeighths"; -0xac5,"fiveeighths"; -0xac6,"seveneighths"; -0xac9,"trademark"; -0xaca,"signaturemark"; -0xacb,"trademarkincircle"; -0xacc,"leftopentriangle"; -0xacd,"rightopentriangle"; -0xace,"emopencircle"; -0xacf,"emopenrectangle"; -0xad0,"leftsinglequotemark"; -0xad1,"rightsinglequotemark"; -0xad2,"leftdoublequotemark"; -0xad3,"rightdoublequotemark"; -0xad4,"prescription"; -0xad6,"minutes"; -0xad7,"seconds"; -0xad9,"latincross"; -0xada,"hexagram"; -0xadb,"filledrectbullet"; -0xadc,"filledlefttribullet"; -0xadd,"filledrighttribullet"; -0xade,"emfilledcircle"; -0xadf,"emfilledrect"; -0xae0,"enopencircbullet"; -0xae1,"enopensquarebullet"; -0xae2,"openrectbullet"; -0xae3,"opentribulletup"; -0xae4,"opentribulletdown"; -0xae5,"openstar"; -0xae6,"enfilledcircbullet"; -0xae7,"enfilledsqbullet"; -0xae8,"filledtribulletup"; -0xae9,"filledtribulletdown"; -0xaea,"leftpointer"; -0xaeb,"rightpointer"; -0xaec,"club"; -0xaed,"diamond"; -0xaee,"heart"; -0xaf0,"maltesecross"; -0xaf1,"dagger"; -0xaf2,"doubledagger"; -0xaf3,"checkmark"; -0xaf4,"ballotcross"; -0xaf5,"musicalsharp"; -0xaf6,"musicalflat"; -0xaf7,"malesymbol"; -0xaf8,"femalesymbol"; -0xaf9,"telephone"; -0xafa,"telephonerecorder"; -0xafb,"phonographcopyright"; -0xafc,"caret"; -0xafd,"singlelowquotemark"; -0xafe,"doublelowquotemark"; -0xaff,"cursor"; -0xba3,"leftcaret"; -0xba6,"rightcaret"; -0xba8,"downcaret"; -0xba9,"upcaret"; -0xbc0,"overbar"; -0xbc2,"downtack"; -0xbc3,"upshoe"; -0xbc4,"downstile"; -0xbc6,"underbar"; -0xbca,"jot"; -0xbcc,"quad"; -0xbce,"uptack"; -0xbcf,"circle"; -0xbd3,"upstile"; -0xbd6,"downshoe"; -0xbd8,"rightshoe"; -0xbda,"leftshoe"; -0xbdc,"lefttack"; -0xbfc,"righttack"; -0xcdf,"hebrew_doublelowline"; -0xce0,"hebrew_aleph"; -0xce1,"hebrew_bet"; -0xce1,"hebrew_beth"; -0xce2,"hebrew_gimel"; -0xce2,"hebrew_gimmel"; -0xce3,"hebrew_dalet"; -0xce3,"hebrew_daleth"; -0xce4,"hebrew_he"; -0xce5,"hebrew_waw"; -0xce6,"hebrew_zain"; -0xce6,"hebrew_zayin"; -0xce7,"hebrew_chet"; -0xce7,"hebrew_het"; -0xce8,"hebrew_tet"; -0xce8,"hebrew_teth"; -0xce9,"hebrew_yod"; -0xcea,"hebrew_finalkaph"; -0xceb,"hebrew_kaph"; -0xcec,"hebrew_lamed"; -0xced,"hebrew_finalmem"; -0xcee,"hebrew_mem"; -0xcef,"hebrew_finalnun"; -0xcf0,"hebrew_nun"; -0xcf1,"hebrew_samech"; -0xcf1,"hebrew_samekh"; -0xcf2,"hebrew_ayin"; -0xcf3,"hebrew_finalpe"; -0xcf4,"hebrew_pe"; -0xcf5,"hebrew_finalzade"; -0xcf5,"hebrew_finalzadi"; -0xcf6,"hebrew_zade"; -0xcf6,"hebrew_zadi"; -0xcf7,"hebrew_qoph"; -0xcf7,"hebrew_kuf"; -0xcf8,"hebrew_resh"; -0xcf9,"hebrew_shin"; -0xcfa,"hebrew_taw"; -0xcfa,"hebrew_taf"; -0xFF7E,"Hebrew_switch"; -0xda1,"Thai_kokai"; -0xda2,"Thai_khokhai"; -0xda3,"Thai_khokhuat"; -0xda4,"Thai_khokhwai"; -0xda5,"Thai_khokhon"; -0xda6,"Thai_khorakhang"; -0xda7,"Thai_ngongu"; -0xda8,"Thai_chochan"; -0xda9,"Thai_choching"; -0xdaa,"Thai_chochang"; -0xdab,"Thai_soso"; -0xdac,"Thai_chochoe"; -0xdad,"Thai_yoying"; -0xdae,"Thai_dochada"; -0xdaf,"Thai_topatak"; -0xdb0,"Thai_thothan"; -0xdb1,"Thai_thonangmontho"; -0xdb2,"Thai_thophuthao"; -0xdb3,"Thai_nonen"; -0xdb4,"Thai_dodek"; -0xdb5,"Thai_totao"; -0xdb6,"Thai_thothung"; -0xdb7,"Thai_thothahan"; -0xdb8,"Thai_thothong"; -0xdb9,"Thai_nonu"; -0xdba,"Thai_bobaimai"; -0xdbb,"Thai_popla"; -0xdbc,"Thai_phophung"; -0xdbd,"Thai_fofa"; -0xdbe,"Thai_phophan"; -0xdbf,"Thai_fofan"; -0xdc0,"Thai_phosamphao"; -0xdc1,"Thai_moma"; -0xdc2,"Thai_yoyak"; -0xdc3,"Thai_rorua"; -0xdc4,"Thai_ru"; -0xdc5,"Thai_loling"; -0xdc6,"Thai_lu"; -0xdc7,"Thai_wowaen"; -0xdc8,"Thai_sosala"; -0xdc9,"Thai_sorusi"; -0xdca,"Thai_sosua"; -0xdcb,"Thai_hohip"; -0xdcc,"Thai_lochula"; -0xdcd,"Thai_oang"; -0xdce,"Thai_honokhuk"; -0xdcf,"Thai_paiyannoi"; -0xdd0,"Thai_saraa"; -0xdd1,"Thai_maihanakat"; -0xdd2,"Thai_saraaa"; -0xdd3,"Thai_saraam"; -0xdd4,"Thai_sarai"; -0xdd5,"Thai_saraii"; -0xdd6,"Thai_saraue"; -0xdd7,"Thai_sarauee"; -0xdd8,"Thai_sarau"; -0xdd9,"Thai_sarauu"; -0xdda,"Thai_phinthu"; -0xdde,"Thai_maihanakat_maitho"; -0xddf,"Thai_baht"; -0xde0,"Thai_sarae"; -0xde1,"Thai_saraae"; -0xde2,"Thai_sarao"; -0xde3,"Thai_saraaimaimuan"; -0xde4,"Thai_saraaimaimalai"; -0xde5,"Thai_lakkhangyao"; -0xde6,"Thai_maiyamok"; -0xde7,"Thai_maitaikhu"; -0xde8,"Thai_maiek"; -0xde9,"Thai_maitho"; -0xdea,"Thai_maitri"; -0xdeb,"Thai_maichattawa"; -0xdec,"Thai_thanthakhat"; -0xded,"Thai_nikhahit"; -0xdf0,"Thai_leksun"; -0xdf1,"Thai_leknung"; -0xdf2,"Thai_leksong"; -0xdf3,"Thai_leksam"; -0xdf4,"Thai_leksi"; -0xdf5,"Thai_lekha"; -0xdf6,"Thai_lekhok"; -0xdf7,"Thai_lekchet"; -0xdf8,"Thai_lekpaet"; -0xdf9,"Thai_lekkao"; -0xff31,"Hangul"; -0xff32,"Hangul_Start"; -0xff33,"Hangul_End"; -0xff34,"Hangul_Hanja"; -0xff35,"Hangul_Jamo"; -0xff36,"Hangul_Romaja"; -0xff37,"Hangul_Codeinput"; -0xff38,"Hangul_Jeonja"; -0xff39,"Hangul_Banja"; -0xff3a,"Hangul_PreHanja"; -0xff3b,"Hangul_PostHanja"; -0xff3c,"Hangul_SingleCandidate"; -0xff3d,"Hangul_MultipleCandidate"; -0xff3e,"Hangul_PreviousCandidate"; -0xff3f,"Hangul_Special"; -0xFF7E,"Hangul_switch"; -0xea1,"Hangul_Kiyeog"; -0xea2,"Hangul_SsangKiyeog"; -0xea3,"Hangul_KiyeogSios"; -0xea4,"Hangul_Nieun"; -0xea5,"Hangul_NieunJieuj"; -0xea6,"Hangul_NieunHieuh"; -0xea7,"Hangul_Dikeud"; -0xea8,"Hangul_SsangDikeud"; -0xea9,"Hangul_Rieul"; -0xeaa,"Hangul_RieulKiyeog"; -0xeab,"Hangul_RieulMieum"; -0xeac,"Hangul_RieulPieub"; -0xead,"Hangul_RieulSios"; -0xeae,"Hangul_RieulTieut"; -0xeaf,"Hangul_RieulPhieuf"; -0xeb0,"Hangul_RieulHieuh"; -0xeb1,"Hangul_Mieum"; -0xeb2,"Hangul_Pieub"; -0xeb3,"Hangul_SsangPieub"; -0xeb4,"Hangul_PieubSios"; -0xeb5,"Hangul_Sios"; -0xeb6,"Hangul_SsangSios"; -0xeb7,"Hangul_Ieung"; -0xeb8,"Hangul_Jieuj"; -0xeb9,"Hangul_SsangJieuj"; -0xeba,"Hangul_Cieuc"; -0xebb,"Hangul_Khieuq"; -0xebc,"Hangul_Tieut"; -0xebd,"Hangul_Phieuf"; -0xebe,"Hangul_Hieuh"; -0xebf,"Hangul_A"; -0xec0,"Hangul_AE"; -0xec1,"Hangul_YA"; -0xec2,"Hangul_YAE"; -0xec3,"Hangul_EO"; -0xec4,"Hangul_E"; -0xec5,"Hangul_YEO"; -0xec6,"Hangul_YE"; -0xec7,"Hangul_O"; -0xec8,"Hangul_WA"; -0xec9,"Hangul_WAE"; -0xeca,"Hangul_OE"; -0xecb,"Hangul_YO"; -0xecc,"Hangul_U"; -0xecd,"Hangul_WEO"; -0xece,"Hangul_WE"; -0xecf,"Hangul_WI"; -0xed0,"Hangul_YU"; -0xed1,"Hangul_EU"; -0xed2,"Hangul_YI"; -0xed3,"Hangul_I"; -0xed4,"Hangul_J_Kiyeog"; -0xed5,"Hangul_J_SsangKiyeog"; -0xed6,"Hangul_J_KiyeogSios"; -0xed7,"Hangul_J_Nieun"; -0xed8,"Hangul_J_NieunJieuj"; -0xed9,"Hangul_J_NieunHieuh"; -0xeda,"Hangul_J_Dikeud"; -0xedb,"Hangul_J_Rieul"; -0xedc,"Hangul_J_RieulKiyeog"; -0xedd,"Hangul_J_RieulMieum"; -0xede,"Hangul_J_RieulPieub"; -0xedf,"Hangul_J_RieulSios"; -0xee0,"Hangul_J_RieulTieut"; -0xee1,"Hangul_J_RieulPhieuf"; -0xee2,"Hangul_J_RieulHieuh"; -0xee3,"Hangul_J_Mieum"; -0xee4,"Hangul_J_Pieub"; -0xee5,"Hangul_J_PieubSios"; -0xee6,"Hangul_J_Sios"; -0xee7,"Hangul_J_SsangSios"; -0xee8,"Hangul_J_Ieung"; -0xee9,"Hangul_J_Jieuj"; -0xeea,"Hangul_J_Cieuc"; -0xeeb,"Hangul_J_Khieuq"; -0xeec,"Hangul_J_Tieut"; -0xeed,"Hangul_J_Phieuf"; -0xeee,"Hangul_J_Hieuh"; -0xeef,"Hangul_RieulYeorinHieuh"; -0xef0,"Hangul_SunkyeongeumMieum"; -0xef1,"Hangul_SunkyeongeumPieub"; -0xef2,"Hangul_PanSios"; -0xef3,"Hangul_KkogjiDalrinIeung"; -0xef4,"Hangul_SunkyeongeumPhieuf"; -0xef5,"Hangul_YeorinHieuh"; -0xef6,"Hangul_AraeA"; -0xef7,"Hangul_AraeAE"; -0xef8,"Hangul_J_PanSios"; -0xef9,"Hangul_J_KkogjiDalrinIeung"; -0xefa,"Hangul_J_YeorinHieuh"; -0xeff,"Korean_Won"; -] diff --git a/ide/utils/configwin_types.ml b/ide/utils/configwin_types.mli index ace751c6..9e339d13 100644 --- a/ide/utils/configwin_types.ml +++ b/ide/utils/configwin_types.mli @@ -25,113 +25,6 @@ (** This module contains the types used in Configwin. *) -open Config_file - -let name_to_keysym = - ("Button1", Configwin_keys.xk_Pointer_Button1) :: - ("Button2", Configwin_keys.xk_Pointer_Button2) :: - ("Button3", Configwin_keys.xk_Pointer_Button3) :: - ("Button4", Configwin_keys.xk_Pointer_Button4) :: - ("Button5", Configwin_keys.xk_Pointer_Button5) :: - Configwin_keys.name_to_keysym - -let string_to_key s = - let mask = ref [] in - let key = try - let pos = String.rindex s '-' in - for i = 0 to pos - 1 do - let m = match s.[i] with - 'C' -> `CONTROL - | 'S' -> `SHIFT - | 'L' -> `LOCK - | 'M' -> `MOD1 - | 'A' -> `MOD1 - | '1' -> `MOD1 - | '2' -> `MOD2 - | '3' -> `MOD3 - | '4' -> `MOD4 - | '5' -> `MOD5 - | _ -> - Minilib.log s; - raise Not_found - in - mask := m :: !mask - done; - String.sub s (pos+1) (String.length s - pos - 1) - with _ -> - s - in - try - !mask, List.assoc key name_to_keysym - with - e -> - Minilib.log s; - raise e - -let key_to_string (m, k) = - let s = List.assoc k Configwin_keys.keysym_to_name in - match m with - [] -> s - | _ -> - let rec iter m s = - match m with - [] -> s - | c :: m -> - iter m (( - match c with - `CONTROL -> "C" - | `SHIFT -> "S" - | `LOCK -> "L" - | `MOD1 -> "A" - | `MOD2 -> "2" - | `MOD3 -> "3" - | `MOD4 -> "4" - | `MOD5 -> "5" - | _ -> raise Not_found - ) ^ s) - in - iter m ("-" ^ s) - -let modifiers_to_string m = - let rec iter m s = - match m with - [] -> s - | c :: m -> - iter m (( - match c with - `CONTROL -> "<ctrl>" - | `SHIFT -> "<shft>" - | `LOCK -> "<lock>" - | `MOD1 -> "<alt>" - | `MOD2 -> "<mod2>" - | `MOD3 -> "<mod3>" - | `MOD4 -> "<mod4>" - | `MOD5 -> "<mod5>" - | _ -> raise Not_found - ) ^ s) - in - iter m "" - -let value_to_key v = - match v with - Raw.String s -> string_to_key s - | _ -> - Minilib.log "value_to_key"; - raise Not_found - -let key_to_value k = - Raw.String (key_to_string k) - -let key_cp_wrapper = - { - to_raw = key_to_value ; - of_raw = value_to_key ; - } - -(** A class to define key options, with the {!Config_file} module. *) -class key_cp = - [(Gdk.Tags.modifier list * int)] Config_file.cp_custom_type key_cp_wrapper - (** This type represents a string or filename parameter, or any other type, depending on the given conversion functions. *) type 'a string_param = { @@ -188,49 +81,6 @@ type custom_param = { custom_framed : string option ; (** optional label for an optional frame *) } ;; -type color_param = { - color_label : string; (** the label of the parameter *) - mutable color_value : string; (** the current value of the parameter *) - color_editable : bool ; (** indicates if the value can be changed *) - color_f_apply : (string -> unit) ; (** the function to call to apply the new value of the parameter *) - color_help : string option ; (** optional help string *) - color_expand : bool ; (** expand the entry widget or not *) - } ;; - -type date_param = { - date_label : string ; (** the label of the parameter *) - mutable date_value : int * int * int ; (** day, month, year *) - date_editable : bool ; (** indicates if the value can be changed *) - date_f_string : (int * int * int) -> string ; - (** the function used to display the current value (day, month, year) *) - date_f_apply : ((int * int * int) -> unit) ; - (** the function to call to apply the new value (day, month, year) of the parameter *) - date_help : string option ; (** optional help string *) - date_expand : bool ; (** expand the entry widget or not *) - } ;; - -type font_param = { - font_label : string ; (** the label of the parameter *) - mutable font_value : string ; (** the font name *) - font_editable : bool ; (** indicates if the value can be changed *) - font_f_apply : (string -> unit) ; - (** the function to call to apply the new value of the parameter *) - font_help : string option ; (** optional help string *) - font_expand : bool ; (** expand the entry widget or not *) - } ;; - - -type hotkey_param = { - hk_label : string ; (** the label of the parameter *) - mutable hk_value : (Gdk.Tags.modifier list * int) ; - (** The value, as a list of modifiers and a key code *) - hk_editable : bool ; (** indicates if the value can be changed *) - hk_f_apply : ((Gdk.Tags.modifier list * int) -> unit) ; - (** the function to call to apply the new value of the paramter *) - hk_help : string option ; (** optional help string *) - hk_expand : bool ; (** expand or not *) - } - type modifiers_param = { md_label : string ; (** the label of the parameter *) mutable md_value : Gdk.Tags.modifier list ; @@ -248,17 +98,11 @@ type modifiers_param = { type parameter_kind = String_param of string string_param | List_param of (GData.tooltips -> <box: GObj.widget ; apply : unit>) - | Filename_param of string string_param | Bool_param of bool_param | Text_param of string string_param | Combo_param of combo_param | Custom_param of custom_param - | Color_param of color_param - | Date_param of date_param - | Font_param of font_param - | Hotkey_param of hotkey_param | Modifiers_param of modifiers_param - | Html_param of string string_param ;; (** This type represents the structure of the configuration window. *) @@ -275,28 +119,3 @@ type return_button = | Return_cancel (** The user closed the window with the cancel button or the window manager but never clicked on the apply button.*) - -(** {2 Bindings in the html editor} *) - -type html_binding = { - mutable html_key : (Gdk.Tags.modifier list * int) ; - mutable html_begin : string ; - mutable html_end : string ; - } - -let htmlbinding_cp_wrapper = - let w = Config_file.tuple3_wrappers - key_cp_wrapper - Config_file.string_wrappers - Config_file.string_wrappers - in - { - to_raw = (fun v -> w.to_raw (v.html_key, v.html_begin, v.html_end)) ; - of_raw = - (fun r -> let (k,b,e) = w.of_raw r in - { html_key = k ; html_begin = b ; html_end = e } - ) ; - } - -class htmlbinding_cp = - [html_binding] Config_file.option_cp htmlbinding_cp_wrapper diff --git a/ide/utils/editable_cells.ml b/ide/utils/editable_cells.ml deleted file mode 100644 index 33968b8d..00000000 --- a/ide/utils/editable_cells.ml +++ /dev/null @@ -1,113 +0,0 @@ -open Gobject - -let create l = - let hbox = GPack.hbox () in - let scw = GBin.scrolled_window - ~hpolicy:`AUTOMATIC - ~vpolicy:`AUTOMATIC - ~packing:(hbox#pack ~expand:true) () in - - let columns = new GTree.column_list in - let command_col = columns#add Data.string in - let coq_col = columns#add Data.string in - let store = GTree.list_store columns - in - -(* populate the store *) - let _ = List.iter (fun (x,y) -> - let row = store#append () in - store#set ~row ~column:command_col x; - store#set ~row ~column:coq_col y) - l - in - let view = GTree.view ~model:store ~packing:scw#add_with_viewport () in - - (* Alternate colors for the rows *) - view#set_rules_hint true; - - let renderer_comm = GTree.cell_renderer_text [`EDITABLE true] in - ignore (renderer_comm#connect#edited - ~callback:(fun (path:Gtk.tree_path) (s:string) -> - store#set - ~row:(store#get_iter path) - ~column:command_col s)); - let first = - GTree.view_column ~title:"Coq Command to try" - ~renderer:(renderer_comm,["text",command_col]) - () - in ignore (view#append_column first); - - let renderer_coq = GTree.cell_renderer_text [`EDITABLE true] in - ignore(renderer_coq#connect#edited - ~callback:(fun (path:Gtk.tree_path) (s:string) -> - store#set - ~row:(store#get_iter path) - ~column:coq_col s)); - let second = - GTree.view_column ~title:"Coq Command to insert" - ~renderer:(renderer_coq,["text",coq_col]) - () - in ignore (view#append_column second); - - let vbox = GPack.button_box `VERTICAL ~packing:hbox#pack ~layout:`SPREAD () - in - let up = GButton.button ~stock:`GO_UP ~label:"Up" ~packing:(vbox#pack ~expand:true ~fill:false) () in - let down = GButton.button - ~stock:`GO_DOWN - ~label:"Down" - ~packing:(vbox#pack ~expand:true ~fill:false) () - in - let add = GButton.button ~stock:`ADD - ~label:"Add" - ~packing:(vbox#pack ~expand:true ~fill:false) - () - in - let remove = GButton.button ~stock:`REMOVE - ~label:"Remove" - ~packing:(vbox#pack ~expand:true ~fill:false) () - in - - ignore (add#connect#clicked - ~callback:(fun b -> - let n = store#append () in - view#selection#select_iter n)); - ignore (remove#connect#clicked - ~callback:(fun b -> match view#selection#get_selected_rows with - | [] -> () - | path::_ -> - let iter = store#get_iter path in - ignore (store#remove iter); - )); - ignore (up#connect#clicked - ~callback:(fun b -> - match view#selection#get_selected_rows with - | [] -> () - | path::_ -> - let iter = store#get_iter path in - ignore (GtkTree.TreePath.prev path); - let upiter = store#get_iter path in - ignore (store#swap iter upiter); - )); - ignore (down#connect#clicked - ~callback:(fun b -> - match view#selection#get_selected_rows with - | [] -> () - | path::_ -> - let iter = store#get_iter path in - GtkTree.TreePath.next path; - try let upiter = store#get_iter path in - ignore (store#swap iter upiter) - with _ -> () - )); - let get_data () = - let start_path = GtkTree.TreePath.from_string "0" in - let start_iter = store#get_iter start_path in - let rec all acc = - let new_acc = (store#get ~row:start_iter ~column:command_col, - store#get ~row:start_iter ~column:coq_col)::acc - in - if store#iter_next start_iter then all new_acc else List.rev new_acc - in all [] - in - (hbox,get_data) - diff --git a/ide/utils/okey.ml b/ide/utils/okey.ml deleted file mode 100644 index 8f6cb382..00000000 --- a/ide/utils/okey.ml +++ /dev/null @@ -1,169 +0,0 @@ -(*********************************************************************************) -(* Cameleon *) -(* *) -(* Copyright (C) 2005 Institut National de Recherche en Informatique et *) -(* en Automatique. All rights reserved. *) -(* *) -(* This program is free software; you can redistribute it and/or modify *) -(* it under the terms of the GNU Library General Public License as *) -(* published by the Free Software Foundation; either version 2 of the *) -(* License, or any later version. *) -(* *) -(* This program is distributed in the hope that it will be useful, *) -(* but WITHOUT ANY WARRANTY; without even the implied warranty of *) -(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) -(* GNU Library General Public License for more details. *) -(* *) -(* You should have received a copy of the GNU Library General Public *) -(* License along with this program; if not, write to the Free Software *) -(* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA *) -(* 02111-1307 USA *) -(* *) -(* Contact: Maxence.Guesdon@inria.fr *) -(* *) -(*********************************************************************************) - -type modifier = Gdk.Tags.modifier - -type handler = { - cond : (unit -> bool) ; - cback : (unit -> unit) ; - } - -type handler_spec = int * int * Gdk.keysym - (** mods * mask * key *) - -let int_of_modifier = function - `SHIFT -> 1 - | `LOCK -> 2 - | `CONTROL -> 4 - | `MOD1 -> 8 - | `MOD2 -> 16 - | `MOD3 -> 32 - | `MOD4 -> 64 - | `MOD5 -> 128 - | `BUTTON1 -> 256 - | `BUTTON2 -> 512 - | `BUTTON3 -> 1024 - | `BUTTON4 -> 2048 - | `BUTTON5 -> 4096 - | `HYPER -> 1 lsl 22 - | `META -> 1 lsl 20 - | `RELEASE -> 1 lsl 30 - | `SUPER -> 1 lsl 21 - -let int_of_modifiers l = - List.fold_left (fun acc -> fun m -> acc + (int_of_modifier m)) 0 l - -module H = - struct - type t = handler_spec * handler - let equal (m,k) (mods, mask, key) = - (k = key) && ((m land mask) = mods) - - let filter_with_mask mods mask key l = - List.filter (fun a -> (fst a) <> (mods, mask, key)) l - - let find_handlers mods key l = - List.map snd - (List.filter - (fun ((m,ma,k),_) -> equal (mods,key) (m,ma,k)) - l - ) - - end - -let (table : (int, H.t list ref) Hashtbl.t) = Hashtbl.create 13 - -let key_press w ev = - let key = GdkEvent.Key.keyval ev in - let modifiers = GdkEvent.Key.state ev in - try - let (r : H.t list ref) = Hashtbl.find table (Oo.id w) in - let l = H.find_handlers (int_of_modifiers modifiers) key !r in - match l with - [] -> false - | _ -> - List.iter - (fun h -> - if h.cond () then - try h.cback () - with e -> Minilib.log (Printexc.to_string e) - else () - ) - l; - true - with - Not_found -> - false - -let associate_key_press w = - ignore ((w#event#connect#key_press ~callback: (key_press w)) : GtkSignal.id) - -let default_modifiers = ref ([] : modifier list) -let default_mask = ref ([`MOD2 ; `MOD3 ; `MOD4 ; `MOD5 ; `LOCK] : modifier list) - -let set_default_modifiers l = default_modifiers := l -let set_default_mask l = default_mask := l - -let remove_widget (w : < event : GObj.event_ops ; ..>) () = - try - let r = Hashtbl.find table (Oo.id w) in - r := [] - with - Not_found -> - () - -let add1 ?(remove=false) w - ?(cond=(fun () -> true)) - ?(mods= !default_modifiers) - ?(mask= !default_mask) - k callback = - - let r = - try Hashtbl.find table (Oo.id w) - with Not_found -> - let r = ref [] in - Hashtbl.add table (Oo.id w) r; - ignore (w#connect#destroy ~callback: (remove_widget w)); - associate_key_press w; - r - in - let n_mods = int_of_modifiers mods in - let n_mask = lnot (int_of_modifiers mask) in - let new_h = { cond = cond ; cback = callback } in - if remove then - ( - let l = H.filter_with_mask n_mods n_mask k !r in - r := ((n_mods, n_mask, k), new_h) :: l - ) - else - r := ((n_mods, n_mask, k), new_h) :: !r - -let add w - ?(cond=(fun () -> true)) - ?(mods= !default_modifiers) - ?(mask= !default_mask) - k callback = - add1 w ~cond ~mods ~mask k callback - -let add_list w - ?(cond=(fun () -> true)) - ?(mods= !default_modifiers) - ?(mask= !default_mask) - k_list callback = - List.iter (fun k -> add w ~cond ~mods ~mask k callback) k_list - -let set w - ?(cond=(fun () -> true)) - ?(mods= !default_modifiers) - ?(mask= !default_mask) - k callback = - add1 ~remove: true w ~cond ~mods ~mask k callback - -let set_list w - ?(cond=(fun () -> true)) - ?(mods= !default_modifiers) - ?(mask= !default_mask) - k_list callback = - List.iter (fun k -> set w ~cond ~mods ~mask k callback) k_list diff --git a/ide/utils/okey.mli b/ide/utils/okey.mli deleted file mode 100644 index 84ea4df4..00000000 --- a/ide/utils/okey.mli +++ /dev/null @@ -1,115 +0,0 @@ -(*********************************************************************************) -(* Cameleon *) -(* *) -(* Copyright (C) 2005 Institut National de Recherche en Informatique et *) -(* en Automatique. All rights reserved. *) -(* *) -(* This program is free software; you can redistribute it and/or modify *) -(* it under the terms of the GNU Library General Public License as *) -(* published by the Free Software Foundation; either version 2 of the *) -(* License, or any later version. *) -(* *) -(* This program is distributed in the hope that it will be useful, *) -(* but WITHOUT ANY WARRANTY; without even the implied warranty of *) -(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) -(* GNU Library General Public License for more details. *) -(* *) -(* You should have received a copy of the GNU Library General Public *) -(* License along with this program; if not, write to the Free Software *) -(* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA *) -(* 02111-1307 USA *) -(* *) -(* Contact: Maxence.Guesdon@inria.fr *) -(* *) -(*********************************************************************************) - -(** Okey interface. - - Once the lib is compiled and installed, you can use it by referencing - it with the [Okey] module. You must add [okey.cmo] or [okey.cmx] - on the commande line when you link. -*) - -type modifier = Gdk.Tags.modifier - -(** Set the default modifier list. The first default value is [[]].*) -val set_default_modifiers : modifier list -> unit - -(** Set the default modifier mask. The first default value is - [[`MOD2 ; `MOD3 ; `MOD4 ; `MOD5 ; `LOCK]]. - The mask defines the modifiers not taken into account - when looking for the handler of a key press event. -*) -val set_default_mask : modifier list -> unit - -(** [add widget key callback] associates the [callback] function to the event - "key_press" with the given [key] for the given [widget]. - - @param remove when true, the previous handlers for the given key and modifier - list are not kept. - @param cond this function is a guard: the [callback] function is not called - if the [cond] function returns [false]. - The default [cond] function always returns [true]. - - @param mods the list of modifiers. If not given, the default modifiers - are used. - You can set the default modifiers with function {!Okey.set_default_modifiers}. - - @param mask the list of modifiers which must not be taken - into account to trigger the given handler. [mods] - and [mask] must not have common modifiers. If not given, the default mask - is used. - You can set the default modifiers mask with function {!Okey.set_default_mask}. -*) -val add : - < connect : < destroy : callback: (unit -> unit) -> GtkSignal.id; .. >; - event : GObj.event_ops; get_oid : int; .. > -> - ?cond: (unit -> bool) -> - ?mods: modifier list -> - ?mask: modifier list -> - Gdk.keysym -> - (unit -> unit) -> - unit - -(** It calls {!Okey.add} for each given key.*) -val add_list : - < connect : < destroy : callback: (unit -> unit) -> GtkSignal.id; .. >; - event : GObj.event_ops; get_oid : int; .. > -> - ?cond: (unit -> bool) -> - ?mods: modifier list -> - ?mask: modifier list -> - Gdk.keysym list -> - (unit -> unit) -> - unit - -(** Like {!Okey.add} but the previous handlers for the - given modifiers and key are not kept.*) -val set : - < connect : < destroy : callback: (unit -> unit) -> GtkSignal.id; .. >; - event : GObj.event_ops; get_oid : int; .. > -> - ?cond: (unit -> bool) -> - ?mods: modifier list -> - ?mask: modifier list -> - Gdk.keysym -> - (unit -> unit) -> - unit - -(** It calls {!Okey.set} for each given key.*) -val set_list : - < connect : < destroy : callback: (unit -> unit) -> GtkSignal.id; .. >; - event : GObj.event_ops; get_oid : int; .. > -> - ?cond: (unit -> bool) -> - ?mods: modifier list -> - ?mask: modifier list -> - Gdk.keysym list -> - (unit -> unit) -> - unit - -(** Remove the handlers associated to the given widget. - This is automatically done when a widget is destroyed but - you can do it yourself. *) -val remove_widget : - < connect : < destroy : callback: (unit -> unit) -> GtkSignal.id; .. >; - event : GObj.event_ops; get_oid : int; .. > -> - unit -> - unit diff --git a/ide/wg_Command.ml b/ide/wg_Command.ml index 946aaf01..8eddfb31 100644 --- a/ide/wg_Command.ml +++ b/ide/wg_Command.ml @@ -1,14 +1,16 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) open Preferences -class command_window name coqtop = +class command_window name coqtop coqops router = let frame = Wg_Detachable.detachable ~title:(Printf.sprintf "Query pane (%s)" name) () in let _ = frame#hide in @@ -21,11 +23,20 @@ class command_window name coqtop = notebook#misc#set_size_request ~width:600 ~height:500 (); notebook#misc#grab_focus ()) in + let route_id = + let r = ref 0 in + fun () -> incr r; !r in + object(self) val frame = frame val notebook = notebook + (* We need access to coqops in order to place queries in the proper + document stint. This should remove access from this module to the + low-level Coq one. *) + val coqops = coqops + method pack_in (f : GObj.widget -> unit) = f frame#coerce val mutable new_page : GObj.widget = (GMisc.label ())#coerce @@ -47,11 +58,13 @@ object(self) method private new_query_aux ?command ?term ?(grab_now=true) () = let frame = GBin.frame ~shadow_type:`NONE () in ignore(notebook#insert_page ~pos:(notebook#page_num new_page) frame#coerce); + let route_id = route_id () in let new_tab_lbl text = let hbox = GPack.hbox ~homogeneous:false () in ignore(GMisc.label ~width:100 ~ellipsize:`END ~text ~packing:hbox#pack()); let b = GButton.button ~packing:hbox#pack () in ignore(b#connect#clicked ~callback:(fun () -> + router#delete_route route_id; views <- List.filter (fun (f,_,_) -> f#get_oid <> frame#coerce#get_oid) views; notebook#remove_page (notebook#page_num frame#coerce))); @@ -83,15 +96,16 @@ object(self) ~vpolicy:`AUTOMATIC ~hpolicy:`AUTOMATIC ~packing:(vbox#pack ~fill:true ~expand:true) () in - let result = GText.view ~packing:r_bin#add () in + let result = Wg_MessageView.message_view () in + router#register_route route_id result; + r_bin#add (result :> GObj.widget); views <- (frame#coerce, result, combo#entry) :: views; let cb clr = result#misc#modify_base [`NORMAL, `NAME clr] in - let _ = background_color#connect#changed cb in - let _ = result#misc#connect#realize (fun () -> cb background_color#get) in + let _ = background_color#connect#changed ~callback:cb in + let _ = result#misc#connect#realize ~callback:(fun () -> cb background_color#get) in let cb ft = result#misc#modify_font (Pango.Font.from_string ft) in stick text_font result cb; result#misc#set_can_focus true; (* false causes problems for selection *) - result#set_editable false; let callback () = let com = combo#entry#text in let arg = entry#text in @@ -100,22 +114,20 @@ object(self) if Str.string_match (Str.regexp "\\. *$") com 0 then com else com ^ " " ^ arg ^" . " in - let log level message = - Ideutils.insert_xml result#buffer message; - result#buffer#insert "\n"; - in let process = - Coq.bind (Coq.query ~logger:log (phrase,Stateid.dummy)) (function - | Interface.Fail (_,l,str) -> - Ideutils.insert_xml result#buffer str; + let next = function + | Interface.Fail (_, _, err) -> + let err = Ideutils.validate err in + result#set err; notebook#set_page ~tab_label:(new_tab_lbl "Error") frame#coerce; - Coq.return () - | Interface.Good res -> - result#buffer#insert res; + Coq.return () + | Interface.Good () -> notebook#set_page ~tab_label:(new_tab_lbl arg) frame#coerce; - Coq.return ()) + Coq.return () + in + coqops#raw_coq_query ~route_id ~next phrase in - result#buffer#set_text ("Result for command " ^ phrase ^ ":\n"); + result#set (Pp.str ("Result for command " ^ phrase ^ ":\n")); Coq.try_grab coqtop process ignore in ignore (combo#entry#connect#activate ~callback); @@ -159,7 +171,7 @@ object(self) self#new_page_maker; self#new_query_aux ~grab_now:false (); frame#misc#hide (); - let _ = background_color#connect#changed self#refresh_color in + let _ = background_color#connect#changed ~callback:self#refresh_color in self#refresh_color background_color#get; ignore(notebook#event#connect#key_press ~callback:(fun ev -> if GdkEvent.Key.keyval ev = GdkKeysyms._Escape then (self#hide; true) diff --git a/ide/wg_Command.mli b/ide/wg_Command.mli index fa50ba5f..1e0eb675 100644 --- a/ide/wg_Command.mli +++ b/ide/wg_Command.mli @@ -1,12 +1,14 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) -class command_window : string -> Coq.coqtop -> +class command_window : string -> Coq.coqtop -> CoqOps.coqops -> Wg_RoutedMessageViews.message_views_router -> object method new_query : ?command:string -> ?term:string -> unit -> unit method pack_in : (GObj.widget -> unit) -> unit diff --git a/ide/wg_Completion.ml b/ide/wg_Completion.ml index aeae3e1f..6a9317bc 100644 --- a/ide/wg_Completion.ml +++ b/ide/wg_Completion.ml @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) module StringOrd = @@ -154,7 +156,7 @@ object (self) let () = store#clear () in let iter prop = let iter = store#append () in - store#set iter column prop + store#set ~row:iter ~column prop in let () = current_completion <- (pref, props) in Proposals.iter iter props @@ -267,7 +269,7 @@ object (self) (** Position of view w.r.t. window *) let (ux, uy) = Gdk.Window.get_position view#misc#window in (** Relative buffer position to view *) - let (dx, dy) = view#window_to_buffer_coords `WIDGET 0 0 in + let (dx, dy) = view#window_to_buffer_coords ~tag:`WIDGET ~x:0 ~y:0 in (** Iter position *) let iter = view#buffer#get_iter pos in let coords = view#get_iter_location iter in @@ -397,11 +399,11 @@ object (self) let () = self#select_first () in let () = obj#misc#show () in let () = self#manage_scrollbar () in - obj#resize 1 1 + obj#resize ~width:1 ~height:1 method private start_callback off = let (x, y, w, h) = self#coordinates (`OFFSET off) in - let () = obj#move x (y + 3 * h / 2) in + let () = obj#move ~x ~y:(y + 3 * h / 2) in () method private update_callback (off, word, props) = @@ -433,21 +435,21 @@ object (self) else false in (** Style handling *) - let _ = view#misc#connect#style_set self#refresh_style in + let _ = view#misc#connect#style_set ~callback:self#refresh_style in let _ = self#refresh_style () in let _ = data#set_resize_mode `PARENT in let _ = frame#set_resize_mode `PARENT in (** Callback to model *) - let _ = model#connect#start_completion self#start_callback in - let _ = model#connect#update_completion self#update_callback in - let _ = model#connect#end_completion self#end_callback in + let _ = model#connect#start_completion ~callback:self#start_callback in + let _ = model#connect#update_completion ~callback:self#update_callback in + let _ = model#connect#end_completion ~callback:self#end_callback in (** Popup interaction *) - let _ = view#event#connect#key_press key_cb in + let _ = view#event#connect#key_press ~callback:key_cb in (** Hiding the popup when necessary*) - let _ = view#misc#connect#hide obj#misc#hide in - let _ = view#event#connect#button_press (fun _ -> self#hide (); false) in - let _ = view#connect#move_cursor move_cb in - let _ = view#event#connect#focus_out (fun _ -> self#hide (); false) in + let _ = view#misc#connect#hide ~callback:obj#misc#hide in + let _ = view#event#connect#button_press ~callback:(fun _ -> self#hide (); false) in + let _ = view#connect#move_cursor ~callback:move_cb in + let _ = view#event#connect#focus_out ~callback:(fun _ -> self#hide (); false) in () end diff --git a/ide/wg_Completion.mli b/ide/wg_Completion.mli index dd496aa5..aa2f36a5 100644 --- a/ide/wg_Completion.mli +++ b/ide/wg_Completion.mli @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) module Proposals : sig type t end diff --git a/ide/wg_Detachable.ml b/ide/wg_Detachable.ml index 3d1b63df..d7536870 100644 --- a/ide/wg_Detachable.ml +++ b/ide/wg_Detachable.ml @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) class type detachable_signals = @@ -19,15 +21,15 @@ class detachable (obj : ([> Gtk.box] as 'a) Gobject.obj) = inherit GPack.box_skel (obj :> Gtk.box Gobject.obj) as super val but = GButton.button () - val win = GWindow.window () + val win = GWindow.window ~type_hint:`DIALOG () val frame = GBin.frame ~shadow_type:`NONE () val mutable detached = false val mutable detached_cb = (fun _ -> ()) val mutable attached_cb = (fun _ -> ()) method child = frame#child - method add = frame#add - method pack ?from ?expand ?fill ?padding w = + method! add = frame#add + method! pack ?from ?expand ?fill ?padding w = if frame#all_children = [] then self#add w else raise (Invalid_argument "detachable#pack") diff --git a/ide/wg_Detachable.mli b/ide/wg_Detachable.mli index a7e8f467..9588cf18 100644 --- a/ide/wg_Detachable.mli +++ b/ide/wg_Detachable.mli @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) class type detachable_signals = diff --git a/ide/wg_Find.ml b/ide/wg_Find.ml index 3d847ddc..296a9423 100644 --- a/ide/wg_Find.ml +++ b/ide/wg_Find.ml @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) let b2c = Ideutils.byte_offset_to_char_offset @@ -84,8 +86,10 @@ class finder name (view : GText.view) = method private backward_search starti = let text = view#buffer#start_iter#get_text ~stop:starti in let regexp = self#regex in - try - let i = Str.search_backward regexp text (String.length text - 1) in + let offs = (String.length text - 1) in + if offs < 0 then None + else try + let i = Str.search_backward regexp text offs in let j = Str.match_end () in Some(view#buffer#start_iter#forward_chars (b2c text i), view#buffer#start_iter#forward_chars (b2c text j)) @@ -101,24 +105,33 @@ class finder name (view : GText.view) = with Not_found -> None method replace_all () = - let rec replace_at (iter : GText.iter) = + let rec replace_at (iter : GText.iter) ct tot = let found = self#forward_search iter in match found with - | None -> () + | None -> + let tot_str = if Int.equal ct tot then "" else " of " ^ string_of_int tot in + let occ_str = CString.plural tot "occurrence" in + let _ = Ideutils.flash_info ("Replaced " ^ string_of_int ct ^ tot_str ^ " " ^ occ_str) in + () | Some (start, stop) -> let text = iter#get_text ~stop:view#buffer#end_iter in let start_mark = view#buffer#create_mark start in let stop_mark = view#buffer#create_mark ~left_gravity:false stop in + let mod_save = view#buffer#modified in + let _ = view#buffer#set_modified false in let _ = view#buffer#delete_interactive ~start ~stop () in let iter = view#buffer#get_iter_at_mark (`MARK start_mark) in - let _ = view#buffer#insert_interactive ~iter (self#replacement text)in + let _ = view#buffer#insert_interactive ~iter (self#replacement text) in + let edited = view#buffer#modified in + let _ = view#buffer#set_modified (edited || mod_save) in let next = view#buffer#get_iter_at_mark (`MARK stop_mark) in let () = view#buffer#delete_mark (`MARK start_mark) in let () = view#buffer#delete_mark (`MARK stop_mark) in - replace_at next + let next_ct = if edited then ct + 1 else ct in + replace_at next next_ct (tot + 1) in let () = view#buffer#begin_user_action () in - let () = replace_at view#buffer#start_iter in + let () = replace_at view#buffer#start_iter 0 0 in view#buffer#end_user_action () method private set_not_found () = @@ -130,22 +143,52 @@ class finder name (view : GText.view) = method private set_normal () = find_entry#misc#modify_base [`NORMAL, `NAME "white"] - method private find_from backward (starti : GText.iter) = + method private find_from backward ?(wrapped=false) (starti : GText.iter) = let found = if backward then self#backward_search starti else self#forward_search starti in match found with | None -> if not backward && not (starti#equal view#buffer#start_iter) then - self#find_from backward view#buffer#start_iter + self#find_from backward ~wrapped:true view#buffer#start_iter else if backward && not (starti#equal view#buffer#end_iter) then - self#find_from backward view#buffer#end_iter + self#find_from backward ~wrapped:true view#buffer#end_iter else + let _ = Ideutils.flash_info "String not found" in self#set_not_found () | Some (start, stop) -> + let text = view#buffer#start_iter#get_text ~stop:view#buffer#end_iter in + let rec find_all offs accum = + if offs > String.length text then + List.rev accum + else try + let i = Str.search_forward self#regex text offs in + let j = Str.match_end () in + find_all (j + 1) (i :: accum) + with Not_found -> List.rev accum + in + let occurs = find_all 0 [] in + let num_occurs = List.length occurs in + (* assoc table of offset, occurrence index pairs *) + let occur_tbl = List.mapi (fun ndx occ -> (occ,ndx+1)) occurs in let _ = view#buffer#select_range start stop in let scroll = `MARK (view#buffer#create_mark stop) in let _ = view#scroll_to_mark ~use_align:false scroll in + let _ = + try + let occ_ndx = List.assoc start#offset occur_tbl in + let occ_str = CString.plural num_occurs "occurrence" in + let wrap_str = if wrapped then + if backward then " (wrapped backwards)" + else " (wrapped)" + else "" + in + Ideutils.flash_info + (string_of_int occ_ndx ^ " of " ^ string_of_int num_occurs ^ + " " ^ occ_str ^ wrap_str) + with Not_found -> + CErrors.anomaly (Pp.str "Occurrence of Find string not in table") + in self#set_found () method find_forward () = @@ -186,8 +229,8 @@ class finder name (view : GText.view) = in let find_cb = generic_cb self#hide self#find_forward in let replace_cb = generic_cb self#hide self#replace in - let _ = find_entry#event#connect#key_press find_cb in - let _ = replace_entry#event#connect#key_press replace_cb in + let _ = find_entry#event#connect#key_press ~callback:find_cb in + let _ = replace_entry#event#connect#key_press ~callback:replace_cb in (** TextView interaction *) let view_cb ev = @@ -197,7 +240,7 @@ class finder name (view : GText.view) = else false else false in - let _ = view#event#connect#key_press view_cb in + let _ = view#event#connect#key_press ~callback:view_cb in () end diff --git a/ide/wg_Find.mli b/ide/wg_Find.mli index 1ef1c4d4..b4c1a40e 100644 --- a/ide/wg_Find.mli +++ b/ide/wg_Find.mli @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) class finder : string -> GText.view -> diff --git a/ide/wg_MessageView.ml b/ide/wg_MessageView.ml index 0330b8ef..a79a093e 100644 --- a/ide/wg_MessageView.ml +++ b/ide/wg_MessageView.ml @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) open Preferences @@ -28,13 +30,14 @@ class type message_view = inherit GObj.widget method connect : message_view_signals method clear : unit - method add : Richpp.richpp -> unit + method add : Pp.t -> unit method add_string : string -> unit - method set : Richpp.richpp -> unit + method set : Pp.t -> unit + method refresh : bool -> unit method push : Ideutils.logger (** same as [add], but with an explicit level instead of [Notice] *) - method buffer : GText.buffer - (** for more advanced text edition *) + method has_selection : bool + method get_selected_text : string end let message_view () : message_view = @@ -42,7 +45,6 @@ let message_view () : message_view = ~highlight_matching_brackets:true ~tag_table:Tags.Message.table () in - let text_buffer = new GText.buffer buffer#as_buffer in let mark = buffer#create_mark ~left_gravity:false buffer#start_iter in let box = GPack.vbox () in let scroll = GBin.scrolled_window @@ -57,46 +59,76 @@ let message_view () : message_view = let () = view#set_left_margin 2 in view#misc#show (); let cb clr = view#misc#modify_base [`NORMAL, `NAME clr] in - let _ = background_color#connect#changed cb in - let _ = view#misc#connect#realize (fun () -> cb background_color#get) in + let _ = background_color#connect#changed ~callback:cb in + let _ = view#misc#connect#realize ~callback:(fun () -> cb background_color#get) in let cb ft = view#misc#modify_font (Pango.Font.from_string ft) in stick text_font view cb; - object (self) + + (* Inserts at point, advances the mark *) + let insert_msg (level, msg) = + let tags = match level with + | Feedback.Error -> [Tags.Message.error] + | Feedback.Warning -> [Tags.Message.warning] + | _ -> [] + in + let mark = `MARK mark in + let width = Ideutils.textview_width view in + Ideutils.insert_xml ~mark buffer ~tags (Richpp.richpp_of_pp width msg); + buffer#insert ~iter:(buffer#get_iter_at_mark mark) "\n" + in + + let mv = object (self) inherit GObj.widget box#as_widget + (* List of displayed messages *) + val mutable last_width = -1 + val mutable msgs = [] + val push = new GUtil.signal () method connect = new message_view_signals_impl box#as_widget push + method refresh force = + (* We need to block updates here due to the following race: + insertion of messages may create a vertical scrollbar, this + will trigger a width change, calling refresh again and + going into an infinite loop. *) + let width = Ideutils.textview_width view in + (* Could still this method race if the scrollbar changes the + textview_width ?? *) + let needed = force || last_width <> width in + if needed then begin + last_width <- width; + buffer#set_text ""; + buffer#move_mark (`MARK mark) ~where:buffer#start_iter; + List.(iter insert_msg (rev msgs)) + end + method clear = - buffer#set_text ""; - buffer#move_mark (`MARK mark) ~where:buffer#start_iter + msgs <- []; self#refresh true method push level msg = - let tags = match level with - | Feedback.Error -> [Tags.Message.error] - | Feedback.Warning -> [Tags.Message.warning] - | _ -> [] - in - let rec non_empty = function - | Xml_datatype.PCData "" -> false - | Xml_datatype.PCData _ -> true - | Xml_datatype.Element (_, _, children) -> List.exists non_empty children - in - if non_empty (Richpp.repr msg) then begin - let mark = `MARK mark in - Ideutils.insert_xml ~mark buffer ~tags msg; - buffer#insert ~iter:(buffer#get_iter_at_mark mark) "\n"; - push#call (level, msg) - end + msgs <- (level, msg) :: msgs; + insert_msg (level, msg); + push#call (level, msg) method add msg = self#push Feedback.Notice msg - method add_string s = self#add (Richpp.richpp_of_string s) + method add_string s = self#add (Pp.str s) method set msg = self#clear; self#add msg - method buffer = text_buffer + method has_selection = buffer#has_selection + method get_selected_text = + if buffer#has_selection then + let start, stop = buffer#selection_bounds in + buffer#get_text ~slice:true ~start ~stop () + else "" end + in + (* Is there a better way to connect the signal ? *) + let w_cb (_ : Gtk.rectangle) = mv#refresh false in + ignore (view#misc#connect#size_allocate ~callback:w_cb); + mv diff --git a/ide/wg_MessageView.mli b/ide/wg_MessageView.mli index 2d34533d..472aaf5e 100644 --- a/ide/wg_MessageView.mli +++ b/ide/wg_MessageView.mli @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) class type message_view_signals = @@ -18,13 +20,14 @@ class type message_view = inherit GObj.widget method connect : message_view_signals method clear : unit - method add : Richpp.richpp -> unit + method add : Pp.t -> unit method add_string : string -> unit - method set : Richpp.richpp -> unit + method set : Pp.t -> unit + method refresh : bool -> unit method push : Ideutils.logger (** same as [add], but with an explicit level instead of [Notice] *) - method buffer : GText.buffer - (** for more advanced text edition *) + method has_selection : bool + method get_selected_text : string end val message_view : unit -> message_view diff --git a/ide/wg_Notebook.ml b/ide/wg_Notebook.ml index 08d7d198..424979d8 100644 --- a/ide/wg_Notebook.ml +++ b/ide/wg_Notebook.ml @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) class ['a] typed_notebook make_page kill_page nb = @@ -50,7 +52,7 @@ object(self) method pages = term_list - method remove_page index = + method! remove_page index = term_list <- Util.List.filteri (fun i x -> if i = index then kill_page x; i <> index) term_list; super#remove_page index diff --git a/ide/wg_Notebook.mli b/ide/wg_Notebook.mli index 34eb1d11..85ecdf6c 100644 --- a/ide/wg_Notebook.mli +++ b/ide/wg_Notebook.mli @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) class ['a] typed_notebook : diff --git a/ide/wg_ProofView.ml b/ide/wg_ProofView.ml index 47c86045..9be562d3 100644 --- a/ide/wg_ProofView.ml +++ b/ide/wg_ProofView.ml @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) open Util @@ -14,11 +16,10 @@ class type proof_view = object inherit GObj.widget method buffer : GText.buffer - method refresh : unit -> unit + method refresh : force:bool -> unit method clear : unit -> unit method set_goals : Interface.goals option -> unit method set_evars : Interface.evar list option -> unit - method width : int end (* tag is the tag to be hooked, item is the item covered by this tag, make_menu @@ -48,7 +49,7 @@ let hook_tag_cb tag menu_content sel_cb hover_cb = hover_cb start stop; false | _ -> false)) -let mode_tactic sel_cb (proof : #GText.view_skel) goals hints = match goals with +let mode_tactic sel_cb (proof : #GText.view_skel) goals ~unfoc_goals hints = match goals with | [] -> assert false | { Interface.goal_hyp = hyps; Interface.goal_ccl = cur_goal; } :: rem_goals -> let on_hover sel_start sel_stop = @@ -66,14 +67,18 @@ let mode_tactic sel_cb (proof : #GText.view_skel) goals hints = match goals with let head_str = Printf.sprintf "%d subgoal%s\n" goals_cnt (if 1 < goals_cnt then "s" else "") in - let goal_str index total = Printf.sprintf - "______________________________________(%d/%d)\n" index total + let goal_str ?(shownum=false) index total = + if shownum then Printf.sprintf + "______________________________________(%d/%d)\n" index total + else Printf.sprintf + "______________________________________\n" in (* Insert current goal and its hypotheses *) let hyps_hints, goal_hints = match hints with | None -> [], [] | Some (hl, h) -> (hl, h) in + let width = Ideutils.textview_width proof in let rec insert_hyp hints hs = match hs with | [] -> () | hyp :: hs -> @@ -84,7 +89,7 @@ let mode_tactic sel_cb (proof : #GText.view_skel) goals hints = match goals with let () = hook_tag_cb tag hint sel_cb on_hover in [tag], hints in - let () = insert_xml ~tags proof#buffer hyp in + let () = insert_xml ~tags proof#buffer (Richpp.richpp_of_pp width hyp) in proof#buffer#insert "\n"; insert_hyp rem_hints hs in @@ -97,22 +102,33 @@ let mode_tactic sel_cb (proof : #GText.view_skel) goals hints = match goals with [tag] else [] in - proof#buffer#insert (goal_str 1 goals_cnt); - insert_xml proof#buffer cur_goal; + proof#buffer#insert (goal_str ~shownum:true 1 goals_cnt); + insert_xml ~tags:[Tags.Proof.goal] proof#buffer (Richpp.richpp_of_pp width cur_goal); proof#buffer#insert "\n" in (* Insert remaining goals (no hypotheses) *) - let fold_goal i _ { Interface.goal_ccl = g } = - proof#buffer#insert (goal_str i goals_cnt); - insert_xml proof#buffer g; + let fold_goal ?(shownum=false) i _ { Interface.goal_ccl = g } = + proof#buffer#insert (goal_str ~shownum i goals_cnt); + insert_xml proof#buffer (Richpp.richpp_of_pp width g); proof#buffer#insert "\n" in - let () = Util.List.fold_left_i fold_goal 2 () rem_goals in - + let () = Util.List.fold_left_i (fold_goal ~shownum:true) 2 () rem_goals in + (* show unfocused goal if option set *) + (* Insert remaining goals (no hypotheses) *) + if Coq.PrintOpt.printing_unfocused () then + begin + ignore(proof#buffer#place_cursor ~where:(proof#buffer#end_iter)); + let unfoc = List.flatten (List.rev (List.map (fun (x,y) -> x@y) unfoc_goals)) in + if unfoc<>[] then + begin + proof#buffer#insert "\nUnfocused Goals:\n"; + Util.List.fold_left_i (fold_goal ~shownum:false) 0 () unfoc + end + end; ignore(proof#buffer#place_cursor ~where:(proof#buffer#end_iter#backward_to_tag_toggle (Some Tags.Proof.goal))); - ignore(proof#scroll_to_mark ~use_align:true ~yalign:0.95 `INSERT) + ignore(proof#scroll_to_mark `INSERT) let rec flatten = function | [] -> [] @@ -122,6 +138,7 @@ let rec flatten = function let display mode (view : #GText.view_skel) goals hints evars = let () = view#buffer#set_text "" in + let width = Ideutils.textview_width view in match goals with | None -> () (* No proof in progress *) @@ -144,7 +161,7 @@ let display mode (view : #GText.view_skel) goals hints evars = (* The proof is finished, with the exception of given up goals. *) view#buffer#insert "No more subgoals, but there are some goals you gave up:\n\n"; let iter goal = - insert_xml view#buffer goal.Interface.goal_ccl; + insert_xml view#buffer (Richpp.richpp_of_pp width goal.Interface.goal_ccl); view#buffer#insert "\n" in List.iter iter given_up_goals; @@ -153,7 +170,7 @@ let display mode (view : #GText.view_skel) goals hints evars = (* All the goals have been resolved but those on the shelf. *) view#buffer#insert "All the remaining goals are on the shelf:\n\n"; let iter goal = - insert_xml view#buffer goal.Interface.goal_ccl; + insert_xml view#buffer (Richpp.richpp_of_pp width goal.Interface.goal_ccl); view#buffer#insert "\n" in List.iter iter shelved_goals @@ -166,13 +183,14 @@ let display mode (view : #GText.view_skel) goals hints evars = view#buffer#insert "This subproof is complete, but there are some unfocused goals:\n\n"; let iter i goal = let () = view#buffer#insert (goal_str (succ i)) in - insert_xml view#buffer goal.Interface.goal_ccl; + insert_xml view#buffer (Richpp.richpp_of_pp width goal.Interface.goal_ccl); view#buffer#insert "\n" in List.iteri iter bg end - | Some { Interface.fg_goals = fg } -> - mode view fg hints + | Some { Interface.fg_goals = fg; bg_goals = bg } -> + mode view fg ~unfoc_goals:bg hints + let proof_view () = let buffer = GSourceView2.source_buffer @@ -187,15 +205,16 @@ let proof_view () = let default_clipboard = GData.clipboard Gdk.Atom.primary in let _ = buffer#add_selection_clipboard default_clipboard in let cb clr = view#misc#modify_base [`NORMAL, `NAME clr] in - let _ = background_color#connect#changed cb in - let _ = view#misc#connect#realize (fun () -> cb background_color#get) in + let _ = background_color#connect#changed ~callback:cb in + let _ = view#misc#connect#realize ~callback:(fun () -> cb background_color#get) in let cb ft = view#misc#modify_font (Pango.Font.from_string ft) in stick text_font view cb; - object + let pf = object inherit GObj.widget view#as_widget val mutable goals = None val mutable evars = None + val mutable last_width = -1 method buffer = text_buffer @@ -205,11 +224,24 @@ let proof_view () = method set_evars evs = evars <- evs - method refresh () = - let dummy _ () = () in - display (mode_tactic dummy) (view :> GText.view_skel) goals None evars - - method width = Ideutils.textview_width (view :> GText.view_skel) + method refresh ~force = + (* We need to block updates here due to the following race: + insertion of messages may create a vertical scrollbar, this + will trigger a width change, calling refresh again and + going into an infinite loop. *) + let width = Ideutils.textview_width view in + (* Could still this method race if the scrollbar changes the + textview_width ?? *) + let needed = force || last_width <> width in + if needed then begin + last_width <- width; + let dummy _ () = () in + display (mode_tactic dummy) view goals None evars + end end - -(* ignore (proof_buffer#add_selection_clipboard cb); *) + in + (* Is there a better way to connect the signal ? *) + (* Can this be done in the object constructor? *) + let w_cb _ = pf#refresh ~force:false in + ignore (view#misc#connect#size_allocate ~callback:w_cb); + pf diff --git a/ide/wg_ProofView.mli b/ide/wg_ProofView.mli index b6eae48b..922f5a69 100644 --- a/ide/wg_ProofView.mli +++ b/ide/wg_ProofView.mli @@ -1,20 +1,21 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) class type proof_view = object inherit GObj.widget method buffer : GText.buffer - method refresh : unit -> unit + method refresh : force:bool -> unit method clear : unit -> unit method set_goals : Interface.goals option -> unit method set_evars : Interface.evar list option -> unit - method width : int end val proof_view : unit -> proof_view diff --git a/ide/wg_RoutedMessageViews.ml b/ide/wg_RoutedMessageViews.ml new file mode 100644 index 00000000..4bd30352 --- /dev/null +++ b/ide/wg_RoutedMessageViews.ml @@ -0,0 +1,47 @@ +(************************************************************************) +(* * 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) *) +(************************************************************************) + +class type message_views_router = object + method route : int -> Wg_MessageView.message_view + method default_route : Wg_MessageView.message_view + + method has_selection : bool + method get_selected_text : string + + method register_route : int -> Wg_MessageView.message_view -> unit + method delete_route : int -> unit +end + +let message_views ~route_0 : message_views_router = + let route_table = Hashtbl.create 17 in + let () = Hashtbl.add route_table 0 route_0 in +object + method route i = + try Hashtbl.find route_table i + with Not_found -> + (* at least the message will be printed somewhere*) + Hashtbl.find route_table 0 + + method default_route = route_0 + + method register_route i mv = Hashtbl.add route_table i mv + + method delete_route i = Hashtbl.remove route_table i + + method has_selection = + Hashtbl.fold (fun _ v -> (||) v#has_selection) route_table false + + method get_selected_text = + Option.default "" + (Hashtbl.fold (fun _ v acc -> + if v#has_selection then Some v#get_selected_text else acc) + route_table None) + +end diff --git a/ide/wg_RoutedMessageViews.mli b/ide/wg_RoutedMessageViews.mli new file mode 100644 index 00000000..cca43d55 --- /dev/null +++ b/ide/wg_RoutedMessageViews.mli @@ -0,0 +1,23 @@ +(************************************************************************) +(* * 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) *) +(************************************************************************) + +class type message_views_router = object + method route : int -> Wg_MessageView.message_view + method default_route : Wg_MessageView.message_view + + method has_selection : bool + method get_selected_text : string + + method register_route : int -> Wg_MessageView.message_view -> unit + method delete_route : int -> unit +end + +val message_views : + route_0:Wg_MessageView.message_view -> message_views_router diff --git a/ide/wg_ScriptView.ml b/ide/wg_ScriptView.ml index 218cedb3..74bc0b8d 100644 --- a/ide/wg_ScriptView.ml +++ b/ide/wg_ScriptView.ml @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) open Preferences @@ -301,28 +303,28 @@ object (self) ~use_align:false ~yalign:0.75 ~within_margin:0.25 `INSERT (* HACK: missing gtksourceview features *) - method right_margin_position = + method! right_margin_position = let prop = { Gobject.name = "right-margin-position"; conv = Gobject.Data.int; } in Gobject.get prop obj - method set_right_margin_position pos = + method! set_right_margin_position pos = let prop = { Gobject.name = "right-margin-position"; conv = Gobject.Data.int; } in Gobject.set prop obj pos - method show_right_margin = + method! show_right_margin = let prop = { Gobject.name = "show-right-margin"; conv = Gobject.Data.boolean; } in Gobject.get prop obj - method set_show_right_margin show = + method! set_show_right_margin show = let prop = { Gobject.name = "show-right-margin"; conv = Gobject.Data.boolean; @@ -460,8 +462,8 @@ object (self) let _ = GtkSignal.connect ~sgn:move_line_signal ~callback obj in (** Plug on preferences *) let cb clr = self#misc#modify_base [`NORMAL, `NAME clr] in - let _ = background_color#connect#changed cb in - let _ = self#misc#connect#realize (fun () -> cb background_color#get) in + let _ = background_color#connect#changed ~callback:cb in + let _ = self#misc#connect#realize ~callback:(fun () -> cb background_color#get) in let cb b = self#set_wrap_mode (if b then `WORD else `NONE) in stick dynamic_word_wrap self cb; diff --git a/ide/wg_ScriptView.mli b/ide/wg_ScriptView.mli index 6cce5e5b..be6510db 100644 --- a/ide/wg_ScriptView.mli +++ b/ide/wg_ScriptView.mli @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) (* An undoable view class *) diff --git a/ide/wg_Segment.ml b/ide/wg_Segment.ml index dbc1740e..0f5ed8d8 100644 --- a/ide/wg_Segment.ml +++ b/ide/wg_Segment.ml @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) open Util @@ -75,7 +77,7 @@ object (self) self#redraw (); end in - let _ = box#misc#connect#size_allocate cb in + let _ = box#misc#connect#size_allocate ~callback:cb in let clicked_cb ev = match model with | None -> true | Some md -> @@ -86,7 +88,7 @@ object (self) let () = clicked#call idx in true in - let _ = eventbox#event#connect#button_press clicked_cb in + let _ = eventbox#event#connect#button_press ~callback:clicked_cb in let cb show = if show then self#misc#show () else self#misc#hide () in stick show_progress_bar self cb; (** Initial pixmap *) @@ -102,7 +104,7 @@ object (self) | `SET (i, color) -> if self#misc#visible then self#fill_range color i (i + 1) in - md#changed changed_cb + md#changed ~callback:changed_cb method private fill_range color i j = match model with | None -> () diff --git a/ide/wg_Segment.mli b/ide/wg_Segment.mli index 29cbbeda..07f545fe 100644 --- a/ide/wg_Segment.mli +++ b/ide/wg_Segment.mli @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) type color = GDraw.color diff --git a/ide/xml_lexer.mll b/ide/xml_lexer.mll index 290f2c89..4a52147e 100644 --- a/ide/xml_lexer.mll +++ b/ide/xml_lexer.mll @@ -83,6 +83,9 @@ let error lexbuf e = last_pos := lexeme_start lexbuf; raise (Error e) +[@@@ocaml.warning "-3"] (* String.lowercase_ascii since 4.03.0 GPR#124 *) +let lowercase = String.lowercase +[@@@ocaml.warning "+3"] } let newline = ['\n'] @@ -219,7 +222,7 @@ and entity = parse { let ident = lexeme lexbuf in try - Hashtbl.find idents (String.lowercase ident) + Hashtbl.find idents (lowercase ident) with Not_found -> "&" ^ ident } diff --git a/ide/xml_printer.ml b/ide/xml_printer.ml index 40ab4ce9..488ef7bf 100644 --- a/ide/xml_printer.ml +++ b/ide/xml_printer.ml @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) open Xml_datatype diff --git a/ide/xml_printer.mli b/ide/xml_printer.mli index f24f51ff..178f7c80 100644 --- a/ide/xml_printer.mli +++ b/ide/xml_printer.mli @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) type xml = Xml_datatype.xml diff --git a/ide/xmlprotocol.ml b/ide/xmlprotocol.ml index aecb317b..e1821921 100644 --- a/ide/xmlprotocol.ml +++ b/ide/xmlprotocol.ml @@ -1,16 +1,21 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) (** Protocol version of this file. This is the date of the last modification. *) (** WARNING: TO BE UPDATED WHEN MODIFIED! *) -let protocol_version = "20150913" +let protocol_version = "20170413" + +type msg_format = Richpp of int | Ppcmds +let msg_format = ref (Richpp 72) (** * Interface of calls to Coq by CoqIde *) @@ -92,10 +97,64 @@ let to_stateid = function let of_stateid i = Element ("state_id",["val",string_of_int (Stateid.to_int i)],[]) -let of_richpp x = Element ("richpp", [], [Richpp.repr x]) -let to_richpp xml = match xml with - | Element ("richpp", [], [x]) -> Richpp.richpp_of_xml x - | x -> raise Serialize.(Marshal_error("richpp",x)) +let to_routeid = function + | Element ("route_id",["val",i],[]) -> + let id = int_of_string i in id + | _ -> raise (Invalid_argument "to_route_id") + +let of_routeid i = Element ("route_id",["val",string_of_int i],[]) + +let of_box (ppb : Pp.block_type) = let open Pp in match ppb with + | Pp_hbox i -> constructor "ppbox" "hbox" [of_int i] + | Pp_vbox i -> constructor "ppbox" "vbox" [of_int i] + | Pp_hvbox i -> constructor "ppbox" "hvbox" [of_int i] + | Pp_hovbox i -> constructor "ppbox" "hovbox" [of_int i] + +let to_box = let open Pp in + do_match "ppbox" (fun s args -> match s with + | "hbox" -> Pp_hbox (to_int (singleton args)) + | "vbox" -> Pp_vbox (to_int (singleton args)) + | "hvbox" -> Pp_hvbox (to_int (singleton args)) + | "hovbox" -> Pp_hovbox (to_int (singleton args)) + | x -> raise (Marshal_error("*ppbox",PCData x)) + ) + +let rec of_pp (pp : Pp.t) = let open Pp in match Pp.repr pp with + | Ppcmd_empty -> constructor "ppdoc" "empty" [] + | Ppcmd_string s -> constructor "ppdoc" "string" [of_string s] + | Ppcmd_glue sl -> constructor "ppdoc" "glue" [of_list of_pp sl] + | Ppcmd_box (bt,s) -> constructor "ppdoc" "box" [of_pair of_box of_pp (bt,s)] + | Ppcmd_tag (t,s) -> constructor "ppdoc" "tag" [of_pair of_string of_pp (t,s)] + | Ppcmd_print_break (i,j) + -> constructor "ppdoc" "break" [of_pair of_int of_int (i,j)] + | Ppcmd_force_newline -> constructor "ppdoc" "newline" [] + | Ppcmd_comment cmd -> constructor "ppdoc" "comment" [of_list of_string cmd] + + +let rec to_pp xpp = let open Pp in + Pp.unrepr @@ + do_match "ppdoc" (fun s args -> match s with + | "empty" -> Ppcmd_empty + | "string" -> Ppcmd_string (to_string (singleton args)) + | "glue" -> Ppcmd_glue (to_list to_pp (singleton args)) + | "box" -> let (bt,s) = to_pair to_box to_pp (singleton args) in + Ppcmd_box(bt,s) + | "tag" -> let (tg,s) = to_pair to_string to_pp (singleton args) in + Ppcmd_tag(tg,s) + | "break" -> let (i,j) = to_pair to_int to_int (singleton args) in + Ppcmd_print_break(i, j) + | "newline" -> Ppcmd_force_newline + | "comment" -> Ppcmd_comment (to_list to_string (singleton args)) + | x -> raise (Marshal_error("*ppdoc",PCData x)) + ) xpp + +let of_richpp x = Element ("richpp", [], [x]) + +(* Run-time Selectable *) +let of_pp (pp : Pp.t) = + match !msg_format with + | Richpp margin -> of_richpp (Richpp.richpp_of_pp margin pp) + | Ppcmds -> of_pp pp let of_value f = function | Good x -> Element ("value", ["val", "good"], [f x]) @@ -104,7 +163,7 @@ let of_value f = function | None -> [] | Some (s, e) -> [("loc_s", string_of_int s); ("loc_e", string_of_int e)] in let id = of_stateid id in - Element ("value", ["val", "fail"] @ loc, [id; of_richpp msg]) + Element ("value", ["val", "fail"] @ loc, [id; of_pp msg]) let to_value f = function | Element ("value", attrs, l) -> @@ -120,7 +179,7 @@ let to_value f = function in let (id, msg) = match l with [id; msg] -> (id, msg) | _ -> raise (Marshal_error("val",PCData "no id attribute")) in let id = to_stateid id in - let msg = to_richpp msg in + let msg = to_pp msg in Fail (id, loc, msg) else raise (Marshal_error("good or fail",PCData ans)) | x -> raise (Marshal_error("value",x)) @@ -147,15 +206,15 @@ let to_evar = function | x -> raise (Marshal_error("evar",x)) let of_goal g = - let hyp = of_list of_richpp g.goal_hyp in - let ccl = of_richpp g.goal_ccl in + let hyp = of_list of_pp g.goal_hyp in + let ccl = of_pp g.goal_ccl in let id = of_string g.goal_id in Element ("goal", [], [id; hyp; ccl]) let to_goal = function | Element ("goal", [], [id; hyp; ccl]) -> - let hyp = to_list to_richpp hyp in - let ccl = to_richpp ccl in - let id = to_string id in + let hyp = to_list to_pp hyp in + let ccl = to_pp ccl in + let id = to_string id in { goal_hyp = hyp; goal_ccl = ccl; goal_id = id; } | x -> raise (Marshal_error("goal",x)) @@ -219,6 +278,7 @@ module ReifType : sig val coq_info_t : coq_info val_t val coq_object_t : 'a val_t -> 'a coq_object val_t val state_id_t : state_id val_t + val route_id_t : route_id val_t val search_cst_t : search_constraint val_t val of_value_type : 'a val_t -> 'a -> xml @@ -254,6 +314,7 @@ end = struct | Coq_info : coq_info val_t | Coq_object : 'a val_t -> 'a coq_object val_t | State_id : state_id val_t + | Route_id : route_id val_t | Search_cst : search_constraint val_t type value_type = Value_type : 'a val_t -> value_type @@ -279,6 +340,7 @@ end = struct let coq_info_t = Coq_info let coq_object_t x = Coq_object x let state_id_t = State_id + let route_id_t = Route_id let search_cst_t = Search_cst let of_value_type (ty : 'a val_t) : 'a -> xml = @@ -300,6 +362,7 @@ end = struct | Pair (t1,t2) -> (of_pair (convert t1) (convert t2)) | Union (t1,t2) -> (of_union (convert t1) (convert t2)) | State_id -> of_stateid + | Route_id -> of_routeid | Search_cst -> of_search_cst in convert ty @@ -323,6 +386,7 @@ end = struct | Pair (t1,t2) -> (to_pair (convert t1) (convert t2)) | Union (t1,t2) -> (to_union (convert t1) (convert t2)) | State_id -> to_stateid + | Route_id -> to_routeid | Search_cst -> to_search_cst in convert ty @@ -344,8 +408,8 @@ end = struct Printf.sprintf "Still focussed: [%a]." pr_focus g.bg_goals else let pr_goal { goal_hyp = hyps; goal_ccl = goal } = - "[" ^ String.concat "; " (List.map Richpp.raw_print hyps) ^ " |- " ^ - Richpp.raw_print goal ^ "]" in + "[" ^ String.concat "; " (List.map Pp.string_of_ppcmds hyps) ^ " |- " ^ + Pp.string_of_ppcmds goal ^ "]" in String.concat " " (List.map pr_goal g.fg_goals) let pr_evar (e : evar) = "[" ^ e.evar_info ^ "]" let pr_status (s : status) = @@ -400,6 +464,7 @@ end = struct | Pair (t1,t2) -> (pr_pair (print t1) (print t2)) | Union (t1,t2) -> (pr_union (print t1) (print t2)) | State_id -> pr_state_id + | Route_id -> pr_int (* This is to break if a rename/refactoring makes the strings below outdated *) type 'a exists = bool @@ -425,6 +490,7 @@ end = struct | Union (t1,t2) -> assert(true : ('a,'b) CSig.union exists); Printf.sprintf "((%s, %s) CSig.union)" (print_val_t t1) (print_val_t t2) | State_id -> assert(true : Stateid.t exists); "Stateid.t" + | Route_id -> assert(true : route_id exists); "route_id" let print_type = function Value_type ty -> print_val_t ty @@ -456,7 +522,7 @@ open ReifType let add_sty_t : add_sty val_t = pair_t (pair_t string_t int_t) (pair_t state_id_t bool_t) let edit_at_sty_t : edit_at_sty val_t = state_id_t -let query_sty_t : query_sty val_t = pair_t string_t state_id_t +let query_sty_t : query_sty val_t = pair_t route_id_t (pair_t string_t state_id_t) let goals_sty_t : goals_sty val_t = unit_t let evars_sty_t : evars_sty val_t = unit_t let hints_sty_t : hints_sty val_t = unit_t @@ -467,6 +533,7 @@ let set_options_sty_t : set_options_sty val_t = list_t (pair_t (list_t string_t) option_value_t) let mkcases_sty_t : mkcases_sty val_t = string_t let quit_sty_t : quit_sty val_t = unit_t +let wait_sty_t : wait_sty val_t = unit_t let about_sty_t : about_sty val_t = unit_t let init_sty_t : init_sty val_t = option_t string_t let interp_sty_t : interp_sty val_t = pair_t (pair_t bool_t bool_t) string_t @@ -478,7 +545,7 @@ let add_rty_t : add_rty val_t = pair_t state_id_t (pair_t (union_t unit_t state_id_t) string_t) let edit_at_rty_t : edit_at_rty val_t = union_t unit_t (pair_t state_id_t (pair_t state_id_t state_id_t)) -let query_rty_t : query_rty val_t = string_t +let query_rty_t : query_rty val_t = unit_t let goals_rty_t : goals_rty val_t = option_t goals_t let evars_rty_t : evars_rty val_t = option_t (list_t evar_t) let hints_rty_t : hints_rty val_t = @@ -491,6 +558,7 @@ let get_options_rty_t : get_options_rty val_t = let set_options_rty_t : set_options_rty val_t = unit_t let mkcases_rty_t : mkcases_rty val_t = list_t (list_t string_t) let quit_rty_t : quit_rty val_t = unit_t +let wait_rty_t : wait_rty val_t = unit_t let about_rty_t : about_rty val_t = coq_info_t let init_rty_t : init_rty val_t = state_id_t let interp_rty_t : interp_rty val_t = pair_t state_id_t (union_t string_t string_t) @@ -512,6 +580,7 @@ let calls = [| "SetOptions", ($)set_options_sty_t, ($)set_options_rty_t; "MkCases", ($)mkcases_sty_t, ($)mkcases_rty_t; "Quit", ($)quit_sty_t, ($)quit_rty_t; + "Wait", ($)wait_sty_t, ($)wait_rty_t; "About", ($)about_sty_t, ($)about_rty_t; "Init", ($)init_sty_t, ($)init_rty_t; "Interp", ($)interp_sty_t, ($)interp_rty_t; @@ -536,6 +605,8 @@ type 'a call = | About : about_sty -> about_rty call | Init : init_sty -> init_rty call | StopWorker : stop_worker_sty -> stop_worker_rty call + (* internal use (fake_ide) only, do not use *) + | Wait : wait_sty -> wait_rty call (* retrocompatibility *) | Interp : interp_sty -> interp_rty call | PrintAst : print_ast_sty -> print_ast_rty call @@ -554,12 +625,13 @@ let id_of_call : type a. a call -> int = function | SetOptions _ -> 9 | MkCases _ -> 10 | Quit _ -> 11 - | About _ -> 12 - | Init _ -> 13 - | Interp _ -> 14 - | StopWorker _ -> 15 - | PrintAst _ -> 16 - | Annotate _ -> 17 + | Wait _ -> 12 + | About _ -> 13 + | Init _ -> 14 + | Interp _ -> 15 + | StopWorker _ -> 16 + | PrintAst _ -> 17 + | Annotate _ -> 18 let str_of_call c = pi1 calls.(id_of_call c) @@ -579,6 +651,7 @@ let mkcases x : mkcases_rty call = MkCases x let search x : search_rty call = Search x let quit x : quit_rty call = Quit x let init x : init_rty call = Init x +let wait x : wait_rty call = Wait x let interp x : interp_rty call = Interp x let stop_worker x : stop_worker_rty call = StopWorker x let print_ast x : print_ast_rty call = PrintAst x @@ -600,6 +673,7 @@ let abstract_eval_call : type a. _ -> a call -> a value = fun handler c -> | SetOptions x -> mkGood (handler.set_options x) | MkCases x -> mkGood (handler.mkcases x) | Quit x -> mkGood (handler.quit x) + | Wait x -> mkGood (handler.wait x) | About x -> mkGood (handler.about x) | Init x -> mkGood (handler.init x) | Interp x -> mkGood (handler.interp x) @@ -624,6 +698,7 @@ let of_answer : type a. a call -> a value -> xml = function | SetOptions _ -> of_value (of_value_type set_options_rty_t) | MkCases _ -> of_value (of_value_type mkcases_rty_t ) | Quit _ -> of_value (of_value_type quit_rty_t ) + | Wait _ -> of_value (of_value_type wait_rty_t ) | About _ -> of_value (of_value_type about_rty_t ) | Init _ -> of_value (of_value_type init_rty_t ) | Interp _ -> of_value (of_value_type interp_rty_t ) @@ -631,6 +706,9 @@ let of_answer : type a. a call -> a value -> xml = function | PrintAst _ -> of_value (of_value_type print_ast_rty_t ) | Annotate _ -> of_value (of_value_type annotate_rty_t ) +let of_answer msg_fmt = + msg_format := msg_fmt; of_answer + let to_answer : type a. a call -> xml -> a value = function | Add _ -> to_value (to_value_type add_rty_t ) | Edit_at _ -> to_value (to_value_type edit_at_rty_t ) @@ -644,6 +722,7 @@ let to_answer : type a. a call -> xml -> a value = function | SetOptions _ -> to_value (to_value_type set_options_rty_t) | MkCases _ -> to_value (to_value_type mkcases_rty_t ) | Quit _ -> to_value (to_value_type quit_rty_t ) + | Wait _ -> to_value (to_value_type wait_rty_t ) | About _ -> to_value (to_value_type about_rty_t ) | Init _ -> to_value (to_value_type init_rty_t ) | Interp _ -> to_value (to_value_type interp_rty_t ) @@ -666,6 +745,7 @@ let of_call : type a. a call -> xml = fun q -> | SetOptions x -> mkCall (of_value_type set_options_sty_t x) | MkCases x -> mkCall (of_value_type mkcases_sty_t x) | Quit x -> mkCall (of_value_type quit_sty_t x) + | Wait x -> mkCall (of_value_type wait_sty_t x) | About x -> mkCall (of_value_type about_sty_t x) | Init x -> mkCall (of_value_type init_sty_t x) | Interp x -> mkCall (of_value_type interp_sty_t x) @@ -689,6 +769,7 @@ let to_call : xml -> unknown_call = | "SetOptions" -> Unknown (SetOptions (mkCallArg set_options_sty_t a)) | "MkCases" -> Unknown (MkCases (mkCallArg mkcases_sty_t a)) | "Quit" -> Unknown (Quit (mkCallArg quit_sty_t a)) + | "Wait" -> Unknown (Wait (mkCallArg wait_sty_t a)) | "About" -> Unknown (About (mkCallArg about_sty_t a)) | "Init" -> Unknown (Init (mkCallArg init_sty_t a)) | "Interp" -> Unknown (Interp (mkCallArg interp_sty_t a)) @@ -701,10 +782,10 @@ let to_call : xml -> unknown_call = let pr_value_gen pr = function | Good v -> "GOOD " ^ pr v - | Fail (id,None,str) -> "FAIL "^Stateid.to_string id^" ["^Richpp.raw_print str^"]" + | Fail (id,None,str) -> "FAIL "^Stateid.to_string id^" ["^ Pp.string_of_ppcmds str ^ "]" | Fail (id,Some(i,j),str) -> "FAIL "^Stateid.to_string id^ - " ("^string_of_int i^","^string_of_int j^")["^Richpp.raw_print str^"]" + " ("^string_of_int i^","^string_of_int j^")["^Pp.string_of_ppcmds str^"]" let pr_value v = pr_value_gen (fun _ -> "FIXME") v let pr_full_value : type a. a call -> a value -> string = fun call value -> match call with | Add _ -> pr_value_gen (print add_rty_t ) value @@ -719,6 +800,7 @@ let pr_full_value : type a. a call -> a value -> string = fun call value -> matc | SetOptions _ -> pr_value_gen (print set_options_rty_t) value | MkCases _ -> pr_value_gen (print mkcases_rty_t ) value | Quit _ -> pr_value_gen (print quit_rty_t ) value + | Wait _ -> pr_value_gen (print wait_rty_t ) value | About _ -> pr_value_gen (print about_rty_t ) value | Init _ -> pr_value_gen (print init_rty_t ) value | Interp _ -> pr_value_gen (print interp_rty_t ) value @@ -740,6 +822,7 @@ let pr_call : type a. a call -> string = fun call -> | SetOptions x -> return set_options_sty_t x | MkCases x -> return mkcases_sty_t x | Quit x -> return quit_sty_t x + | Wait x -> return wait_sty_t x | About x -> return about_sty_t x | Init x -> return init_sty_t x | Interp x -> return interp_sty_t x @@ -760,7 +843,7 @@ let document to_string_fmt = (to_string_fmt (of_value (fun _ -> PCData "b") (Good ()))); Printf.printf "or:\n\n%s\n\nwhere the attributes loc_s and loc_c are optional.\n" (to_string_fmt (of_value (fun _ -> PCData "b") - (Fail (Stateid.initial,Some (15,34),Richpp.richpp_of_string "error message")))); + (Fail (Stateid.initial,Some (15,34), Pp.str "error message")))); document_type_encoding to_string_fmt (* Moved from feedback.mli : This is IDE specific and we don't want to @@ -787,20 +870,14 @@ let to_message_level = let of_message lvl loc msg = let lvl = of_message_level lvl in let xloc = of_option of_loc loc in - let content = of_richpp msg in + let content = of_pp msg in Xml_datatype.Element ("message", [], [lvl; xloc; content]) let to_message xml = match xml with | Xml_datatype.Element ("message", [], [lvl; xloc; content]) -> - Message(to_message_level lvl, to_option to_loc xloc, to_richpp content) + Message(to_message_level lvl, to_option to_loc xloc, to_pp content) | x -> raise (Marshal_error("message",x)) -let is_message xml = - try begin match to_message xml with - | Message(l,c,m) -> Some (l,c,m) - | _ -> None - end with | Marshal_error _ -> None - let to_feedback_content = do_match "feedback_content" (fun s a -> match s,a with | "addedaxiom", _ -> AddedAxiom | "processed", _ -> Processed @@ -816,8 +893,7 @@ let to_feedback_content = do_match "feedback_content" (fun s a -> match s,a with | "workerstatus", [ns] -> let n, s = to_pair to_string to_string ns in WorkerStatus(n,s) - | "goals", [loc;s] -> Goals (to_loc loc, to_string s) - | "custom", [loc;name;x]-> Custom (to_loc loc, to_string name, x) + | "custom", [loc;name;x]-> Custom (to_option to_loc loc, to_string name, x) | "filedependency", [from; dep] -> FileDependency (to_option to_string from, to_string dep) | "fileloaded", [dirpath; filename] -> @@ -849,10 +925,8 @@ let of_feedback_content = function | WorkerStatus(n,s) -> constructor "feedback_content" "workerstatus" [of_pair of_string of_string (n,s)] - | Goals (loc,s) -> - constructor "feedback_content" "goals" [of_loc loc;of_string s] | Custom (loc, name, x) -> - constructor "feedback_content" "custom" [of_loc loc; of_string name; x] + constructor "feedback_content" "custom" [of_option of_loc loc; of_string name; x] | FileDependency (from, depends_on) -> constructor "feedback_content" "filedependency" [ of_option of_string from; @@ -863,23 +937,21 @@ let of_feedback_content = function of_string filename ] | Message (l,loc,m) -> constructor "feedback_content" "message" [ of_message l loc m ] -let of_edit_or_state_id = function - | Edit id -> ["object","edit"], of_edit_id id - | State id -> ["object","state"], of_stateid id +let of_edit_or_state_id id = ["object","state"], of_stateid id let of_feedback msg = let content = of_feedback_content msg.contents in - let obj, id = of_edit_or_state_id msg.id in + let obj, id = of_edit_or_state_id msg.span_id in let route = string_of_int msg.route in Element ("feedback", obj @ ["route",route], [id;content]) +let of_feedback msg_fmt = + msg_format := msg_fmt; of_feedback + let to_feedback xml = match xml with - | Element ("feedback", ["object","edit";"route",route], [id;content]) -> { - id = Edit(to_edit_id id); - route = int_of_string route; - contents = to_feedback_content content } - | Element ("feedback", ["object","state";"route",route], [id;content]) -> { - id = State(to_stateid id); + | Element ("feedback", ["object","state";"route",route], [id;content]) -> { + doc_id = 0; + span_id = to_stateid id; route = int_of_string route; contents = to_feedback_content content } | x -> raise (Marshal_error("feedback",x)) diff --git a/ide/xmlprotocol.mli b/ide/xmlprotocol.mli index 1bb99897..ba6000f0 100644 --- a/ide/xmlprotocol.mli +++ b/ide/xmlprotocol.mli @@ -1,9 +1,11 @@ (************************************************************************) -(* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *) +(* * 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 *) +(* // * 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) *) (************************************************************************) (** * Applicative part of the interface of CoqIde calls to Coq *) @@ -29,6 +31,8 @@ val set_options : set_options_sty -> set_options_rty call val quit : quit_sty -> quit_rty call val init : init_sty -> init_rty call val stop_worker : stop_worker_sty -> stop_worker_rty call +(* internal use (fake_ide) only, do not use *) +val wait : wait_sty -> wait_rty call (* retrocompatibility *) val interp : interp_sty -> interp_rty call val print_ast : print_ast_sty -> print_ast_rty call @@ -40,12 +44,17 @@ val abstract_eval_call : handler -> 'a call -> 'a value val protocol_version : string +(** By default, we still output messages in Richpp so we are + compatible with 8.6, however, 8.7 aware clients will want to + set this to Ppcmds *) +type msg_format = Richpp of int | Ppcmds + (** * XML data marshalling *) val of_call : 'a call -> xml val to_call : xml -> unknown_call -val of_answer : 'a call -> 'a value -> xml +val of_answer : msg_format -> 'a call -> 'a value -> xml val to_answer : 'a call -> xml -> 'a value (* Prints the documentation of this module *) @@ -57,16 +66,8 @@ val pr_call : 'a call -> string val pr_value : 'a value -> string val pr_full_value : 'a call -> 'a value -> string -(** * Serialization of rich documents *) -val of_richpp : Richpp.richpp -> Xml_datatype.xml -val to_richpp : Xml_datatype.xml -> Richpp.richpp - (** * Serializaiton of feedback *) -val of_feedback : Feedback.feedback -> xml +val of_feedback : msg_format -> Feedback.feedback -> xml val to_feedback : xml -> Feedback.feedback -val is_feedback : xml -> bool - -val is_message : xml -> (Feedback.level * Loc.t option * Richpp.richpp) option -val of_message : Feedback.level -> Loc.t option -> Richpp.richpp -> xml -(* val to_message : xml -> Feedback.message *) +val is_feedback : xml -> bool |