mirror of
https://github.com/lihop/godot-xterm.git
synced 2024-11-21 17:20:25 +01:00
feat(term): implement clear() method
Clears all but the bottommost row of the terminal (including scrollback buffer) and moves the bottommost row to the top.
This commit is contained in:
parent
fc03595e29
commit
d00a31fb45
4 changed files with 82 additions and 12 deletions
|
@ -75,8 +75,8 @@ void Terminal::_bind_methods()
|
|||
ClassDB::bind_method(D_METHOD("get_copy_on_selection"), &Terminal::get_copy_on_selection);
|
||||
ClassDB::add_property("Terminal", PropertyInfo(Variant::BOOL, "copy_on_selection"), "set_copy_on_selection", "get_copy_on_selection");
|
||||
|
||||
// Methods.
|
||||
|
||||
// Other methods.
|
||||
ClassDB::bind_method(D_METHOD("clear"), &Terminal::clear);
|
||||
ClassDB::bind_method(D_METHOD("write", "data"), &Terminal::write);
|
||||
ClassDB::bind_method(D_METHOD("get_cursor_pos"), &Terminal::get_cursor_pos);
|
||||
ClassDB::bind_method(D_METHOD("get_cell_size"), &Terminal::get_cell_size);
|
||||
|
@ -642,6 +642,19 @@ double Terminal::get_blink_off_time() const
|
|||
return blink_off_time;
|
||||
}
|
||||
|
||||
void Terminal::clear() {
|
||||
// Resize the terminal to a single row, forcing content above in to the scrollback buffer.
|
||||
tsm_screen_resize(screen, cols, 1);
|
||||
|
||||
// Clear the scrollback buffer (hence clearing the content that was above).
|
||||
tsm_screen_clear_sb(screen);
|
||||
|
||||
// Resize the screen to its original size.
|
||||
tsm_screen_resize(screen, cols, rows);
|
||||
|
||||
refresh();
|
||||
}
|
||||
|
||||
String Terminal::_copy_screen(ScreenCopyFunction func) {
|
||||
char *out;
|
||||
PackedByteArray data;
|
||||
|
|
|
@ -72,6 +72,8 @@ namespace godot
|
|||
void set_blink_off_time(const double p_blink_off_time);
|
||||
double get_blink_off_time() const;
|
||||
|
||||
void clear();
|
||||
|
||||
String copy_all();
|
||||
String copy_selection();
|
||||
void set_copy_on_selection(const bool p_enable);
|
||||
|
|
|
@ -12,7 +12,7 @@ func get_described_class():
|
|||
func pick_cell_color(cell := Vector2i(0, 0)) -> Color:
|
||||
var cell_size = subject.get_cell_size()
|
||||
var pixelv = Vector2(cell) * cell_size + (cell_size / 2)
|
||||
return get_viewport().get_texture().get_image().get_pixelv(cell_size / 2)
|
||||
return get_viewport().get_texture().get_image().get_pixelv(pixelv)
|
||||
|
||||
|
||||
func before_each():
|
||||
|
@ -27,9 +27,20 @@ func before_each():
|
|||
class TestRendering:
|
||||
extends RenderingTest
|
||||
|
||||
# Fill the terminal with colored blocks.
|
||||
func fill_color(color = Color.BLACK, rows: int = subject.get_rows()):
|
||||
subject.write("\u001b[38;2;%d;%d;%dm" % [color.r8, color.g8, color.b8])
|
||||
subject.write("█".repeat(subject.get_cols() * rows))
|
||||
|
||||
func test_render():
|
||||
fill_color(Color.BLUE)
|
||||
await wait_for_signal(subject.draw, 3)
|
||||
await wait_frames(15)
|
||||
var cell_color = pick_cell_color()
|
||||
assert_eq(cell_color, Color.BLUE)
|
||||
|
||||
func test_update():
|
||||
subject.write("\u001b[38;2;255;0;0m")
|
||||
subject.write("█".repeat(subject.get_cols() * subject.get_rows()))
|
||||
fill_color(Color.RED)
|
||||
await get_tree().physics_frame
|
||||
subject.queue_redraw()
|
||||
await wait_for_signal(subject.draw, 3)
|
||||
|
@ -37,6 +48,30 @@ class TestRendering:
|
|||
var cell_color = pick_cell_color(Vector2i(0, 0))
|
||||
assert_eq(cell_color, Color.RED)
|
||||
|
||||
func test_clear_clears_all_but_the_first_row():
|
||||
await wait_frames(15)
|
||||
var cell = Vector2i(0, 1) # Pick a cell not on the first row.
|
||||
var original_color = pick_cell_color(cell)
|
||||
call_deferred("fill_color", Color.CYAN)
|
||||
await wait_for_signal(subject.draw, 3)
|
||||
await wait_frames(15)
|
||||
subject.clear()
|
||||
await wait_for_signal(subject.draw, 3)
|
||||
await wait_frames(15)
|
||||
var cell_color = pick_cell_color(cell)
|
||||
assert_eq(cell_color, original_color)
|
||||
|
||||
func test_clear_keeps_the_last_row():
|
||||
fill_color(Color.GREEN)
|
||||
fill_color(Color.ORANGE, 1)
|
||||
await wait_for_signal(subject.draw, 3)
|
||||
await wait_frames(15)
|
||||
subject.clear()
|
||||
await wait_for_signal(subject.draw, 3)
|
||||
await wait_frames(15)
|
||||
var cell_color = pick_cell_color(Vector2i(0, 0))
|
||||
assert_eq(cell_color, Color.ORANGE)
|
||||
|
||||
|
||||
class TestKeyPressed:
|
||||
extends RenderingTest
|
||||
|
|
|
@ -13,6 +13,13 @@ func before_each():
|
|||
subject.size = Vector2(400, 200)
|
||||
|
||||
|
||||
# Helper function to fill the screen with the given character.
|
||||
func fill_screen(char: String = "A") -> String:
|
||||
var result = char.repeat(subject.get_cols() * subject.get_rows())
|
||||
subject.write(result)
|
||||
return result
|
||||
|
||||
|
||||
class TestInterface:
|
||||
extends TerminalTest
|
||||
|
||||
|
@ -44,8 +51,7 @@ class TestInterface:
|
|||
|
||||
# Methods.
|
||||
|
||||
# TODO: Implement clear() method.
|
||||
func xtest_has_method_clear():
|
||||
func test_has_method_clear():
|
||||
assert_has_method_with_return_type("clear", TYPE_NIL)
|
||||
|
||||
func test_has_method_copy_all():
|
||||
|
@ -196,11 +202,6 @@ class TestWrite:
|
|||
class TestCopy:
|
||||
extends TerminalTest
|
||||
|
||||
func fill_screen(char: String = "A") -> String:
|
||||
var result = char.repeat(subject.get_cols() * subject.get_rows())
|
||||
subject.write(result)
|
||||
return result
|
||||
|
||||
func test_copy_all_copies_the_entire_screen():
|
||||
var text = fill_screen()
|
||||
# The text will be wrapped over multiple lines and copy_all() preserves
|
||||
|
@ -220,3 +221,22 @@ class TestCopy:
|
|||
var text = "アイウエオカキクケコサシスセソ"
|
||||
subject.write(text)
|
||||
assert_string_contains(subject.copy_all(), text)
|
||||
|
||||
|
||||
class TestClear:
|
||||
extends TerminalTest
|
||||
|
||||
func test_clear_an_empty_screen_changes_nothing():
|
||||
var empty_screen = subject.copy_all()
|
||||
subject.clear()
|
||||
var screen_after = subject.copy_all()
|
||||
assert_eq(screen_after, empty_screen)
|
||||
|
||||
func test_clear_when_screen_is_full_clears_all_but_the_bottommost_row():
|
||||
fill_screen()
|
||||
var final_line = "THIS SHOULDN'T BE CLEARED"
|
||||
subject.write(final_line)
|
||||
subject.clear()
|
||||
var screen_after = subject.copy_all()
|
||||
var expected = final_line + "\n".repeat(subject.get_rows())
|
||||
assert_eq(screen_after, expected)
|
||||
|
|
Loading…
Reference in a new issue