305 }).map(_.info) |
305 }).map(_.info) |
306 |
306 |
307 |
307 |
308 /* file-system path completion */ |
308 /* file-system path completion */ |
309 |
309 |
310 def language_path(range: Text.Range): Option[Text.Range] = |
310 def language_path(range: Text.Range): Option[Text.Info[Boolean]] = |
311 snapshot.select(range, Rendering.language_elements, _ => |
311 snapshot.select(range, Rendering.language_elements, _ => |
312 { |
312 { |
313 case Text.Info(info_range, XML.Elem(Markup.Language(Markup.Language.PATH, _, _, _), _)) => |
313 case Text.Info(info_range, XML.Elem(Markup.Language.Path(delimited), _)) => |
314 Some(snapshot.convert(info_range)) |
314 Some((delimited, snapshot.convert(info_range))) |
315 case _ => None |
315 case _ => None |
316 }).headOption.map(_.info) |
316 }).headOption.map({ case Text.Info(_, (delimited, range)) => Text.Info(range, delimited) }) |
317 |
317 |
318 def path_completion(caret: Text.Offset): Option[Completion.Result] = |
318 def path_completion(caret: Text.Offset): Option[Completion.Result] = |
319 { |
319 { |
320 def complete(text: String): List[(String, List[String])] = |
320 def complete(text: String): List[(String, List[String])] = |
321 { |
321 { |
355 def is_wrapped(s: String): Boolean = |
355 def is_wrapped(s: String): Boolean = |
356 s.startsWith("\"") && s.endsWith("\"") || |
356 s.startsWith("\"") && s.endsWith("\"") || |
357 s.startsWith(Symbol.open_decoded) && s.endsWith(Symbol.close_decoded) |
357 s.startsWith(Symbol.open_decoded) && s.endsWith(Symbol.close_decoded) |
358 |
358 |
359 for { |
359 for { |
360 r1 <- language_path(before_caret_range(caret)) |
360 Text.Info(r1, delimited) <- language_path(before_caret_range(caret)) |
361 s1 <- model.get_text(r1) |
361 s1 <- model.get_text(r1) |
362 if is_wrapped(s1) |
362 (r2, s2) <- |
363 r2 = Text.Range(r1.start + 1, r1.stop - 1) |
363 if (is_wrapped(s1)) { |
364 s2 = s1.substring(1, s1.length - 1) |
364 Some((Text.Range(r1.start + 1, r1.stop - 1), s1.substring(1, s1.length - 1))) |
|
365 } |
|
366 else if (delimited) Some((r1, s1)) |
|
367 else None |
365 if Path.is_valid(s2) |
368 if Path.is_valid(s2) |
366 paths = complete(s2) |
369 paths = complete(s2) |
367 if paths.nonEmpty |
370 if paths.nonEmpty |
368 items = paths.map(p => Completion.Item(r2, s2, "", p._2, p._1, 0, false)) |
371 items = paths.map(p => Completion.Item(r2, s2, "", p._2, p._1, 0, false)) |
369 } yield Completion.Result(r2, s2, false, items) |
372 } yield Completion.Result(r2, s2, false, items) |