added arrow keys to move cursor in terminal
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user