Multiplatform text styling for Kotlin command-line applications

Overview

Mordant

Colorful styling for command-line applications

/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.

Usage

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"))

Multiple styles

import com.github.ajalt.mordant.rendering.TextColors.*
val t = Terminal()
t.println("${red("red")} ${white("white")} and ${blue("blue")}")

Foreground and background colors

t.println((yellow on brightGreen)("this is easy to read, right?"))

Background color alone

t.println("The foreground ${brightBlue.bg("color will stay the")} same")

Combine styles and colors

val style = (bold + white + underline)
t.println(style("You can save styles"))
t.println(style("to reuse"))

Nest styles and colors

t.println(white("You ${(blue on yellow)("can ${(black + strikethrough)("nest")} styles")} arbitrarily"))

True color and other color spaces

import com.github.ajalt.mordant.rendering.TextColors.Companion.rgb

t.println(rgb("#b4eeb4")("This will get downsampled on terminals that don't support truecolor"))

Terminal color support detection

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)

Tables

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))
}

Layout

If you need to lay out multiple widgets or strings, you can use the grid builder, which has an API similar to table, but doesn't apply styling by default. There are also the row and column builders if you don't need a full grid.

Markdown

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())

Controlling the cursor

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)

Animations

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, 1, 1)("━")
    }
}

t.cursor.hide(showOnExit = true)
repeat(120) {
    a.update(it)
    Thread.sleep(25)
}

Progress bars

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.

Installation

Mordant is distributed through Maven Central.

dependencies {
   implementation("com.github.ajalt.mordant:mordant:2.0.0-beta4")
}
In version 2.0, the maven coordinates changed. Make sure you're using the new coordinates if you're updating from an older version.
If you're using Maven instead of Gradle, use <artifactId>mordant-jvm</artifactId>

Snapshots

Snapshot builds are also available

You'll need to add the Sonatype snapshots repository:

repositories {
    maven {
        url = uri("https://oss.sonatype.org/content/repositories/snapshots/")
    }
}

