src/Pure/PIDE/document.ML
changeset 44441 fe95e4306b4b
parent 44440 aa2abd81f460
child 44444 33a5616a7571
equal deleted inserted replaced
44440:aa2abd81f460 44441:fe95e4306b4b
    22     Header of node_header |
    22     Header of node_header |
    23     Perspective of command_id list
    23     Perspective of command_id list
    24   type edit = string * node_edit
    24   type edit = string * node_edit
    25   type state
    25   type state
    26   val init_state: state
    26   val init_state: state
       
    27   val define_command: command_id -> string -> state -> state
    27   val join_commands: state -> unit
    28   val join_commands: state -> unit
    28   val cancel_execution: state -> Future.task list
    29   val cancel_execution: state -> Future.task list
    29   val define_command: command_id -> string -> state -> state
       
    30   val update_perspective: version_id -> version_id -> string -> command_id list -> state -> state
    30   val update_perspective: version_id -> version_id -> string -> command_id list -> state -> state
    31   val edit: version_id -> version_id -> edit list -> state -> (command_id * exec_id) list * state
    31   val edit: version_id -> version_id -> edit list -> state -> (command_id * exec_id) list * state
    32   val execute: version_id -> state -> state
    32   val execute: version_id -> state -> state
    33   val state: unit -> state
    33   val state: unit -> state
    34   val change_state: (state -> state) -> unit
    34   val change_state: (state -> state) -> unit
    73   Node {header = header, perspective = perspective, entries = entries, result = result};
    73   Node {header = header, perspective = perspective, entries = entries, result = result};
    74 
    74 
    75 fun map_node f (Node {header, perspective, entries, result}) =
    75 fun map_node f (Node {header, perspective, entries, result}) =
    76   make_node (f (header, perspective, entries, result));
    76   make_node (f (header, perspective, entries, result));
    77 
    77 
    78 val no_perspective: perspective = (K false, []);
    78 fun make_perspective ids : perspective =
       
    79   (Inttab.defined (Inttab.make (map (rpair ()) ids)), ids);
       
    80 
       
    81 val no_perspective = make_perspective [];
    79 val no_print = Lazy.value ();
    82 val no_print = Lazy.value ();
    80 val no_result = Lazy.value Toplevel.toplevel;
    83 val no_result = Lazy.value Toplevel.toplevel;
    81 
    84 
    82 val empty_node =
    85 val empty_node =
    83   make_node (Exn.Exn (ERROR "Bad theory header"), no_perspective, Entries.empty, no_result);
    86   make_node (Exn.Exn (ERROR "Bad theory header"), no_perspective, Entries.empty, no_result);
    91 fun get_header (Node {header, ...}) = header;
    94 fun get_header (Node {header, ...}) = header;
    92 fun set_header header =
    95 fun set_header header =
    93   map_node (fn (_, perspective, entries, result) => (header, perspective, entries, result));
    96   map_node (fn (_, perspective, entries, result) => (header, perspective, entries, result));
    94 
    97 
    95 fun get_perspective (Node {perspective, ...}) = perspective;
    98 fun get_perspective (Node {perspective, ...}) = perspective;
    96 fun set_perspective perspective =
    99 fun set_perspective ids =
    97   let val pred = Inttab.defined (Inttab.make (map (rpair ()) perspective)) in
   100   map_node (fn (header, _, entries, result) => (header, make_perspective ids, entries, result));
    98     map_node (fn (header, _, entries, result) => (header, (pred, perspective), entries, result))
       
    99   end;
       
   100 
   101 
   101 fun map_entries f (Node {header, perspective, entries, result}) =
   102 fun map_entries f (Node {header, perspective, entries, result}) =
   102   make_node (header, perspective, f entries, result);
   103   make_node (header, perspective, f entries, result);
   103 fun fold_entries start f (Node {entries, ...}) = Entries.fold start f entries;
   104 fun fold_entries start f (Node {entries, ...}) = Entries.fold start f entries;
   104 fun first_entry start P (Node {entries, ...}) = Entries.get_first start P entries;
   105 fun first_entry start P (Node {entries, ...}) = Entries.get_first start P entries;
   343 fun is_changed node' ((_, id), exec) =
   344 fun is_changed node' ((_, id), exec) =
   344   (case try (the_entry node') id of
   345   (case try (the_entry node') id of
   345     NONE => true
   346     NONE => true
   346   | SOME exec' => exec' <> exec);
   347   | SOME exec' => exec' <> exec);
   347 
   348 
   348 fun init_theory deps (name, node) =
   349 fun init_theory deps name node =
   349   let
   350   let
   350     val (thy_name, imports, uses) = Exn.release (get_header node);
   351     val (thy_name, imports, uses) = Exn.release (get_header node);
   351     (* FIXME provide files via Scala layer *)
   352     (* FIXME provide files via Scala layer *)
   352     val (dir, files) =
   353     val (dir, files) =
   353       if ML_System.platform_is_cygwin then (Path.current, [])
   354       if ML_System.platform_is_cygwin then (Path.current, [])
   354       else (Path.dir (Path.explode name), map (apfst Path.explode) uses);
   355       else (Path.dir (Path.explode name), map (apfst Path.explode) uses);
   355 
   356 
   356     val parents =
   357     val parents =
   357       imports |> map (fn import =>
   358       imports |> map (fn import =>
   358         (case Thy_Info.lookup_theory import of
   359         (case Thy_Info.lookup_theory import of  (* FIXME more robust!? *)
   359           SOME thy => thy
   360           SOME thy => thy
   360         | NONE =>
   361         | NONE =>
   361             get_theory (Position.file_only import)
   362             get_theory (Position.file_only import)
   362               (#2 (Future.join (the (AList.lookup (op =) deps import))))));
   363               (#2 (Future.join (the (AList.lookup (op =) deps import))))));
   363   in Thy_Load.begin_theory dir thy_name imports files parents end;
   364   in Thy_Load.begin_theory dir thy_name imports files parents end;
   364 
   365 
   365 fun new_exec (command_id, command) (assigns, execs, exec) =
   366 fun new_exec state init command_id (assigns, execs, exec) =
   366   let
   367   let
       
   368     val command = the_command state command_id;
   367     val exec_id' = new_id ();
   369     val exec_id' = new_id ();
   368     val exec' = exec |> Lazy.map (fn (st, _) =>
   370     val exec' = exec |> Lazy.map (fn (st, _) =>
   369       let val tr = Toplevel.put_id (print_id exec_id') (Future.join command)
   371       let val tr =
       
   372         Future.join command
       
   373         |> Toplevel.modify_init init
       
   374         |> Toplevel.put_id (print_id exec_id');
   370       in run_command tr st end);
   375       in run_command tr st end);
   371   in ((command_id, exec_id') :: assigns, (exec_id', (command_id, exec')) :: execs, exec') end;
   376   in ((command_id, exec_id') :: assigns, (exec_id', (command_id, exec')) :: execs, exec') end;
   372 
   377 
   373 in
   378 in
   374 
   379 
   383         (fn deps => fn (name, node) =>
   388         (fn deps => fn (name, node) =>
   384           (case first_entry NONE (is_changed (node_of old_version name)) node of
   389           (case first_entry NONE (is_changed (node_of old_version name)) node of
   385             NONE => Future.value (([], [], []), node)
   390             NONE => Future.value (([], [], []), node)
   386           | SOME ((prev, id), _) =>
   391           | SOME ((prev, id), _) =>
   387               let
   392               let
   388                 fun init () = init_theory deps (name, node);
   393                 fun init () = init_theory deps name node;
   389                 fun get_command id =
       
   390                   (id, the_command state id |> Future.map (Toplevel.modify_init init));
       
   391               in
   394               in
   392                 (singleton o Future.forks)
   395                 (singleton o Future.forks)
   393                   {name = "Document.edit", group = NONE,
   396                   {name = "Document.edit", group = NONE,
   394                     deps = map (Future.task_of o #2) deps, pri = 2, interrupts = false}
   397                     deps = map (Future.task_of o #2) deps, pri = 2, interrupts = false}
   395                   (fn () =>
   398                   (fn () =>
   397                       val prev_exec =
   400                       val prev_exec =
   398                         (case prev of
   401                         (case prev of
   399                           NONE => no_id
   402                           NONE => no_id
   400                         | SOME prev_id => the_default no_id (the_entry node prev_id));
   403                         | SOME prev_id => the_default no_id (the_entry node prev_id));
   401                       val (assigns, execs, last_exec) =
   404                       val (assigns, execs, last_exec) =
   402                         fold_entries (SOME id) (new_exec o get_command o #2 o #1)
   405                         fold_entries (SOME id) (new_exec state init o #2 o #1)
   403                           node ([], [], #2 (the_exec state prev_exec));
   406                           node ([], [], #2 (the_exec state prev_exec));
   404                       val node' = node
   407                       val node' = node
   405                         |> fold update_entry assigns
   408                         |> fold update_entry assigns
   406                         |> set_result (Lazy.map #1 last_exec);
   409                         |> set_result (Lazy.map #1 last_exec);
   407                     in ((assigns, execs, [(name, node')]), node') end)
   410                     in ((assigns, execs, [(name, node')]), node') end)