How do I make a Command Bar?

Does anyone know how to make a command bar that updates suggestions whenever a known command is detected? Here’s a picture of what i’m talking about. At the top of the image there is a textbox which I want to make into a command bar. I have a frame under it that auto resizes when a textbox is put into it.


Auto resized frame:

(I also have the commands I want to search through for the suggestions in an easy to access folder.) Please ignore the on the right in the first picture I only need the bar at the top.

You’ll need an array of the commands your system has. Preferably one built entirely out of strings which represent the command names. As the user inputs text, use TextBox:GetPropertyChangedSignal(“Text”) to generate an RBXScriptSignal (event) to detect each individual input. From here, you have two options:

  1. Build a function that iterates through each command and collects the commands that begin with the given prefix, where the given prefix is the current set state of TextBox.Text:
local function getWordsStartingWith(words: {string}, prefix: string): {string}
    local prefixLength = string.len(prefix)
    local result       = {}

    for _, word in words do
        if string.sub(word, 1, prefixLength) == prefix then
            table.insert(result, word)
        end
    end

    return result
end

You can then build a set of TextLabels to show the results of the above function. As the user combs through the TextLabels, you can maintain an index into the result array. Upon pressing Tab or Enter, the suggestion can be auto-completed or executed.


The above method is not the most efficient solution available for an auto-suggestion algorithm.

  1. There are more efficient ways of handling this problem, and the most popular solution is the Trie data structure. This data structure allows us to immediately begin procuring results that are tailored towards the given prefix, completely avoiding all unrelated words. This provides a massive runtime boost, but at the cost of memory, of course. Fortunately for us, memory is in abundance these days.

A while back, I made a grassroots, case-insensitive implementation of this data-structure. I made some minor changes as I dusted it up for this post. You can grab the code here:

local Trie = require(--[[Path.to.Trie]])
local commandsTrie = Trie.new(commands)
local function onTextChanged()
    local suggestions = commandsTrie:GetWords(commandBar.Text)

    -- ...
end

commandBar:GetPropertyChangedSignal("Text"):Connect(onTextChanged)
2 Likes

Thank you so much Ziffix, This is a massive help. :smiley:

No problem! Don’t forget to mark my reply as the solution to your post

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.