Skip to content

Instantly share code, notes, and snippets.

@jocelyn
Last active October 18, 2018 16:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jocelyn/c2a211315898639fc65c3108343a950b to your computer and use it in GitHub Desktop.
Save jocelyn/c2a211315898639fc65c3108343a950b to your computer and use it in GitHub Desktop.
ANSI console control
note
description: "Summary description for {CONSOLE_ANSI_CONTROL}."
date: "$Date$"
revision: "$Revision$"
EIS: "name=ANSI escape codes", "protocol=URI", "src=http://ascii-table.com/ansi-escape-sequences.php"
EIS: "name=ANSI escape codes (MS)", "protocol=URI", "src=https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences"
class
CONSOLE_ANSI_CONTROL
inherit
ANY
redefine
default_create
end
create
default_create
feature {NONE} -- Initialization
default_create
local
i: INTEGER
do
io.output.end_of_file.do_nothing
i := initialize_terminal
ansi_enabled := (i = 0)
end
initialize_terminal: INTEGER
external "C inline"
alias "[
#ifdef EIF_WINDOWS
{
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (hOut == INVALID_HANDLE_VALUE) {
return GetLastError();
}
DWORD dwMode = 0;
if (!GetConsoleMode(hOut, &dwMode)) {
return GetLastError();
}
dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
if (!SetConsoleMode(hOut, dwMode)) {
return GetLastError();
}
return 0;
}
#else
/* Check for other platforms */
return 0;
#endif
]"
end
ansi_enabled: BOOLEAN
feature -- Control
set_control (m: READABLE_STRING_8)
do
if ansi_enabled then
io.output.put_string ("%/27/[")
io.output.put_string (m)
end
end
feature -- Control: attributes
reset_attributes do set_control ("0m") end
set_bold do set_control ("1m") end
set_underline do set_control ("4m") end
unset_underline do set_control ("24m") end
set_blink do set_control ("5m") end
set_reverse_video do set_control ("7m") end
unset_reverse_video do set_control ("27m") end
set_concealed do set_control ("9m") end
feature -- Control: foreground colors
reset_foreground_color do set_control ("39m") end
set_foreground_color_to_black do set_control ("30m") end
set_foreground_color_to_red do set_control ("31m") end
set_foreground_color_to_green do set_control ("32m") end
set_foreground_color_to_yellow do set_control ("33m") end
set_foreground_color_to_blue do set_control ("34m") end
set_foreground_color_to_magenta do set_control ("35m") end
set_foreground_color_to_cyan do set_control ("36m") end
set_foreground_color_to_white do set_control ("37m") end
feature -- Control: background colors
reset_background_color do set_control ("49m") end
set_background_color_to_black do set_control ("40m") end
set_background_color_to_red do set_control ("41m") end
set_background_color_to_green do set_control ("42m") end
set_background_color_to_yellow do set_control ("43m") end
set_background_color_to_blue do set_control ("44m") end
set_background_color_to_magenta do set_control ("45m") end
set_background_color_to_cyan do set_control ("46m") end
set_background_color_to_white do set_control ("47m") end
feature -- Control
move_cursor_to_column (a_column: INTEGER)
require
valid_column: a_column >= 0 and a_column <= 32_767
do
set_control (a_column.out + "G")
end
move_cursor_to_line (a_line: INTEGER)
require
valid_line: a_line >= 0 and a_line <= 32_767
do
set_control (a_line.out + "d")
end
move_cursor_to_position (a_line, a_column: INTEGER) do set_control (a_line.out + ";" + a_column.out + "H") end
move_cursor_up (nb: INTEGER) do set_control (nb.out + "A") end
move_cursor_down (nb: INTEGER) do set_control (nb.out + "B") end
move_cursor_forward (nb: INTEGER) do set_control (nb.out + "C") end
move_cursor_backward (nb: INTEGER) do set_control (nb.out + "D") end
save_cursor do set_control ("s") end
restore_cursor do set_control ("u") end
show_cursor do set_control ("?25h") end
hide_cursor do set_control ("?25l") end
erase_display_from_cursor do set_control ("0J") end -- from the cursor position (inclusive) up to the end of the display
erase_display_until_cursor do set_control ("1J") end -- from the beginning of the display up to the cursor (including the cursor position)
erase_display do set_control ("2J") end
erase_line_from_cursor do set_control ("0K") end -- from the cursor position (inclusive) up to the end of the line
erase_line_until_cursor do set_control ("1K") end -- from the beginning of the line up to the cursor (including the cursor position)
erase_line do set_control ("2K") end
feature -- Modes
enable_line_wrapping_mode do set_control ("=7h") end
reset_line_wrapping_mode do set_control ("=l") end
end
class
TEST_CONSOLE
inherit
SHARED_EXECUTION_ENVIRONMENT
create
make
feature {NONE} -- Initialization
make
-- Instantiate Current object.
local
ansi_control: CONSOLE_ANSI_CONTROL
n: INTEGER
do
create ansi_control
ansi_control.erase_display
print ("This demonstrates the use of ANSI control on terminal%N%N")
print ("Hello")
ansi_control.save_cursor
ansi_control.set_foreground_color_to_red
print (" Eiffel!")
print ("%N")
n := 10
ansi_control.hide_cursor
ansi_control.move_cursor_to_column (n + 1)
ansi_control.set_foreground_color_to_cyan
print (create {STRING}.make_filled ('_', n))
ansi_control.move_cursor_to_column (1)
print ("...")
across
1 |..| n as ic
loop
ansi_control.erase_line_until_cursor
ansi_control.set_foreground_color_to_yellow
ansi_control.move_cursor_to_column (n + ic.item)
print ("#")
ansi_control.move_cursor_to_column (1)
ansi_control.set_foreground_color_to_green
print (ic.item)
execution_environment.sleep (1_000_000_000 // n)
end
ansi_control.erase_line_until_cursor
ansi_control.move_cursor_to_column (1)
print ("Done%N")
ansi_control.erase_line
ansi_control.set_background_color_to_white
ansi_control.set_foreground_color_to_blue
ansi_control.show_cursor
ansi_control.restore_cursor
ansi_control.move_cursor_backward (1)
ansi_control.erase_line_until_cursor
ansi_control.move_cursor_to_column (1)
print ("Bye")
ansi_control.reset_background_color
ansi_control.reset_foreground_color
ansi_control.move_cursor_to_position (6, 1)
print ("See you ")
from
n := 40
until
n = 1
loop
ansi_control.move_cursor_to_column (8)
ansi_control.erase_display_from_cursor
ansi_control.move_cursor_to_column (7 + n)
print ("soon!")
execution_environment.sleep (10_000_000)
n := n - 1
end
print ("%N")
end
end
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-18-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-18-0 http://www.eiffel.com/developers/xml/configuration-1-18-0.xsd" name="enhanced_console" uuid="E9F31201-09EC-40A7-A2D1-FDA34135B09E">
<target name="enhanced_console">
<root class="TEST_CONSOLE" feature="make"/>
<setting name="console_application" value="false"/>
<capability>
<void_safety support="all"/>
</capability>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<cluster name="src" location=".\" recursive="false"/>
</target>
</system>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment