18 ParserRuleSet, ModeProvider, XModeHandler} |
18 ParserRuleSet, ModeProvider, XModeHandler} |
19 import org.gjt.sp.jedit.indent.IndentRule |
19 import org.gjt.sp.jedit.indent.IndentRule |
20 import org.gjt.sp.jedit.buffer.JEditBuffer |
20 import org.gjt.sp.jedit.buffer.JEditBuffer |
21 |
21 |
22 |
22 |
23 object Token_Markup |
23 object Token_Markup { |
24 { |
|
25 /* line context */ |
24 /* line context */ |
26 |
25 |
27 def mode_rule_set(mode: String): ParserRuleSet = |
26 def mode_rule_set(mode: String): ParserRuleSet = |
28 new ParserRuleSet(mode, "MAIN") |
27 new ParserRuleSet(mode, "MAIN") |
29 |
28 |
30 object Line_Context |
29 object Line_Context { |
31 { |
|
32 def init(mode: String): Line_Context = |
30 def init(mode: String): Line_Context = |
33 new Line_Context(mode, Some(Scan.Finished), Line_Structure.init) |
31 new Line_Context(mode, Some(Scan.Finished), Line_Structure.init) |
34 |
32 |
35 def refresh(buffer: JEditBuffer, line: Int): Unit = |
33 def refresh(buffer: JEditBuffer, line: Int): Unit = |
36 buffer.markTokens(line, DummyTokenHandler.INSTANCE) |
34 buffer.markTokens(line, DummyTokenHandler.INSTANCE) |
37 |
35 |
38 def before(buffer: JEditBuffer, line: Int): Line_Context = |
36 def before(buffer: JEditBuffer, line: Int): Line_Context = |
39 if (line == 0) init(JEdit_Lib.buffer_mode(buffer)) |
37 if (line == 0) init(JEdit_Lib.buffer_mode(buffer)) |
40 else after(buffer, line - 1) |
38 else after(buffer, line - 1) |
41 |
39 |
42 def after(buffer: JEditBuffer, line: Int): Line_Context = |
40 def after(buffer: JEditBuffer, line: Int): Line_Context = { |
43 { |
|
44 val line_mgr = JEdit_Lib.buffer_line_manager(buffer) |
41 val line_mgr = JEdit_Lib.buffer_line_manager(buffer) |
45 def context = |
42 def context = |
46 line_mgr.getLineContext(line) match { |
43 line_mgr.getLineContext(line) match { |
47 case c: Line_Context => Some(c) |
44 case c: Line_Context => Some(c) |
48 case _ => None |
45 case _ => None |
54 } |
51 } |
55 } |
52 } |
56 } |
53 } |
57 |
54 |
58 class Line_Context( |
55 class Line_Context( |
59 val mode: String, |
56 val mode: String, |
60 val context: Option[Scan.Line_Context], |
57 val context: Option[Scan.Line_Context], |
61 val structure: Line_Structure) |
58 val structure: Line_Structure) |
62 extends TokenMarker.LineContext(mode_rule_set(mode), null) |
59 extends TokenMarker.LineContext(mode_rule_set(mode), null) { |
63 { |
|
64 def get_context: Scan.Line_Context = context.getOrElse(Scan.Finished) |
60 def get_context: Scan.Line_Context = context.getOrElse(Scan.Finished) |
65 |
61 |
66 override def hashCode: Int = (mode, context, structure).hashCode |
62 override def hashCode: Int = (mode, context, structure).hashCode |
67 override def equals(that: Any): Boolean = |
63 override def equals(that: Any): Boolean = |
68 that match { |
64 that match { |
73 } |
69 } |
74 |
70 |
75 |
71 |
76 /* tokens from line (inclusive) */ |
72 /* tokens from line (inclusive) */ |
77 |
73 |
78 private def try_line_tokens(syntax: Outer_Syntax, buffer: JEditBuffer, line: Int) |
74 private def try_line_tokens( |
79 : Option[List[Token]] = |
75 syntax: Outer_Syntax, |
80 { |
76 buffer: JEditBuffer, |
|
77 line: Int |
|
78 ): Option[List[Token]] = { |
81 val line_context = Line_Context.before(buffer, line) |
79 val line_context = Line_Context.before(buffer, line) |
82 for { |
80 for { |
83 ctxt <- line_context.context |
81 ctxt <- line_context.context |
84 text <- JEdit_Lib.get_text(buffer, JEdit_Lib.line_range(buffer, line)) |
82 text <- JEdit_Lib.get_text(buffer, JEdit_Lib.line_range(buffer, line)) |
85 } yield Token.explode_line(syntax.keywords, text, ctxt)._1 |
83 } yield Token.explode_line(syntax.keywords, text, ctxt)._1 |
131 else Iterator.empty |
129 else Iterator.empty |
132 |
130 |
133 |
131 |
134 /* command spans */ |
132 /* command spans */ |
135 |
133 |
136 def command_span(syntax: Outer_Syntax, buffer: JEditBuffer, offset: Text.Offset) |
134 def command_span( |
137 : Option[Text.Info[Command_Span.Span]] = |
135 syntax: Outer_Syntax, |
138 { |
136 buffer: JEditBuffer, |
|
137 offset: Text.Offset |
|
138 ): Option[Text.Info[Command_Span.Span]] = { |
139 val keywords = syntax.keywords |
139 val keywords = syntax.keywords |
140 |
140 |
141 def maybe_command_start(i: Text.Offset): Option[Text.Info[Token]] = |
141 def maybe_command_start(i: Text.Offset): Option[Text.Info[Token]] = |
142 token_reverse_iterator(syntax, buffer, i). |
142 token_reverse_iterator(syntax, buffer, i). |
143 find(info => keywords.is_before_command(info.info) || info.info.is_command) |
143 find(info => keywords.is_before_command(info.info) || info.info.is_command) |
145 def maybe_command_stop(i: Text.Offset): Option[Text.Info[Token]] = |
145 def maybe_command_stop(i: Text.Offset): Option[Text.Info[Token]] = |
146 token_iterator(syntax, buffer, i). |
146 token_iterator(syntax, buffer, i). |
147 find(info => keywords.is_before_command(info.info) || info.info.is_command) |
147 find(info => keywords.is_before_command(info.info) || info.info.is_command) |
148 |
148 |
149 if (JEdit_Lib.buffer_range(buffer).contains(offset)) { |
149 if (JEdit_Lib.buffer_range(buffer).contains(offset)) { |
150 val start_info = |
150 val start_info = { |
151 { |
|
152 val info1 = maybe_command_start(offset) |
151 val info1 = maybe_command_start(offset) |
153 info1 match { |
152 info1 match { |
154 case Some(Text.Info(range1, tok1)) if tok1.is_command => |
153 case Some(Text.Info(range1, tok1)) if tok1.is_command => |
155 val info2 = maybe_command_start(range1.start - 1) |
154 val info2 = maybe_command_start(range1.start - 1) |
156 info2 match { |
155 info2 match { |
165 case Some(Text.Info(range, tok)) => |
164 case Some(Text.Info(range, tok)) => |
166 (keywords.is_before_command(tok), range.start, range.stop) |
165 (keywords.is_before_command(tok), range.start, range.stop) |
167 case None => (false, 0, 0) |
166 case None => (false, 0, 0) |
168 } |
167 } |
169 |
168 |
170 val stop_info = |
169 val stop_info = { |
171 { |
|
172 val info1 = maybe_command_stop(start_next) |
170 val info1 = maybe_command_stop(start_next) |
173 info1 match { |
171 info1 match { |
174 case Some(Text.Info(range1, tok1)) if tok1.is_command && start_before_command => |
172 case Some(Text.Info(range1, tok1)) if tok1.is_command && start_before_command => |
175 maybe_command_stop(range1.stop) |
173 maybe_command_stop(range1.stop) |
176 case _ => info1 |
174 case _ => info1 |
191 } |
189 } |
192 else None |
190 else None |
193 } |
191 } |
194 |
192 |
195 private def _command_span_iterator( |
193 private def _command_span_iterator( |
196 syntax: Outer_Syntax, |
194 syntax: Outer_Syntax, |
197 buffer: JEditBuffer, |
195 buffer: JEditBuffer, |
198 offset: Text.Offset, |
196 offset: Text.Offset, |
199 next_offset: Text.Range => Text.Offset): Iterator[Text.Info[Command_Span.Span]] = |
197 next_offset: Text.Range => Text.Offset |
200 new Iterator[Text.Info[Command_Span.Span]] |
198 ): Iterator[Text.Info[Command_Span.Span]] = { |
201 { |
199 new Iterator[Text.Info[Command_Span.Span]] { |
202 private var next_span = command_span(syntax, buffer, offset) |
200 private var next_span = command_span(syntax, buffer, offset) |
203 def hasNext: Boolean = next_span.isDefined |
201 def hasNext: Boolean = next_span.isDefined |
204 def next(): Text.Info[Command_Span.Span] = |
202 def next(): Text.Info[Command_Span.Span] = { |
205 { |
|
206 val span = next_span.getOrElse(Iterator.empty.next()) |
203 val span = next_span.getOrElse(Iterator.empty.next()) |
207 next_span = command_span(syntax, buffer, next_offset(span.range)) |
204 next_span = command_span(syntax, buffer, next_offset(span.range)) |
208 span |
205 span |
209 } |
206 } |
210 } |
207 } |
|
208 } |
211 |
209 |
212 def command_span_iterator(syntax: Outer_Syntax, buffer: JEditBuffer, offset: Text.Offset) |
210 def command_span_iterator(syntax: Outer_Syntax, buffer: JEditBuffer, offset: Text.Offset) |
213 : Iterator[Text.Info[Command_Span.Span]] = |
211 : Iterator[Text.Info[Command_Span.Span]] = |
214 _command_span_iterator(syntax, buffer, offset max 0, range => range.stop) |
212 _command_span_iterator(syntax, buffer, offset max 0, range => range.stop) |
215 |
213 |
221 |
219 |
222 /* token marker */ |
220 /* token marker */ |
223 |
221 |
224 class Marker( |
222 class Marker( |
225 protected val mode: String, |
223 protected val mode: String, |
226 protected val opt_buffer: Option[Buffer]) extends TokenMarker |
224 protected val opt_buffer: Option[Buffer] |
227 { |
225 ) extends TokenMarker { |
228 addRuleSet(mode_rule_set(mode)) |
226 addRuleSet(mode_rule_set(mode)) |
229 |
227 |
230 override def hashCode: Int = (mode, opt_buffer).hashCode |
228 override def hashCode: Int = (mode, opt_buffer).hashCode |
231 override def equals(that: Any): Boolean = |
229 override def equals(that: Any): Boolean = |
232 that match { |
230 that match { |
238 opt_buffer match { |
236 opt_buffer match { |
239 case None => "Marker(" + mode + ")" |
237 case None => "Marker(" + mode + ")" |
240 case Some(buffer) => "Marker(" + mode + "," + JEdit_Lib.buffer_name(buffer) + ")" |
238 case Some(buffer) => "Marker(" + mode + "," + JEdit_Lib.buffer_name(buffer) + ")" |
241 } |
239 } |
242 |
240 |
243 override def markTokens(context: TokenMarker.LineContext, |
241 override def markTokens( |
244 handler: TokenHandler, raw_line: Segment): TokenMarker.LineContext = |
242 context: TokenMarker.LineContext, |
245 { |
243 handler: TokenHandler, |
|
244 raw_line: Segment |
|
245 ): TokenMarker.LineContext = { |
246 val line = if (raw_line == null) new Segment else raw_line |
246 val line = if (raw_line == null) new Segment else raw_line |
247 val line_context = |
247 val line_context = |
248 context match { case c: Line_Context => c case _ => Line_Context.init(mode) } |
248 context match { case c: Line_Context => c case _ => Line_Context.init(mode) } |
249 val structure = line_context.structure |
249 val structure = line_context.structure |
250 |
250 |
251 val context1 = |
251 val context1 = { |
252 { |
|
253 val opt_syntax = |
252 val opt_syntax = |
254 opt_buffer match { |
253 opt_buffer match { |
255 case Some(buffer) => Isabelle.buffer_syntax(buffer) |
254 case Some(buffer) => Isabelle.buffer_syntax(buffer) |
256 case None => Isabelle.mode_syntax(mode) |
255 case None => Isabelle.mode_syntax(mode) |
257 } |
256 } |
305 } |
304 } |
306 |
305 |
307 |
306 |
308 /* mode provider */ |
307 /* mode provider */ |
309 |
308 |
310 class Mode_Provider(orig_provider: ModeProvider) extends ModeProvider |
309 class Mode_Provider(orig_provider: ModeProvider) extends ModeProvider { |
311 { |
|
312 for (mode <- orig_provider.getModes) addMode(mode) |
310 for (mode <- orig_provider.getModes) addMode(mode) |
313 |
311 |
314 override def loadMode(mode: Mode, xmh: XModeHandler): Unit = |
312 override def loadMode(mode: Mode, xmh: XModeHandler): Unit = { |
315 { |
|
316 super.loadMode(mode, xmh) |
313 super.loadMode(mode, xmh) |
317 Isabelle.mode_token_marker(mode.getName).foreach(mode.setTokenMarker) |
314 Isabelle.mode_token_marker(mode.getName).foreach(mode.setTokenMarker) |
318 Isabelle.indent_rule(mode.getName).foreach(indent_rule => |
315 Isabelle.indent_rule(mode.getName).foreach(indent_rule => |
319 Untyped.set[JList[IndentRule]](mode, "indentRules", JList.of(indent_rule))) |
316 Untyped.set[JList[IndentRule]](mode, "indentRules", JList.of(indent_rule))) |
320 } |
317 } |