Get text and number of line where the match occurred

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”.


And the code I’m using is
изображение

2 Likes

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!

Btw do you know why “match” is nil here even though it finds a match?
изображение

And for the line text, will this work?
изображение

I relized why it was nil and
изображение
Is working like this:

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:

Maybe like this:

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

What exactly IS the AddMatch() function?

It just creates a frame with line number and line text based on the given arguments.
изображение
изображение

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!

1 Like

(reminder that if the above message was what you needed, please mark it as the solution!)

I’m at school now and I’ll try your solution when I get home :slight_smile:

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).

@PoppyandNeivaarecute, 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.

Current code:
изображение
изображение