/mɔː(ɹ)dənt/ A substance used to set (i.e. bind) colored dyes on fabrics 1
Mordant has:
- Easy colorful ANSI output with automatic detection of terminal capabilities
- Markdown rendering directly to the terminal
- Widget for laying out terminal output, including lists, tables, panels, and more
- Support for animating any widget, like progress bars and dashboards
This README documents Mordant 2.0, which is in beta. You can read the docs for Mordant 1.0 here.
Create a Terminal
instance, and import any enum entries you want from TextColors
and
TextStyles
. The println
function on your Terminal
will detect your current terminal
capabilities and automatically downsample ANSI codes if necessary.
import com.github.ajalt.mordant.rendering.TextColors.*
import com.github.ajalt.mordant.rendering.TextStyles.*
val t = Terminal()
t.println(red("This text will be red on terminals that support color"))
import com.github.ajalt.mordant.rendering.TextColors.*
val t = Terminal()
t.println("${red("red")} ${white("white")} and ${blue("blue")}")
t.println((yellow on brightGreen)("this is easy to read, right?"))
t.println("The foreground ${brightBlue.bg("color will stay the")} same")
val style = (bold + white + underline)
t.println(style("You can save styles"))
t.println(style("to reuse"))
t.println(white("You ${(blue on yellow)("can ${(black + strikethrough)("nest")} styles")} arbitrarily"))
import com.github.ajalt.mordant.rendering.TextColors.Companion.rgb
t.println(rgb("#b4eeb4")("This will get downsampled on terminals that don't support truecolor"))
By default, Terminal()
will try to detect ANSI support in the current stdout stream. If you'd
like to override the detection, you can pass a specific value to the Terminal
constructor.
For example, to always output ANSI RGB color codes, even if stdout is currently directed to a file, you can do this:
Terminal(AnsiLevel.TRUECOLOR)
Use the table
DSL to quickly create tables. Mordant handles ANSI styles and wide characters like
CJK and emoji.
val t = Terminal()
t.println(table {
header { row("CJK", "Emojis") }
body { row("모ㄹ단ㅌ", "🙊🙉🙈") }
})
Mordant gives you lots of customization for your tables, including striped row styles, row and column spans, and different border styles.
table {
borderStyle = SQUARE_DOUBLE_SECTION_SEPARATOR
align = RIGHT
outerBorder = false
column(0) {
align = LEFT
borders = ALL
style = magenta
}
column(3) {
borders = ALL
style = magenta
}
header {
style(magenta, bold = true)
row("", "Projected Cost", "Actual Cost", "Difference")
}
body {
rowStyles(blue, brightBlue)
borders = TOM_BOTTOM
row("Food", "$400", "$200", "$200")
row("Data", "$100", "$150", "-$50")
row("Rent", "$800", "$800", "$0")
row("Candles", "$0", "$3,600", "-$3,600")
row("Utility", "$145", "$150", "-$5")
}
footer {
style(bold = true)
row {
cell("Subtotal")
cell("$-3,455") { columnSpan = 3 }
}
}
captionBottom("Budget courtesy @dril", TextStyle(dim = true))
}
Mordant can render GitHub Flavored Markdown. Hyperlinks will even be clickable if you're on a terminal that supports it, like recent versions of iTerm or Windows Terminal.
val t = Terminal()
t.printMarkdown(File("README.md").readText())
You can show and hide the cursor, move it around, and clear parts of the screen with the cursor
property on Terminal
. If your terminal doesn't support cursor movements (like when output is
redirected to a file) these commands are no-ops.
val t = Terminal()
t.cursor.move {
up(3)
startOfLine()
clearScreenAfterCursor()
}
t.cursor.hide(showOnExit = true)
You can animate any widget like a table with Terminal.animation
, or any regular
string with Terminal.textAnimation
.
val t = Terminal()
val a = t.textAnimation<Int> { frame ->
(1..50).joinToString("") {
val hue = (frame + it) * 3 % 360
t.colors.hsv(hue, 100, 100)("━")
}
}
t.cursor.hide(showOnExit = true)
repeat(120) {
a.update(it)
Thread.sleep(25)
}
You can create customizable progress bars that automatically compute speed and time remaining.
val t = Terminal()
val progress = t.progressAnimation {
text("my-file.iso")
percentage()
progressBar()
completed()
speed("B/s")
timeRemaining()
}
The progressAnimation
builder is currently JVM-only. On other platforms, you can still use
t.animation { progressLayout { ... } }
which will render the same widget, you'll just need to call progress.update
manually.
Call progress.start
to animate the progress, and progress.update
or progress.advance
as your
task completes.
Mordant is distributed through Maven Central.
dependencies {
implementation("com.github.ajalt.mordant:mordant:2.0.0-beta2")
}
In version 2.0, the maven coordinates changed. Make sure you're using the new coordinates if you're updating from an older version.
Copyright 2018-2021 AJ Alt
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.