The goal of Terminus is to make writing visually appealing command line applications fast, efficient, and intuitive. It aims to provide both high level building blocks like menus and user prompts (y/n, multiple choice, REPL, etc.) as well as lower level access to ANSI codes for users that one more complete control.
Please note: Terminus is an early stage project. I am actively seeking feedback and additional contributers, so get in touch if this is something that interests you!
Usage/Examples
The Terminal class is a shared singleton that provides the primary interface for outputting text, moving the cursor, and interacting with the terminal. When first instantiated, the input mode is set to .cbreak and echoing is turned off.
import Terminus
let terminal = Terminal.shared
Printing output
To print to the screen use one of the terminal‘s write methods:
Terminal/write(_:attributes:)
Terminal/write(attributedString:).
terminal.write("Hello world!")
Text Attributes
Most modern terminal emulators support text styling and color (256 is typical). To add one or more styles to text you can pass an array of attributes when calling write. See Attribute for the list of text styles and color support.
terminal.write("I am bold and underlined.\n", attributes: [.bold, .underline])
You can also use attributed strings to add styling as in:
var attributedString = AttributedString("Hello, bold, underlined, world.")
if let boldRange = attributedString.range(of: "bold") {
attributedString[boldRange].terminalTextAttributes = [.bold]
}
if let underlinedRange = attributedString.range(of: "underlined") {
attributedString[underlinedRange].terminalTextAttributes = [.underline]
}
terminal.write(attributedString: attributedString)
Colors
Terminal cells have a foreground color (typically white) and background color (typically black). Colors can be explicitly defined using RGB or selected by name from built-in color palettes.
You can specify the foreground color using Attribute/color(_:) and any Color specified in RGB.
let greenColor = Color(r:0, g:255, b:0)
terminal.write("Grass is green.\n", attributes: [.color(greenColor)])
To set both the foreground and background colors use Attribute/colorPair(_:) passing in a ColorPair.
let redColor = Color(r: 255, g:0, b:0)
let grayColor = Color(r: 200, g:200, b:200)
let redOnGray = ColorPair(foreground: redColor, background: grayColor)
terminal.write("Red rum.\n", attributes: [.colorPair(redOnGray)])
Terminus also has built-in color palettes that can be used to specify colors by name. Colors from palettes are passed around just like any other Color in Terminus.
let palette = XTermPalette()
let blueOneYellow = ColorPair(foreground: palette.Blue1, background: palette.Yellow1)
terminal.write("Blue on yellow", attributes: [.colorPair(blueOneYellow)])
To capture an entire line of text (until a “\n” is received) use the Terminal/getLine() function.
let line = terminal.getLine()
Getting User Input
To catpure a single keypress use Terminal/getKey().
terminal.write("Press any key: ")
if let key = try? terminal.getKey() {
terminal.write("\nYou pressed the \(key.rawValue) key.")
}
To capture an entire line of text (until a “\n” is received) use the Terminal/getLine() function.
let line = terminal.getLine()
Documentation
You can find the DocC files on the Swift Package Index or compile and view them yourself using XCode or the DocC package.
Installation
Swift Package Manager
To use Terminus in your own Swift PM based project, simply add it as a dependency for your package and executable target:
let package = Package(
// name, platforms, products, etc.
dependencies: [
// other dependencies
.package(url: "https://github.com/jbadger3/Terminus", from: "0.1.0"),
],
targets: [
.executableTarget(name: "YourAppName", dependencies: [
// other dependencies
.product(name: "Terminus", package: "Terminus"),
]),
// other targets
]
)
From XCode
In your current CLI project
Select File > Swift Packages > Add Package Dependency.
Choose a rule for dependency management. Click next.
Click Finish.
Credits/Resources
I am by no means an expert in all things terminal, nor can I say that I haven’t cherry picked bits of code that I liked from other projects. Packages, sources of inspiration, and sources with valuable information include:
ConsolKit from the folks that make Vapor, an http server in swift.
What is it?
The goal of Terminus is to make writing visually appealing command line applications fast, efficient, and intuitive. It aims to provide both high level building blocks like menus and user prompts (y/n, multiple choice, REPL, etc.) as well as lower level access to ANSI codes for users that one more complete control.
Usage/Examples
The
Terminal
class is a shared singleton that provides the primary interface for outputting text, moving the cursor, and interacting with the terminal. When first instantiated, the input mode is set to .cbreak and echoing is turned off.Printing output
To print to the screen use one of the
terminal
‘s write methods:Terminal/write(_:attributes:)
Terminal/write(attributedString:)
.Text Attributes
Most modern terminal emulators support text styling and color (256 is typical). To add one or more styles to text you can pass an array of attributes when calling write. See
Attribute
for the list of text styles and color support.You can also use attributed strings to add styling as in:
Colors
Terminal cells have a foreground color (typically white) and background color (typically black). Colors can be explicitly defined using RGB or selected by name from built-in color palettes.
You can specify the foreground color using
Attribute/color(_:)
and anyColor
specified in RGB.To set both the foreground and background colors use
Attribute/colorPair(_:)
passing in aColorPair
.Terminus also has built-in color palettes that can be used to specify colors by name. Colors from palettes are passed around just like any other
Color
in Terminus.To capture an entire line of text (until a “\n” is received) use the
Terminal/getLine()
function.Getting User Input
To catpure a single keypress use
Terminal/getKey()
.To capture an entire line of text (until a “\n” is received) use the
Terminal/getLine()
function.Documentation
You can find the DocC files on the Swift Package Index or compile and view them yourself using XCode or the DocC package.
Installation
Swift Package Manager
To use
Terminus
in your own Swift PM based project, simply add it as a dependency for your package and executable target:From XCode
In your current CLI project
Credits/Resources
I am by no means an expert in all things terminal, nor can I say that I haven’t cherry picked bits of code that I liked from other projects. Packages, sources of inspiration, and sources with valuable information include:
ConsolKit from the folks that make Vapor, an http server in swift.
commandlinekit from Matthias Zenger over at Google
Termios - a more comprehensive Swifty wrapper for termios than I have implemented here.
XTerm control sequences One of the definitive sources of console related info IMO.
The standard C library read function
Blog on terminal emulators and termios
On buffering of low level input streams at the kernel level
Summary of ANSI Codes
rainbow : A nifty ANSI text styling package.
The TTY demystified : A great article about the history and inner workings of the TTY subsystem.