Skip to content

Commit deede1b

Browse files
committed
ansi coloring for haxelib help
1 parent be2fff1 commit deede1b

File tree

6 files changed

+177
-8
lines changed

6 files changed

+177
-8
lines changed

client.hxml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22
-cp hx3compat/std
33
-cp hx4compat/std
44
-cp crypto/src
5+
-cp haxe-strings/src
56
-neko run.n
67
-main haxelib.client.Main

run.n

2.93 KB
Binary file not shown.

src/haxelib/client/Main.hx

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ using StringTools;
4040
using Lambda;
4141
using haxelib.MetaData;
4242
using haxelib.api.RepoReformatter;
43+
using haxelib.client.ansi.Ansi;
4344

4445
@:structInit
4546
class CommandInfo {
@@ -153,8 +154,12 @@ class Main {
153154
var maxLength = 0;
154155

155156
inline function checkLength(line:String)
156-
if (line.length > maxLength)
157-
maxLength = line.length;
157+
{
158+
var regexp = ~/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -\]*[@-~])/g;
159+
if (regexp.replace(line, '').length > maxLength)
160+
maxLength = regexp.replace(line, '').length;
161+
}
162+
158163

159164
function generateLines(data:List<UsageData>, generate:(UsageData -> String)):Array<{usage:String, description:String}>
160165
return [
@@ -164,27 +169,29 @@ class Main {
164169
{usage: line, description: item.description};
165170
}];
166171

167-
final switchLines = generateLines(Args.generateSwitchDocs(), (flag) -> '--${flag.name}');
168-
final optionLines = generateLines(Args.generateOptionDocs(), (flag) -> combineAliases(flag.name, flag.aliases) + ' ${flag.parameter}');
172+
final switchLines = generateLines(Args.generateSwitchDocs(), (flag) -> '--${flag.name}'.fg(ORANGE).attr(INTENSITY_BOLD).reset());
173+
final optionLines = generateLines(Args.generateOptionDocs(), (flag) -> combineAliases(flag.name, flag.aliases).fg(ORANGE).attr(INTENSITY_BOLD).reset() + ' ${flag.parameter}'.fg(ORANGE).reset());
169174

170175
final categories = new Map<String, Array<{usage:String, description:String}>>();
171176
for (command in Args.generateCommandDocs()) {
172177
checkLength(command.name);
173178
final categoryName = command.category.getName();
174179
if (!categories.exists(categoryName))
175180
categories[categoryName] = [];
176-
categories[categoryName].push({usage: command.name, description: command.description});
181+
categories[categoryName].push({usage: '${command.name.fg(ORANGE).attr(INTENSITY_BOLD).reset()}', description: command.description});
177182
}
178183

179184
Cli.print('Haxe Library Manager $VERSION - (c)2006-2024 Haxe Foundation');
180-
Cli.print(" Usage: haxelib [command] [options]");
185+
Cli.print(' Usage: '.fg(DARK_ORANGE).attr(INTENSITY_BOLD).reset() + 'haxelib '.fg(ORANGE).attr(INTENSITY_BOLD).reset() + '[command] '.fg(ORANGE) + '[options]'.reset());
186+
Cli.print('');
181187

182188
inline function display(type:String, lines:Array<{usage:String, description:String}>) {
183-
Cli.print(' $type');
189+
Cli.print(' $type'.fg(DARK_ORANGE).attr(INTENSITY_BOLD).reset());
184190
for (line in lines) {
185191
final padded = line.usage.rpad(' ', maxLength);
186-
Cli.print(' $padded : ${line.description}');
192+
Cli.print(' $padded ${line.description}');
187193
}
194+
Cli.print('');
188195
}
189196

190197
for (name => commands in categories)

