I’m making a plugin that finds certain string in every script. I got it working, but there is one problem: I don’t know how to get a line number where the match occurred and the text that this line contains. Currenly the line number is being displayed as 0 and content of the line is being displayed as “Placeholder text”.
I’ll try to figure out a script to do this. in the mean time, here is what you can do:
For the number of lines, count how many times \n appears in the source up until the point where the matched text is. You may need to subtract 1 from this number, due to the first line not having a \n
For getting the line of text, the best way I can think of is getting the \n before, then getting the one after it. Once you get the number of both the \n, you can then just do string.sub(). Note that this may not work on the first and last line of a script - to counter this add a check that if it can’t find one BEFORE, make the sub start at 1, and if there is not a \n after it, make the sub have no end!
I found a forum post on how to get the amount of lines in a script. You can change it so that when a line is the same to the line found, you return the number of lines.
Here is the link:
function getLines(s, lineNeedToBefound)
local lines = {};
local str = "";
for i = 1, string.len(s.Source) do
if (string.sub(s.Source, i, i) == "\n") then
lines[#lines+1] = str;
if str == lineNeedToBefound then
return #lines
else
str = "";
end
else
str = str..string.sub(s.Source, i, i);
end
end
if (str ~= "") then
lines[#lines+1] = str;
end
return #lines;
end
You could loop through all the lines in the string like so:
local lines = source:split("\n")
for lineNumber, statement in pairs(lines) do
for _, match in statement:gmatch(SearchText) do
-- Your code here
end
end
If I would do this to every script, my plugin would be absolete just because of how slow it would be.
Something like this should work, I just don’t know the right pattern to put into gmatch.
local TempSource = source
while string.find(TempSource, SearchText) do
local Position = string.find(TempSource, SearchText)
local Start = 0
local End = -1
for i = 1, Position do
if TempSource[i] == '\n' then
Start = i + 1
end
end
End = (string.find(TempSource, Position)-1) or -1
local LineNumber = 1
for i = 1, Position do
if TempSource[i] == "\n" then
LineNumber+=1
end
end
AddMatch(newResult, LineNumber, string.sub(TempSource, Start, End))
TempSource = string.sub(TempSource, End, -1)
end
I feel like this may be the only way. It shouldn’t be too slow: from experience searching through scripts using plugins and command line is surprisingly fast!
I decided to use string.split(source, "\n") because it is the easiest way. I though about it before creating this topic, but I though that it will slow down the search alot (it does not).
@SeargentAUS, I really appreciate your help, but, even if the concept of your script is right, your script doesn’t seem to be working due to some issues and is hardly faster than the string.split method. Thank you for for spending time finding solution to my issue.