init
This commit is contained in:
408
orderedit.lua
Normal file
408
orderedit.lua
Normal file
@@ -0,0 +1,408 @@
|
||||
-- SPDX-FileCopyrightText: 2017 Daniel Ratcliffe
|
||||
--
|
||||
-- SPDX-License-Identifier: LicenseRef-CCPL
|
||||
|
||||
-- Get file to edit
|
||||
|
||||
local x, y = 1, 1
|
||||
local w, h = term.getSize()
|
||||
local scrollX, scrollY = 0, 0
|
||||
|
||||
local tLines = {""}
|
||||
local bRunning = true
|
||||
|
||||
local returnvalue = nil
|
||||
|
||||
-- Colours
|
||||
local highlightColour, keywordColour, textColour, bgColour, errorColour
|
||||
|
||||
bgColour = colours.black
|
||||
textColour = colours.white
|
||||
highlightColour = colours.white
|
||||
keywordColour = colours.white
|
||||
errorColour = colours.white
|
||||
|
||||
-- Menus
|
||||
local menu = require "cc.internal.menu"
|
||||
local current_menu
|
||||
local menu_items = {}
|
||||
table.insert(menu_items, "Done")
|
||||
|
||||
local status_ok, status_text
|
||||
|
||||
local tCompletions
|
||||
local nCompletion
|
||||
|
||||
local function redrawLines(line, endLine)
|
||||
if not endLine then endLine = line end
|
||||
|
||||
local colour = term.getTextColour()
|
||||
|
||||
-- Highlight all lines between line and endLine, highlighting further lines if their
|
||||
-- lexer state has changed and aborting at the end of the screen.
|
||||
local changed = false
|
||||
while (changed or line <= endLine) and line - scrollY < h do
|
||||
term.setCursorPos(1 - scrollX, line - scrollY)
|
||||
term.clearLine()
|
||||
|
||||
local contents = tLines[line]
|
||||
if not contents then break end
|
||||
print(contents)
|
||||
|
||||
line = line + 1
|
||||
end
|
||||
|
||||
term.setTextColor(colours.white)
|
||||
term.setCursorPos(x - scrollX, y - scrollY)
|
||||
end
|
||||
|
||||
local function redrawText()
|
||||
redrawLines(scrollY + 1, scrollY + h - 1)
|
||||
end
|
||||
|
||||
local function redrawMenu()
|
||||
-- Clear line
|
||||
term.setCursorPos(1, h)
|
||||
term.clearLine()
|
||||
|
||||
-- Draw line numbers
|
||||
term.setCursorPos(w - #("Ln " .. y) + 1, h)
|
||||
term.setTextColour(highlightColour)
|
||||
term.write("Ln ")
|
||||
term.setTextColour(textColour)
|
||||
term.write(y)
|
||||
|
||||
term.setCursorPos(1, h)
|
||||
if current_menu then
|
||||
-- Draw menu
|
||||
menu.draw(current_menu)
|
||||
else
|
||||
-- Draw status
|
||||
term.setTextColour(colors.yellow)
|
||||
term.write("Press ctrl to view options")
|
||||
term.setTextColour(textColour)
|
||||
end
|
||||
|
||||
-- Reset cursor
|
||||
term.setCursorPos(x - scrollX, y - scrollY)
|
||||
term.setCursorBlink(not current_menu)
|
||||
end
|
||||
|
||||
local tMenuFuncs = {
|
||||
Done = function()
|
||||
local order = table.concat(tLines,"\n")
|
||||
term.clear()
|
||||
returnvalue = order
|
||||
end
|
||||
}
|
||||
|
||||
local function setCursor(newX, newY)
|
||||
local _, oldY = x, y
|
||||
x, y = newX, newY
|
||||
local screenX = x - scrollX
|
||||
local screenY = y - scrollY
|
||||
|
||||
local bRedraw = false
|
||||
if screenX < 1 then
|
||||
scrollX = x - 1
|
||||
screenX = 1
|
||||
bRedraw = true
|
||||
elseif screenX > w then
|
||||
scrollX = x - w
|
||||
screenX = w
|
||||
bRedraw = true
|
||||
end
|
||||
|
||||
if screenY < 1 then
|
||||
scrollY = y - 1
|
||||
screenY = 1
|
||||
bRedraw = true
|
||||
elseif screenY > h - 1 then
|
||||
scrollY = y - (h - 1)
|
||||
screenY = h - 1
|
||||
bRedraw = true
|
||||
end
|
||||
|
||||
if bRedraw then
|
||||
redrawText()
|
||||
elseif y ~= oldY then
|
||||
redrawLines(math.min(y, oldY), math.max(y, oldY))
|
||||
else
|
||||
redrawLines(y)
|
||||
end
|
||||
|
||||
redrawMenu()
|
||||
end
|
||||
|
||||
-- Actual program functionality begins
|
||||
|
||||
term.setBackgroundColour(bgColour)
|
||||
term.clear()
|
||||
term.setCursorPos(x, y)
|
||||
term.setCursorBlink(true)
|
||||
|
||||
redrawText()
|
||||
redrawMenu()
|
||||
|
||||
local function acceptCompletion()
|
||||
if nCompletion then
|
||||
-- Append the completion
|
||||
local sCompletion = tCompletions[nCompletion]
|
||||
tLines[y] = tLines[y] .. sCompletion
|
||||
setCursor(x + #sCompletion, y)
|
||||
end
|
||||
end
|
||||
|
||||
local function handleMenuEvent(event)
|
||||
assert(current_menu)
|
||||
|
||||
local result = menu.handle_event(current_menu, table.unpack(event, 1, event.n))
|
||||
if result == false then
|
||||
current_menu = nil
|
||||
redrawMenu()
|
||||
elseif result ~= nil then
|
||||
tMenuFuncs[result]()
|
||||
current_menu = nil
|
||||
redrawMenu()
|
||||
end
|
||||
end
|
||||
|
||||
-- Handle input
|
||||
while bRunning do
|
||||
local event = table.pack(os.pullEvent())
|
||||
if event[1] == "key" then
|
||||
if current_menu then
|
||||
handleMenuEvent(event)
|
||||
if returnvalue then
|
||||
return returnvalue
|
||||
end
|
||||
else
|
||||
local key = event[2]
|
||||
if key == keys.up then
|
||||
if nCompletion then
|
||||
-- Cycle completions
|
||||
nCompletion = nCompletion - 1
|
||||
if nCompletion < 1 then
|
||||
nCompletion = #tCompletions
|
||||
end
|
||||
redrawLines(y)
|
||||
|
||||
elseif y > 1 then
|
||||
-- Move cursor up
|
||||
setCursor(
|
||||
math.min(x, #tLines[y - 1] + 1),
|
||||
y - 1
|
||||
)
|
||||
end
|
||||
|
||||
elseif key == keys.down then
|
||||
if nCompletion then
|
||||
-- Cycle completions
|
||||
nCompletion = nCompletion + 1
|
||||
if nCompletion > #tCompletions then
|
||||
nCompletion = 1
|
||||
end
|
||||
redrawLines(y)
|
||||
|
||||
elseif y < #tLines then
|
||||
-- Move cursor down
|
||||
setCursor(
|
||||
math.min(x, #tLines[y + 1] + 1),
|
||||
y + 1
|
||||
)
|
||||
end
|
||||
|
||||
elseif key == keys.tab then
|
||||
if nCompletion and x == #tLines[y] + 1 then
|
||||
-- Accept autocomplete
|
||||
acceptCompletion()
|
||||
else
|
||||
-- Indent line
|
||||
local sLine = tLines[y]
|
||||
tLines[y] = string.sub(sLine, 1, x - 1) .. " " .. string.sub(sLine, x)
|
||||
setCursor(x + 4, y)
|
||||
end
|
||||
|
||||
elseif key == keys.pageUp then
|
||||
-- Move up a page
|
||||
local newY
|
||||
if y - (h - 1) >= 1 then
|
||||
newY = y - (h - 1)
|
||||
else
|
||||
newY = 1
|
||||
end
|
||||
setCursor(
|
||||
math.min(x, #tLines[newY] + 1),
|
||||
newY
|
||||
)
|
||||
elseif key == keys.pageDown then
|
||||
-- Move down a page
|
||||
local newY
|
||||
if y + (h - 1) <= #tLines then
|
||||
newY = y + (h - 1)
|
||||
else
|
||||
newY = #tLines
|
||||
end
|
||||
local newX = math.min(x, #tLines[newY] + 1)
|
||||
setCursor(newX, newY)
|
||||
|
||||
elseif key == keys.home then
|
||||
-- Move cursor to the beginning
|
||||
if x > 1 then
|
||||
setCursor(1, y)
|
||||
end
|
||||
|
||||
elseif key == keys["end"] then
|
||||
-- Move cursor to the end
|
||||
local nLimit = #tLines[y] + 1
|
||||
if x < nLimit then
|
||||
setCursor(nLimit, y)
|
||||
end
|
||||
|
||||
elseif key == keys.left then
|
||||
if x > 1 then
|
||||
-- Move cursor left
|
||||
setCursor(x - 1, y)
|
||||
elseif x == 1 and y > 1 then
|
||||
setCursor(#tLines[y - 1] + 1, y - 1)
|
||||
end
|
||||
|
||||
elseif key == keys.right then
|
||||
local nLimit = #tLines[y] + 1
|
||||
if x < nLimit then
|
||||
-- Move cursor right
|
||||
setCursor(x + 1, y)
|
||||
elseif nCompletion and x == #tLines[y] + 1 then
|
||||
-- Accept autocomplete
|
||||
acceptCompletion()
|
||||
elseif x == nLimit and y < #tLines then
|
||||
-- Go to next line
|
||||
setCursor(1, y + 1)
|
||||
end
|
||||
|
||||
elseif key == keys.delete then
|
||||
local nLimit = #tLines[y] + 1
|
||||
if x < nLimit then
|
||||
local sLine = tLines[y]
|
||||
tLines[y] = string.sub(sLine, 1, x - 1) .. string.sub(sLine, x + 1)
|
||||
redrawLines(y)
|
||||
elseif y < #tLines then
|
||||
tLines[y] = tLines[y] .. tLines[y + 1]
|
||||
table.remove(tLines, y + 1)
|
||||
redrawText()
|
||||
end
|
||||
|
||||
elseif key == keys.backspace then
|
||||
if x > 1 then
|
||||
-- Remove character
|
||||
local sLine = tLines[y]
|
||||
if x > 4 and string.sub(sLine, x - 4, x - 1) == " " and not string.sub(sLine, 1, x - 1):find("%S") then
|
||||
tLines[y] = string.sub(sLine, 1, x - 5) .. string.sub(sLine, x)
|
||||
setCursor(x - 4, y)
|
||||
else
|
||||
tLines[y] = string.sub(sLine, 1, x - 2) .. string.sub(sLine, x)
|
||||
setCursor(x - 1, y)
|
||||
end
|
||||
elseif y > 1 then
|
||||
-- Remove newline
|
||||
local sPrevLen = #tLines[y - 1]
|
||||
tLines[y - 1] = tLines[y - 1] .. tLines[y]
|
||||
table.remove(tLines, y)
|
||||
setCursor(sPrevLen + 1, y - 1)
|
||||
redrawText()
|
||||
end
|
||||
|
||||
elseif (key == keys.enter or key == keys.numPadEnter) then
|
||||
-- Newline
|
||||
local sLine = tLines[y]
|
||||
local _, spaces = string.find(sLine, "^[ ]+")
|
||||
if not spaces then
|
||||
spaces = 0
|
||||
end
|
||||
tLines[y] = string.sub(sLine, 1, x - 1)
|
||||
table.insert(tLines, y + 1, string.rep(' ', spaces) .. string.sub(sLine, x))
|
||||
setCursor(spaces + 1, y + 1)
|
||||
redrawText()
|
||||
|
||||
elseif key == keys.leftCtrl or key == keys.rightCtrl then
|
||||
current_menu = menu.create(menu_items)
|
||||
redrawMenu()
|
||||
end
|
||||
end
|
||||
elseif event[1] == "char" then
|
||||
if current_menu then
|
||||
handleMenuEvent(event)
|
||||
else
|
||||
-- Input text
|
||||
local sLine = tLines[y]
|
||||
tLines[y] = string.sub(sLine, 1, x - 1) .. event[2] .. string.sub(sLine, x)
|
||||
setCursor(x + 1, y)
|
||||
end
|
||||
|
||||
elseif event[1] == "paste" then
|
||||
-- Close menu if open
|
||||
if current_menu then
|
||||
current_menu = nil
|
||||
redrawMenu()
|
||||
end
|
||||
|
||||
-- Input text
|
||||
local text = event[2]
|
||||
local sLine = tLines[y]
|
||||
tLines[y] = string.sub(sLine, 1, x - 1) .. text .. string.sub(sLine, x)
|
||||
setCursor(x + #text, y)
|
||||
|
||||
elseif event[1] == "mouse_click" then
|
||||
local button, cx, cy = event[2], event[3], event[4]
|
||||
if current_menu then
|
||||
handleMenuEvent(event)
|
||||
else
|
||||
if button == 1 then
|
||||
-- Left click
|
||||
if cy < h then
|
||||
local newY = math.min(math.max(scrollY + cy, 1), #tLines)
|
||||
local newX = math.min(math.max(scrollX + cx, 1), #tLines[newY] + 1)
|
||||
setCursor(newX, newY)
|
||||
else
|
||||
current_menu = menu.create(menu_items)
|
||||
redrawMenu()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
elseif event[1] == "mouse_scroll" then
|
||||
if not current_menu then
|
||||
local direction = event[2]
|
||||
if direction == -1 then
|
||||
-- Scroll up
|
||||
if scrollY > 0 then
|
||||
-- Move cursor up
|
||||
scrollY = scrollY - 1
|
||||
redrawText()
|
||||
end
|
||||
|
||||
elseif direction == 1 then
|
||||
-- Scroll down
|
||||
local nMaxScroll = #tLines - (h - 1)
|
||||
if scrollY < nMaxScroll then
|
||||
-- Move cursor down
|
||||
scrollY = scrollY + 1
|
||||
redrawText()
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
elseif event[1] == "term_resize" then
|
||||
w, h = term.getSize()
|
||||
setCursor(x, y)
|
||||
redrawMenu()
|
||||
redrawText()
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
-- Cleanup
|
||||
term.clear()
|
||||
term.setCursorBlink(false)
|
||||
term.setCursorPos(1, 1)
|
||||
Reference in New Issue
Block a user