Skip to content
This repository was archived by the owner on Sep 1, 2020. It is now read-only.

Commit 7383eda

Browse files
committed
Merge pull request scala#4563 from adriaanm/jline-shade
Corral, shade & embed jline.
2 parents e1cc99f + dfb70b6 commit 7383eda

17 files changed

+373
-275
lines changed

build.sbt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ lazy val interactive = configureAsSubproject(project)
191191
.settings(disableDocsAndPublishingTasks: _*)
192192
.dependsOn(compiler)
193193

194+
// TODO: SI-9339 embed shaded copy of jline & its interface (see #4563)
194195
lazy val repl = configureAsSubproject(project)
195196
.settings(
196197
libraryDependencies += jlineDep,

build.xml

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,10 @@ TODO:
275275
<dependency groupId="biz.aQute" artifactId="bnd" version="1.50.0"/>
276276
</artifact:dependencies>
277277

278+
<artifact:dependencies pathId="jarjar.classpath">
279+
<dependency groupId="com.googlecode.jarjar" artifactId="jarjar" version="1.3"/>
280+
</artifact:dependencies>
281+
278282
<!-- JUnit -->
279283
<property name="junit.version" value="4.11"/>
280284
<artifact:dependencies pathId="junit.classpath" filesetId="junit.fileset">
@@ -696,7 +700,7 @@ TODO:
696700
<property name="partest-javaagent.description" value="Scala Compiler Testing Tool (compiler-specific java agent)"/>
697701

698702
<!-- projects without project-specific options: forkjoin, manual, bin, repl -->
699-
<for list="actors,compiler,interactive,scaladoc,library,parser-combinators,partest,partest-extras,partest-javaagent,reflect,scalap,swing,xml,continuations-plugin,continuations-library" param="project">
703+
<for list="actors,compiler,interactive,scaladoc,library,parser-combinators,partest,partest-extras,partest-javaagent,reflect,scalap,swing,xml,continuations-plugin,continuations-library,repl-jline" param="project">
700704
<sequential>
701705
<!-- description is mandatory -->
702706
<init-project-prop project="@{project}" name="package" default=""/> <!-- used by mvn-package, copy-bundle, make-bundle -->
@@ -799,6 +803,11 @@ TODO:
799803
<path id="quick.repl.build.path">
800804
<path refid="quick.compiler.build.path"/>
801805
<pathelement location="${build-quick.dir}/classes/repl"/>
806+
</path>
807+
808+
<path id="quick.repl-jline.build.path">
809+
<path refid="quick.repl.build.path"/>
810+
<pathelement location="${build-quick.dir}/classes/repl-jline"/>
802811
<path refid="repl.deps.classpath"/>
803812
</path>
804813

@@ -873,6 +882,8 @@ TODO:
873882
<fileset dir="${build-quick.dir}/classes/actors"/>
874883
</path>
875884

885+
<path id="pack.repl-jline.files"> <fileset dir="${build-quick.dir}/classes/repl-jline"/> </path>
886+
876887
<path id="pack.compiler.files">
877888
<fileset dir="${build-quick.dir}/classes/compiler"/>
878889

@@ -1076,6 +1087,7 @@ TODO:
10761087
</patternset>
10771088

10781089
<taskdef resource="scala/tools/ant/sabbus/antlib.xml" classpathref="starr.compiler.path"/>
1090+
<taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask" classpathref="jarjar.classpath" />
10791091
</target>
10801092

10811093
<!-- ===========================================================================
@@ -1157,7 +1169,31 @@ TODO:
11571169
<staged-build with="locker" stage="quick" project="compiler"/> </target>
11581170

11591171
<target name="quick.repl" depends="quick.comp">
1160-
<staged-build with="locker" stage="quick" project="repl"/> </target>
1172+
<staged-build with="locker" stage="quick" project="repl"/>
1173+
<staged-build with="locker" stage="quick" project="repl-jline"/>
1174+
1175+
<staged-pack project="repl-jline"/>
1176+
1177+
<!-- make jline_embedded jar with classes of repl-jline and jline, then shade-->
1178+
<jarjar jarfile="${build-pack.dir}/${repl-jline.targetdir}/scala-repl-jline-embedded.jar" whenmanifestonly="fail">
1179+
<zipfileset src="${jline:jline:jar}"/>
1180+
<zipfileset src="${build-pack.dir}/${repl-jline.targetdir}/${repl-jline.targetjar}"/>
1181+
1182+
<rule pattern="org.fusesource.**" result="scala.tools.fusesource_embedded.@1"/>
1183+
<rule pattern="jline.**" result="scala.tools.jline_embedded.@1"/>
1184+
<rule pattern="scala.tools.nsc.interpreter.jline.**" result="scala.tools.nsc.interpreter.jline_embedded.@1"/>
1185+
<keep pattern="scala.tools.**"/>
1186+
</jarjar>
1187+
1188+
<!-- unzip jar to repl's class dir to obtain
1189+
- standard repl-jline
1190+
- a shaded repl-jline (scala/tools/nsc/interpreter/jline_embedded) & jline (scala.tools.jline_embedded)
1191+
-->
1192+
<copy todir="${build-quick.dir}/classes/repl">
1193+
<zipfileset src="${build-pack.dir}/${repl-jline.targetdir}/${repl-jline.targetjar}"/>
1194+
<zipfileset src="${build-pack.dir}/${repl-jline.targetdir}/scala-repl-jline-embedded.jar"/>
1195+
</copy>
1196+
</target>
11611197

11621198
<target name="quick.scaladoc" depends="quick.comp">
11631199
<staged-build with="locker" stage="quick" project="scaladoc" version="scaladoc"/> </target>

src/repl/scala/tools/nsc/interpreter/session/FileBackedHistory.scala renamed to src/repl-jline/scala/tools/nsc/interpreter/jline/FileBackedHistory.scala

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
/* NSC -- new Scala compiler
2-
* Copyright 2005-2013 LAMP/EPFL
2+
* Copyright 2005-2015 LAMP/EPFL
33
* @author Paul Phillips
44
*/
55

6-
package scala.tools.nsc
7-
package interpreter
8-
package session
6+
package scala.tools.nsc.interpreter.jline
97

10-
import scala.tools.nsc.io._
11-
import FileBackedHistory._
8+
import _root_.jline.console.history.PersistentHistory
9+
10+
11+
import scala.tools.nsc.interpreter
12+
import scala.tools.nsc.io.{File, Path}
1213

1314
/** TODO: file locking.
14-
*/
15-
trait FileBackedHistory extends JLineHistory with JPersistentHistory {
15+
*/
16+
trait FileBackedHistory extends JLineHistory with PersistentHistory {
1617
def maxSize: Int
17-
protected lazy val historyFile: File = defaultFile
18+
19+
protected lazy val historyFile: File = FileBackedHistory.defaultFile
1820
private var isPersistent = true
1921

2022
locally {
@@ -27,6 +29,7 @@ trait FileBackedHistory extends JLineHistory with JPersistentHistory {
2729
try op
2830
finally isPersistent = saved
2931
}
32+
3033
def addLineToFile(item: CharSequence): Unit = {
3134
if (isPersistent)
3235
append(item + "\n")
@@ -37,6 +40,7 @@ trait FileBackedHistory extends JLineHistory with JPersistentHistory {
3740
val lines = asStrings map (_ + "\n")
3841
historyFile.writeAll(lines: _*)
3942
}
43+
4044
/** Append one or more lines to the history file. */
4145
protected def append(lines: String*): Unit = {
4246
historyFile.appendAll(lines: _*)
@@ -54,31 +58,36 @@ trait FileBackedHistory extends JLineHistory with JPersistentHistory {
5458
// than abandon hope we'll try to read it as ISO-8859-1
5559
case _: Exception =>
5660
try historyFile.lines("ISO-8859-1").toIndexedSeq
57-
catch { case _: Exception => Vector() }
61+
catch {
62+
case _: Exception => Vector()
63+
}
5864
}
5965
}
6066

61-
repldbg("Loading " + lines.size + " into history.")
67+
interpreter.repldbg("Loading " + lines.size + " into history.")
6268

6369
// avoid writing to the history file
6470
withoutSaving(lines takeRight maxSize foreach add)
6571
// truncate the history file if it's too big.
6672
if (lines.size > maxSize) {
67-
repldbg("File exceeds maximum size: truncating to " + maxSize + " entries.")
73+
interpreter.repldbg("File exceeds maximum size: truncating to " + maxSize + " entries.")
6874
sync()
6975
}
7076
moveToEnd()
7177
}
7278

7379
def flush(): Unit = ()
80+
7481
def purge(): Unit = historyFile.truncate()
7582
}
7683

7784
object FileBackedHistory {
7885
// val ContinuationChar = '\003'
7986
// val ContinuationNL: String = Array('\003', '\n').mkString
80-
import Properties.userHome
87+
88+
import scala.tools.nsc.Properties.userHome
8189

8290
def defaultFileName = ".scala_history"
91+
8392
def defaultFile: File = File(Path(userHome) / defaultFileName)
8493
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/* NSC -- new Scala compiler
2+
* Copyright 2005-2013 LAMP/EPFL
3+
* @author Paul Phillips
4+
*/
5+
6+
package scala.tools.nsc.interpreter.jline
7+
8+
import scala.tools.nsc.interpreter
9+
10+
import _root_.jline.console.completer.ArgumentCompleter.{ ArgumentDelimiter, ArgumentList }
11+
12+
// implements a jline interface
13+
class JLineDelimiter extends ArgumentDelimiter {
14+
def toJLine(args: List[String], cursor: Int) = args match {
15+
case Nil => new ArgumentList(new Array[String](0), 0, 0, cursor)
16+
case xs => new ArgumentList(xs.toArray, xs.size - 1, xs.last.length, cursor)
17+
}
18+
19+
def delimit(buffer: CharSequence, cursor: Int) = {
20+
val p = interpreter.Parsed(buffer.toString, cursor)
21+
toJLine(p.args, cursor)
22+
}
23+
24+
def isDelimiter(buffer: CharSequence, cursor: Int) = interpreter.Parsed(buffer.toString, cursor).isDelimiter
25+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/* NSC -- new Scala compiler
2+
* Copyright 2005-2013 LAMP/EPFL
3+
* @author Paul Phillips
4+
*/
5+
6+
package scala.tools.nsc.interpreter.jline
7+
8+
import java.util.{Iterator => JIterator, ListIterator => JListIterator}
9+
10+
import _root_.jline.{console => jconsole}
11+
import jconsole.history.History.{Entry => JEntry}
12+
import jconsole.history.{History => JHistory}
13+
14+
import scala.tools.nsc.interpreter
15+
import scala.tools.nsc.interpreter.session.{History, SimpleHistory}
16+
17+
18+
/** A straight scalification of the jline interface which mixes
19+
* in the sparse jline-independent one too.
20+
*/
21+
trait JLineHistory extends JHistory with History {
22+
def size: Int
23+
def isEmpty: Boolean
24+
def index: Int
25+
def clear(): Unit
26+
def get(index: Int): CharSequence
27+
def add(line: CharSequence): Unit
28+
def replace(item: CharSequence): Unit
29+
30+
def entries(index: Int): JListIterator[JEntry]
31+
def entries(): JListIterator[JEntry]
32+
def iterator: JIterator[JEntry]
33+
34+
def current(): CharSequence
35+
def previous(): Boolean
36+
def next(): Boolean
37+
def moveToFirst(): Boolean
38+
def moveToLast(): Boolean
39+
def moveTo(index: Int): Boolean
40+
def moveToEnd(): Unit
41+
42+
override def historicize(text: String): Boolean = {
43+
text.lines foreach add
44+
moveToEnd()
45+
true
46+
}
47+
}
48+
49+
object JLineHistory {
50+
class JLineFileHistory extends SimpleHistory with FileBackedHistory {
51+
override def add(item: CharSequence): Unit = {
52+
if (!isEmpty && last == item)
53+
interpreter.repldbg("Ignoring duplicate entry '" + item + "'")
54+
else {
55+
super.add(item)
56+
addLineToFile(item)
57+
}
58+
}
59+
override def toString = "History(size = " + size + ", index = " + index + ")"
60+
61+
import scala.collection.JavaConverters._
62+
63+
override def asStrings(from: Int, to: Int): List[String] =
64+
entries(from).asScala.take(to - from).map(_.value.toString).toList
65+
66+
case class Entry(index: Int, value: CharSequence) extends JEntry {
67+
override def toString = value.toString
68+
}
69+
70+
private def toEntries(): Seq[JEntry] = buf.zipWithIndex map { case (x, i) => Entry(i, x)}
71+
def entries(idx: Int): JListIterator[JEntry] = toEntries().asJava.listIterator(idx)
72+
def entries(): JListIterator[JEntry] = toEntries().asJava.listIterator()
73+
def iterator: JIterator[JEntry] = toEntries().iterator.asJava
74+
}
75+
76+
def apply(): History = try new JLineFileHistory catch { case x: Exception => new SimpleHistory() }
77+
}

0 commit comments

Comments
 (0)