diff --git a/build.sbt b/build.sbt index 100d379..2c0e1ed 100644 --- a/build.sbt +++ b/build.sbt @@ -84,7 +84,7 @@ pomExtra := ( ) -lazy val benchmarks = project in file("benchmarks") dependsOn(root) +lazy val benchmarks = project in file("benchmarks") aggregate (root) scalaVersion in benchmarks := "2.11.8" diff --git a/src/main/scala/gnieh/pp/package.scala b/src/main/scala/gnieh/pp/package.scala index 277d49c..3fc7509 100644 --- a/src/main/scala/gnieh/pp/package.scala +++ b/src/main/scala/gnieh/pp/package.scala @@ -27,7 +27,7 @@ package object pp { def nest(indent: Int)(inner: Doc): Doc = NestDoc(indent, inner) - /* Deindent the document */ + /** Deindent the document */ @inline def unnest(indent: Int)(inner: Doc): Doc = nest(-indent)(inner) @@ -66,6 +66,11 @@ package object pp { val empty: Doc = EmptyDoc + /** Renders the document with prepending n spaces to the current column */ + @inline + def indent(i: Int)(doc: Doc): Doc = + hang(i)(ConsDoc(TextDoc(" " * i), doc)) + /** Renders the document with nesting level set to the current column */ @inline def align(doc: Doc): Doc = @@ -184,30 +189,30 @@ package object pp { group(vcat(docs)) @inline - implicit def s2doc(s: String) = + implicit def s2doc(s: String): Doc = string(s) @inline - implicit def i2doc(i: Int) = + implicit def i2doc(i: Int): Doc = int(i) @inline - implicit def l2doc(l: Long) = + implicit def l2doc(l: Long): Doc = long(l) @inline - implicit def f2doc(f: Float) = + implicit def f2doc(f: Float): Doc = float(f) @inline - implicit def d2doc(d: Double) = + implicit def d2doc(d: Double): Doc = double(d) @inline - implicit def c2doc(c: Char) = + implicit def c2doc(c: Char): Doc = char(c) - implicit def opt2doc[T <% Doc](o: Option[T]): Doc = o match { + implicit def opt2doc[T](o: Option[T])(implicit ev: T => Doc): Doc = o match { case Some(d) => d case None => empty } diff --git a/src/test/scala/gnieh/pp/tests/IndentTest.scala b/src/test/scala/gnieh/pp/tests/IndentTest.scala new file mode 100644 index 0000000..272cd13 --- /dev/null +++ b/src/test/scala/gnieh/pp/tests/IndentTest.scala @@ -0,0 +1,23 @@ +package gnieh.pp.tests + +import gnieh.pp._ + +class IndentTest extends PpTest { + "the indent operator" should "indent text as block" in { + val docs: List[Doc] = List("line1", "line2", "line3") + val finalDoc = indent(2)(vcat(docs)) + + render80(finalDoc) should be(" line1\n line2\n line3") + } + it should "behave as original Haskell implementation" in { + val doc = indent(4)(fillSep(words("the indent combinator indents these words !"))) + + val expectedRender = + """ the indent + | combinator + | indents these + | words !""".stripMargin + + render20(doc) should be(expectedRender) + } +} diff --git a/src/test/scala/gnieh/pp/tests/ListCombinatorsTest.scala b/src/test/scala/gnieh/pp/tests/ListCombinatorsTest.scala index cdbb5b2..4fa851c 100644 --- a/src/test/scala/gnieh/pp/tests/ListCombinatorsTest.scala +++ b/src/test/scala/gnieh/pp/tests/ListCombinatorsTest.scala @@ -30,5 +30,4 @@ class ListCombinatorsTest extends PpTest { val test2 = "some" :+: align(vsep(someText)) render80(test2) should be("some text\n to\n lay\n out") } - }