License

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.
Comments
  • Is there a way to display several progress bars?

    Is there a way to display several progress bars?

    Hi!

    I really enjoy your code, you are super talented and I learned many cool Kotlin tricks reading your code :)

    My issue is: I want to present several progress bars. Simple use case will be downloading two (or more) files simultaneously - trying to display a progress-bar per file

    I tried several approaches utilizing progressAnimation, one terminal with multiple progress bars, and several terminals with progressAnimation each. Digging a little into the code I realized that this is not the way that I should use your code Sadly my attempts failed miserably :(

    My workaround is not using the progress bars at all and using styled text instead - but I feel like there is possibly a better solution

    Can you please hint to me about what should I do?

    Thanks a bunch!!

    (p.s. I don't mind having both progress bars at the same line but I would prefer them one per line)

    opened by yoelp2k 8
  • IntelliJ console is not detected from a code started via Gradle's JavaExec task

    IntelliJ console is not detected from a code started via Gradle's JavaExec task

    I have a Java application with the library and start it from IntelliJ IDEA via a Gradle JavaExec task. The console is not detected in that scenario.

    The detector code actually fails on the line

    if (!consoleAvailable()) return NONE

    opened by jonnyzzz 7
  • Can we support Kotlin/Native for this library?

    Can we support Kotlin/Native for this library?

    As the title said, can we make this library fit KMPP?, Then I can use this library to develop a command-line tool that could run without JVM on any Platform, Like MacOSX Linux and Windows. 😄

    opened by wuseal 7
  • Animation could overdraw instead of clear to avoid flicker

    Animation could overdraw instead of clear to avoid flicker

    When rendering an animation at high speed there is unfortunately some ugly flicker in most terminals. I suspect the cause is that Animation starts by clearing the space previously used. This is nice and simple but causes flicker. For a flicker-free experience, text should be emitted that covers the entire previous area so clearing isn't used at all.

    Perhaps a simple optimization would be to notice when the size of the rendered widget hasn't changed and just skip the clear, or allow animations to opt-in to that when they know that their rendered widget will always overdraw everything anyway?

    opened by mikehearn 5
  • ProgressBar deletes previous text in IntelliJ Terminal (Jedi)

    ProgressBar deletes previous text in IntelliJ Terminal (Jedi)

    Version: mordant-jvm:2.0.0-beta8 OS: MacOS 13.0.1

    I've noticed, that my application with progress bar works fine in iTerm, but works strangely in IntelliJ Terminal (I've checked on IntelliJ IDEA 2022.3 RC). Even it works fine in IntelliJ Terminal but inside docker container with -tty.

    I think the problem is in the detection of ij terminal:

    val ij = isIntellijConsole() // intellij console is interactive, even through System.console == null
    

    However, for me, ij terminal has System.console != null.

    So, when I unset env variables from com.github.ajalt.mordant.terminal.TerminalDetection#hasIdeaEnvvar my program starts working as expected.

    I've created small reproduce project: https://github.com/zinoviy23/terminal-kotlin-test There is a small script run.sh. When it executed in ij terminal like ./run.sh, progress bar deletes previous lines. But without ij terminal environment variables it works fine: ./run.sh -e.

    opened by zinoviy23 4
  • Widgets don't compute correct width for Emoji sequences

    Widgets don't compute correct width for Emoji sequences

    If you render a Widget, e.g. a grid, emoji sequences like

    • regional letters to make up flags, e.g. 🇩🇪
    • emojis with skin tone modifier, e.g. 👨🏾‍🦱
    • ZWJ (ZERO WIDTH JOINER) joined emojis , e.g. 👩‍👩‍👦‍👦 seem to render with an incorrectly rendered width.

    Sample:

     Terminal().render(
                        grid {
                            cellBorders = NONE
                            it.forEachIndexed { i, (_, maxWidth) ->
                                column(i) {
                                    width = ColumnWidth.Fixed(maxWidth + [email protected])
                                    if (i > 0) padding(0, [email protected])
                                }
                            }
                            row {
                                whitespace = PRE_LINE
                                verticalAlign = TOP
                                overflowWrap = BREAK_WORD
                                cellsFrom(it.map { it.first.toString() + "🇩🇪👨🏾‍🦱👩‍👩‍👦‍👦" })
                            }
                        }
                    )
    

    Above code renders as:

    LOREM IPSUM DOLOR SIT AMET, CONSETETUR       LOREM IPSUM DOLOR SIT AMET,
    SADIPSCING ELITR, SED DIAM NONUMY            CONSETETUR SADIPSCING ELITR,
    EIRMOD.🇩🇪👨🏾‍🦱👩‍👩‍👦‍👦                      SED DIAM NONUMY
                                                 EIRMOD.🇩🇪👨🏾‍🦱👩‍👩‍👦‍👦
    

    whereas the words "SED DIAM NONUMY" of the second column appear too much to the left.

    opened by bkahlert 4
  • Idea: more generalization for ptys

    Idea: more generalization for ptys

    I updated to latest Mordant today - looks good. I found the way stderr is handled a little odd. Why is it done as a sort of transformation of TerminalInterface/Terminal? It feels a bit like Terminal should just be a wrapper around an arbitrary byte stream and maybe a set of environment variables, rather than special cased for stderr/stdout, as that way you can easily connect it to things like a telnet or ssh session. Note that this would require modifying StdoutTerminalInterface.

    opened by mikehearn 4
  • Mordant 2.0 max table width

    Mordant 2.0 max table width

    I have a table with 10 columns. The text gets always truncated even if I set OverflowWrap.NORMAL. It seems there is a table max-width that I am not able to override. Is there any way to have tables with a width that depends exclusively on the content?

    opened by fabriziofortino 4
  • IntelliJ detection misfires if the program has a command line containing the word

    IntelliJ detection misfires if the program has a command line containing the word "idea"

    This line in TerminalDetection.kt:

    getJavaProperty("sun.java.command")?.contains("idea", ignoreCase = true) == true

    will cause terminal corruption if you run a program with the word "idea" anywhere in the command line arguments. (yup, debugging this one was fun 😆 ). I filed https://github.com/JetBrains/jediterm/issues/253 to request a specific env var to be set, but for now, the sun.java.command check should probably be removed. The others look fairly specific but this one is too broad and will cause obscure bugs for any tool that is used on files in the default IntelliJ project directory (e.g. ~/IdeaProjects).

    opened by mikehearn 3
  • A grid with a single column and fixed width n only hold n-1 characters

    A grid with a single column and fixed width n only hold n-1 characters

    The following code should render a grid with a single cell (fixed 80 width) and its content of 80 1-width characters in a single line.

    Terminal().render(
                        grid {
                            cellBorders = NONE
                            padding(0, 0, 0, 0)
                            column(0) {
                                width = ColumnWidth.Fixed(80)
                            }
                            row {
                                whitespace = PRE_LINE
                                verticalAlign = TOP
                                overflowWrap = BREAK_WORD
                                cell("Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod.")
                            }
                        }
                    )
    

    Expected

    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod.
    

    Actual

    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
    eirmod.
    

    Removing one character from the content string makes the grid widget consume only a single line.

    opened by bkahlert 3
  • No border between rows, or bottom border when borders = Borders.LEFT_RIGHT

    No border between rows, or bottom border when borders = Borders.LEFT_RIGHT

    I am trying to get this table layout:

    +-----------------+-------------+----------+
    | Column A        | Column B    | Column C |
    +-----------------+-------------+----------+
    | Lorem Ipsum...  | 123         | A        |
    | Lorem Ipsum...  | 123         | B        |
    | Lorem Ipsum...  | 123         | C        |
    +-----------------+-------------+----------+
    

    i.e I don't want borders between the rows, as in the default:

    +-----------------+-------------+----------+
    | Column A        | Column B    | Column C |
    +-----------------+-------------+----------+
    | Lorem Ipsum...  | 123         | A        |
    +-----------------+-------------+----------+
    | Lorem Ipsum...  | 123         | B        |
    +-----------------+-------------+----------+
    | Lorem Ipsum...  | 123         | C        |
    +-----------------+-------------+----------+
    

    So I used borders = Borders.LEFT_RIGHT:

    borderType = BorderType.ASCII
    header {
        row("Column A", "Column B", "Column C")
    }
    body {
        borders = Borders.LEFT_RIGHT
        for (thing in things) {
            ...
        }
    }
    

    What I get now is:

    +-----------------+-------------+----------+
    | Column A        | Column B    | Column C |
    +-----------------+-------------+----------+
    | Lorem Ipsum...  | 123         | A        |
    | Lorem Ipsum...  | 123         | B        |
    | Lorem Ipsum...  | 123         | C        |
    

    i.e the price is the bottom border.

    The only way I found to overcome this is to do something really nasty:

    borderType = BorderType.ASCII
    header {
        row("Column A", "Column B", "Column C")
    }
    body {
        borders = Borders.LEFT_RIGHT
        for ((idx, thing) in things.withIndex()) {
            row {
                cells(...)
                if (idx == things.lastIndex) {
                    borders = Borders.LEFT_RIGHT_BOTTOM
                }
            }
        }
    }
    

    Which I assume isn't what we want to demand from the user of the library...

    So either I'm missing the really simple way to do this, or it's missing.

    opened by amirabiri 3
  • TerminalDetection not detecting IntelliJ

    TerminalDetection not detecting IntelliJ

    The TerminalDetection computes AnsiLevel.NONE although I'm running my unit tests inside of IntelliJ (Build #IU-221.6008.13, built on July 19, 2022).

    The runningInIdeaJavaAgent method does not match. On my mac ManagementFactory.getRuntimeMXBean() returns the following elements

    0 = "-Dorg.gradle.internal.worker.tmpdir=/Users/bkahlert/Development/com.bkahlert/kommons/build/tmp/jvmTest/work"
    1 = "-Dorg.gradle.native=false"
    2 = "-agentlib:jdwp=transport=dt_socket,server=n,suspend=y,address=127.0.0.1:56426"
    3 = "-javaagent:/Users/bkahlert/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-coroutines-core-jvm/1.6.1/97fd74ccf54a863d221956ffcd21835e168e2aaa/kotlinx-coroutines-core-jvm-1.6.1.jar"
    4 = "--add-opens=java.base/java.util=ALL-UNNAMED"
    5 = "--add-opens=java.base/java.lang=ALL-UNNAMED"
    6 = "-Xms128m"
    7 = "-Xmx512m"
    8 = "-Dfile.encoding=UTF-8"
    9 = "-Duser.country=US"
    10 = "-Duser.language=en"
    11 = "-Duser.variant"
    12 = "-ea"
    

    System.getProperty("sun.java.command") reports "worker.org.gradle.process.internal.worker.GradleWorkerMain 'Gradle Test Executor 61'"

    My environment reported by System.getenv() does neither contain IDEA_INITIAL_DIRECTORY, __INTELLIJ_COMMAND_HISTFILE__ nor TERMINAL_EMULATOR.

    The following environment properties might help you:

    ...
    "JAVA_MAIN_CLASS_56145" -> "worker.org.gradle.process.internal.worker.GradleWorkerMain"
    "TOOLBOX_VERSION" -> "1.25.12424"
    "__CFBundleIdentifier" -> "com.jetbrains.intellij"
    "SHELL" -> "/bin/zsh"
    "__CF_USER_TEXT_ENCODING" -> "0x40E34E6:0x0:0x0"
    
    opened by bkahlert 1
  • Protected strings such as URLs

    Protected strings such as URLs

    If you render a widget containing an URL/URI — depending on the whitespace setting — it might be wrapped which makes IntelliJ no longer detect it.

    Consequently, you can no longer click on it.

    It would be great if there was a means to protect certain strings, e.g. by a regular expression.

    opened by bkahlert 0
  • Support for scrolling regions

    Support for scrolling regions

    A really nice VTS feature that is missing, are Scrolling Margins.

    Usage Idea

    To keep usage in line with table I suggest something like this:

    scrollingRegion {
      width = Int
      height = Int
      smooth = Boolean
      t.println("REALLY LONG TEXT...")
    }
    

    This would set the scrolling margins from the current line (which would need to be tracked or somehow got from DECXCPR) to the current line + height (and maybe there is a need to scroll some lines with SU, to make sure the height is respected).

    After the block, the scrolling margin would be reset.

    noteworthy things

    • DECSTBM is used to set top and bottom margins
    • DECLRMM needs to be set to be able to set left and right margins
    • DECSLRM is used to set left and right margins
    • DECSCLM can be used to set to smooth scrolling mode
    • DECSSCLS can be used to set the scroll speed
    • There should probably be a kind of failsafe, so the margins are reset if the code inside the block fails
    opened by Sett17 0
  • Problems with MinGW Terminal

    Problems with MinGW Terminal

    Hello :-) I'm the author of https://github.com/Framstag/taskdown

    I use mordant (the latest beta) to add colored output in the terminal and (with the new beta) to print nicely formatted Markdown to the terminal.

    This works perfectly under Linux and under Windows native, however it does not work under MinGW (under Windows). The problem occurs with the standard installation, but also with the integration inf MinGW in the new Windows terminal (calling bash.exe -l -i from the terminal configuration).

    The problem is, that I use MinGW under Windows as preferred working environment.

    I'm not sure what exactly the problem is, or if it is even a problem of mordant itself. IF I call my program with TERM=dumb (the problem disappears (unsurprisingly)). I tried to set TERM to other values to trick the autodetection mechanism, but did not find a variant to resulted in working output.

    DOS Shell: grafik

    MinGW bash: grafik

    I obviously need some help, and I'm willing to help you if you give me advice what to do.

    opened by Framstag 3
  • Mordant 2.0: interactive list support

    Mordant 2.0: interactive list support

    It would be nice to have a Widget to support the interactive selection of items from a list.

    Something similar to this: https://github.com/DmitryBogomolov/cli-list-select

    opened by fabriziofortino 1
