Edit module source through plugin with tables?

Hello,

Currently, I am trying to make a plugin that will automate work for me, and one of these is compiling all of my packages into a single list for intellisense. The problem here is that, I am not sure how I could do this, as BaseScript.Source takes a string. Any help?

I am not sure what you mean. Do you mean changing a script’s source to be a dictionary to all of your modules for intellisence? Is this what you mean:

Don’t mind the bug where it doesn’t change path (:FindFirstChild("ArrayModule")).

Yeah, that’s exactly what I mean, how did you do that?

I made a function that takes a directory and converts them into table as strings. If it is a folder, it will use the function itself inside, if it is a ModuleScript, it will require it.

local function generateTable(moduleScript: ModuleScript, directory: Instance, depth: number)
	local result = "{"
	
	for _, object in directory:GetChildren() do
		if not (object:IsA("Folder") or object:IsA("ModuleScript"))then
			continue
		end
		
		result ..= ("\n%s[%q] = "):format(("\t"):rep(depth), object.Name)
		
		if object:IsA("Folder") or object:IsA("Configuration") then
			result ..= generateTable(moduleScript, object, depth + 1)
			result ..= `\n{("\t"):rep(depth)}};`
		else
			result ..= `require({generatePath(moduleScript, object)});`
		end
	end
	
	return result
end

After seeing this, I got reminded of me making something like and made a plugin, you can insert my plugin and check the TableGeneration module: Module Tracker Plugin - Easily Create Dictionaries of Modules
I do not know if I am not allowed to answer you this way and if this is seen as advertisement, if it is so then please tell me. I will remove it.

Wait, how do I make this work when pressing a button? Example:

User Presses Intellisense Button
The PackageList module gets updated with the source, where it reads from a package folder and gets all the modules.

The function just seems a little confusing.

This function simply generates a code as string, you can set Source property of a ModuleScript to it.

The function takes three parameters, ModuleScript is taken for generating path from it i.e: script:FindFirstChild("•••"):FindFirstChild("•••").... Directory is the instance which will “turn into a table”. depth shows how much tabs to be used which will increase as table nestes.

function SetSource(moduleScript: ModuleScript, directories: {Instance})
	local result = "return {"
	
	for _, directory in directories do
		result ..= ("\n\t[%q] = %s\n\t};"):format(directory.Name, generateTable(moduleScript, directory, 2))
	end
	
	if result == "return {" then
		moduleScript.Source = "return {}"
		
		return
	end
	
	result ..= "\n};"
	
	moduleScript.Source = result
end

This will set source of the ModuleScript to return a dictionary of directories and modules inside it.

I used another function as well that creates a path from an instance to another:

function generatePath(moduleScript: ModuleScript, toInstance: Instance)
	local result = ""
	
	if moduleScript:IsAncestorOf(toInstance) then
		local currentInstance = toInstance
		
		repeat
			result = (":FindFirstChild(%q)"):format(currentInstance.Name) .. result
			currentInstance = currentInstance.Parent
		until currentInstance == moduleScript
		
		result = "script" .. result
	elseif moduleScript:IsDescendantOf(toInstance) then
		local currentInstance = moduleScript
		
		result = "script"
		
		repeat
			result ..= ".Parent"
			
			currentInstance = currentInstance.Parent
		until currentInstance == toInstance
	else
		local commonAncestor = moduleScript
		
		repeat
			commonAncestor = commonAncestor.Parent
		until commonAncestor:IsAncestorOf(moduleScript) and commonAncestor:IsAncestorOf(toInstance)
		
		result = generatePath(moduleScript, commonAncestor) .. generatePath(commonAncestor, toInstance):sub(7)
	end
	
	return result
end

Alright thanks for this, but when I tried using Folder:GetChildren() (with modules inside) it just generated an empty table with no require path. Also, it looks like if there are no contents inside of a table this happens:

return {
	["ModuleScript"] = {}
	};
};
1 Like

I have modified the generateTable function, I hope it work properly now. Now if it is empty, it should not add extra bracket but will not look nice. :expressionless:

1 Like

Alright, it’s fixed, but as I said before, if I just do Folder:GetChildren it will return an empty table even if it is a module.

My setup:

image

What it generates:

return {
	["ModuleScript"] = {
		["ModuleScript"] = require(script.Parent.Parent.Parent:FindFirstChild("Packages"):FindFirstChild("Client"):FindFirstChild("ModuleScript"):FindFirstChild("ModuleScript"));
	};
};
1 Like

Hey! I fixed the SetSource function having modules as empty tables. Here’s the new function:

function SetSource(moduleScript: ModuleScript, directories: {Instance})
	local result = "return {"

	for _, directory in directories do
		if directory:IsA("ModuleScript") then
			result ..= ("\n\t[%q] = %s\n\t};"):format(directory.Name, `require({generatePath(moduleScript, directory)})`)
			continue
		end
		result ..= ("\n\t[%q] = %s\n\t};"):format(directory.Name, generateTable(moduleScript, directory, 2))
	end

	if result == "return {" then
		moduleScript.Source = "return {}"

		return
	end

	for _, directory in directories do
		if not directory:IsA("ModuleScript") then
			result ..= "\n};"
		end
	end

	moduleScript.Source = result
end

Anyways, you’re an absolute godsend for sending me this code, I have been searching for ages.

1 Like

Okay, apparently that didn’t work either. I fixed it once again, here is the final version (im confident):

local function SetSource(moduleScript: ModuleScript, directories: {Instance})
	local result = "return {"

	for _, directory in directories do
		if directory:IsA("ModuleScript") then
			result ..= ("\n\t[%q] = %s\n\t;"):format(directory.Name, `require({generatePath(moduleScript, directory)})`)
			continue
		end
		result ..= ("\n\t[%q] = %s\n\t};"):format(directory.Name, generateTable(moduleScript, directory, 2))
	end

	if result == "return {" then
		moduleScript.Source = "return {}"

		return
	end

	result ..= "\n};"

	moduleScript.Source = result
end
1 Like

May I use this function for my plugin? As you know, I used the function I had sent previously and now I know there is a bug. Thanks.

Of course! That is the main reason I sent this to you. All I have to say that the formatting is kind of screwed up but I guess you can fix it on your own time.

1 Like

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