View difference between Paste ID: zdsKtFFd and 2ZgLdxtF
SHOW: | | - or go back to the newest paste.
1-
local tArgs = {...}
1+
2
local w, h = term.getSize()
3
local lChanged = false
4
local pChanged = true
5
local mChanged = true
6
local numlength = 1
7
local type = 1
8
local tabNum = 0
9
local mode = "edit"
10
local clickStart, clickEnd, prevline, currentLine, currentPos
11
local cTables, cComTab, program, colTab = {}, {}, {}, {}
12
cParTab = {}
13
if mode == "edit" then
14
	colTab[1] = colors.lightGray
15
	colTab[2] = colors.green
16
	colTab[3] = colors.red
17
	colTab[4] = colors.orange
18
	colTab[5] = colors.lightBlue
19
	colTab[6] = colors.white
20
elseif mode == "read" then
21
	colTab[1] = colors.white
22
	colTab[2] = colors.white
23
	colTab[3] = colors.white
24
	colTab[4] = colors.white
25
	colTab[5] = colors.white
26
	colTab[6] = colors.white
27
end
28
local location = {
29
	["x"] = 1,
30
	["y"] = 1
31
}
32
local position = {
33
	["x"] = 1,
34
	["y"] = 1
35
}
36
local conditionals = {
37
	["if"] = {"end", colors.red, colors.pink},
38
	["while"] = {"end", colors.red, colors.pink},
39
	["for"] = {"end", colors.red, colors.pink},
40
	["function"] = {"end", colors.red, colors.pink}
41
}
42
local keywords = {
43
	["if"] = colors.yellow,
44
	["then"] = colors.yellow,
45
	["else"] = colors.yellow,
46
	["elseif"] = colors.yellow,
47
	["end"] = colors.yellow,
48
	["function"] = colors.yellow,
49
	["while"] = colors.yellow,
50
	["for"] = colors.yellow,
51
	["in"] = colors.yellow,
52
	["do"] = colors.yellow,
53
	["local"] = colors.yellow,
54
	["repeat"] = colors.yellow,
55
	["until"] = colors.yellow,
56
	["next"] = colors.yellow,
57
	["and"] = colors.orange,
58
	["or"] = colors.orange,
59
	["not"] = colors.orange,
60
	["true"] = colors.orange,
61
	["false"] = colors.orange,
62
	["nil"] = colors.gray,
63
	["break"] = colors.purple,
64
	["return"] = colors.purple,
65
	["print"] = colors.pink,
66
	["write"] = colors.pink,
67
	["pairs"] = colors.pink,
68
	["ipairs"] = colors.pink,
69
	["type"] = colors.blue,
70
	["tostring"] = colors.blue,
71
	["tonumber"] = colors.blue,
72
	["assert"] = colors.blue,
73
	["setmetatable"] = colors.blue
74
}
75
76-
if tArgs[1] and fs.exists(tArgs[1]) then
76+
77-
	for line in io.lines(tArgs[1]) do
