|
1 | 1 | /* Part of SWI-Prolog |
2 | 2 |
|
3 | 3 | Author: Jan Wielemaker |
4 | | - E-mail: J.Wielemaker@vu.nl |
5 | | - WWW: http://www.swi-prolog.org |
6 | | - Copyright (c) 2010-2025, VU University Amsterdam |
| 4 | + E-mail: jan@swi-prolog.org |
| 5 | + WWW: https://www.swi-prolog.org |
| 6 | + Copyright (c) 2010-2026, VU University Amsterdam |
7 | 7 | CWI, Amsterdam |
8 | 8 | SWI-Prolog Solutions b.v. |
9 | 9 | All rights reserved. |
|
107 | 107 | % terminal, it adds ANSI escape sequences according to Attributes. |
108 | 108 | % For example, to print a text in bold cyan, do |
109 | 109 | % |
110 | | -% == |
| 110 | +% ``` |
111 | 111 | % ?- ansi_format([bold,fg(cyan)], 'Hello ~w', [world]). |
112 | | -% == |
| 112 | +% ``` |
113 | 113 | % |
114 | 114 | % Attributes is either a single attribute, a list thereof or a term |
115 | 115 | % that is mapped to concrete attributes based on the current theme |
|
128 | 128 | % - fg(R,G,B), bg(R,G,B) |
129 | 129 | % 24-bit (direct color) specification. The components are |
130 | 130 | % integers in the range 0..255. |
| 131 | +% - href(URL) |
| 132 | +% Wrap the output as a link using ansi_hyperlink/3. |
131 | 133 | % |
132 | | -% Defined color constants are below. `default` can be used to |
133 | | -% access the default color of the terminal. |
| 134 | +% Defined color constants are below. `default` can be used to access |
| 135 | +% the default color of the terminal. |
134 | 136 | % |
135 | 137 | % - black, red, green, yellow, blue, magenta, cyan, white |
136 | 138 | % |
|
149 | 151 | class_attrs(Class, Attr), |
150 | 152 | Attr \== [], |
151 | 153 | !, |
152 | | - phrase(sgr_codes_ex(Attr), Codes), |
153 | | - atomic_list_concat(Codes, ;, Code), |
| 154 | + ( selectchk(href(HREF), Attr, Attr1) |
| 155 | + -> true |
| 156 | + ; Attr1 = Attr |
| 157 | + ), |
| 158 | + phrase(sgr_codes_ex(Attr1), Codes), |
| 159 | + atomics_to_string(Codes, ;, Code), |
154 | 160 | with_output_to( |
155 | 161 | Stream, |
156 | 162 | ( format('\e[~wm', [Code]), |
157 | | - format(Format, Args), |
| 163 | + format_content(Format, Args, HREF), |
158 | 164 | format('\e[0m') |
159 | 165 | ) |
160 | 166 | ), |
161 | 167 | flush_output. |
162 | 168 | ansi_format(Stream, _Attr, Format, Args) :- |
163 | 169 | format(Stream, Format, Args). |
164 | 170 |
|
| 171 | +format_content(Format, Args, HREF) :- |
| 172 | + var(HREF), |
| 173 | + !, |
| 174 | + format(Format, Args). |
| 175 | +format_content(Format, Args, HREF) :- |
| 176 | + format(string(Label), Format, Args), |
| 177 | + ansi_hyperlink(current_output, HREF, Label). |
| 178 | + |
165 | 179 | sgr_codes_ex(X) --> |
166 | 180 | { var(X), |
167 | 181 | !, |
|
411 | 425 | class_attrs(Attrs, Attrs). |
412 | 426 |
|
413 | 427 | %! ansi_hyperlink(+Stream, +Location) is det. |
414 | | -%! ansi_hyperlink(+Stream, +URL, +Label) is det. |
| 428 | +%! ansi_hyperlink(+Stream, +Location, +Label) is det. |
| 429 | +% |
| 430 | +% Create a hyperlink for a terminal emulator using the ``OSC 8`` |
| 431 | +% escape sequence. Location is one of |
| 432 | +% |
| 433 | +% - An absolute URL |
| 434 | +% - An atom (interpreted as a file name) |
| 435 | +% - A term `File:Line` |
| 436 | +% - A term `File:Line:Column` |
415 | 437 | % |
416 | | -% Create a hyperlink for a terminal emulator. The file is fairly easy, |
417 | | -% but getting the line and column across is not as there seems to be |
418 | | -% no established standard. The current implementation emits, i.e., |
419 | | -% inserting a capital ``L`` before the line. |
| 438 | +% There is no official standard for encoding the `Line` and `Column`. |
| 439 | +% The current implementation emits, i.e., inserting a capital ``L`` |
| 440 | +% before the line. |
420 | 441 | % |
421 | 442 | % ``file://AbsFileName[#LLine[:Column]]`` |
422 | 443 | % |
|
0 commit comments