src/haxelib/client/ansi/Ansi.hx

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package haxelib.client.ansi;
2+
3+
4+
/**
5+
* https://en.wikipedia.org/wiki/ANSI_escape_code
6+
* http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/c327.html
7+
* http://ascii-table.com/ansi-escape-sequences.php
8+
*/
9+
class Ansi {
10+
11+
/**
12+
* ANSI escape sequence header
13+
*/
14+
public static inline final ESC = "\x1B[";
15+
16+
inline
17+
public static function reset(str:String):String
18+
return str + ESC + "0m";
19+
20+
21+
/**
22+
* sets the given text attribute
23+
*/
24+
inline
25+
public static function attr(str:String, attr:AnsiTextAttribute):String
26+
return ESC + (attr) + "m" + str;
27+
28+
29+
/**
30+
* set the text background color
31+
*
32+
* <pre><code>
33+
* >>> Ansi.bg(RED) == "\x1B[41m"
34+
* </code></pre>
35+
*/
36+
inline
37+
public static function bg(str: String, color:AnsiColor):String
38+
return ESC + "4" + color + "m" + str;
39+
40+
41+
/**
42+
* Clears the screen and moves the cursor to the home position
43+
*/
44+
inline
45+
public static function clearScreen():String
46+
return ESC + "2J";
47+
48+
49+
/**
50+
* Clear all characters from current position to the end of the line including the character at the current position
51+
*/
52+
inline
53+
public static function clearLine():String
54+
return ESC + "K";
55+
56+
57+
/**
58+
* set the text foreground color
59+
*
60+
* <pre><code>
61+
* >>> Ansi.fg(RED) == "\x1B[31m"
62+
* </code></pre>
63+
*/
64+
inline
65+
public static function fg(str: String, color:AnsiColor):String
66+
return ESC + "38;5;" + color + "m" + str;
67+
68+
}
69+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* SPDX-FileCopyrightText: © Vegard IT GmbH (https://vegardit.com) and contributors
3+
* SPDX-FileContributor: Sebastian Thomschke, Vegard IT GmbH
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
package haxelib.client.ansi;
7+
8+
#if (haxe_ver < 4.3) @:enum #else enum #end
9+
abstract AnsiColor(Int) {
10+
final BLACK = 0;
11+
final RED = 1;
12+
final GREEN = 2;
13+
final YELLOW = 3;
14+
final BLUE = 4;
15+
final MAGENTA = 5;
16+
final CYAN = 6;
17+
final WHITE = 7;
18+
final DEFAULT = 9;
19+
final ORANGE = 216;
20+
final DARK_ORANGE = 215;
21+
final ORANGE_BRIGHT = 208;
22+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* SPDX-FileCopyrightText: © Vegard IT GmbH (https://vegardit.com) and contributors
3+
* SPDX-FileContributor: Sebastian Thomschke, Vegard IT GmbH
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
package haxelib.client.ansi;
7+
8+
/**
9+
* https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_codes
10+
*/
11+
#if (haxe_ver < 4.3) @:enum #else enum #end
12+
abstract AnsiTextAttribute(Int) {
13+
14+
/**
15+
* All colors/text-attributes off
16+
*/
17+
final RESET = 0;
18+
19+
final INTENSITY_BOLD = 1;
20+
21+
/**
22+
* Not widely supported.
23+
*/
24+
final INTENSITY_FAINT = 2;
25+
26+
/**
27+
* Not widely supported.
28+
*/
29+
final ITALIC = 3;
30+
31+
final UNDERLINE_SINGLE = 4;
32+
33+
final BLINK_SLOW = 5;
34+
35+
/**
36+
* Not widely supported.
37+
*/
38+
final BLINK_FAST = 6;
39+
40+
final NEGATIVE = 7;
41+
42+
/**
43+
* Not widely supported.
44+
*/
45+
final HIDDEN = 8;
46+
47+
/**
48+
* Not widely supported.
49+
*/
50+
final STRIKETHROUGH = 9;
51+
52+
/**
53+
* Not widely supported.
54+
*/
55+
final UNDERLINE_DOUBLE = 21;
56+
57+
final INTENSITY_OFF = 22;
58+
59+
final ITALIC_OFF = 23;
60+
61+
final UNDERLINE_OFF = 24;
62+
63+
final BLINK_OFF = 25;
64+
65+
final NEGATIVE_OFF = 27;
66+
67+
final HIDDEN_OFF = 28;
68+
69+
final STRIKTHROUGH_OFF = 29;
70+
}

0 commit comments

Comments
 (0)