1

I'm currently programming a proof of concept text editor for computerCraft, in Lua; one feature will be line counting. How would one count the lines in a string, or at least count the newline characters? There would also ideally be line numbers at the side of the display/terminal, which may work with the same code.

I couldn't find any good enough search results, would appreciate a link if it's been answered already.

I've no idea how to do this, the ideal results would be an array with all the lines of text separated into different entries; this would answer both problems; but more 'bespoke' options may be present

Hopefully with help I can achieve an output like this...

1 |while true do
2 |sleep(0)
3 |write("Example")
4 |write("Script\n\n")
5 |end
:
PPPe Code Editor ~ 5 lines

...refreshing when something changes

VBW
  • 97
  • 10
  • Just a hint, if you intend to also do syntax highlighting you'll want something more involved than just gsub/strmatch _very_ soon. I ended up writing a Lua tokenizer in pure Lua for a similar use-case. If it's available in ConputerCraft, check out LPEG. – dualed Apr 23 '19 at 18:15
  • I'll make a more advanced version with stuff like that at some point, once I get more experience with the display features..! +ZX80s didn't have syntax highlighting, and their editor is what inspired me to make this (even if it works more like vi) ... ... ... I will google LPeg :) – VBW Apr 24 '19 at 12:30

2 Answers2

0

Start with a string:

local str = "One sentence.\nAnother sentence.\nThe end."

Then:

local lines = {}
for line in (str):gmatch("[%a+%s]+") do 
    table.insert(lines, line) 
end

for i, line in ipairs(lines) do
    print("Line " .. i .. ": " .. line)
end

This will print:

Line 1: One sentence.
Line 2: Another Sentence.
Line 3: The end.

You may need to tweak the search pattern to handle lines with other characters, but that’s a good exercise for the programmer.

brianolive
  • 1,573
  • 2
  • 9
  • 19
0

You can use string.gsub, as it returns the number of performed substitutions as the second result:

local _, replacements = string.gsub(text, "\n", "\n")

Update (4/22/19): If you need to add a line number to each line (the original question was about line counting), then you can still use string.gsub, but you'll need to provide a function that will count the lines, for example:

lines = 1
local text = "1 |"..string.gsub(text, "\n", function(s) lines = lines + 1 return s..lines.." |" end)
print(text)
print(lines)

For your text, this will print:

1 |while true do
2 |sleep(0)
3 |write("Example")
4 |write("Script\n\n")
5 |end
5
Paul Kulchenko
  • 25,884
  • 3
  • 38
  • 56
  • +1 for a nice var which can be printed on each display refresh and a good solution to the line count, but will take a lot of fiddling to use for line numbering – VBW Apr 22 '19 at 08:35