terminal colors, multi-line strings; bump to 0.8
This commit is contained in:
@@ -25,6 +25,11 @@ val fib = lazySequence(0 to 1) { i, f ->
|
|||||||
|
|
||||||
println(fib[10])
|
println(fib[10])
|
||||||
```
|
```
|
||||||
|
### Terminal colors
|
||||||
|
```kotlin
|
||||||
|
Terminal.print("Hello, ", Terminal.STYLES.BOLD)
|
||||||
|
Terminal.println("World!", Terminal.COLORS.RED.brighter.fg, Terminal.COLORS.WHITE.bg)
|
||||||
|
```
|
||||||
### Unix `uniq`
|
### Unix `uniq`
|
||||||
```kotlin
|
```kotlin
|
||||||
val inp = sequenceOf("AAA", "BBB", "AAA", "AAA", "AAA", "BBB")
|
val inp = sequenceOf("AAA", "BBB", "AAA", "AAA", "AAA", "BBB")
|
||||||
|
@@ -5,7 +5,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group = "me.alex_s168"
|
group = "me.alex_s168"
|
||||||
version = "0.7"
|
version = "0.8"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
@@ -1,33 +0,0 @@
|
|||||||
package blitz
|
|
||||||
|
|
||||||
import blitz.collections.contents
|
|
||||||
import blitz.collections.easyMappingSequence
|
|
||||||
import blitz.func.*
|
|
||||||
import blitz.func.io.*
|
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
|
||||||
// pureCat(args)
|
|
||||||
// .impure()
|
|
||||||
|
|
||||||
val inp = sequenceOf("AAA", "BBB", "AAA", "AAA", "AAA", "BBB")
|
|
||||||
val out = inp.easyMappingSequence { i, s, m ->
|
|
||||||
if (s(i-1) == m(i)) null
|
|
||||||
else m(i)
|
|
||||||
}
|
|
||||||
println(out.contents)
|
|
||||||
}
|
|
||||||
|
|
||||||
// `cat` command
|
|
||||||
fun pureCat(args: Array<String>): Monad<Unit> =
|
|
||||||
args
|
|
||||||
.ifEmpty { arrayOf("-") }
|
|
||||||
.map {
|
|
||||||
if (it == "-") readIn()
|
|
||||||
else unit(it)
|
|
||||||
.asPath()
|
|
||||||
.read()
|
|
||||||
.stringify()
|
|
||||||
}
|
|
||||||
.rewrap()
|
|
||||||
.flatten()
|
|
||||||
.reduce { s -> print(s) }
|
|
@@ -1,5 +1,13 @@
|
|||||||
package blitz
|
package blitz
|
||||||
|
|
||||||
|
@Deprecated(
|
||||||
|
level = DeprecationLevel.ERROR,
|
||||||
|
message = "Will be removed in the future!",
|
||||||
|
replaceWith = ReplaceWith(
|
||||||
|
"Terminal.warn",
|
||||||
|
"blitz.term.Terminal"
|
||||||
|
)
|
||||||
|
)
|
||||||
fun warn(msg: String) {
|
fun warn(msg: String) {
|
||||||
System.err.println(msg)
|
System.err.println(msg)
|
||||||
}
|
}
|
53
src/main/kotlin/blitz/str/MutMultiLineString.kt
Normal file
53
src/main/kotlin/blitz/str/MutMultiLineString.kt
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
package blitz.str
|
||||||
|
|
||||||
|
class MutMultiLineString(
|
||||||
|
var fill: Char
|
||||||
|
) {
|
||||||
|
val lines = mutableListOf<MutString>()
|
||||||
|
|
||||||
|
// TODO: wrap at \n
|
||||||
|
|
||||||
|
/** if out of bounds, extends with @see fill */
|
||||||
|
operator fun get(row: Int, col: Int): Char {
|
||||||
|
if (row >= lines.size) {
|
||||||
|
repeat(row - lines.size + 1) {
|
||||||
|
lines.add(MutString(fill = fill))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lines[row][col]
|
||||||
|
}
|
||||||
|
|
||||||
|
/** if out of bounds, extends with @see fill */
|
||||||
|
operator fun set(row: Int, col: Int, value: Char) {
|
||||||
|
if (row >= lines.size) {
|
||||||
|
repeat(row - lines.size + 1) {
|
||||||
|
lines.add(MutString(fill = fill))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lines[row].fill = fill
|
||||||
|
}
|
||||||
|
lines[row][col] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
/** if out of bounds, extends with @see fill */
|
||||||
|
operator fun set(row: Int, colStart: Int, value: CharSequence) {
|
||||||
|
if (row >= lines.size) {
|
||||||
|
repeat(row - lines.size + 1) {
|
||||||
|
lines.add(MutString(fill = fill))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lines[row].fill = fill
|
||||||
|
}
|
||||||
|
lines[row][colStart] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
/** if out of bounds, extends with @see fill */
|
||||||
|
operator fun set(rowStart: Int, colStart: Int, value: MutMultiLineString) {
|
||||||
|
value.lines.forEachIndexed { index, line ->
|
||||||
|
this[index + rowStart, colStart] = line
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String =
|
||||||
|
lines.joinToString(separator = "\n")
|
||||||
|
}
|
61
src/main/kotlin/blitz/str/MutString.kt
Normal file
61
src/main/kotlin/blitz/str/MutString.kt
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
package blitz.str
|
||||||
|
|
||||||
|
class MutString(
|
||||||
|
init: String = "",
|
||||||
|
var fill: Char
|
||||||
|
): CharSequence, Appendable {
|
||||||
|
private val builder = StringBuilder(init)
|
||||||
|
|
||||||
|
override val length: Int
|
||||||
|
get() = builder.length
|
||||||
|
|
||||||
|
override operator fun get(index: Int): Char {
|
||||||
|
if (index >= length) {
|
||||||
|
repeat(index - length + 1) {
|
||||||
|
builder.append(fill)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builder[index]
|
||||||
|
}
|
||||||
|
|
||||||
|
/** if out of bounds, extends with @see fill */
|
||||||
|
operator fun set(index: Int, value: Char) {
|
||||||
|
if (index >= length) {
|
||||||
|
repeat(index - length + 1) {
|
||||||
|
builder.append(fill)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
builder[index] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
/** if out of bounds, extends with @see fill */
|
||||||
|
operator fun set(start: Int, str: CharSequence) {
|
||||||
|
if (start >= length) {
|
||||||
|
repeat(start - length + 1) {
|
||||||
|
builder.append(fill)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
builder.insert(start, str)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String =
|
||||||
|
builder.toString()
|
||||||
|
|
||||||
|
override fun append(csq: CharSequence?): Appendable {
|
||||||
|
builder.append(csq)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun append(csq: CharSequence?, start: Int, end: Int): Appendable {
|
||||||
|
builder.append(csq, start, end)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun append(c: Char): Appendable {
|
||||||
|
builder.append(c)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun subSequence(startIndex: Int, endIndex: Int): CharSequence =
|
||||||
|
builder.subSequence(startIndex, endIndex)
|
||||||
|
}
|
16
src/main/kotlin/blitz/term/AnsiiStr.kt
Normal file
16
src/main/kotlin/blitz/term/AnsiiStr.kt
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package blitz.term
|
||||||
|
|
||||||
|
class AnsiiMode(internal val values: MutableList<Int>) {
|
||||||
|
constructor(mo: Int): this(mutableListOf(mo))
|
||||||
|
|
||||||
|
operator fun plus(other: AnsiiMode): AnsiiMode =
|
||||||
|
AnsiiMode((values + other.values).toMutableList())
|
||||||
|
}
|
||||||
|
|
||||||
|
private val escape = (27).toChar()
|
||||||
|
|
||||||
|
fun ansiiStr(str: String, vararg modes: AnsiiMode) =
|
||||||
|
if (modes.isEmpty())
|
||||||
|
str
|
||||||
|
else
|
||||||
|
"$escape[${modes.flatMap { it.values }.joinToString(separator = ";")}m$str$escape[0m"
|
70
src/main/kotlin/blitz/term/Terminal.kt
Normal file
70
src/main/kotlin/blitz/term/Terminal.kt
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
package blitz.term
|
||||||
|
|
||||||
|
object Terminal {
|
||||||
|
object COLORS {
|
||||||
|
val BLACK = Color(AnsiiMode(30), AnsiiMode(40))
|
||||||
|
val RED = Color(AnsiiMode(31), AnsiiMode(41))
|
||||||
|
val GREEN = Color(AnsiiMode(32), AnsiiMode(42))
|
||||||
|
val YELLOW = Color(AnsiiMode(33), AnsiiMode(43))
|
||||||
|
val BLUE = Color(AnsiiMode(34), AnsiiMode(44))
|
||||||
|
val MAGENTA = Color(AnsiiMode(35), AnsiiMode(45))
|
||||||
|
val CYAN = Color(AnsiiMode(36), AnsiiMode(46))
|
||||||
|
val WHITE = Color(AnsiiMode(37), AnsiiMode(47))
|
||||||
|
}
|
||||||
|
|
||||||
|
object STYLES {
|
||||||
|
val BOLD = AnsiiMode(1)
|
||||||
|
val DIM = AnsiiMode(2)
|
||||||
|
val UNDERLINE = AnsiiMode(4)
|
||||||
|
val BLINK = AnsiiMode(5)
|
||||||
|
}
|
||||||
|
|
||||||
|
class Color(
|
||||||
|
val fg: AnsiiMode,
|
||||||
|
val bg: AnsiiMode,
|
||||||
|
brighterIn: Color? = null,
|
||||||
|
darkerIn: Color? = null
|
||||||
|
) {
|
||||||
|
private fun ch(mode: AnsiiMode): Int =
|
||||||
|
mode.values[0]
|
||||||
|
|
||||||
|
private fun brighterChannel(va: Int): Int =
|
||||||
|
if (va <= 50) va + 60 else va
|
||||||
|
|
||||||
|
private fun darkerChannel(va: Int): Int =
|
||||||
|
if (va >= 50) va - 60 else va
|
||||||
|
|
||||||
|
val brighter by lazy { Color(AnsiiMode(brighterChannel(ch(fg))), AnsiiMode(brighterChannel(ch(bg)))) }
|
||||||
|
val darker by lazy { Color(AnsiiMode(darkerChannel(ch(fg))), AnsiiMode(darkerChannel(ch(bg)))) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun encodeString(str: String, vararg modes: AnsiiMode) =
|
||||||
|
ansiiStr(str, *modes)
|
||||||
|
|
||||||
|
fun print(str: String, vararg modes: AnsiiMode) {
|
||||||
|
kotlin.io.print(encodeString(str, *modes))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun println(str: String, vararg modes: AnsiiMode) {
|
||||||
|
kotlin.io.println(encodeString(str, *modes))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun err(str: String, vararg modes: AnsiiMode) {
|
||||||
|
System.err.print(encodeString(str, *modes))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun errln(str: String, vararg modes: AnsiiMode) {
|
||||||
|
System.err.println(encodeString(str, *modes))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated(
|
||||||
|
"Use errln instead!",
|
||||||
|
ReplaceWith(
|
||||||
|
"errln(str, *modes)",
|
||||||
|
"blitz.term.Terminal.errln"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
fun warn(str: String, vararg modes: AnsiiMode) {
|
||||||
|
errln(str, *modes)
|
||||||
|
}
|
||||||
|
}
|
16
src/test/kotlin/uniq.kt
Normal file
16
src/test/kotlin/uniq.kt
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import blitz.collections.contents
|
||||||
|
import blitz.collections.easyMappingSequence
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class GeneratorSequences {
|
||||||
|
@Test
|
||||||
|
fun uniq() {
|
||||||
|
val inp = sequenceOf("AAA", "BBB", "AAA", "AAA", "AAA", "BBB")
|
||||||
|
val out = inp.easyMappingSequence { i, s, m ->
|
||||||
|
if (s(i-1) == m(i)) null
|
||||||
|
else m(i)
|
||||||
|
}.filterNotNull()
|
||||||
|
assertEquals(out.contents, listOf("AAA", "BBB", "AAA", "BBB").contents)
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user