added arrow keys to move cursor in terminal
This commit is contained in:
@@ -46,6 +46,12 @@ func _input(event: InputEvent) -> void:
|
|||||||
KEY_DOWN:
|
KEY_DOWN:
|
||||||
terminal.NavigateHistory(-1)
|
terminal.NavigateHistory(-1)
|
||||||
|
|
||||||
|
KEY_LEFT:
|
||||||
|
terminal.MoveCursorLeft()
|
||||||
|
|
||||||
|
KEY_RIGHT:
|
||||||
|
terminal.MoveCursorRight()
|
||||||
|
|
||||||
if event.unicode > 31:
|
if event.unicode > 31:
|
||||||
var character = char(event.unicode)
|
var character = char(event.unicode)
|
||||||
|
|
||||||
|
|||||||
@@ -8,9 +8,11 @@ class_name TerminalControls
|
|||||||
@onready var scroll: ScrollContainer = $MarginContainer/ScrollContainer
|
@onready var scroll: ScrollContainer = $MarginContainer/ScrollContainer
|
||||||
@export var terminalLine: RichTextLabel
|
@export var terminalLine: RichTextLabel
|
||||||
|
|
||||||
var terminalHistory: Array[String] = []
|
var terminalHistory: Array[String] = [""]
|
||||||
var historyIndex: int = -1
|
var historyIndex: int = -1
|
||||||
|
|
||||||
|
var cursorIndexFromEnd: int = 0
|
||||||
|
|
||||||
var command: String
|
var command: String
|
||||||
var directory: String = "~/"
|
var directory: String = "~/"
|
||||||
var fileSystem: Dictionary = {
|
var fileSystem: Dictionary = {
|
||||||
@@ -37,7 +39,7 @@ func _ready() -> void:
|
|||||||
func _on_caret_timer_timeout() -> void:
|
func _on_caret_timer_timeout() -> void:
|
||||||
caret.visible = !caret.visible
|
caret.visible = !caret.visible
|
||||||
|
|
||||||
func reset_blink() -> void:
|
func ResetBlink() -> void:
|
||||||
caret.visible = true
|
caret.visible = true
|
||||||
blink_timer.start() # Resets the countdown
|
blink_timer.start() # Resets the countdown
|
||||||
|
|
||||||
@@ -45,19 +47,37 @@ func reset_blink() -> void:
|
|||||||
func InputChar(input) -> void:
|
func InputChar(input) -> void:
|
||||||
if input == null:
|
if input == null:
|
||||||
return
|
return
|
||||||
else:
|
|
||||||
command = input
|
var fullText = terminalLine.text
|
||||||
terminalLine.text += command
|
var insertPos = fullText.length() - cursorIndexFromEnd
|
||||||
|
|
||||||
|
var before = fullText.left(insertPos)
|
||||||
|
var after = fullText.right(cursorIndexFromEnd)
|
||||||
|
|
||||||
|
terminalLine.text = before + input + after
|
||||||
|
|
||||||
UpdateCaretPos()
|
UpdateCaretPos()
|
||||||
|
|
||||||
await get_tree().physics_frame
|
await get_tree().physics_frame
|
||||||
reset_blink()
|
ResetBlink()
|
||||||
|
|
||||||
func InputDelChar() -> void:
|
func InputDelChar() -> void:
|
||||||
if terminalLine.text.length() > ("user@work " + directory).length() + 1:
|
var minLength = ("user@work " + directory).length() + 1
|
||||||
terminalLine.text = terminalLine.text.left(-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()
|
UpdateCaretPos()
|
||||||
|
|
||||||
await get_tree().physics_frame
|
await get_tree().physics_frame
|
||||||
reset_blink()
|
ResetBlink()
|
||||||
|
|
||||||
func EnterCommand() -> void:
|
func EnterCommand() -> void:
|
||||||
var fullText = terminalLine.text
|
var fullText = terminalLine.text
|
||||||
@@ -70,6 +90,7 @@ func EnterCommand() -> void:
|
|||||||
if userInput != "":
|
if userInput != "":
|
||||||
terminalHistory.append(userInput)
|
terminalHistory.append(userInput)
|
||||||
historyIndex = 0
|
historyIndex = 0
|
||||||
|
cursorIndexFromEnd = 0
|
||||||
|
|
||||||
match parts[0]:
|
match parts[0]:
|
||||||
"ls", "list":
|
"ls", "list":
|
||||||
@@ -123,6 +144,33 @@ func EnterCommand() -> void:
|
|||||||
UpdateCaretPos()
|
UpdateCaretPos()
|
||||||
GetBottomScroll()
|
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 ---
|
# --- History and FileSystem Helpers ---
|
||||||
|
|
||||||
func NavigateHistory(direction: int):
|
func NavigateHistory(direction: int):
|
||||||
@@ -243,15 +291,28 @@ func GetBottomScroll():
|
|||||||
scroll.set_deferred("scroll_vertical", scrollMax)
|
scroll.set_deferred("scroll_vertical", scrollMax)
|
||||||
|
|
||||||
func UpdateCaretPos():
|
func UpdateCaretPos():
|
||||||
|
|
||||||
await get_tree().physics_frame
|
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 = visibleText
|
||||||
ruler.text = visible_text
|
ruler.custom_minimum_size.x = terminalLine.size.x
|
||||||
|
ruler.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||||
|
|
||||||
var last_char_index = ruler.text.length() - 1
|
var totalLen = visibleText.length()
|
||||||
var char_rect = ruler.get_character_bounds(max(0, last_char_index))
|
var targetIndex = clampi(totalLen - cursorIndexFromEnd, 0, totalLen)
|
||||||
caret.position.x = char_rect.end.x + 1
|
|
||||||
caret.position.y = terminalLine.get_content_height() - 50
|
|
||||||
|
|
||||||
|
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