Implemented basic Tab-autocompletion for agent console.
This commit is contained in:
@@ -4,5 +4,5 @@
|
|||||||
--opt:size
|
--opt:size
|
||||||
--passL:"-s" # Strip symbols, such as sensitive function names
|
--passL:"-s" # Strip symbols, such as sensitive function names
|
||||||
-d:CONFIGURATION="PLACEHOLDERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPLACEHOLDER"
|
-d:CONFIGURATION="PLACEHOLDERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPLACEHOLDER"
|
||||||
-d:MODULES="12"
|
-d:MODULES="255"
|
||||||
-o:"/mnt/c/Users/jakob/Documents/Projects/conquest/bin/monarch.x64.exe"
|
-o:"/mnt/c/Users/jakob/Documents/Projects/conquest/bin/monarch.x64.exe"
|
||||||
@@ -60,6 +60,9 @@ proc Console*(agent: UIAgent): ConsoleComponent =
|
|||||||
#[
|
#[
|
||||||
Text input callback function for managing console history and autocompletion
|
Text input callback function for managing console history and autocompletion
|
||||||
]#
|
]#
|
||||||
|
var currentCompletionIndex: int = -1
|
||||||
|
var lastMatches: seq[string] = @[]
|
||||||
|
|
||||||
proc callback(data: ptr ImGuiInputTextCallbackData): cint {.cdecl.} =
|
proc callback(data: ptr ImGuiInputTextCallbackData): cint {.cdecl.} =
|
||||||
|
|
||||||
let component = cast[ConsoleComponent](data.UserData)
|
let component = cast[ConsoleComponent](data.UserData)
|
||||||
@@ -108,8 +111,61 @@ proc callback(data: ptr ImGuiInputTextCallbackData): cint {.cdecl.} =
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
of ImGui_InputTextFlags_CallbackCompletion.int32:
|
of ImGui_InputTextFlags_CallbackCompletion.int32:
|
||||||
# Handle Tab-autocompletion
|
# Handle Tab-autocompletion for agent commands
|
||||||
discard
|
let commands = getCommands(component.agent.modules).mapIt(it.name & " ") & @["help "]
|
||||||
|
|
||||||
|
# Get the word to complete
|
||||||
|
let inputEndPos = data.CursorPos
|
||||||
|
var inputStartPos = inputEndPos
|
||||||
|
|
||||||
|
while inputStartPos > 0:
|
||||||
|
let c = cast[ptr UncheckedArray[char]](data.Buf)[inputStartPos - 1]
|
||||||
|
if c in [' ', '\t', ',', ';']:
|
||||||
|
break
|
||||||
|
dec inputStartPos
|
||||||
|
|
||||||
|
let inputLen = inputEndPos - inputStartPos
|
||||||
|
var currentWord = newString(inputLen)
|
||||||
|
for i in 0..<inputLen:
|
||||||
|
currentWord[i] = cast[ptr UncheckedArray[char]](data.Buf)[inputStartPos + i]
|
||||||
|
|
||||||
|
# Check for matches
|
||||||
|
var matches: seq[string] = @[]
|
||||||
|
for cmd in commands:
|
||||||
|
if cmd.toLowerAscii().startsWith(currentWord.toLowerAscii()):
|
||||||
|
matches.add(cmd)
|
||||||
|
|
||||||
|
# No matching commands found
|
||||||
|
if matches.len() == 0:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
elif matches.len() == 1:
|
||||||
|
data.ImGuiInputTextCallbackData_DeleteChars(inputStartPos.cint, inputLen.cint)
|
||||||
|
data.ImGuiInputTextCallbackData_InsertChars(data.CursorPos, matches[0].cstring, nil)
|
||||||
|
|
||||||
|
# More than 1 matching command -> complete common prefix
|
||||||
|
else:
|
||||||
|
var prefixLen = inputLen
|
||||||
|
|
||||||
|
while prefixLen < matches[0].len():
|
||||||
|
let c = matches[0][prefixLen]
|
||||||
|
var allMatch = true
|
||||||
|
|
||||||
|
for i in 1 ..< matches.len():
|
||||||
|
if prefixLen >= matches[i].len() or matches[i][prefixLen] != c:
|
||||||
|
allMatch = false
|
||||||
|
break
|
||||||
|
|
||||||
|
if not allMatch:
|
||||||
|
break
|
||||||
|
|
||||||
|
inc prefixLen
|
||||||
|
|
||||||
|
if prefixLen > inputLen:
|
||||||
|
data.ImGuiInputTextCallbackData_DeleteChars(inputStartPos.cint, inputLen.cint)
|
||||||
|
data.ImGuiInputTextCallbackData_InsertChars(data.CursorPos, matches[0][0..<prefixLen].cstring, nil)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
else: discard
|
else: discard
|
||||||
|
|
||||||
|
|||||||
@@ -82,3 +82,12 @@ proc getModules*(modules: uint32 = 0): seq[Module] =
|
|||||||
for m in manager.modules:
|
for m in manager.modules:
|
||||||
if (modules and cast[uint32](m.moduleType)) == cast[uint32](m.moduleType):
|
if (modules and cast[uint32](m.moduleType)) == cast[uint32](m.moduleType):
|
||||||
result.add(m)
|
result.add(m)
|
||||||
|
|
||||||
|
proc getCommands*(modules: uint32 = 0): seq[Command] =
|
||||||
|
if modules == 0:
|
||||||
|
for m in manager.modules:
|
||||||
|
result.add(m.commands)
|
||||||
|
else:
|
||||||
|
for m in manager.modules:
|
||||||
|
if (modules and cast[uint32](m.moduleType)) == cast[uint32](m.moduleType):
|
||||||
|
result.add(m.commands)
|
||||||
Reference in New Issue
Block a user