Releases(2.0.0-beta10)
  • 2.0.0-beta10(Dec 18, 2022)

    Changed

    • JVM: terminal detection now uses JNA to call kernel functions directly.
    • Interactive state of stdin and stdout are now detected separately.
    • Terminal size detection is now fast since it does not need a subprocess. Terminal size is detected automatically at startup.

    Fixed

    • Detect terminal correctly when running in the IntelliJ terminal tab, but not through a run action. (#76)

    Deprecated

    • timeoutMs parameter to TerminalDetection.updateTerminalSize. This function is now fast on all platforms.
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0-beta9(Nov 26, 2022)

  • 2.0.0-beta8(Oct 16, 2022)

    Added

    • Implemented hideInput for prompts on native targets (#63)
    • Improve cell-width calculation for emoji sequences like skin tone modifiers (#64)
    • Added Theme.plus to combine two themes
    • Added Padding.plus to combine two padding values

    Changed

    • Replaced most of the Padding constructor and Widget.withPadding overloads with a unified builder interface
    • Renamed the top level row and column builders to horizonalLayout and verticalLayout, respectively
    • Update Kotlin to 1.7.20
    • Kotlin/Native: use new default memory manager. Objects are no longer frozen.

    Removed

    • Removed buildWidget. Use horizonalLayout and verticalLayout instead.
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0-beta7(Jun 12, 2022)

    Added

    • Functionality for reading user input: Terminal.readLineOrNull, Terminal.prompt and various Prompt classes
    • TerminalRecorder that saves output to memory rather than printing it.
    • TerminalRecorder.outputAsHtml() that can render recorded output as an html file.

    Changed

    • When building tables, borders has been renamed cellBorders, and outerBorder: Boolean has been replaced with tableBorders: Borders?, which allows more control over the table's outside borders. (#58)
    • Update Kotlin to 1.7.0

    Fixed

    • Avoid clobbering output when using Terminal.forStdErr while an animation is running. (#54)

    Deprecated

    • Deprecated the VirtualTerminalInterface. Use TerminalRecorder instead.
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0-beta6(May 8, 2022)

    Changed

    • Update Kotlin to 1.6.20
    • Publish JS target with the IR format in addition to LEGACY

    Fixed

    • Fix race condition when using ProgressAnimation and adding interceptors in JVM (#55)
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0-beta5(Feb 27, 2022)

    Added

    • Progress bars and other single-line animations are now supported in the IntelliJ console (#49)
    • Added bottomTitle to Panel
    • Terminal.forStdErr for printing to stderr rather than stdout
    • Add macosArm64 target for native M1 macs

    Changed

    • Update Kotlin to 1.6.10
    • Breaking change: Renamed Table and Panel's borderStyle property to borderType and borderTextStyle to borderStyle
    • Breaking change: Renamed TerminalInfo's stdinInteractive and stdoutInteractive to inputInteractive and outputInteractive, respectively
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0-beta4(Dec 5, 2021)

    Added

    • Spinner widget that displays a looping animation
    • EmptyEidget widget that can be used as a placeholder in layouts
    • row{} and column{} widget layouts that create a single row/column of widgets

    Fixed

    • Reduced flickering on high frame rate animations
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0-beta3(Oct 26, 2021)

    Changed

    • Update Kotlin to 1.5.31
    • Update Colormath to 3.0. If you use any colormath colors directly, you may need to update your imports.

    Fixed

    • Fixed exception thrown when parsing markdown tables with empty cells
    • Fixed rendering of markdown image reference links and link content
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0-beta2(Jun 2, 2021)

    Added

    • Published artifacts for macOS

    Changed

    • Update Kotlin to 1.5.10
    • All text instances and print functions now default to preformatted whitespace, meaning that spaces and newlines will be preserved. You can explicitly pass Whitespace.NORMAL to restore the previous behavior.
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0-beta1(Mar 26, 2021)

    Added

    • Table.contentToCsv to render a table's cells to csv format
    • Added support for JavaScript and linux native targets (thanks to @DrewCarlson)
    • Getter properties for standard theme styles

    Changed

    • Update Kotlin to 1.4.31
    • Improve terminal capabilities detection
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0-alpha2(Feb 2, 2021)

    Added

    • Terminal.progressAnimation builder to create a customizable progress bar animation
    • Improved cursor APIs and added ability to produce cursor ANSI codes as a string
    • Add ability to override detected terminal interactivity separately from the ANSI capabilities (#7)

    Changed

    • Rework theming system to simplify customization
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0-alpha1(Feb 2, 2021)

    Mordant 2.0 is a rewrite that retains the simple APIs of Mordant 1.0, and adds support for rendering complex widgets.

    Added

    • Added renderable widgets, including tables, panels, and lists
    • Added markdown rendering
    • Added a theme system to customize text styles on an entire terminal instance
    • Added animations that automatically clear the previous frame when redrawing

    Changed

    • Improved terminal capability detection
    • ANSI colors and styles can now be applied through the TextColors and TextStyles top-level objects, and Terminal.print will downsample th resulting strings based on the detected terminal capabilities.
    Source code(tar.gz)
    Source code(zip)
  • 1.2.1(Mar 17, 2019)

  • 1.2.0(Aug 19, 2018)

    • Add functions for generating ANSI cursor movement
    • Add ability to generate ANSI color code from any colormath color object.
    • Update colormath to 1.2.0
    Source code(tar.gz)
    Source code(zip)
  • 1.1.0(Jul 15, 2018)

  • 1.0.1(Apr 8, 2018)

Loading layout is a container view that manages easy switching between loading, completed and other states of your screen with a single line.

Loading layout is a container view that manages easy switching between loading, completed and other states of your screen with a single line.

ValarTech 16 Jul 5, 2022
A simple and flexible Fillable Progress Layout written in Kotlin

FillProgressLayout ?? A simple and flexible Fill Progress Layout written in Kotlin ?? Netflix button animation using FillProgressLayout Support Librar

null 78 Sep 20, 2022
Custom Progress bar with stages developed in kotlin.

Custom-Progress-SeekBar A fully Customizable Semi Circle Arc Progress Bar. You can customize the the width and color of both progress and progress pla

null 5 Dec 28, 2022
Sector progress bar with kotlin

SectorProgressBar Sector progress bar You can visually see the use of this libra

LiteSoftTeam 3 Feb 18, 2022
KDoctor - A command-line tool that helps to set up the environment for Kotlin Multiplatform Mobile app development

KDoctor is a command-line tool that helps to set up the environment for Kotlin Multiplatform Mobile app development.

Kotlin 331 Dec 29, 2022
A starter project to build command-line tools in Kotlin Multiplatform

A starter project to build command-line tools in Kotlin Multiplatform Contains a re-implementation of a real world CLI tool: git-standup Installation

null 0 May 2, 2022
An all-in-one Jetpack Compose component to handle text styling inside TextFields

An all-in-one Jetpack Compose component to handle text styling inside TextFields

Paweł Chochura 26 Dec 14, 2022
Tools for Kotlin/Kscript to easy write shell command line in kotlin code

Kscript Tools Easy way to run shell command line in kotlin and other tools Usage Used in kscript: @file:DependsOn("com.sealwu:kscript-tools:1.0.2") Us

Seal 4 Dec 12, 2022
Create kotlin android project with one line of command.

README This is an android application template project built with kotlin language and some useful libraries. It provides a creator script to quickly c

nekocode 1.6k Dec 20, 2022
Create kotlin android project with one line of command.

README This is an android application template project built with kotlin language and some useful libraries. It provides a creator script to quickly c

nekocode 1.6k Dec 20, 2022
Create kotlin android project with one line of command.

README This is an android application template project built with kotlin language and some useful libraries. It provides a creator script to quickly c

nekocode 1.6k Dec 20, 2022
A command-line student management system in Kotlin

Student Management System Done as a part of NITK GSDC Android Study Jams 2021 Th

Ranjana Kambhammettu 2 Dec 24, 2021
Utility - The cross-platform native Kotlin command line tool template

Utility The cross-platform native Kotlin command line tool template. Usage Make

null 0 Jan 3, 2022
kinstall is an easy way to install gradle-based command-line kotlin projects that use the application plugin.

kinstall kinstall is an easy way to install gradle-based command-line kotlin projects that use the application plugin. use First, install kinstall its

david kilmer 0 Apr 24, 2022
A library that gives full control over text related technologies such as bidirectional algorithm, open type shaping, text typesetting and text rendering

Tehreer-Android Tehreer is a library which gives full control over following text related technologies. Bidirectional Algorithm OpenType Shaping Engin

Tehreer 61 Dec 15, 2022
Speech-Text Converter is a simple task that enable the user to convert the speech to text or convert text to speech (by Mic)

Speech-Text Converter About Speech-Text Converter is a simple task that enable the user to convert the speech to text or convert text to speech (by Mi

Kareem Saeed 1 Oct 21, 2021
Android application compatible with ZX2C4's Pass command line application

Password Store Download Documentation We're in the process of rewriting our documentation from scratch, and the work-in-progress state can be seen her

Android Password Store 2.2k Jan 8, 2023
Android Java wrapper around ffmpeg command line binary

FFMPEG Library for Android This project is a Java wrapper around an ffmpeg command line binary for use in Android applications. It depends on the andr

Guardian Project 555 Dec 5, 2022
Command-line tool to count per-package methods in Android .dex files

dex-method-counts Simple tool to output per-package method counts in an Android DEX executable grouped by package, to aid in getting under the 65,536

Mihai Parparita 2.6k Nov 25, 2022