src/Tools/VSCode/src/vscode_resources.scala
changeset 64727 13e37567a0d6
parent 64726 c534a2ac537d
child 64729 4eccd9bc5fd9
equal deleted inserted replaced
64726:c534a2ac537d 64727:13e37567a0d6
     9 
     9 
    10 import isabelle._
    10 import isabelle._
    11 
    11 
    12 import java.net.{URI, URISyntaxException}
    12 import java.net.{URI, URISyntaxException}
    13 import java.io.{File => JFile}
    13 import java.io.{File => JFile}
       
    14 
       
    15 import scala.util.parsing.input.{Reader, CharSequenceReader}
    14 
    16 
    15 
    17 
    16 object VSCode_Resources
    18 object VSCode_Resources
    17 {
    19 {
    18   /* file URIs */
    20   /* file URIs */
    62     val name = super.import_name(qualifier, master, s)
    64     val name = super.import_name(qualifier, master, s)
    63     if (name.node.startsWith("file://") || name.node.forall(c => c != '/' && c != '\\')) name
    65     if (name.node.startsWith("file://") || name.node.forall(c => c != '/' && c != '\\')) name
    64     else name.copy(node = "file://" + name.node)
    66     else name.copy(node = "file://" + name.node)
    65   }
    67   }
    66 
    68 
       
    69   override def with_thy_reader[A](name: Document.Node.Name, f: Reader[Char] => A): A =
       
    70   {
       
    71     val uri = name.node
       
    72     get_model(uri) match {
       
    73       case Some(model) =>
       
    74         val reader = new CharSequenceReader(model.doc.make_text)
       
    75         f(reader)
       
    76 
       
    77       case None =>
       
    78         val file = VSCode_Resources.canonical_file(uri)
       
    79         if (!file.isFile) error("No such file: " + quote(file.toString))
       
    80 
       
    81         val reader = Scan.byte_reader(file)
       
    82         try { f(reader) } finally { reader.close }
       
    83     }
       
    84   }
       
    85 
    67 
    86 
    68   /* document models */
    87   /* document models */
    69 
    88 
    70   def get_model(uri: String): Option[Document_Model] = state.value.models.get(uri)
    89   def get_model(uri: String): Option[Document_Model] = state.value.models.get(uri)
    71 
    90 
    72   def update_model(session: Session, uri: String, text: String)
    91   def update_model(session: Session, uri: String, text: String)
    73   {
    92   {
    74     state.change(st =>
    93     state.change(st =>
    75       {
    94       {
    76         val model = st.models.getOrElse(uri, Document_Model.init(session, uri))
    95         val model = st.models.getOrElse(uri, Document_Model.init(session, uri))
    77         val model1 = (model.update_text(text) getOrElse model).copy(external_file = false)
    96         val model1 = (model.update_text(text) getOrElse model).external(false)
    78         st.copy(
    97         st.copy(
    79           models = st.models + (uri -> model1),
    98           models = st.models + (uri -> model1),
    80           pending_input = st.pending_input + uri)
    99           pending_input = st.pending_input + uri)
    81       })
   100       })
    82   }
   101   }
    84   def close_model(uri: String): Option[Document_Model] =
   103   def close_model(uri: String): Option[Document_Model] =
    85     state.change_result(st =>
   104     state.change_result(st =>
    86       st.models.get(uri) match {
   105       st.models.get(uri) match {
    87         case None => (None, st)
   106         case None => (None, st)
    88         case Some(model) =>
   107         case Some(model) =>
    89           (Some(model), st.copy(models = st.models + (uri -> model.copy(external_file = true))))
   108           (Some(model), st.copy(models = st.models + (uri -> model.external(true))))
    90       })
   109       })
    91 
   110 
    92   def sync_models(changed_files: Set[JFile]): Boolean =
   111   def sync_models(changed_files: Set[JFile]): Boolean =
    93     state.change_result(st =>
   112     state.change_result(st =>
    94       {
   113       {
   102         else (true,
   121         else (true,
   103           st.copy(
   122           st.copy(
   104             models = (st.models /: changed_models)(_ + _),
   123             models = (st.models /: changed_models)(_ + _),
   105             pending_input = (st.pending_input /: changed_models.iterator.map(_._1))(_ + _)))
   124             pending_input = (st.pending_input /: changed_models.iterator.map(_._1))(_ + _)))
   106       })
   125       })
       
   126 
       
   127 
       
   128   /* resolve dependencies */
       
   129 
       
   130   def resolve_dependencies(session: Session): Boolean =
       
   131   {
       
   132     val thys =
       
   133       (for ((_, model) <- state.value.models.iterator if model.is_theory)
       
   134        yield (model.node_name, Position.none)).toList
       
   135     val deps = new Thy_Info(this).dependencies("", thys).deps
       
   136 
       
   137     state.change_result(st =>
       
   138       {
       
   139         val loaded_models =
       
   140           for {
       
   141             uri <- deps.map(_.name.node)
       
   142             if get_model(uri).isEmpty
       
   143             text <-
       
   144               try { Some(File.read(VSCode_Resources.canonical_file(uri))) }
       
   145               catch { case ERROR(_) => None }
       
   146           }
       
   147           yield {
       
   148             val model = Document_Model.init(session, uri)
       
   149             val model1 = (model.update_text(text) getOrElse model).external(true)
       
   150             (uri, model1)
       
   151           }
       
   152         if (loaded_models.isEmpty) (false, st)
       
   153         else
       
   154           (true,
       
   155             st.copy(
       
   156               models = st.models ++ loaded_models,
       
   157               pending_input = st.pending_input ++ loaded_models.map(_._1)))
       
   158       })
       
   159   }
   107 
   160 
   108 
   161 
   109   /* pending input */
   162   /* pending input */
   110 
   163 
   111   def flush_input(session: Session)
   164   def flush_input(session: Session)