77+
78-
		program[#program + 1] = tostring(line)
78+
79-
		program[#program] = program[#program]:gsub("    ", "$___")
79+
80
	term.setCursorPos(xPos, yPos)
81-
	if #program == 0 then
81+
82-
		program[1] = ""
82+
83
	term.write(string)
84-
elseif tArgs[1] then
84+
85-
	program[1] = ""
85+
86
local function codeDraw(string, xPos, yPos)
87
	local string = string or ""
88
	local xPos = xPos - location["x"] + 1
89
	local sStart, sEnd = 1, 1 + w - numlength
90
	local tabDraw = true
91
	local multiComment = false
92
	while #string > 0 and xPos <= sEnd do
93
		--[[for i in pairs(cComTab) do
94
			if mode == "edit" then
95
				if not multiComment and (yPos-1 == cComTab[i][1][2]-location["y"] + 1 and xPos-3 >= cComTab[i][1][1]-location["x"] + 1) or (yPos-1 == cComTab[i][2][2]-location["y"]+1 and xPos-2 <= cComTab[i][2][1]-location["x"]+1) or (yPos-1 > cComTab[i][1][2]-location["y"]+1 and yPos-1 < cComTab[i][2][2]-location["y"]+1) then
96
					colTab[1] = colors.green
97
					colTab[2] = colors.green
98
					colTab[3] = colors.green
99
					colTab[4] = colors.green
100
					colTab[5] = colors.green
101
					colTab[6] = colors.green
102
					multiComment = true
103
					break
104
				elseif multiComment then
105
					colTab[1] = colors.lightGray
106
					colTab[2] = colors.green
107
					colTab[3] = colors.red
108
					colTab[4] = colors.orange
109
					colTab[5] = colors.lightBlue
110
					colTab[6] = colors.white
111
					multiComment = false
112
				end
113
			end
114
		end]]--
115
		if string:find("^%$___") then
116
			local _, en = string:find("^%$___")
117
			if en >= sStart and xPos <= sEnd then
118
				if tabDraw and not multiComment then
119
					draw("   |", xPos, yPos, colTab[1], colors.black)
120
				else
121
					draw("    ", xPos, yPos, colTab[1], colors.black)
122
				end
123
			end
124
			string = string:sub(en + 1)
125
			xPos = xPos + en
126
		elseif string:find("^%-%-.*") then
127
			tabDraw = false
128
			local _, en = string:find("^%-%-.*")
129
			if en >= sStart and xPos <= sEnd then
130
				draw(string:sub(1, en), xPos, yPos, colTab[2], colors.black)
131
			end
132
			string = string:sub(en + 1)
133
			xPos = xPos + en
134
		elseif string:find("^\".-[^\\]\"") then
135
			tabDraw = false
136
			local _, en = string:find("^\".-[^\\]\"")
137
			if en >= sStart and xPos <= sEnd then
138
				draw(string:sub(1, en), xPos, yPos, colTab[3], colors.black)
139
			end
140
			string = string:sub(en + 1)
141
			xPos = xPos + en
142
		elseif string:find("^\'.-[^\\]\'") then
143
			tabDraw = false
144
			local _, en = string:find("^\'.-[^\\]\'")
145
			if en >= sStart and xPos <= sEnd then
146
				draw(string:sub(1, en), xPos, yPos, colTab[3], colors.black)
147
			end
148
			string = string:sub(en + 1)
149
			xPos = xPos + en
150
		elseif string:find("^\"\"") then
151
			tabDraw = false
152
			local _, en = string:find("^\"\"")
153
			if en >= sStart and xPos <= sEnd then
154
				draw(string:sub(1, en), xPos, yPos, colTab[3], colors.black)
155
			end
156
			string = string:sub(en + 1)
157
			xPos = xPos + en
158
		elseif string:find("^\'\'") then
159
			tabDraw = false
160
			local _, en = string:find("^\'\'")
161
			if en >= sStart and xPos <= sEnd then
162
				draw(string:sub(1, en), xPos, yPos, colTab[3], colors.black)
163
			end
164
			string = string:sub(en + 1)
165
			xPos = xPos + en
166
		elseif string:find("^%[%[.-%]%]") then
167
			tabDraw = false
168
			local _, en = string:find("^%[%[.-%]%]")
169
			if en >= sStart and xPos <= sEnd then
170
				draw(string:sub(1, en), xPos, yPos, colTab[3], colors.black)
171
			end
172
			string = string:sub(en + 1)
173
			xPos = xPos + en
174
		elseif string:find("^%d+") then
175
			tabDraw = false
176
			local _, en = string:find("^%d+")
177
			if en >= sStart and xPos <= sEnd then
178
				draw(string:sub(1, en), xPos, yPos, colTab[4], colors.black)
179
			end
180
			string = string:sub(en + 1)
181
			xPos = xPos + en
182
		elseif string:find("^%p") then
183
			tabDraw = false
184
			local _, en = string:find("^%p")
185
			if en >= sStart and xPos <= sEnd then
186
				draw(string:sub(1, en), xPos, yPos, colTab[5], colors.black)
187
			end
188
			string = string:sub(en + 1)
189
			xPos = xPos + en
190
		elseif string:find("^[%a_]+") then
191
			tabDraw = false
192
			local _, en = string:find("^[%a_]+")
193
			local test = string:sub(1, en)
194
			local color = colors.white
195
			if keywords[test] and mode == "edit" then
196
				color = keywords[test]
197
			end
198
			if multiComment then
199
				color = colors.green
200
			end
201
			if en >= sStart and xPos <= sEnd then
202
				draw(string:sub(1, en), xPos, yPos, color, colors.black)
203
			end
204
			string = string:sub(en + 1)
205
			xPos = xPos + en
206
		elseif string:find("^[^%w_]") then
207
			tabDraw = false
208
			local _, en = string:find("^[^%w_]")
209
			if en >= sStart and xPos <= sEnd then
210
				draw(string:sub(1, en), xPos, yPos, colTab[6], colors.black)
211
			end
212
			string = string:sub(en + 1)
213
			xPos = xPos + en
214
		end
215
	end
216
end
217
218
local function printMenu()
219
	term.setCursorPos(1, 1)
220
	term.setBackgroundColor(colors.lightGray)
221
	term.clearLine()
222
	draw("Press CTRL for menu...", 1, 1, colors.gray, colors.lightGray)
223
end
224
225
local function saveFile(codeTable, filename)
226
	local tempFile = {}
227
	for i, v in ipairs(codeTable) do
228
		tempFile[i] = v:gsub("$___", "    ")
229
	end
230
	local sFile = fs.open(filename, "w")
231
	for _, v in ipairs(tempFile) do
232
		sFile.writeLine(v)
233
	end
234
	sFile.close()
235
end
236
237
local function showProgram()
238
	multiComment = false
239
	numlength = #tostring(#program - location["y"] + 1 >= h and location["y"] + h - 1  or #program)
240
	for y = location["y"], #program - location["y"] + 1 >= h - 1 and location["y"] + h - 2  or #program do
241
		codeDraw(program[y], 1 + numlength, y - location["y"] + 2)
242
    end
243
end
244
245
local function showProgramLine(line)
246
	numlength = #tostring(#program - location["y"] + 1 >= h and location["y"] + h - 1  or #program)
247
	codeDraw(program[line], 1 + numlength, line - location["y"] + 2)
248
end
249
250
local function showNumbers()
251
	local activeLoops = {}
252
	local up, down
253
	for _, v in pairs(cTables) do
254
		if currentLine >= v[1] and currentLine <= v[2] then
255
			activeLoops[#activeLoops + 1] = {v[1], v[2]}
256
		end
257
	end
258
	if #activeLoops > 0 then
259
		local key, mini = 0, #program
260
		for i, v in pairs(activeLoops) do
261
			if v[2] - v[1] < mini then
262
				key, mini = i, v[2] - v[1]
263
			end
264
		end
265
		if key > 0 then
266
			up, down = activeLoops[key][1], activeLoops[key][2]
267
		end
268
	end
269
	for y = location["y"], #program - location["y"] + 1 >= h - 1 and location["y"] + h - 2  or #program do
270
		local text, back = colors.gray, colors.lightGray
271
		if up and down and y > up and y < down then
272
			text, back = colors.red, colors.pink
273
		elseif up and down and (y == up or y == down) then
274
			text, back = colors.pink, colors.red
275
		end
276
		draw(tostring(y), 1, y - location["y"] + 2, text, back)
277
		if #tostring(y) < numlength then
278
			write(" ")
279
		end
280
	end
281
end
282
283
local function addLetter(char, str, pos)
284
	return str:sub(0, pos - 1) .. tostring(char) .. str:sub(pos)
285
end
286
287
local function removeLetter(str, pos)
288
	return str:sub(0, pos) .. str:sub(pos + 2)
289
end
290
291
local function fixCursorPos()
292
	if position["y"] < 1 then
293
		pChanged = true
294
		location["y"] = location["y"] + position["y"] - 1
295-
local function checkParenthesis()
295+
296-
	local cancelNum = 0
296+
297-
	local pString = ""
297+
298-
	pBreaks = {}
298+
299-
	local cBrackets = {}
299+
300-
	pBreaks[1] = 0
300+
301-
	for y = 1, #program do
301+
302-
		pString = pString .. program[y]
302+
303-
		pBreaks[y+1] = #program[y] + pBreaks[y]
303+
304
	elseif location["y"] + h - 1 > #program then
305-
	while pString:find("[%[%{%(]") do
305+
306-
		local oppChar
306+
307-
		local st, en = pString:find("[%[%{%(]")
307+
308-
		term.setBackgroundColor(colors.magenta)
308+
309-
		local char = pString:sub(st, st)
309+
310-
		if char == "[" then oppChar = "]"
310+
311-
		elseif char == "{" then oppChar = "}"
311+
312-
		elseif char == "(" then oppChar = ")" end
312+
313-
		st, en = pString:find("%b" .. char .. oppChar)
313+
314-
		if st and en then
314+
315-
			local x1, y1, x2, y2
315+
316-
			local active = true
316+
317-
			for i, v in pairs(pBreaks) do
317+
318-
				if st <= v and active then
318+
319-
					x1 = st - pBreaks[i - 1]
319+
320-
					y1 = i - 1
320+
321-
					active = false
321+
322
					dollarNum = nil
323-
				if en <= v then
323+
324-
					x2 = en - pBreaks[i - 1]
324+
325-
					y2 = i - 1
325+
326
		end
327-
				if x1 and y1 and x2 and y2 then 
327+
328-
					cBrackets[#cBrackets + 1] = {x1, y1, x2, y2, char, oppChar}
328+
329-
					break 
329+
330
	end
331
	if position["x"] + location["x"] - 1 > #program[position["y"] + location["y"] - 1] then
332-
			pString = pString:sub(1, st - 1) .. " " .. pString:sub(st + 1)
332+
333-
			pString = pString:sub(1, en - 1) .. " " .. pString:sub(en + 1)
333+
334-
		else
334+
335-
			st, en = pString:find("[%[%{%(]")
335+
336-
			pString = pString:sub(1, st - 1) .. " " .. pString:sub(st + 1)
336+
337
		position["x"] = 1
338
	elseif position["x"] > w - numlength then
339-
	return cBrackets
339+
340
		location["x"] = location["x"] + position["x"] - (w-numlength)
341
		position["x"] = w - numlength
342-
local function checkConditionals()
342+
343-
	local cWords = {}
343+
344-
	local active = false
344+
345-
	local cancelNum = 0
345+
346-
	local cConditional = {}
346+
347-
	for y = 1, #program do
347+
348-
		for i in pairs(conditionals) do
348+
349-
			local test = program[y]:gsub(" ", "")
349+
350-
			local st = test:find(i)
350+
351-
			local _, en = program[y]:find(i)
351+
352-
			if st and en then
352+
353-
				if st == 1 and (en == #program[y] or program[y]:sub(en + 1, en + 1) == " ") then
353+
354-
					cWords[#cWords + 1] = {}
354+
355-
					cWords[#cWords][1] = y
355+
356-
					cancelNum = cancelNum + 1
356+
357-
					cConditional[cancelNum] = #cWords
357+
358-
					active = true
358+
359
term.setCursorBlink(true)
360
while true do
361
	if mode == "edit" then
362-
		if active and program[y]:find("end") then
362+
363-
			cWords[cConditional[cancelNum]][2] = y
363+
364-
			cancelNum = cancelNum - 1
364+
365-
			if cancelNum == 0 then
365+
366-
				active = false
366+
367-
				if y > location["y"] + h - 2 then
367+
368
	if pChanged or program[currentLine]:sub(currentPos - 2, currentPos - 1) == "]]" then
369
		--cTables = checkConditionals()
370
		term.setBackgroundColor(colors.black)
371
		term.clear()
372
		showProgram()
373-
	local rem = {}
373+
374-
	for i = 1, #cWords do
374+
375-
		if not (cWords[i][1] and cWords[i][2]) then
375+
376-
			rem[#rem + 1] = i
376+
377
		term.setBackgroundColor(colors.black)
378
		term.clearLine()
379-
	for i, v in pairs(rem) do
379+
380-
		table.remove(cWords, v - i + 1)
380+
381
	end
382-
	return cWords
382+
383
		printMenu()
384
		mChanged = false
385-
function checkMultiComments()
385+
386-
	local cComments = {}
386+
387-
	local active = false
387+
388-
	local cancelNum = 0
388+
389-
	local cConditional = {}
389+
390-
	for y = 1, #program do
390+
391-
		if program[y]:find("%-%-%[%[") and not active then
391+
392-
			active = true
392+
393-
			local st = program[y]:find("%-%-%[%[")
393+
394-
			cComments[#cComments + 1] = {}
394+
395-
			cComments[#cComments][1]= {st, y}
395+
396-
		elseif program[y]:find("%]%]") and active then
396+
397-
			active = false
397+
398-
			local _, en = program[y]:find("%]%]")
398+
399-
			cComments[#cComments][2] = {en, y}
399+
400
	end]]
401
	if mode == "edit" then
402-
	local rem = {}
402+
403-
	for i = 1, #cComments do
403+
404-
		if #cComments[i] < 2  then
404+
405-
			rem[#rem + 1] = i
405+
406
	local events = {os.pullEvent()}
407
	if events[1] == "char" and mode == "edit" then
408-
	for i, v in pairs(rem) do
408+
409-
		table.remove(cComments, v - i + 1)
409+
410
		position["x"] = position["x"] + 1
411-
	return cComments
411+
412
		if events[2] == keys.up then   --^
413
				position["y"] = position["y"] - 1
414
		elseif events[2] == keys.down then   --v
415
				position["y"] = position["y"] + 1
416
		elseif events[2] == keys.right then   -->
417
			if (position["x"] + location["x"] - 1) % 4 == 1 and position["x"] + location["x"] - 1 < #program[currentLine] and program[currentLine]:sub(position["x"] + location["x"] - 1, position["x"] + location["x"] + 2) == "$___" then
418
				position["x"] = position["x"] + 4
419
			elseif currentLine < #program and currentPos > #program[currentLine] then
420
				position["x"] = 1 - location["x"] + 1
421
				position["y"] = position["y"] + 1
422
			else
423
				position["x"] = position["x"] + 1
424
			end
425
		elseif events[2] == keys.left then   --<
426
			if (position["x"] + location["x"] - 1) % 4 == 1 and position["x"] + location["x"] - 1 > 4 and program[currentLine]:sub(position["x"] + location["x"] - 5, position["x"] + location["x"] - 2) == "$___" then
427
				position["x"] = position["x"] - 4
428
			elseif currentLine > 1 and currentPos == 1 then
429
				position["x"] = #program[currentLine - 1] + 1
430
				position["y"] = position["y"] - 1
431
			else
432
				position["x"] = position["x"] - 1
433
			end
434
		end
435
		if events[2] == keys.backspace and mode == "edit" then
436
			lChanged = true
437
			if (position["x"] + location["x"] - 1) % 4 == 1 and position["x"] + location["x"] - 1 > 4 and program[currentLine]:sub(position["x"] + location["x"] - 5, position["x"] + location["x"] - 2) == "$___"  then
438
				for i = 1, 4 do
439
					program[currentLine] = removeLetter(program[currentLine], location["x"] + position["x"] - 6)
440
					position["x"] = position["x"] - 4
441
				end
442
			elseif currentLine > 1 and currentPos == 1 then
443
				position["y"] = position["y"] - 1
444
				location["x"] = (location["x"] > #program[currentLine - 1] or location["x"] + w - #tostring(currentLine - 1) < #program[currentLine - 1]) and #program[currentLine - 1] + 1 or location["x"]
445
				position["x"] = #program[currentLine - 1] - location["x"] + 2
446
				program[currentLine - 1] = program[currentLine - 1] .. (table.remove(program, currentLine))
447
				pChanged = true
448
                        else
449
				program[currentLine] = removeLetter(program[currentLine], currentPos - 2)
450
				position["x"] = position["x"] - 1
451
			end
452
		end
453
		if events[2] == keys.enter and mode == "edit" then
454
			pChanged = true
455
			table.insert(program, currentLine + 1, program[currentLine]:sub(position["x"] + location["x"] - 1))
456
			program[currentLine] = program[currentLine]:sub(1, position["x"] + location["x"] - 2)
457
			program[currentLine + 1] = string.rep("$___", tabNum) .. program[currentLine + 1]
458
			position["y"] = position["y"] + 1
459
			position["x"] = 1 + tabNum * 4
460
		end
461
		if events[2] == keys.tab and mode == "edit" then
462
			lChanged = true
463
			if (position["x"] + location["x"] - 1) % 4 == 1 then
464
				program[currentLine] = addLetter("$___", program[currentLine], position["x"] + location["x"] - 1)
465
			else
466
				local num = (position["x"] + location["x"] - 1) % 4 + 1
467
				if num == 4 then num = 2 end
468
				program[currentLine] = addLetter(string.rep(" ", num), program[currentLine], position["x"] + location["x"] - 1)
469
			end
470
			position["x"] = position["x"] + 4
471
		end
472
	end
473
	if events[1] == "mouse_click" and events[2] == 1 and #program >= events[4] + location["y"] - 2 and events[4] > 1 then
474
		position["y"] = events[4] - 1
475
		position["x"] = events[3] - numlength
476
	elseif events[1] == "mouse_drag" and events[2] == 1 then
477
		clickEnd = {events[3] + location["x"] - 1, events[4] + location["y"] - 1}
478
	end
479
	if events[1] == "mouse_scroll" then
480
		pChanged = true
481
		location["y"] = location["y"] + events[2]
482
	end
483
end