207 Markup.COMMENT, Markup.LANGUAGE) |
207 Markup.COMMENT, Markup.LANGUAGE) |
208 |
208 |
209 def completion_context(caret: Text.Offset): Option[Completion.Context] = |
209 def completion_context(caret: Text.Offset): Option[Completion.Context] = |
210 if (caret > 0) { |
210 if (caret > 0) { |
211 val result = |
211 val result = |
212 snapshot.select_markup(Text.Range(caret - 1, caret + 1), Some(completion_elements), _ => |
212 snapshot.select_markup(Text.Range(caret - 1, caret + 1), completion_elements, _ => |
213 { |
213 { |
214 case Text.Info(_, XML.Elem(Markup.Language(language, symbols), _)) => |
214 case Text.Info(_, XML.Elem(Markup.Language(language, symbols), _)) => |
215 Some(Completion.Context(language, symbols)) |
215 Some(Completion.Context(language, symbols)) |
216 case Text.Info(_, XML.Elem(markup, _)) => |
216 case Text.Info(_, XML.Elem(markup, _)) => |
217 if (completion_elements(markup.name)) |
217 Some(Completion.Context(Markup.Language.UNKNOWN, true)) |
218 Some(Completion.Context(Markup.Language.UNKNOWN, true)) |
|
219 else None |
|
220 }) |
218 }) |
221 result match { |
219 result match { |
222 case Text.Info(_, context) :: _ => Some(context) |
220 case Text.Info(_, context) :: _ => Some(context) |
223 case Nil => None |
221 case Nil => None |
224 } |
222 } |
237 { |
235 { |
238 if (snapshot.is_outdated) None |
236 if (snapshot.is_outdated) None |
239 else { |
237 else { |
240 val results = |
238 val results = |
241 snapshot.cumulate_markup[(Protocol.Status, Int)]( |
239 snapshot.cumulate_markup[(Protocol.Status, Int)]( |
242 range, (Protocol.Status.init, 0), Some(overview_elements), _ => |
240 range, (Protocol.Status.init, 0), overview_elements, _ => |
243 { |
241 { |
244 case ((status, pri), Text.Info(_, elem)) => |
242 case ((status, pri), Text.Info(_, elem)) => |
245 if (elem.name == Markup.WARNING || elem.name == Markup.ERROR) |
243 if (elem.name == Markup.WARNING || elem.name == Markup.ERROR) |
246 Some((status, pri max Rendering.message_pri(elem.name))) |
244 Some((status, pri max Rendering.message_pri(elem.name))) |
247 else if (overview_elements(elem.name)) |
245 else |
248 Some((Protocol.command_status(status, elem.markup), pri)) |
246 Some((Protocol.command_status(status, elem.markup), pri)) |
249 else None |
|
250 }) |
247 }) |
251 if (results.isEmpty) None |
248 if (results.isEmpty) None |
252 else { |
249 else { |
253 val (status, pri) = |
250 val (status, pri) = |
254 ((Protocol.Status.init, 0) /: results) { |
251 ((Protocol.Status.init, 0) /: results) { |
273 Markup.TYPING, Markup.FREE, Markup.SKOLEM, Markup.BOUND, |
270 Markup.TYPING, Markup.FREE, Markup.SKOLEM, Markup.BOUND, |
274 Markup.VAR, Markup.TFREE, Markup.TVAR) |
271 Markup.VAR, Markup.TFREE, Markup.TVAR) |
275 |
272 |
276 def highlight(range: Text.Range): Option[Text.Info[Color]] = |
273 def highlight(range: Text.Range): Option[Text.Info[Color]] = |
277 { |
274 { |
278 snapshot.select_markup(range, Some(highlight_elements), _ => |
275 snapshot.select_markup(range, highlight_elements, _ => |
279 { |
276 { |
280 case Text.Info(info_range, elem) => |
277 case info => Some(Text.Info(snapshot.convert(info.range), highlight_color)) |
281 if (highlight_elements(elem.name)) |
278 }) match { case Text.Info(_, info) :: _ => Some(info) case _ => None } |
282 Some(Text.Info(snapshot.convert(info_range), highlight_color)) |
|
283 else None |
|
284 }) match { case Text.Info(_, info) :: _ => Some(info) case _ => None } |
|
285 } |
279 } |
286 |
280 |
287 |
281 |
288 private val hyperlink_elements = |
282 private val hyperlink_elements = |
289 Set(Markup.ENTITY, Markup.PATH, Markup.POSITION, Markup.URL) |
283 Set(Markup.ENTITY, Markup.PATH, Markup.POSITION, Markup.URL) |
303 } |
297 } |
304 |
298 |
305 def hyperlink(range: Text.Range): Option[Text.Info[PIDE.editor.Hyperlink]] = |
299 def hyperlink(range: Text.Range): Option[Text.Info[PIDE.editor.Hyperlink]] = |
306 { |
300 { |
307 snapshot.cumulate_markup[List[Text.Info[PIDE.editor.Hyperlink]]]( |
301 snapshot.cumulate_markup[List[Text.Info[PIDE.editor.Hyperlink]]]( |
308 range, Nil, Some(hyperlink_elements), _ => |
302 range, Nil, hyperlink_elements, _ => |
309 { |
303 { |
310 case (links, Text.Info(info_range, XML.Elem(Markup.Path(name), _))) |
304 case (links, Text.Info(info_range, XML.Elem(Markup.Path(name), _))) |
311 if Path.is_ok(name) => |
305 if Path.is_ok(name) => |
312 val jedit_file = PIDE.thy_load.append(snapshot.node_name.master_dir, Path.explode(name)) |
306 val jedit_file = PIDE.thy_load.append(snapshot.node_name.master_dir, Path.explode(name)) |
313 val link = PIDE.editor.hyperlink_file(jedit_file) |
307 val link = PIDE.editor.hyperlink_file(jedit_file) |
347 |
341 |
348 private val active_elements = |
342 private val active_elements = |
349 Set(Markup.BROWSER, Markup.GRAPHVIEW, Markup.SENDBACK, Markup.DIALOG, Markup.SIMP_TRACE) |
343 Set(Markup.BROWSER, Markup.GRAPHVIEW, Markup.SENDBACK, Markup.DIALOG, Markup.SIMP_TRACE) |
350 |
344 |
351 def active(range: Text.Range): Option[Text.Info[XML.Elem]] = |
345 def active(range: Text.Range): Option[Text.Info[XML.Elem]] = |
352 snapshot.select_markup(range, Some(active_elements), command_state => |
346 snapshot.select_markup(range, active_elements, command_state => |
353 { |
347 { |
354 case Text.Info(info_range, elem @ Protocol.Dialog(_, serial, _)) |
348 case Text.Info(info_range, elem @ Protocol.Dialog(_, serial, _)) |
355 if !command_state.results.defined(serial) => |
349 if !command_state.results.defined(serial) => |
|
350 Some(Text.Info(snapshot.convert(info_range), elem)) |
|
351 case Text.Info(info_range, elem) => |
|
352 if (elem.name == Markup.BROWSER || |
|
353 elem.name == Markup.GRAPHVIEW || |
|
354 elem.name == Markup.SENDBACK || |
|
355 elem.name == Markup.SIMP_TRACE) |
356 Some(Text.Info(snapshot.convert(info_range), elem)) |
356 Some(Text.Info(snapshot.convert(info_range), elem)) |
357 case Text.Info(info_range, elem) => |
357 else None |
358 if (elem.name == Markup.BROWSER || |
358 }) match { case Text.Info(_, info) :: _ => Some(info) case _ => None } |
359 elem.name == Markup.GRAPHVIEW || |
|
360 elem.name == Markup.SENDBACK || |
|
361 elem.name == Markup.SIMP_TRACE) |
|
362 Some(Text.Info(snapshot.convert(info_range), elem)) |
|
363 else None |
|
364 }) match { case Text.Info(_, info) :: _ => Some(info) case _ => None } |
|
365 |
359 |
366 |
360 |
367 def command_results(range: Text.Range): Command.Results = |
361 def command_results(range: Text.Range): Command.Results = |
368 { |
362 { |
369 val results = |
363 val results = |
370 snapshot.select_markup[Command.Results](range, None, command_state => |
364 snapshot.select_markup[Command.Results](range, _ => true, command_state => |
371 { case _ => Some(command_state.results) }).map(_.info) |
365 { case _ => Some(command_state.results) }).map(_.info) |
372 (Command.Results.empty /: results)(_ ++ _) |
366 (Command.Results.empty /: results)(_ ++ _) |
373 } |
367 } |
374 |
368 |
|
369 private val tooltip_message_elements = |
|
370 Set(Markup.WRITELN, Markup.WARNING, Markup.ERROR, Markup.BAD) |
|
371 |
375 def tooltip_message(range: Text.Range): Option[Text.Info[XML.Body]] = |
372 def tooltip_message(range: Text.Range): Option[Text.Info[XML.Body]] = |
376 { |
373 { |
377 val results = |
374 val results = |
378 snapshot.cumulate_markup[List[Text.Info[Command.Results.Entry]]](range, Nil, |
375 snapshot.cumulate_markup[List[Text.Info[Command.Results.Entry]]]( |
379 Some(Set(Markup.WRITELN, Markup.WARNING, Markup.ERROR, Markup.BAD)), _ => |
376 range, Nil, tooltip_message_elements, _ => |
380 { |
377 { |
381 case (msgs, Text.Info(info_range, |
378 case (msgs, Text.Info(info_range, |
382 XML.Elem(Markup(name, props @ Markup.Serial(serial)), body))) |
379 XML.Elem(Markup(name, props @ Markup.Serial(serial)), body))) |
383 if name == Markup.WRITELN || name == Markup.WARNING || name == Markup.ERROR => |
380 if name == Markup.WRITELN || name == Markup.WARNING || name == Markup.ERROR => |
384 val entry: Command.Results.Entry = |
381 val entry: Command.Results.Entry = |
431 if (prev.range == r) Text.Info(r, (t, p :: info)) else Text.Info(r, (t, List(p))) |
428 if (prev.range == r) Text.Info(r, (t, p :: info)) else Text.Info(r, (t, List(p))) |
432 } |
429 } |
433 |
430 |
434 val results = |
431 val results = |
435 snapshot.cumulate_markup[Text.Info[(Timing, List[(Boolean, XML.Tree)])]]( |
432 snapshot.cumulate_markup[Text.Info[(Timing, List[(Boolean, XML.Tree)])]]( |
436 range, Text.Info(range, (Timing.zero, Nil)), Some(tooltip_elements), _ => |
433 range, Text.Info(range, (Timing.zero, Nil)), tooltip_elements, _ => |
437 { |
434 { |
438 case (Text.Info(r, (t1, info)), Text.Info(_, XML.Elem(Markup.Timing(t2), _))) => |
435 case (Text.Info(r, (t1, info)), Text.Info(_, XML.Elem(Markup.Timing(t2), _))) => |
439 Some(Text.Info(r, (t1 + t2, info))) |
436 Some(Text.Info(r, (t1 + t2, info))) |
440 case (prev, Text.Info(r, XML.Elem(Markup.Entity(kind, name), _))) => |
437 case (prev, Text.Info(r, XML.Elem(Markup.Entity(kind, name), _))) => |
441 val kind1 = space_explode('_', kind).mkString(" ") |
438 val kind1 = space_explode('_', kind).mkString(" ") |
484 Rendering.information_pri -> JEdit_Lib.load_icon(options.string("gutter_information_icon")), |
481 Rendering.information_pri -> JEdit_Lib.load_icon(options.string("gutter_information_icon")), |
485 Rendering.warning_pri -> JEdit_Lib.load_icon(options.string("gutter_warning_icon")), |
482 Rendering.warning_pri -> JEdit_Lib.load_icon(options.string("gutter_warning_icon")), |
486 Rendering.legacy_pri -> JEdit_Lib.load_icon(options.string("gutter_legacy_icon")), |
483 Rendering.legacy_pri -> JEdit_Lib.load_icon(options.string("gutter_legacy_icon")), |
487 Rendering.error_pri -> JEdit_Lib.load_icon(options.string("gutter_error_icon"))) |
484 Rendering.error_pri -> JEdit_Lib.load_icon(options.string("gutter_error_icon"))) |
488 |
485 |
489 private val gutter_elements = Set(Markup.WRITELN, Markup.WARNING, Markup.ERROR) |
486 private val gutter_elements = |
|
487 Set(Markup.WRITELN, Markup.WARNING, Markup.ERROR) |
490 |
488 |
491 def gutter_message(range: Text.Range): Option[Icon] = |
489 def gutter_message(range: Text.Range): Option[Icon] = |
492 { |
490 { |
493 val results = |
491 val results = |
494 snapshot.cumulate_markup[Int](range, 0, Some(gutter_elements), _ => |
492 snapshot.cumulate_markup[Int](range, 0, gutter_elements, _ => |
495 { |
493 { |
496 case (pri, Text.Info(_, XML.Elem(Markup(Markup.WRITELN, _), |
494 case (pri, Text.Info(_, XML.Elem(Markup(Markup.WRITELN, _), |
497 List(XML.Elem(Markup(Markup.INFORMATION, _), _))))) => |
495 List(XML.Elem(Markup(Markup.INFORMATION, _), _))))) => |
498 Some(pri max Rendering.information_pri) |
496 Some(pri max Rendering.information_pri) |
499 case (pri, Text.Info(_, XML.Elem(Markup(Markup.WARNING, _), body))) => |
497 case (pri, Text.Info(_, XML.Elem(Markup(Markup.WARNING, _), body))) => |
521 private val squiggly_elements = Set(Markup.WRITELN, Markup.WARNING, Markup.ERROR) |
519 private val squiggly_elements = Set(Markup.WRITELN, Markup.WARNING, Markup.ERROR) |
522 |
520 |
523 def squiggly_underline(range: Text.Range): List[Text.Info[Color]] = |
521 def squiggly_underline(range: Text.Range): List[Text.Info[Color]] = |
524 { |
522 { |
525 val results = |
523 val results = |
526 snapshot.cumulate_markup[Int](range, 0, Some(squiggly_elements), _ => |
524 snapshot.cumulate_markup[Int](range, 0, squiggly_elements, _ => |
527 { |
525 { |
528 case (pri, Text.Info(_, elem)) => |
526 case (pri, Text.Info(_, elem)) => |
529 if (Protocol.is_information(elem)) |
527 if (Protocol.is_information(elem)) |
530 Some(pri max Rendering.information_pri) |
528 Some(pri max Rendering.information_pri) |
531 else if (squiggly_elements(elem.name)) |
529 else |
532 Some(pri max Rendering.message_pri(elem.name)) |
530 Some(pri max Rendering.message_pri(elem.name)) |
533 else None |
|
534 }) |
531 }) |
535 for { |
532 for { |
536 Text.Info(r, pri) <- results |
533 Text.Info(r, pri) <- results |
537 color <- squiggly_colors.get(pri) |
534 color <- squiggly_colors.get(pri) |
538 } yield Text.Info(r, color) |
535 } yield Text.Info(r, color) |
551 Markup.ERROR_MESSAGE, Markup.INFORMATION) |
548 Markup.ERROR_MESSAGE, Markup.INFORMATION) |
552 |
549 |
553 def line_background(range: Text.Range): Option[(Color, Boolean)] = |
550 def line_background(range: Text.Range): Option[(Color, Boolean)] = |
554 { |
551 { |
555 val results = |
552 val results = |
556 snapshot.cumulate_markup[Int](range, 0, Some(line_background_elements), _ => |
553 snapshot.cumulate_markup[Int](range, 0, line_background_elements, _ => |
557 { |
554 { |
558 case (pri, Text.Info(_, elem)) => |
555 case (pri, Text.Info(_, elem)) => |
559 val name = elem.name |
556 val name = elem.name |
560 if (name == Markup.INFORMATION) |
557 if (name == Markup.INFORMATION) |
561 Some(pri max Rendering.information_pri) |
558 Some(pri max Rendering.information_pri) |
565 else None |
562 else None |
566 }) |
563 }) |
567 val pri = (0 /: results) { case (p1, Text.Info(_, p2)) => p1 max p2 } |
564 val pri = (0 /: results) { case (p1, Text.Info(_, p2)) => p1 max p2 } |
568 |
565 |
569 val is_separator = pri > 0 && |
566 val is_separator = pri > 0 && |
570 snapshot.cumulate_markup[Boolean](range, false, Some(Set(Markup.SEPARATOR)), _ => |
567 snapshot.cumulate_markup[Boolean](range, false, Set(Markup.SEPARATOR), _ => |
571 { |
568 { |
572 case (_, Text.Info(_, elem)) => |
569 case (_, Text.Info(_, elem)) => |
573 if (elem.name == Markup.SEPARATOR) Some(true) else None |
570 if (elem.name == Markup.SEPARATOR) Some(true) else None |
574 }).exists(_.info) |
571 }).exists(_.info) |
575 |
572 |
591 if (snapshot.is_outdated) List(Text.Info(range, outdated_color)) |
588 if (snapshot.is_outdated) List(Text.Info(range, outdated_color)) |
592 else |
589 else |
593 for { |
590 for { |
594 Text.Info(r, result) <- |
591 Text.Info(r, result) <- |
595 snapshot.cumulate_markup[(Option[Protocol.Status], Option[Color])]( |
592 snapshot.cumulate_markup[(Option[Protocol.Status], Option[Color])]( |
596 range, (Some(Protocol.Status.init), None), Some(background1_elements), command_state => |
593 range, (Some(Protocol.Status.init), None), background1_elements, command_state => |
597 { |
594 { |
598 case (((Some(status), color), Text.Info(_, XML.Elem(markup, _)))) |
595 case (((Some(status), color), Text.Info(_, XML.Elem(markup, _)))) |
599 if (Protocol.command_status_markup(markup.name)) => |
596 if (Protocol.command_status_markup(markup.name)) => |
600 Some((Some(Protocol.command_status(status, markup)), color)) |
597 Some((Some(Protocol.command_status(status, markup)), color)) |
601 case (_, Text.Info(_, XML.Elem(Markup(Markup.BAD, _), _))) => |
598 case (_, Text.Info(_, XML.Elem(Markup(Markup.BAD, _), _))) => |
624 } yield Text.Info(r, color) |
621 } yield Text.Info(r, color) |
625 } |
622 } |
626 |
623 |
627 |
624 |
628 def background2(range: Text.Range): List[Text.Info[Color]] = |
625 def background2(range: Text.Range): List[Text.Info[Color]] = |
629 snapshot.select_markup(range, Some(Set(Markup.TOKEN_RANGE)), _ => |
626 snapshot.select_markup(range, Set(Markup.TOKEN_RANGE), _ => |
630 { |
627 { |
631 case Text.Info(_, elem) => |
628 case Text.Info(_, elem) => |
632 if (elem.name == Markup.TOKEN_RANGE) Some(light_color) else None |
629 if (elem.name == Markup.TOKEN_RANGE) Some(light_color) else None |
633 }) |
630 }) |
634 |
631 |
635 |
632 |
636 def bullet(range: Text.Range): List[Text.Info[Color]] = |
633 def bullet(range: Text.Range): List[Text.Info[Color]] = |
637 snapshot.select_markup(range, Some(Set(Markup.BULLET)), _ => |
634 snapshot.select_markup(range, Set(Markup.BULLET), _ => |
638 { |
635 { |
639 case Text.Info(_, elem) => |
636 case Text.Info(_, elem) => |
640 if (elem.name == Markup.BULLET) Some(bullet_color) else None |
637 if (elem.name == Markup.BULLET) Some(bullet_color) else None |
641 }) |
638 }) |
642 |
639 |
643 |
640 |
644 private val foreground_elements = |
641 private val foreground_elements = |
645 Set(Markup.STRING, Markup.ALTSTRING, Markup.VERBATIM, Markup.CARTOUCHE, Markup.ANTIQUOTED) |
642 Set(Markup.STRING, Markup.ALTSTRING, Markup.VERBATIM, Markup.CARTOUCHE, Markup.ANTIQUOTED) |
646 |
643 |
647 def foreground(range: Text.Range): List[Text.Info[Color]] = |
644 def foreground(range: Text.Range): List[Text.Info[Color]] = |
648 snapshot.select_markup(range, Some(foreground_elements), _ => |
645 snapshot.select_markup(range, foreground_elements, _ => |
649 { |
646 { |
650 case Text.Info(_, elem) => |
647 case Text.Info(_, elem) => |
651 if (elem.name == Markup.ANTIQUOTED) Some(antiquoted_color) |
648 if (elem.name == Markup.ANTIQUOTED) Some(antiquoted_color) else Some(quoted_color) |
652 else if (foreground_elements(elem.name)) Some(quoted_color) |
|
653 else None |
|
654 }) |
649 }) |
655 |
650 |
656 |
651 |
657 private val text_colors: Map[String, Color] = Map( |
652 private val text_colors: Map[String, Color] = Map( |
658 Markup.KEYWORD1 -> keyword1_color, |
653 Markup.KEYWORD1 -> keyword1_color, |
687 |
682 |
688 def text_color(range: Text.Range, color: Color): List[Text.Info[Color]] = |
683 def text_color(range: Text.Range, color: Color): List[Text.Info[Color]] = |
689 { |
684 { |
690 if (color == Token_Markup.hidden_color) List(Text.Info(range, color)) |
685 if (color == Token_Markup.hidden_color) List(Text.Info(range, color)) |
691 else |
686 else |
692 snapshot.cumulate_markup(range, color, Some(text_color_elements), _ => |
687 snapshot.cumulate_markup(range, color, text_color_elements, _ => |
693 { |
688 { |
694 case (_, Text.Info(_, elem)) => text_colors.get(elem.name) |
689 case (_, Text.Info(_, elem)) => text_colors.get(elem.name) |
695 }) |
690 }) |
696 } |
691 } |
697 |
692 |
698 |
693 |
699 /* nested text structure -- folds */ |
694 /* nested text structure -- folds */ |
700 |
695 |
701 private val fold_depth_elements = Set(Markup.TEXT_FOLD, Markup.GOAL, Markup.SUBGOAL) |
696 private val fold_depth_elements = |
|
697 Set(Markup.TEXT_FOLD, Markup.GOAL, Markup.SUBGOAL) |
702 |
698 |
703 def fold_depth(range: Text.Range): List[Text.Info[Int]] = |
699 def fold_depth(range: Text.Range): List[Text.Info[Int]] = |
704 snapshot.cumulate_markup[Int](range, 0, Some(fold_depth_elements), _ => |
700 snapshot.cumulate_markup[Int](range, 0, fold_depth_elements, _ => |
705 { |
701 { |
706 case (depth, Text.Info(_, elem)) => |
702 case (depth, _) => Some(depth + 1) |
707 if (fold_depth_elements(elem.name)) Some(depth + 1) else None |
|
708 }) |
703 }) |
709 } |
704 } |