ANSITerminal is an open source Swift library to access ANSI Terminal and (almost) all of its features. It's including text coloring, text styling, cursor and screen handling, and direct keyboard input. ANSITerminal is based on standard ANSI features which is commonly supported on Unix terminals especially such as xterm and VT-100 compatible. This library currently only supports Linux and macOS, simply because Swift isn't officially available on Windows yet.
Latest version is v.0.0.3 at May, 26th 2019. There are a simple demo and also a simple game made using this library. Have fun! :)
Using ANSITerminal library is as easy as putting
import ANSITerminal in your Swift program then you will be able to use any functions or extensions provided by this library. The main advantage of using this library instead of something like ncurses is it doesn't take over the whole screen. You may use this library to complement your common console program.
Using Swift Package Manager
ANSITerminal only supports library distribution through Swift Package Manager. To use ANSITerminal, simply add a dependency into your project's
package.swift file. Here's
package.swift example from ansiDemo project.
// swift-tools-version:5.0 import PackageDescription let package = Package( name: "ansiDemo", dependencies: [ .package(url: "https://github.com/pakLebah/ANSITerminal", from: "0.0.3"), ], targets: [ .target( name: "ansiDemo", dependencies: ["ANSITerminal"], path: "Sources"), ] )
You just need to add a package dependency pointed to ANSITerminal's GitHub repo and
"ANSITerminal" item into target dependency. Then you should be able to put
import ANSITerminal in your Swift program and enjoy ANSI terminal features. That's all.
If you find a missing ANSI feature that you need, you could simply call
swift package edit ANSITerminal. SPM will create a local copy of ANSITerminal for you, so you could add any missing features by yourself. Everytime you build the project, Swift will refers to the local copy instead of the original source. Once you done with it, don't forget to send a pull request to me. I'll be happy to accept any useful contributions to ANSITerminal from anyone.
ANSI color is available as property to
String type through extension. To color a text, simply follow the text with the color's name. For example,
'text'.blue will produce text (blue text)* on the screen. To set text background color, simply follow the text with the color's name but with
on prefix. For example,
'text'.onCyan will produce text (black text over cyan background) on the screen. As coloring is available as property to
String, you may combine them. For example,
'text'.blue.onCyan will produce text (blue text over cyan background) on the screen. In case you prefer more expressive property name, you may want to use
as prefix for text color. So, instead of
'text'.blue you could use
'text'.asBlue. It's so easy!
But the color name property is only available for the 16 system colors. Most ANSI terminals also support 256 colors. To use 256 colors palette, use
foreColor(_:) type extension method to set text color and
backColor(_:) to set text background color. You may also want to use
colors(_: _:) that combines text color and background color respectively. Those type methods work just like the type properties mentioned before. Since 256 is too many to define correct and consistent name for each of them, you have to use the color index for 256 color palette. For example,
'text'.foreColor(196) will produce text (red text) on the screen. As in 16 colors properties, there are also more expressive method names for 256 colors methods, using
with prefix. So, instead of
'text'.foreColor(196) you could also use
String extension mechanism sets color only for the text. After the text, the color is set back to the default, both for text and background color. If you want more control over the mechanism, you could use
setColor(fore: back:) function for 16 colors system and
setColors(_: _:) function for 256 colors palette. Those functions do not revert color back to the default, so you must not forget to call
setDefault(color: style:) to turn ANSI attributes (either color or style) back to the default. Otherwise, your terminal color will stay with the last color and style settings.
Below are the default color palettes for ANSI terminal. You may need to look it up if you want to get the color number of 256 colors palette.
ANSI Color Palette
16 Colors (System)
216 Colors (by block)
Similar to text coloring, text styling is also available as property to
String type. To style a text, simply follow the text with a style name. For example,
'text'.bold will produce text on the screen,
'text'.italic will produce text on the screen, etc. There are 10 styles available on ANSI terminal, but not all of them are supported by every kind of ANSI terminal. Fortunately,
inverse are mostly supported. So, if you want to use the other styles, make sure your users' terminal supports them.
Since color and style are both ANSI attributes, you may also combine them in a text. For example,
'text'.blue.bold will text (bold blue text) on the screen. Also similar to text coloring, there is also
setStyle(_:) function to fix a text style until you call
setDefault(color: style:) function to turn ANSI attributes (color and style) back to the default.
Here are the available text styles on ANSI terminal:
Cursor and Screen Handling
Cursor Related Functions
storeCursorPosition()to store current cursor position.
restoreCursorPosition()to restore last saved cursor position. Please note that this function sometimes has a side effect to also reset color and style to default on some terminals.
cursorOn()to make cursor visible.
cursorOff()to make cursor invisible (hidden).
moveTo(_: _:)to position cursor to given
readCursorPosition() → (row: col:)to get current cursor position.
Screen Related Functions
clearScreen()to clear the entire screen and put cursor at home position.
clearLine()to clear the entire line of current cursor position.
clearToEndOfLine()to clear the line of current cursor position to the end of line.
scrollRegion(top: bottom:)to set scrolling region of the screen.
readScreenSize() → (row: col:)to get current screen size in
col[umn]. Please note that this function is not supported on emulated terminal such as VS Code's integrated terminal or repl.it's web terminal.**
Keyboard Input Handling
keyPressed() → Boolto check whether any keys on the keyboard is pressed.
readCode() → Intto read keyboard input one by one directly from standard input as ASCII code.
readChar() → Characterto read keyboard input one by one directly from standard input as
readKey() → (code: meta: )to read keyboard input in advance manner, returns ASCII code and meta keys (
alt), if available. This function is important for complex keyboard input such as arrow keys, function keys (F1..F12), and any other possible combinations, which are common in games.
delay(_:)to suspend program execution in milliseconds.
clearBuffer(isOut: isIn:)to clear standard input/output buffer.
write(_:... suspend:)to directly write a (bunch of) text into standard output with optional
suspenddelay, it also has
writeln(_:... suspend:)if you need a
newlineafter the (bunch of) text.
stripAttributes(from:) → Stringto strip all colors and styles from a text to get the actual text, which could be useful to get the actual text's length after adding colors/styles.
ask(_:) → Stringis a shortcut to ask for a question from user.
I consider those as the most useful and used functions in common console applications. You should look into the source code files to see the rest of available functions. I will update the documentation to be more complete. A simple demo program is available here. There is also a simple console game that I made using this library, it's a slide game.
If you have any issues using this library, feel free to submit an issue. Thank you.
* GitHub's Markdown doesn't support custom text color via CSS.
** XCode's integrated console doesn't support ANSI at all.