/
ProjectNavigation.scala
82 lines (73 loc) · 2.62 KB
/
ProjectNavigation.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/* sbt -- Simple Build Tool
* Copyright 2008, 2009, 2010, 2011 Mark Harrah
*/
package sbt
import ProjectNavigation._
import Project.updateCurrent
import Keys.sessionSettings
import CommandSupport.logger
import complete.{DefaultParsers, Parser}
import DefaultParsers._
import java.net.URI
object ProjectNavigation
{
sealed trait Navigate
final object ShowCurrent extends Navigate
final object Root extends Navigate
final class ChangeBuild(val base: URI) extends Navigate
final class ChangeProject(val id: String) extends Navigate
def command(s: State): Parser[() => State] =
if(s get sessionSettings isEmpty) failure("No project loaded") else (new ProjectNavigation(s)).command
}
final class ProjectNavigation(s: State)
{
val extracted = Project extract s
import extracted.{curi => uri, cid => pid, structure, session}
val builds = structure.units.keys.toSet
val projects = Load.getBuild(structure.units, uri).defined.keys
def setProject(nuri: URI, nid: String) =
{
val neval = if(uri == nuri) session.currentEval else mkEval(nuri)
updateCurrent(s.put(sessionSettings, session.setCurrent(nuri, nid, neval)))
}
def mkEval(nuri: URI) = Load.lazyEval(structure.units(nuri).unit)
def getRoot(uri: URI) = Load.getRootProject(structure.units)(uri)
def apply(action: Navigate): State =
action match
{
case ShowCurrent => show(); s
case Root => setProject(uri, getRoot(uri))
case b: ChangeBuild => changeBuild(b.base)
/* else if(to.forall(_ == '.'))
if(to.length > 1) gotoParent(to.length - 1, nav, s) else s */ // semantics currently undefined
case s: ChangeProject => selectProject(s.id)
}
def show(): Unit = logger(s).info(pid + " (in build " + uri + ")")
def selectProject(to: String): State =
if( structure.units(uri).defined.contains(to) )
setProject(uri, to)
else
fail("Invalid project name '" + to + "' (type 'projects' to list available projects).")
def changeBuild(to: URI): State =
{
val newBuild = (uri resolve to).normalize
if(structure.units contains newBuild)
setProject(newBuild, getRoot(newBuild))
else
fail("Invalid build unit '" + newBuild + "' (type 'projects' to list available builds).")
}
def fail(msg: String): State =
{
logger(s).error(msg)
s.fail
}
import complete.Parser._
import complete.Parsers._
val parser: Parser[Navigate] =
{
val buildP = token('^') ~> token(Uri(builds) map(u => new ChangeBuild(u) ) )
val projectP = token(ID map (id => new ChangeProject(id)) examples projects.toSet )
success(ShowCurrent) | ( token(Space) ~> (token('/' ^^^ Root) | buildP | projectP) )
}
val command: Parser[() => State] = Command.applyEffect(parser)(apply)
}