From 1c9d43a5f7bac6a7bb66ff32ce4554ed82fddacd Mon Sep 17 00:00:00 2001 From: Brazly Date: Mon, 16 Feb 2026 20:20:23 +0000 Subject: [PATCH] added arrow keys to move cursor in terminal --- Assets/Scripts/Player Controls/interact.gd | 6 ++ .../Scripts/UI/terminal/terminal_controls.gd | 101 ++++++++++++++---- 2 files changed, 87 insertions(+), 20 deletions(-) diff --git a/Assets/Scripts/Player Controls/interact.gd b/Assets/Scripts/Player Controls/interact.gd index 0a69c1a..d8b2a3f 100644 --- a/Assets/Scripts/Player Controls/interact.gd +++ b/Assets/Scripts/Player Controls/interact.gd @@ -45,6 +45,12 @@ func _input(event: InputEvent) -> void: KEY_DOWN: terminal.NavigateHistory(-1) + + KEY_LEFT: + terminal.MoveCursorLeft() + + KEY_RIGHT: + terminal.MoveCursorRight() if event.unicode > 31: var character = char(event.unicode) diff --git a/Assets/Scripts/UI/terminal/terminal_controls.gd b/Assets/Scripts/UI/terminal/terminal_controls.gd index 7d6d01d..879b9e9 100644 --- a/Assets/Scripts/UI/terminal/terminal_controls.gd +++ b/Assets/Scripts/UI/terminal/terminal_controls.gd @@ -8,9 +8,11 @@ class_name TerminalControls @onready var scroll: ScrollContainer = $MarginContainer/ScrollContainer @export var terminalLine: RichTextLabel -var terminalHistory: Array[String] = [] +var terminalHistory: Array[String] = [""] var historyIndex: int = -1 +var cursorIndexFromEnd: int = 0 + var command: String var directory: String = "~/" var fileSystem: Dictionary = { @@ -37,7 +39,7 @@ func _ready() -> void: func _on_caret_timer_timeout() -> void: caret.visible = !caret.visible -func reset_blink() -> void: +func ResetBlink() -> void: caret.visible = true blink_timer.start() # Resets the countdown @@ -45,19 +47,37 @@ func reset_blink() -> void: func InputChar(input) -> void: if input == null: return - else: - command = input - terminalLine.text += command - UpdateCaretPos() - await get_tree().physics_frame - reset_blink() + + var fullText = terminalLine.text + var insertPos = fullText.length() - cursorIndexFromEnd + + var before = fullText.left(insertPos) + var after = fullText.right(cursorIndexFromEnd) + + terminalLine.text = before + input + after + + UpdateCaretPos() + + await get_tree().physics_frame + ResetBlink() func InputDelChar() -> void: - if terminalLine.text.length() > ("user@work " + directory).length() + 1: - terminalLine.text = terminalLine.text.left(-1) + var minLength = ("user@work " + directory).length() + 1 + if terminalLine.text.length() <= minLength: + return + + var fullText = terminalLine.text + var deletePos = fullText.length() - cursorIndexFromEnd + + if deletePos > minLength: + var before = fullText.left(deletePos - 1) + var after = fullText.right(cursorIndexFromEnd) + + terminalLine.text = before + after UpdateCaretPos() - await get_tree().physics_frame - reset_blink() + + await get_tree().physics_frame + ResetBlink() func EnterCommand() -> void: var fullText = terminalLine.text @@ -70,6 +90,7 @@ func EnterCommand() -> void: if userInput != "": terminalHistory.append(userInput) historyIndex = 0 + cursorIndexFromEnd = 0 match parts[0]: "ls", "list": @@ -123,6 +144,33 @@ func EnterCommand() -> void: UpdateCaretPos() GetBottomScroll() + +func MoveCursorLeft(): + var full_text = terminalLine.get_parsed_text() + var last_newline_pos = full_text.rfind("\n") + + # The prompt starts after the last newline (or at 0 if it's the first line) + var prompt_start_index = last_newline_pos + 1 if last_newline_pos != -1 else 0 + var prompt_length = ("user@work " + directory + " ").length() + + # The absolute index we aren't allowed to go before + var min_allowed_index = prompt_start_index + prompt_length + + # Calculate current target index + var current_target = full_text.length() - cursorIndexFromEnd + + if current_target > min_allowed_index: + cursorIndexFromEnd += 1 + UpdateCaretPos() + ResetBlink() + +func MoveCursorRight(): + + cursorIndexFromEnd = clampi(cursorIndexFromEnd - 1, 0, terminalLine.text.length()) + + UpdateCaretPos() + ResetBlink() + # --- History and FileSystem Helpers --- func NavigateHistory(direction: int): @@ -243,15 +291,28 @@ func GetBottomScroll(): scroll.set_deferred("scroll_vertical", scrollMax) func UpdateCaretPos(): - await get_tree().physics_frame - var visible_text = terminalLine.get_parsed_text() + var visibleText = terminalLine.get_parsed_text() - ruler.autowrap_mode =TextServer.AUTOWRAP_WORD_SMART - ruler.text = visible_text + ruler.text = visibleText + ruler.custom_minimum_size.x = terminalLine.size.x + ruler.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART - var last_char_index = ruler.text.length() - 1 - var char_rect = ruler.get_character_bounds(max(0, last_char_index)) - caret.position.x = char_rect.end.x + 1 - caret.position.y = terminalLine.get_content_height() - 50 + var totalLen = visibleText.length() + var targetIndex = clampi(totalLen - cursorIndexFromEnd, 0, totalLen) + if totalLen == 0: + caret.position = Vector2.ZERO + return + + var lastCharBounds = ruler.get_character_bounds(max(0, totalLen - 1)) + var targetCharBounds = ruler.get_character_bounds(targetIndex) + + if cursorIndexFromEnd == 0: + caret.position.x = lastCharBounds.end.x + caret.position.y = lastCharBounds.position.y + else: + caret.position.x = targetCharBounds.position.x + caret.position.y = targetCharBounds.position.y + + caret.position.x += 1