Ansi.java
package com.guinetik.hexafun.examples.tui;
/**
* ANSI escape code utilities for terminal styling.
* No external dependencies - pure Java terminal control.
*
* <p>Usage:
* <pre class="language-java">{@code
* import static com.guinetik.hexafun.examples.tui.Ansi.*;
*
* System.out.println(color("Hello", GREEN, BOLD));
* System.out.println(color(center("Title", 40), BG_BLUE, WHITE));
* }</pre>
*/
public final class Ansi {
private Ansi() {}
// ═══════════════════════════════════════════════════════════════════
// TEXT STYLES
// ═══════════════════════════════════════════════════════════════════
public static final String RESET = "\u001B[0m";
public static final String BOLD = "\u001B[1m";
public static final String DIM = "\u001B[2m";
public static final String ITALIC = "\u001B[3m";
public static final String UNDERLINE = "\u001B[4m";
// ═══════════════════════════════════════════════════════════════════
// FOREGROUND COLORS
// ═══════════════════════════════════════════════════════════════════
public static final String BLACK = "\u001B[30m";
public static final String RED = "\u001B[31m";
public static final String GREEN = "\u001B[32m";
public static final String YELLOW = "\u001B[33m";
public static final String BLUE = "\u001B[34m";
public static final String MAGENTA = "\u001B[35m";
public static final String CYAN = "\u001B[36m";
public static final String WHITE = "\u001B[37m";
// Bright variants
public static final String BRIGHT_BLACK = "\u001B[90m";
public static final String BRIGHT_RED = "\u001B[91m";
public static final String BRIGHT_GREEN = "\u001B[92m";
public static final String BRIGHT_YELLOW = "\u001B[93m";
public static final String BRIGHT_BLUE = "\u001B[94m";
public static final String BRIGHT_MAGENTA = "\u001B[95m";
public static final String BRIGHT_CYAN = "\u001B[96m";
public static final String BRIGHT_WHITE = "\u001B[97m";
// ═══════════════════════════════════════════════════════════════════
// BACKGROUND COLORS
// ═══════════════════════════════════════════════════════════════════
public static final String BG_BLACK = "\u001B[40m";
public static final String BG_RED = "\u001B[41m";
public static final String BG_GREEN = "\u001B[42m";
public static final String BG_YELLOW = "\u001B[43m";
public static final String BG_BLUE = "\u001B[44m";
public static final String BG_MAGENTA = "\u001B[45m";
public static final String BG_CYAN = "\u001B[46m";
public static final String BG_WHITE = "\u001B[47m";
// ═══════════════════════════════════════════════════════════════════
// CURSOR & SCREEN CONTROL
// ═══════════════════════════════════════════════════════════════════
public static final String CLEAR_SCREEN = "\u001B[2J";
public static final String CLEAR = CLEAR_SCREEN;
public static final String CURSOR_HOME = "\u001B[H";
public static final String HIDE_CURSOR = "\u001B[?25l";
public static final String SHOW_CURSOR = "\u001B[?25h";
// Alternate screen buffer (doesn't pollute scrollback)
public static final String ALT_SCREEN_ON = "\u001B[?1049h";
public static final String ALT_SCREEN_OFF = "\u001B[?1049l";
// ═══════════════════════════════════════════════════════════════════
// BOX DRAWING - UNICODE
// ═══════════════════════════════════════════════════════════════════
// Single line
public static final String BOX_TOP_LEFT = "\u250C"; // ┌
public static final String BOX_TOP_RIGHT = "\u2510"; // ┐
public static final String BOX_BOTTOM_LEFT = "\u2514"; // └
public static final String BOX_BOTTOM_RIGHT = "\u2518"; // ┘
public static final String BOX_HORIZONTAL = "\u2500"; // ─
public static final String BOX_VERTICAL = "\u2502"; // │
public static final String BOX_T_DOWN = "\u252C"; // ┬
public static final String BOX_T_UP = "\u2534"; // ┴
public static final String BOX_T_RIGHT = "\u251C"; // ├
public static final String BOX_T_LEFT = "\u2524"; // ┤
public static final String BOX_CROSS = "\u253C"; // ┼
// Double line
public static final String DBOX_TOP_LEFT = "\u2554"; // ╔
public static final String DBOX_TOP_RIGHT = "\u2557"; // ╗
public static final String DBOX_BOTTOM_LEFT = "\u255A"; // ╚
public static final String DBOX_BOTTOM_RIGHT = "\u255D"; // ╝
public static final String DBOX_HORIZONTAL = "\u2550"; // ═
public static final String DBOX_VERTICAL = "\u2551"; // ║
// ═══════════════════════════════════════════════════════════════════
// NERDFONT SYMBOLS
// ═══════════════════════════════════════════════════════════════════
// Common symbols
public static final String CHECK = "\uEAB2"; // nf-cod-check
public static final String CROSS = "\uEA76"; // nf-cod-close
public static final String BULLET = "\uEABC"; // nf-cod-circle
public static final String ARROW_RIGHT = "\uEA9C"; // nf-cod-arrow_right
public static final String ARROW_LEFT = "\uEA9B"; // nf-cod-arrow_left
public static final String STAR = "\uF005"; // nf-fa-star
public static final String EMPTY_STAR = "\uEA6A"; // nf-cod-star_empty
// Icons
public static final String ICON_TASK = "\uEB67"; // nf-cod-tasklist
public static final String ICON_DASHBOARD = "\uEACD"; // nf-cod-dashboard
public static final String ICON_ADD = "\uEA60"; // nf-cod-add
public static final String ICON_TRASH = "\uEA81"; // nf-cod-trash
public static final String ICON_CHECK_ALL = "\uEBB1"; // nf-cod-check_all
public static final String ICON_INBOX = "\uEB09"; // nf-cod-inbox
public static final String ICON_FOLDER = "\uEA83"; // nf-cod-folder
public static final String ICON_FLAME = "\uEAF2"; // nf-cod-flame
public static final String ICON_GEAR = "\uEAF8"; // nf-cod-gear
public static final String ICON_EYE = "\uEAE5"; // nf-cod-eye
public static final String ICON_INFO = "\uEAFC"; // nf-cod-info
public static final String ICON_EDIT = "\uEA73"; // nf-cod-edit
public static final String ICON_SEARCH = "\uEA6D"; // nf-cod-search
public static final String ICON_HOME = "\uEAF0"; // nf-cod-home
public static final String ICON_TERMINAL = "\uEA85"; // nf-cod-terminal
// Progress bar blocks
public static final String BLOCK_FULL = "\u2588"; // █
public static final String BLOCK_LIGHT = "\u2591"; // ░
public static final String BLOCK_MED = "\u2592"; // ▒
public static final String BLOCK_DARK = "\u2593"; // ▓
// Powerline separators
public static final String PL_LEFT = "\uE0B0"; // nf-pl-left_hard_divider
public static final String PL_RIGHT = "\uE0B2"; // nf-pl-right_hard_divider
public static final String PL_LEFT_SOFT = "\uE0B1"; // nf-pl-left_soft_divider
public static final String PL_RIGHT_SOFT = "\uE0B3"; // nf-pl-right_soft_divider
// ═══════════════════════════════════════════════════════════════════
// HELPER METHODS
// ═══════════════════════════════════════════════════════════════════
/** Apply ANSI codes to text with auto-reset */
public static String color(String text, String... codes) {
if (codes.length == 0) return text;
StringBuilder sb = new StringBuilder();
for (String code : codes) {
sb.append(code);
}
return sb.append(text).append(RESET).toString();
}
/** Bold text shorthand */
public static String bold(String text) {
return BOLD + text + RESET;
}
/** Dim text shorthand */
public static String dim(String text) {
return DIM + text + RESET;
}
/** Clear screen (side effect) */
public static void clear() {
System.out.print(CLEAR_SCREEN + CURSOR_HOME);
System.out.flush();
}
/** Hide cursor (side effect) */
public static void hideCursor() {
System.out.print(HIDE_CURSOR);
System.out.flush();
}
/** Show cursor (side effect) */
public static void showCursor() {
System.out.print(SHOW_CURSOR);
System.out.flush();
}
// ═══════════════════════════════════════════════════════════════════
// STRING UTILITIES
// ═══════════════════════════════════════════════════════════════════
/** Repeat a character n times */
public static String repeat(char c, int count) {
return String.valueOf(c).repeat(Math.max(0, count));
}
/** Repeat a string n times */
public static String repeat(String s, int count) {
return s.repeat(Math.max(0, count));
}
/** Right-pad string to width */
public static String pad(String text, int width) {
if (text.length() >= width) {
return text.substring(0, width);
}
return text + " ".repeat(width - text.length());
}
/** Left-pad string to width */
public static String padLeft(String text, int width) {
if (text.length() >= width) {
return text.substring(0, width);
}
return " ".repeat(width - text.length()) + text;
}
/** Center string within width */
public static String center(String text, int width) {
if (text.length() >= width) {
return text.substring(0, width);
}
int padding = (width - text.length()) / 2;
return (
" ".repeat(padding) +
text +
" ".repeat(width - text.length() - padding)
);
}
/** Truncate string with ellipsis if too long */
public static String truncate(String text, int maxWidth) {
if (text.length() <= maxWidth) return text;
return text.substring(0, Math.max(0, maxWidth - 3)) + "...";
}
/** Join strings with newlines */
public static String lines(String... lines) {
return String.join("\n", lines) + "\n";
}
}