Having trouble finding "\n" with string.find()

So I’m trying to make a system where it adds lines of text to a TextLabel, but deletes the first line when it is full (TextBounds.Y>AbsoluteSize.Y) to make an automatic “scrolling down” effect. (You know how in the command prompt if the screen fills up with text it automatically scrolls down to make the rest of the lines visible?)

This is what I came up with:

function ShowLine(display,text)
	if #display.Text==0 then --if there is no text
		display.Text = text
		display.Text = display.Text .. "\n" .. text --concatenate on next line
	if display.TextBounds.Y > display.AbsoluteSize.Y then -- if screen is full
		local _,nextLineEnd = string.find(display.Text,"\n") -- find where the first \n ends
		display.Text = string.gsub(display.Text,string.sub(display.Text,1,nextLineEnd),"",1) -- remove the first line
		print(nextLineEnd) -- keeps printing weird numbers

for _,text in pairs(textToPrint) do ShowLine(screen,text) wait() end

Everything works fine until the screen fills up, then although TextBounds.Y>AbsoluteSize.Y is satisfied (You can tell because print(nextLineEnd) fires), it doesn’t delete the first line and “scroll down”, and print(nextLineEnd) keeps printing 106 or 108, although the length of each line is completely different.

I’m guessing that the problem is that string.find() doesn’t exactly know where the "\n"s are located, but I don’t exactly know how I can rectify this issue.

Can somebody help? (The linked video is the current result btw)

P.S. this is my first post on the developer forum, please don’t bully me lol

Personally I would just use the following to remove the first line:

tempTable = string.split(display.Text, "\n") -- Split string into table
table.remove(tempTable, 1) -- Remove first line
display.Text = table.concat(tempTable, "\n")

I am not sure why your code is not working but the above worked for me.


Wow, I haven’t thought of that! Thx for the help, it works now :smiley:

Hi, welcome to the dev forum!

Great that it works. :slight_smile: I did look at your code and saw nothing wrong. So I quickly tried it in studio, and it works fine for me as long as the display doesn’t have TextScaled or TextWrapped set to true.

Then I noticed you make these changes to the UI from a server script. Usually you would want to do this from a localscript, as the UI itself is also local. It may at times lead to bugs like this, for example if the server doesn’t see the locally updated screen size. But even when I tested that, I still couldn’t reproduce the bug you described. :stuck_out_tongue:

So I’m not sure what’s wrong, but wanna say that the effect looks pretty cool, like a legit command line interface. :slight_smile:

One last thing, you can also use regular expressions for this. the gsub function can take a regex pattern, for example:

display.Text = string.gsub(display.Text, ".-\n", "", 1)

This is computationally a bit cheaper than making a table and removing the first entry: all other entries are shifted one to the left, which is a bit expensive for big tables. That is not a big issue here as the table size stays small due to the limitation on screen space, it’s just for insight.

This regex example uses the pattern “.-\n” which means, look for the pattern of any sequence of characters (dot followed by minus sign) which has \n after it. The minus sign is a non-greedy modifier, so that it takes any characters up to the first \n, and the \n itself, and replaces it once by an empty string. This results in removing the first line from your original string.

But there is an even better way to do it. Instead of using string.gsub like above, we can simply
use string.match to directly extract the inverse of this pattern, using the greedy modifier * (asterisk):

However, we don’t want to keep the \n at the start, so instead of capturing the pattern match, we capture only the group we are interested in, using brackets () :

display.Text = string.match(display.Text, "\n(.*)")

For more info on regex, have a look here:

Best of luck!