completions + refactor
This commit is contained in:
228
common/edit.lua
228
common/edit.lua
@@ -15,14 +15,12 @@ local scrollY = 0
|
|||||||
local lastPos = { x = 1, y = 1 }
|
local lastPos = { x = 1, y = 1 }
|
||||||
local tLines = { }
|
local tLines = { }
|
||||||
local fileInfo
|
local fileInfo
|
||||||
local lastAction
|
|
||||||
local actions
|
local actions
|
||||||
local lastSave
|
local lastSave
|
||||||
local dirty = { y = 1, ey = h }
|
local dirty = { y = 1, ey = h }
|
||||||
local mark = { }
|
local mark = { }
|
||||||
local searchPattern
|
local searchPattern
|
||||||
local undo = { chain = { }, pointer = 0 }
|
local undo = { chain = { }, pointer = 0 }
|
||||||
local complete = { }
|
|
||||||
|
|
||||||
h = h - 1
|
h = h - 1
|
||||||
|
|
||||||
@@ -142,28 +140,19 @@ local page = UI.Page {
|
|||||||
{ text = 'Go to line... ^g', event = 'menu_action', action = 'goto_line' },
|
{ text = 'Go to line... ^g', event = 'menu_action', action = 'goto_line' },
|
||||||
{ text = 'Mark all ^a', event = 'menu_action', action = 'mark_all' },
|
{ text = 'Mark all ^a', event = 'menu_action', action = 'mark_all' },
|
||||||
} },
|
} },
|
||||||
|
{ text = 'Code', dropdown = {
|
||||||
|
{ text = 'Complete ^space', event = 'menu_action', action = 'autocomplete' },
|
||||||
|
} },
|
||||||
},
|
},
|
||||||
status = UI.Text {
|
status = UI.Text {
|
||||||
textColor = color.statusColor,
|
textColor = color.statusColor,
|
||||||
x = -11, width = 10,
|
x = -9, width = 9,
|
||||||
align = 'right',
|
align = 'right',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
gotoLine = UI.SlideOut {
|
gotoLine = UI.MiniSlideOut {
|
||||||
x = -15, height = 1, y = -2,
|
x = -15, y = -2,
|
||||||
noFill = true,
|
label = 'Line',
|
||||||
close = UI.Button {
|
|
||||||
x = -1,
|
|
||||||
backgroundColor = color.panelColor,
|
|
||||||
backgroundFocusColor = color.panelColor,
|
|
||||||
text = 'x',
|
|
||||||
event = 'slide_hide',
|
|
||||||
noPadding = true,
|
|
||||||
},
|
|
||||||
label = UI.Text {
|
|
||||||
x = 2,
|
|
||||||
value = 'Line',
|
|
||||||
},
|
|
||||||
lineNo = UI.TextEntry {
|
lineNo = UI.TextEntry {
|
||||||
x = 7, width = 7,
|
x = 7, width = 7,
|
||||||
limit = 5,
|
limit = 5,
|
||||||
@@ -176,8 +165,7 @@ local page = UI.Page {
|
|||||||
},
|
},
|
||||||
show = function(self)
|
show = function(self)
|
||||||
self.lineNo:reset()
|
self.lineNo:reset()
|
||||||
UI.SlideOut.show(self)
|
UI.MiniSlideOut.show(self)
|
||||||
self:addTransition('slideLeft', { easing = 'outBounce' })
|
|
||||||
end,
|
end,
|
||||||
eventHandler = function(self, event)
|
eventHandler = function(self, event)
|
||||||
if event.type == 'accept' then
|
if event.type == 'accept' then
|
||||||
@@ -187,24 +175,12 @@ local page = UI.Page {
|
|||||||
self:hide()
|
self:hide()
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return UI.SlideOut.eventHandler(self, event)
|
return UI.MiniSlideOut.eventHandler(self, event)
|
||||||
end,
|
end,
|
||||||
},
|
},
|
||||||
search = UI.SlideOut {
|
search = UI.MiniSlideOut {
|
||||||
x = -20, height = 1, y = -2,
|
x = -20, y = -2,
|
||||||
noFill = true,
|
label = 'Find',
|
||||||
close = UI.Button {
|
|
||||||
x = -1,
|
|
||||||
backgroundColor = color.panelColor,
|
|
||||||
backgroundFocusColor = color.panelColor,
|
|
||||||
text = 'x',
|
|
||||||
event = 'slide_hide',
|
|
||||||
noPadding = true,
|
|
||||||
},
|
|
||||||
label = UI.Text {
|
|
||||||
x = 2,
|
|
||||||
value = 'Find',
|
|
||||||
},
|
|
||||||
search = UI.TextEntry {
|
search = UI.TextEntry {
|
||||||
x = 7, width = 12,
|
x = 7, width = 12,
|
||||||
limit = 512,
|
limit = 512,
|
||||||
@@ -217,8 +193,7 @@ local page = UI.Page {
|
|||||||
},
|
},
|
||||||
show = function(self)
|
show = function(self)
|
||||||
self.search:markAll()
|
self.search:markAll()
|
||||||
UI.SlideOut.show(self)
|
UI.MiniSlideOut.show(self)
|
||||||
self:addTransition('slideLeft', { easing = 'outBounce' })
|
|
||||||
end,
|
end,
|
||||||
eventHandler = function(self, event)
|
eventHandler = function(self, event)
|
||||||
if event.type == 'accept' then
|
if event.type == 'accept' then
|
||||||
@@ -233,24 +208,12 @@ local page = UI.Page {
|
|||||||
self:hide()
|
self:hide()
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return UI.SlideOut.eventHandler(self, event)
|
return UI.MiniSlideOut.eventHandler(self, event)
|
||||||
end,
|
end,
|
||||||
},
|
},
|
||||||
save_as = UI.SlideOut {
|
save_as = UI.MiniSlideOut {
|
||||||
x = -24, height = 1, y = -2,
|
x = -24, y = -2,
|
||||||
noFill = true,
|
label = 'Save',
|
||||||
close = UI.Button {
|
|
||||||
x = -1,
|
|
||||||
backgroundColor = color.panelColor,
|
|
||||||
backgroundFocusColor = color.panelColor,
|
|
||||||
text = 'x',
|
|
||||||
event = 'slide_hide',
|
|
||||||
noPadding = true,
|
|
||||||
},
|
|
||||||
label = UI.Text {
|
|
||||||
x = 2,
|
|
||||||
value = 'Save',
|
|
||||||
},
|
|
||||||
filename = UI.TextEntry {
|
filename = UI.TextEntry {
|
||||||
x = 7, width = 16,
|
x = 7, width = 16,
|
||||||
limit = 512,
|
limit = 512,
|
||||||
@@ -263,11 +226,8 @@ local page = UI.Page {
|
|||||||
},
|
},
|
||||||
show = function(self)
|
show = function(self)
|
||||||
self.filename.value = fileInfo.abspath
|
self.filename.value = fileInfo.abspath
|
||||||
if self.filename.value then
|
|
||||||
self.filename:setPosition(#self.filename.value)
|
self.filename:setPosition(#self.filename.value)
|
||||||
end
|
UI.MiniSlideOut.show(self)
|
||||||
UI.SlideOut.show(self)
|
|
||||||
self:addTransition('slideLeft', { easing = 'outBounce' })
|
|
||||||
end,
|
end,
|
||||||
eventHandler = function(self, event)
|
eventHandler = function(self, event)
|
||||||
if event.type == 'accept' then
|
if event.type == 'accept' then
|
||||||
@@ -278,70 +238,45 @@ local page = UI.Page {
|
|||||||
self:hide()
|
self:hide()
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return UI.SlideOut.eventHandler(self, event)
|
return UI.MiniSlideOut.eventHandler(self, event)
|
||||||
end,
|
end,
|
||||||
},
|
},
|
||||||
unsaved = UI.SlideOut {
|
unsaved = UI.Question {
|
||||||
x = -26, height = 1, y = -2,
|
x = -25, y = -2,
|
||||||
noFill = true,
|
label = 'Save',
|
||||||
close = UI.Button {
|
|
||||||
x = -1,
|
|
||||||
backgroundColor = color.panelColor,
|
|
||||||
backgroundFocusColor = color.panelColor,
|
|
||||||
text = 'x',
|
|
||||||
event = 'slide_hide',
|
|
||||||
noPadding = true,
|
|
||||||
},
|
|
||||||
label = UI.Text {
|
|
||||||
x = 2,
|
|
||||||
value = 'Save',
|
|
||||||
},
|
|
||||||
yes = UI.Button {
|
|
||||||
x = 7,
|
|
||||||
text = 'Yes',
|
|
||||||
backgroundColor = color.panelColor,
|
|
||||||
event = 'save_yes',
|
|
||||||
},
|
|
||||||
no = UI.Button {
|
|
||||||
x = 13,
|
|
||||||
text = 'No',
|
|
||||||
backgroundColor = color.panelColor,
|
|
||||||
event = 'save_no',
|
|
||||||
},
|
|
||||||
cancel = UI.Button {
|
cancel = UI.Button {
|
||||||
x = 18,
|
x = 16,
|
||||||
text = 'Cancel',
|
text = 'Cancel',
|
||||||
backgroundColor = color.panelColor,
|
backgroundColor = color.panelColor,
|
||||||
event = 'save_cancel',
|
event = 'question_cancel',
|
||||||
},
|
},
|
||||||
show = function(self, action)
|
show = function(self, action)
|
||||||
self.action = action
|
self.action = action
|
||||||
UI.SlideOut.show(self)
|
UI.MiniSlideOut.show(self)
|
||||||
self:addTransition('slideLeft', { easing = 'outBounce' })
|
|
||||||
end,
|
end,
|
||||||
eventHandler = function(self, event)
|
eventHandler = function(self, event)
|
||||||
if event.type == 'save_yes' then
|
if event.type == 'question_yes' then
|
||||||
if actions.save() then
|
if actions.save() then
|
||||||
self:hide()
|
self:hide()
|
||||||
actions.process(self.action)
|
actions.process(self.action)
|
||||||
end
|
end
|
||||||
elseif event.type == 'save_no' then
|
elseif event.type == 'question_no' then
|
||||||
actions.process(self.action, true)
|
actions.process(self.action, true)
|
||||||
self:hide()
|
self:hide()
|
||||||
elseif event.type == 'save_cancel' then
|
elseif event.type == 'question_cancel' then
|
||||||
self:hide()
|
self:hide()
|
||||||
end
|
end
|
||||||
return UI.SlideOut.eventHandler(self, event)
|
return UI.MiniSlideOut.eventHandler(self, event)
|
||||||
end,
|
end,
|
||||||
},
|
},
|
||||||
file_open = UI.FileSelect {
|
file_open = UI.FileSelect {
|
||||||
modal = true,
|
modal = true,
|
||||||
enable = function() end,
|
enable = function() end,
|
||||||
transitionHint = 'expandUp',
|
|
||||||
show = function(self)
|
show = function(self)
|
||||||
UI.FileSelect.enable(self, fs.getDir(fileInfo.abspath))
|
UI.FileSelect.enable(self, fs.getDir(fileInfo.abspath))
|
||||||
self:focusFirst()
|
self:focusFirst()
|
||||||
self:draw()
|
self:draw()
|
||||||
|
self:addTransition('expandUp', { easing = 'outBounce', ticks = 12 })
|
||||||
end,
|
end,
|
||||||
eventHandler = function(self, event)
|
eventHandler = function(self, event)
|
||||||
if event.type == 'select_cancel' then
|
if event.type == 'select_cancel' then
|
||||||
@@ -353,6 +288,49 @@ local page = UI.Page {
|
|||||||
return UI.FileSelect.eventHandler(self, event)
|
return UI.FileSelect.eventHandler(self, event)
|
||||||
end,
|
end,
|
||||||
},
|
},
|
||||||
|
completions = UI.SlideOut {
|
||||||
|
x = -12, y = 2,
|
||||||
|
transitionHint = 'slideLeft',
|
||||||
|
grid = UI.Grid {
|
||||||
|
x = 2, y = 2, ey = -2,
|
||||||
|
columns = {
|
||||||
|
{ key = 'text', heading = 'Completion' },
|
||||||
|
},
|
||||||
|
accelerators = {
|
||||||
|
[ ' ' ] = 'down',
|
||||||
|
backspace = 'slide_hide',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
show = function(self, values)
|
||||||
|
local m = 12
|
||||||
|
for _, v in pairs(values) do
|
||||||
|
m = #v.text > m and #v.text or m
|
||||||
|
end
|
||||||
|
m = m + 3
|
||||||
|
m = m > self.parent.width and self.parent.width or m
|
||||||
|
self.ox = -m
|
||||||
|
self:resize()
|
||||||
|
self.grid:setValues(values)
|
||||||
|
self.grid:setIndex(1)
|
||||||
|
UI.SlideOut.show(self)
|
||||||
|
end,
|
||||||
|
cancel = UI.Button {
|
||||||
|
y = -1, x = -9,
|
||||||
|
text = 'Cancel',
|
||||||
|
backgroundColor = colors.black,
|
||||||
|
backgroundFocusColor = colors.black,
|
||||||
|
textColor = colors.lightGray,
|
||||||
|
event = 'slide_hide',
|
||||||
|
},
|
||||||
|
eventHandler = function(self, event)
|
||||||
|
if event.type == 'grid_select' then
|
||||||
|
actions.process('insertText', x, y, event.selected.complete)
|
||||||
|
self:hide()
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
return UI.SlideOut.eventHandler(self, event)
|
||||||
|
end,
|
||||||
|
},
|
||||||
editor = UI.Window {
|
editor = UI.Window {
|
||||||
y = 2,
|
y = 2,
|
||||||
backgroundColor = colors.black,
|
backgroundColor = colors.black,
|
||||||
@@ -648,52 +626,24 @@ actions = {
|
|||||||
end,
|
end,
|
||||||
|
|
||||||
autocomplete = function()
|
autocomplete = function()
|
||||||
if lastAction ~= 'autocomplete' or not complete.results then
|
local sLine = tLines[y]:sub(1, x - 1):match("[a-zA-Z0-9_%.]+$")
|
||||||
local sLine = tLines[y]:sub(1, x - 1)
|
local results = sLine and textutils.complete(sLine, _ENV) or { }
|
||||||
local nStartPos = sLine:find("[a-zA-Z0-9_%.]+$")
|
|
||||||
if nStartPos then
|
|
||||||
sLine = sLine:sub(nStartPos)
|
|
||||||
end
|
|
||||||
if #sLine > 0 then
|
|
||||||
complete.results = textutils.complete(sLine)
|
|
||||||
else
|
|
||||||
complete.results = { }
|
|
||||||
end
|
|
||||||
complete.index = 0
|
|
||||||
complete.x = x
|
|
||||||
end
|
|
||||||
|
|
||||||
if #complete.results == 0 then
|
if #results == 0 then
|
||||||
setError('No completions available')
|
setError('No completions available')
|
||||||
|
|
||||||
elseif #complete.results == 1 then
|
elseif #results == 1 then
|
||||||
actions.insertText(x, y, complete.results[1])
|
actions.insertText(x, y, results[1])
|
||||||
complete.results = nil
|
|
||||||
|
|
||||||
elseif #complete.results > 1 then
|
elseif #results > 1 then
|
||||||
local prefix = complete.results[1]
|
local prefix = sLine:match('^.+%.(.*)$') or sLine
|
||||||
for n = 1, #complete.results do
|
for i = 1, #results do
|
||||||
local result = complete.results[n]
|
results[i] = {
|
||||||
while #prefix > 0 do
|
text = prefix .. results[i],
|
||||||
if result:find(prefix, 1, true) == 1 then
|
complete = results[i],
|
||||||
break
|
}
|
||||||
end
|
|
||||||
prefix = prefix:sub(1, #prefix - 1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if #prefix > 0 then
|
|
||||||
actions.insertText(x, y, prefix)
|
|
||||||
complete.results = nil
|
|
||||||
else
|
|
||||||
if complete.index > 0 then
|
|
||||||
actions.deleteText(complete.x, y, complete.x + #complete.results[complete.index], y)
|
|
||||||
end
|
|
||||||
complete.index = complete.index + 1
|
|
||||||
if complete.index > #complete.results then
|
|
||||||
complete.index = 1
|
|
||||||
end
|
|
||||||
actions.insertText(complete.x, y, complete.results[complete.index])
|
|
||||||
end
|
end
|
||||||
|
page.completions:show(results)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@@ -775,7 +725,6 @@ actions = {
|
|||||||
dirty = { y = 1, ey = h }
|
dirty = { y = 1, ey = h }
|
||||||
mark = { }
|
mark = { }
|
||||||
undo = { chain = { }, pointer = 0 }
|
undo = { chain = { }, pointer = 0 }
|
||||||
complete = { }
|
|
||||||
|
|
||||||
tLines = { }
|
tLines = { }
|
||||||
if fs.exists(fileInfo.abspath) then
|
if fs.exists(fileInfo.abspath) then
|
||||||
@@ -1323,7 +1272,7 @@ actions = {
|
|||||||
redraw()
|
redraw()
|
||||||
end,
|
end,
|
||||||
|
|
||||||
process = function(action, param, param2)
|
process = function(action, ...)
|
||||||
if not actions[action] then
|
if not actions[action] then
|
||||||
error('Invaid action: ' .. action)
|
error('Invaid action: ' .. action)
|
||||||
end
|
end
|
||||||
@@ -1331,8 +1280,7 @@ actions = {
|
|||||||
local wasMarking = mark.continue
|
local wasMarking = mark.continue
|
||||||
mark.continue = false
|
mark.continue = false
|
||||||
|
|
||||||
actions[action](param, param2)
|
actions[action](...)
|
||||||
lastAction = action
|
|
||||||
|
|
||||||
if x ~= lastPos.x or y ~= lastPos.y then
|
if x ~= lastPos.x or y ~= lastPos.y then
|
||||||
actions.setCursor()
|
actions.setCursor()
|
||||||
|
|||||||
Reference in New Issue
Block a user