more editor work

This commit is contained in:
kepler155c@gmail.com
2020-04-04 20:55:29 -06:00
parent f655cc5965
commit 0a7ec352cc
2 changed files with 136 additions and 95 deletions

View File

@@ -23,7 +23,6 @@ local mark = { }
local searchPattern
local undo = { chain = { }, pointer = 0 }
local complete = { }
local page
h = h - 1
@@ -116,28 +115,31 @@ local keyMapping = {
[ 'control-r' ] = 'refresh',
}
page = UI.Page {
local page = UI.Page {
backgroundColor = color.panelColor,
menuBar = UI.MenuBar {
transitionHint = 'slideLeft',
buttons = {
{ text = 'File', dropdown = {
{ text = 'New ', event = 'menu_action', action = 'file_new' },
{ text = 'Open ', event = 'menu_action', action = 'file_open' },
{ spacer = true },
{ text = 'Save ^s', event = 'menu_action', action = 'save' },
{ text = 'Save As... ^S', event = 'menu_action', action = 'save_as', noFocus = true },
{ text = 'Save As... ^S', event = 'menu_action', action = 'save_as' },
{ spacer = true },
{ text = 'Run', event = 'menu_action', action = 'run' },
{ spacer = true },
{ text = 'Quit ^q', event = 'menu_action', action = 'exit', noFocus = true },
{ text = 'Quit ^q', event = 'menu_action', action = 'exit' },
} },
{ text = 'Edit', dropdown = {
{ text = 'Cut ^x', event = 'menu_action', action = 'cut' },
{ text = 'Copy ^c', event = 'menu_action', action = 'copy' },
{ text = 'Paste ^V', event = 'menu_action', action = 'paste_internal' },
{ spacer = true },
{ text = 'Find... ^f', event = 'menu_action', action = 'find_prompt', noFocus = true },
{ text = 'Find... ^f', event = 'menu_action', action = 'find_prompt' },
{ text = 'Find Next ^n', event = 'menu_action', action = 'find_next' },
{ spacer = true },
{ text = 'Go to line... ^g', event = 'menu_action', action = 'goto_line', noFocus = true },
{ text = 'Go to line... ^g', event = 'menu_action', action = 'goto_line' },
{ text = 'Mark all ^a', event = 'menu_action', action = 'mark_all' },
} },
},
@@ -172,10 +174,6 @@ page = UI.Page {
[ 'enter' ] = 'accept',
},
},
disable = function(self)
UI.SlideOut.disable(self)
self:setFocus(page.editor)
end,
show = function(self)
self.lineNo:reset()
UI.SlideOut.show(self)
@@ -217,10 +215,6 @@ page = UI.Page {
[ 'enter' ] = 'accept',
},
},
disable = function(self)
UI.SlideOut.disable(self)
self:setFocus(page.editor)
end,
show = function(self)
self.search:markAll()
UI.SlideOut.show(self)
@@ -267,10 +261,6 @@ page = UI.Page {
[ 'enter' ] = 'accept',
},
},
disable = function(self)
UI.SlideOut.disable(self)
self:setFocus(page.editor)
end,
show = function(self)
self.filename.value = fileInfo.abspath
if self.filename.value then
@@ -283,7 +273,7 @@ page = UI.Page {
if event.type == 'accept' then
local text = self.filename.value
if text and #text > 0 then
actions.save(shell.resolve(text))
actions.save('/' .. text)
end
self:hide()
return true
@@ -291,7 +281,7 @@ page = UI.Page {
return UI.SlideOut.eventHandler(self, event)
end,
},
quit = UI.SlideOut {
unsaved = UI.SlideOut {
x = -26, height = 1, y = -2,
noFill = true,
close = UI.Button {
@@ -306,13 +296,13 @@ page = UI.Page {
x = 2,
value = 'Save',
},
save = UI.Button {
yes = UI.Button {
x = 7,
text = 'Yes',
backgroundColor = color.panelColor,
event = 'save_yes',
},
quit = UI.Button {
no = UI.Button {
x = 13,
text = 'No',
backgroundColor = color.panelColor,
@@ -324,34 +314,52 @@ page = UI.Page {
backgroundColor = color.panelColor,
event = 'save_cancel',
},
disable = function(self)
UI.SlideOut.disable(self)
self:setFocus(page.editor)
end,
show = function(self)
show = function(self, action)
self.action = action
UI.SlideOut.show(self)
self:addTransition('slideLeft', { easing = 'outBounce' })
end,
eventHandler = function(self, event)
if event.type == 'save_yes' then
if actions.save() then
UI:quit()
self:hide()
actions.process(self.action)
end
elseif event.type == 'save_no' then
UI:quit()
actions.process(self.action, true)
self:hide()
elseif event.type == 'save_cancel' then
self:hide()
end
return UI.SlideOut.eventHandler(self, event)
end,
},
file_open = UI.FileSelect {
modal = true,
enable = function() end,
transitionHint = 'expandUp',
show = function(self)
UI.FileSelect.enable(self, fs.getDir(fileInfo.abspath))
self:focusFirst()
self:draw()
end,
eventHandler = function(self, event)
if event.type == 'select_cancel' then
self:disable()
elseif event.type == 'select_file' then
self:disable()
actions.process('open', event.file)
end
return UI.FileSelect.eventHandler(self, event)
end,
},
editor = UI.Window {
y = 2,
backgroundColor = colors.black,
transitionHint = 'slideRight',
focus = function(self)
if self.focused then
page.editor:setCursorPos(x - scrollX, y - scrollY)
self:setCursorPos(x - scrollX, y - scrollY)
self:setCursorBlink(true)
else
self:setCursorBlink(false)
@@ -380,6 +388,7 @@ page = UI.Page {
elseif ie.code == "mouse_click" or
ie.code == 'mouse_drag' or
--ie.code == 'mouse_up' or
ie.code == 'shift-mouse_click' or
ie.code == 'mouse_down' or
ie.code == 'mouse_doubleclick' then
@@ -405,14 +414,17 @@ page = UI.Page {
notification = UI.Notification { },
enable = function(self)
UI.Page.enable(self)
self:setFocus(page.editor)
self:setFocus(self.editor)
end,
checkFocus = function(self)
if not self.focused or not self.focused.enabled then
-- if no current focus, set it to the editor
self:setFocus(self.editor)
end
end,
eventHandler = function(self, event)
if event.type == 'menu_action' then
actions.process(event.element.action)
if not event.element.noFocus then -- hacky
self:setFocus(self.editor)
end
return true
end
return UI.Page.eventHandler(self, event)
@@ -435,6 +447,10 @@ local function getFileInfo(path)
fi.isReadOnly = fs.isReadOnly(fi.abspath)
end
if multishell then
multishell.setTitle(multishell.getCurrent(), fs.getName(fi.path))
end
return fi
end
@@ -446,40 +462,6 @@ local function setError(pattern, ...)
page.notification:error(string.format(pattern, ...))
end
local function load(path)
fileInfo = getFileInfo(path)
tLines = {}
if fs.exists(fileInfo.abspath) then
local file = io.open(fileInfo.abspath, "r")
local sLine = file:read()
while sLine do
table.insert(tLines, sLine)
sLine = file:read()
end
file:close()
end
if #tLines == 0 then
table.insert(tLines, '')
end
local name = fileInfo.path
if fileInfo.isNew then
if not fileInfo.dirExists then
setStatus('"%s" [New DIRECTORY]', name)
else
setStatus('"%s" [New File]', name)
end
elseif fileInfo.isReadOnly then
setStatus('"%s" [readonly] %dL, %dC',
name, #tLines, fs.getSize(fileInfo.abspath))
else
setStatus('"%s" %dL, %dC',
name, #tLines, fs.getSize(fileInfo.abspath))
end
end
local function save( _sPath )
-- Create intervening folder
local sDir = _sPath:sub(1, _sPath:len() - fs.getName(_sPath):len() )
@@ -758,6 +740,76 @@ actions = {
page.search:show()
end,
file_open = function(force)
if not force and undo.chain[#undo.chain] ~= lastSave then
page.unsaved:show('file_open')
else
page.file_open:show('file_open')
end
end,
file_new = function(force)
if not force and undo.chain[#undo.chain] ~= lastSave then
page.unsaved:show('file_new')
else
actions.open('/untitled.txt')
end
end,
open = function(filename)
if not actions.load(filename) then
setError('Unable to load file')
end
end,
load = function(path)
if fs.exists(path) and fs.isDir(path) then
return false
end
fileInfo = getFileInfo(path)
x, y = 1, 1
scrollX, scrollY = 0, 0
lastPos = { x = 1, y = 1 }
lastSave = nil
dirty = { y = 1, ey = h }
mark = { }
undo = { chain = { }, pointer = 0 }
complete = { }
tLines = { }
if fs.exists(fileInfo.abspath) then
local file = io.open(fileInfo.abspath, "r")
local sLine = file:read()
while sLine do
table.insert(tLines, sLine)
sLine = file:read()
end
file:close()
end
if #tLines == 0 then
table.insert(tLines, '')
end
local name = fileInfo.path
if fileInfo.isNew then
if not fileInfo.dirExists then
setStatus('"%s" [New DIRECTORY]', name)
else
setStatus('"%s" [New File]', name)
end
elseif fileInfo.isReadOnly then
setStatus('"%s" [readonly] %dL, %dC',
name, #tLines, fs.getSize(fileInfo.abspath))
else
setStatus('"%s" %dL, %dC',
name, #tLines, fs.getSize(fileInfo.abspath))
end
return true
end,
save = function(filename)
filename = filename or fileInfo.abspath
if fs.isReadOnly(filename) then
@@ -767,9 +819,6 @@ actions = {
if ok then
lastSave = undo.chain[#undo.chain]
fileInfo = getFileInfo(filename)
if multishell then
multishell.setTitle(multishell.getCurrent(), fileInfo.path)
end
setStatus('"%s" %dL, %dC written',
fileInfo.path, #tLines, fs.getSize(fileInfo.abspath))
return true
@@ -783,9 +832,9 @@ actions = {
page.save_as:show()
end,
exit = function()
if undo.chain[#undo.chain] ~= lastSave then
page.quit:show()
exit = function(force)
if not force and undo.chain[#undo.chain] ~= lastSave then
page.unsaved:show('exit')
else
UI:quit()
end
@@ -810,12 +859,9 @@ actions = {
end,
status = function()
local modified = ''
if undo.chain[1] then
modified = '[Modified] '
end
local modified = undo.chain[#undo.chain] == lastSave and '' or '[Modified] '
setStatus('"%s" %s%d lines --%d%%--',
fileInfo.path, modified, #tLines,
fileInfo.abspath, modified, #tLines,
math.floor((y - 1) / (#tLines - 1) * 100))
end,
@@ -1299,23 +1345,10 @@ actions = {
end,
}
local tArgs = { ... }
if #tArgs == 0 then
error( "Usage: edit <path>" )
end
-- Error checking
local sPath = shell.resolve(tArgs[1])
if fs.exists(sPath) and fs.isDir(sPath) then
error( "Cannot edit a directory." )
end
load(tArgs[1])
if multishell then
multishell.setTitle(multishell.getCurrent(), fs.getName(sPath))
local args = { ... }
if not actions.load(args[1] and args[1] or 'untitled.txt') then
error('Error opening file')
end
UI:setPage(page)
UI:start()

View File

@@ -65,4 +65,12 @@
run = "SoundPlayer",
iconExt = "\030 \031 \128\0307\159\129\030 \0317\149\0310\144\0300\031 \155\030 \0310\137\144\010\0307\0317\128\128\128\030 \149\0300\031 \149\030 \128\0310\149\0300\031 \149\010\030 \031 \128\0317\130\0307\031 \144\030 \0317\149\0310\129\134\152\129",
},
[ "464c4ffd019e1e9691dcf0537c797353ef2b1c1d4833d3d463e5b74ae4547344" ] = {
title = "Editor",
category = "Apps",
run = "edit",
iconExt = "7\
¨¨¨¨f€0¨\
¨¨f€0¨¨f€",
}
}