mirror of
https://github.com/kepler155c/opus
synced 2025-01-03 20:30:28 +00:00
autorun overhaul + shell input readline commands + launcher option + shell colors
This commit is contained in:
parent
8fede6f507
commit
b71ca0d545
@ -30,6 +30,19 @@ local function nextWord(line, cx)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function prevWord(line, cx)
|
||||||
|
local nOffset = 1
|
||||||
|
while nOffset <= #line do
|
||||||
|
local nNext = line:find("%W%w", nOffset)
|
||||||
|
if nNext and nNext < cx then
|
||||||
|
nOffset = nNext + 1
|
||||||
|
else
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nOffset - 1 < cx and nOffset - 1
|
||||||
|
end
|
||||||
|
|
||||||
function Entry:updateScroll()
|
function Entry:updateScroll()
|
||||||
if self.pos - self.scroll > self.width then
|
if self.pos - self.scroll > self.width then
|
||||||
self.scroll = self.pos - (self.width)
|
self.scroll = self.pos - (self.width)
|
||||||
@ -38,109 +51,198 @@ function Entry:updateScroll()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function moveLeft(entry)
|
||||||
|
if entry.pos > 0 then
|
||||||
|
entry.pos = math.max(entry.pos - 1, 0)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function moveRight(entry)
|
||||||
|
local input = tostring(entry.value)
|
||||||
|
if entry.pos < #input then
|
||||||
|
entry.pos = math.min(entry.pos + 1, #input)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function moveStart(entry)
|
||||||
|
if entry.pos ~= 0 then
|
||||||
|
entry.pos = 0
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function moveEnd(entry)
|
||||||
|
if entry.pos ~= #tostring(entry.value) then
|
||||||
|
entry.pos = #tostring(entry.value)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function backspace(entry)
|
||||||
|
if entry.pos > 0 then
|
||||||
|
local input = tostring(entry.value)
|
||||||
|
entry.value = input:sub(1, entry.pos - 1) .. input:sub(entry.pos + 1)
|
||||||
|
entry.pos = entry.pos - 1
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function moveWordRight(entry)
|
||||||
|
local nx = nextWord(entry.value, entry.pos + 1)
|
||||||
|
if nx then
|
||||||
|
entry.pos = math.min(nx - 1, #entry.value)
|
||||||
|
elseif entry.pos < #entry.value then
|
||||||
|
entry.pos = #entry.value
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local function moveWordLeft(entry)
|
||||||
|
if entry.pos ~= 0 then
|
||||||
|
local lx = 1
|
||||||
|
while true do
|
||||||
|
local nx = nextWord(entry.value, lx)
|
||||||
|
if not nx or nx >= entry.pos then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
lx = nx
|
||||||
|
end
|
||||||
|
if not lx then
|
||||||
|
entry.pos = 0
|
||||||
|
else
|
||||||
|
entry.pos = lx - 1
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function delete(entry)
|
||||||
|
local input = tostring(entry.value)
|
||||||
|
if entry.pos < #input then
|
||||||
|
entry.value = input:sub(1, entry.pos) .. input:sub(entry.pos + 2)
|
||||||
|
entry.update = true
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- credit for cut functions to: https://github.com/SquidDev-CC/mbs/blob/master/lib/readline.lua
|
||||||
|
local function cutFromStart(entry)
|
||||||
|
if entry.pos > 0 then
|
||||||
|
local input = tostring(entry.value)
|
||||||
|
os.queueEvent('clipboard_copy', input:sub(1, entry.pos))
|
||||||
|
entry.value = input:sub(entry.pos + 1)
|
||||||
|
entry.pos = 0
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function cutToEnd(entry)
|
||||||
|
local input = tostring(entry.value)
|
||||||
|
if entry.pos < #input then
|
||||||
|
os.queueEvent('clipboard_copy', input:sub(entry.pos + 1))
|
||||||
|
entry.value = input:sub(1, entry.pos)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function cutNextWord(entry)
|
||||||
|
local input = tostring(entry.value)
|
||||||
|
if entry.pos < #input then
|
||||||
|
local ex = nextWord(entry.value, entry.pos)
|
||||||
|
if ex then
|
||||||
|
os.queueEvent('clipboard_copy', input:sub(entry.pos + 1, ex))
|
||||||
|
entry.value = input:sub(1, entry.pos) .. input:sub(ex + 1)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function cutPrevWord(entry)
|
||||||
|
if entry.pos > 0 then
|
||||||
|
local sx = prevWord(entry.value, entry.pos)
|
||||||
|
if sx then
|
||||||
|
local input = tostring(entry.value)
|
||||||
|
os.queueEvent('clipboard_copy', input:sub(sx + 1, entry.pos))
|
||||||
|
entry.value = input:sub(1, sx) .. input:sub(entry.pos + 1)
|
||||||
|
entry.pos = sx
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function insertChar(entry, ie)
|
||||||
|
local input = tostring(entry.value)
|
||||||
|
if #input < entry.limit then
|
||||||
|
entry.value = input:sub(1, entry.pos) .. ie.ch .. input:sub(entry.pos + 1)
|
||||||
|
entry.pos = entry.pos + 1
|
||||||
|
entry.update = true
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function copy(entry)
|
||||||
|
os.queueEvent('clipboard_copy', entry.value)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function paste(entry, ie)
|
||||||
|
local input = tostring(entry.value)
|
||||||
|
if #input + #ie.text > entry.limit then
|
||||||
|
ie.text = ie.text:sub(1, entry.limit-#input)
|
||||||
|
end
|
||||||
|
entry.value = input:sub(1, entry.pos) .. ie.text .. input:sub(entry.pos + 1)
|
||||||
|
entry.pos = entry.pos + #ie.text
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local function moveCursor(entry, ie)
|
||||||
|
-- need starting x passed in instead of hardcoding 3
|
||||||
|
entry.pos = math.max(0, math.min(ie.x - 3 + entry.scroll, #entry.value))
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local function clearLine(entry)
|
||||||
|
local input = tostring(entry.value)
|
||||||
|
if #input > 0 then
|
||||||
|
entry:reset()
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local mappings = {
|
||||||
|
[ 'left' ] = moveLeft,
|
||||||
|
[ 'control-b' ] = moveLeft,
|
||||||
|
[ 'right' ] = moveRight,
|
||||||
|
[ 'control-f' ] = moveRight,
|
||||||
|
[ 'home' ] = moveStart,
|
||||||
|
[ 'control-a' ] = moveStart,
|
||||||
|
[ 'end' ] = moveEnd,
|
||||||
|
[ 'control-e' ] = moveEnd,
|
||||||
|
[ 'backspace' ] = backspace,
|
||||||
|
[ 'control-right' ] = moveWordRight,
|
||||||
|
[ 'alt-f' ] = moveWordRight,
|
||||||
|
[ 'control-left' ] = moveWordLeft,
|
||||||
|
[ 'alt-b' ] = moveWordLeft,
|
||||||
|
[ 'delete' ] = delete,
|
||||||
|
[ 'control-u' ] = cutFromStart,
|
||||||
|
[ 'control-k' ] = cutToEnd,
|
||||||
|
[ 'control-d' ] = cutNextWord,
|
||||||
|
[ 'control-w' ] = cutPrevWord,
|
||||||
|
[ 'char' ] = insertChar,
|
||||||
|
[ 'copy' ] = copy,
|
||||||
|
[ 'paste' ] = paste,
|
||||||
|
[ 'control-y' ] = paste,
|
||||||
|
[ 'mouse_click' ] = moveCursor,
|
||||||
|
[ 'mouse_rightclick' ] = clearLine,
|
||||||
|
}
|
||||||
|
|
||||||
function Entry:process(ie)
|
function Entry:process(ie)
|
||||||
local updated = false
|
local action = mappings[ie.code]
|
||||||
|
local updated
|
||||||
|
|
||||||
if ie.code == 'left' then
|
if action then
|
||||||
if self.pos > 0 then
|
updated = action(self, ie)
|
||||||
self.pos = math.max(self.pos - 1, 0)
|
|
||||||
updated = true
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif ie.code == 'right' then
|
|
||||||
local input = tostring(self.value)
|
|
||||||
if self.pos < #input then
|
|
||||||
self.pos = math.min(self.pos + 1, #input)
|
|
||||||
updated = true
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif ie.code == 'home' then
|
|
||||||
if self.pos ~= 0 then
|
|
||||||
self.pos = 0
|
|
||||||
updated = true
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif ie.code == 'end' then
|
|
||||||
if self.pos ~= #tostring(self.value) then
|
|
||||||
self.pos = #tostring(self.value)
|
|
||||||
updated = true
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif ie.code == 'backspace' then
|
|
||||||
if self.pos > 0 then
|
|
||||||
local input = tostring(self.value)
|
|
||||||
self.value = input:sub(1, self.pos - 1) .. input:sub(self.pos + 1)
|
|
||||||
self.pos = self.pos - 1
|
|
||||||
updated = true
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif ie.code == 'control-right' then
|
|
||||||
local nx = nextWord(self.value, self.pos + 1)
|
|
||||||
if nx then
|
|
||||||
self.pos = math.min(nx - 1, #self.value)
|
|
||||||
elseif self.pos < #self.value then
|
|
||||||
self.pos = #self.value
|
|
||||||
end
|
|
||||||
updated = true
|
|
||||||
|
|
||||||
elseif ie.code == 'control-left' then
|
|
||||||
if self.pos ~= 0 then
|
|
||||||
local lx = 1
|
|
||||||
while true do
|
|
||||||
local nx = nextWord(self.value, lx)
|
|
||||||
if not nx or nx >= self.pos then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
lx = nx
|
|
||||||
end
|
|
||||||
if not lx then
|
|
||||||
self.pos = 0
|
|
||||||
else
|
|
||||||
self.pos = lx - 1
|
|
||||||
end
|
|
||||||
updated = true
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif ie.code == 'delete' then
|
|
||||||
local input = tostring(self.value)
|
|
||||||
if self.pos < #input then
|
|
||||||
self.value = input:sub(1, self.pos) .. input:sub(self.pos + 2)
|
|
||||||
self.update = true
|
|
||||||
updated = true
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif ie.code == 'char' then
|
|
||||||
local input = tostring(self.value)
|
|
||||||
if #input < self.limit then
|
|
||||||
self.value = input:sub(1, self.pos) .. ie.ch .. input:sub(self.pos + 1)
|
|
||||||
self.pos = self.pos + 1
|
|
||||||
self.update = true
|
|
||||||
updated = true
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif ie.code == 'copy' then
|
|
||||||
os.queueEvent('clipboard_copy', self.value)
|
|
||||||
|
|
||||||
elseif ie.code == 'paste' then
|
|
||||||
local input = tostring(self.value)
|
|
||||||
if #input + #ie.text > self.limit then
|
|
||||||
ie.text = ie.text:sub(1, self.limit-#input)
|
|
||||||
end
|
|
||||||
self.value = input:sub(1, self.pos) .. ie.text .. input:sub(self.pos + 1)
|
|
||||||
self.pos = self.pos + #ie.text
|
|
||||||
updated = true
|
|
||||||
|
|
||||||
elseif ie.code == 'mouse_click' then
|
|
||||||
-- need starting x passed in instead of hardcoding 3
|
|
||||||
self.pos = math.max(0, math.min(ie.x - 3 + self.scroll, #self.value))
|
|
||||||
updated = true
|
|
||||||
|
|
||||||
elseif ie.code == 'mouse_rightclick' then
|
|
||||||
local input = tostring(self.value)
|
|
||||||
if #input > 0 then
|
|
||||||
self:reset()
|
|
||||||
updated = true
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
self:updateScroll()
|
self:updateScroll()
|
||||||
|
@ -6,6 +6,25 @@ local _gsub = string.gsub
|
|||||||
|
|
||||||
local Terminal = { }
|
local Terminal = { }
|
||||||
|
|
||||||
|
local mapColorToGray = {
|
||||||
|
[ colors.white ] = colors.white,
|
||||||
|
[ colors.orange ] = colors.lightGray,
|
||||||
|
[ colors.magenta ] = colors.lightGray,
|
||||||
|
[ colors.lightBlue ] = colors.lightGray,
|
||||||
|
[ colors.yellow ] = colors.lightGray,
|
||||||
|
[ colors.lime ] = colors.lightGray,
|
||||||
|
[ colors.pink ] = colors.lightGray,
|
||||||
|
[ colors.gray ] = colors.gray,
|
||||||
|
[ colors.lightGray ] = colors.lightGray,
|
||||||
|
[ colors.cyan ] = colors.lightGray,
|
||||||
|
[ colors.purple ] = colors.gray,
|
||||||
|
[ colors.blue ] = colors.gray,
|
||||||
|
[ colors.brown ] = colors.gray,
|
||||||
|
[ colors.green ] = colors.lightGray,
|
||||||
|
[ colors.red ] = colors.gray,
|
||||||
|
[ colors.black ] = colors.black,
|
||||||
|
}
|
||||||
|
|
||||||
-- Replacement for window api with scrolling and buffering
|
-- Replacement for window api with scrolling and buffering
|
||||||
function Terminal.window(parent, sx, sy, w, h, isVisible)
|
function Terminal.window(parent, sx, sy, w, h, isVisible)
|
||||||
isVisible = isVisible ~= false
|
isVisible = isVisible ~= false
|
||||||
@ -243,32 +262,17 @@ function Terminal.getContents(win, parent)
|
|||||||
return lines
|
return lines
|
||||||
end
|
end
|
||||||
|
|
||||||
function Terminal.toGrayscale(ct)
|
function Terminal.colorToGrayscale(c)
|
||||||
local scolors = {
|
return mapColorToGray[c]
|
||||||
[ colors.white ] = colors.white,
|
end
|
||||||
[ colors.orange ] = colors.lightGray,
|
|
||||||
[ colors.magenta ] = colors.lightGray,
|
|
||||||
[ colors.lightBlue ] = colors.lightGray,
|
|
||||||
[ colors.yellow ] = colors.lightGray,
|
|
||||||
[ colors.lime ] = colors.lightGray,
|
|
||||||
[ colors.pink ] = colors.lightGray,
|
|
||||||
[ colors.gray ] = colors.gray,
|
|
||||||
[ colors.lightGray ] = colors.lightGray,
|
|
||||||
[ colors.cyan ] = colors.lightGray,
|
|
||||||
[ colors.purple ] = colors.gray,
|
|
||||||
[ colors.blue ] = colors.gray,
|
|
||||||
[ colors.brown ] = colors.gray,
|
|
||||||
[ colors.green ] = colors.lightGray,
|
|
||||||
[ colors.red ] = colors.gray,
|
|
||||||
[ colors.black ] = colors.black,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
function Terminal.toGrayscale(ct)
|
||||||
local methods = { 'setBackgroundColor', 'setBackgroundColour',
|
local methods = { 'setBackgroundColor', 'setBackgroundColour',
|
||||||
'setTextColor', 'setTextColour' }
|
'setTextColor', 'setTextColour' }
|
||||||
for _,v in pairs(methods) do
|
for _,v in pairs(methods) do
|
||||||
local fn = ct[v]
|
local fn = ct[v]
|
||||||
ct[v] = function(c)
|
ct[v] = function(c)
|
||||||
fn(scolors[c])
|
fn(mapColorToGray[c])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
_G.requireInjector(_ENV)
|
|
||||||
|
|
||||||
local class = require('class')
|
local class = require('class')
|
||||||
local Config = require('config')
|
local Config = require('config')
|
||||||
local Event = require('event')
|
local Event = require('event')
|
||||||
|
@ -362,6 +362,7 @@ local Config = require('config')
|
|||||||
local Entry = require('entry')
|
local Entry = require('entry')
|
||||||
local History = require('history')
|
local History = require('history')
|
||||||
local Input = require('input')
|
local Input = require('input')
|
||||||
|
local Terminal = require('terminal')
|
||||||
|
|
||||||
local colors = _G.colors
|
local colors = _G.colors
|
||||||
local os = _G.os
|
local os = _G.os
|
||||||
@ -372,22 +373,12 @@ local oldTerm
|
|||||||
local terminal = term.current()
|
local terminal = term.current()
|
||||||
|
|
||||||
if not terminal.scrollUp then
|
if not terminal.scrollUp then
|
||||||
local Terminal = require('terminal')
|
|
||||||
terminal = Terminal.window(term.current())
|
terminal = Terminal.window(term.current())
|
||||||
terminal.setMaxScroll(200)
|
terminal.setMaxScroll(200)
|
||||||
oldTerm = term.redirect(terminal)
|
oldTerm = term.redirect(terminal)
|
||||||
end
|
end
|
||||||
|
|
||||||
local config = {
|
local config = {
|
||||||
standard = {
|
|
||||||
textColor = colors.white,
|
|
||||||
commandTextColor = colors.lightGray,
|
|
||||||
directoryTextColor = colors.gray,
|
|
||||||
directoryBackgroundColor = colors.black,
|
|
||||||
promptTextColor = colors.gray,
|
|
||||||
promptBackgroundColor = colors.black,
|
|
||||||
directoryColor = colors.gray,
|
|
||||||
},
|
|
||||||
color = {
|
color = {
|
||||||
textColor = colors.white,
|
textColor = colors.white,
|
||||||
commandTextColor = colors.yellow,
|
commandTextColor = colors.yellow,
|
||||||
@ -396,15 +387,20 @@ local config = {
|
|||||||
promptTextColor = colors.blue,
|
promptTextColor = colors.blue,
|
||||||
promptBackgroundColor = colors.black,
|
promptBackgroundColor = colors.black,
|
||||||
directoryColor = colors.green,
|
directoryColor = colors.green,
|
||||||
|
fileColor = colors.white,
|
||||||
|
backgroundColor = colors.black,
|
||||||
},
|
},
|
||||||
displayDirectory = true,
|
displayDirectory = true,
|
||||||
}
|
}
|
||||||
|
|
||||||
Config.load('shellprompt', config)
|
Config.load('shellprompt', config)
|
||||||
|
|
||||||
local _colors = config.standard
|
local _colors = config.color
|
||||||
if term.isColor() then
|
if not term.isColor() then
|
||||||
_colors = config.color
|
_colors = { }
|
||||||
|
for k, v in pairs(config.color) do
|
||||||
|
_colors[k] = Terminal.colorToGrayscale(v)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function autocompleteArgument(program, words)
|
local function autocompleteArgument(program, words)
|
||||||
@ -536,9 +532,9 @@ local function autocomplete(line)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if #tDirs > 0 then
|
if #tDirs > 0 then
|
||||||
textutils.tabulate(_colors.directoryColor, tDirs, colors.white, tFiles)
|
textutils.tabulate(_colors.directoryColor, tDirs, _colors.fileColor, tFiles)
|
||||||
else
|
else
|
||||||
textutils.tabulate(colors.white, tFiles)
|
textutils.tabulate(_colors.fileColor, tFiles)
|
||||||
end
|
end
|
||||||
|
|
||||||
term.setTextColour(_colors.promptTextColor)
|
term.setTextColour(_colors.promptTextColor)
|
||||||
@ -546,7 +542,7 @@ local function autocomplete(line)
|
|||||||
term.write("$ " )
|
term.write("$ " )
|
||||||
|
|
||||||
term.setTextColour(_colors.commandTextColor)
|
term.setTextColour(_colors.commandTextColor)
|
||||||
term.setBackgroundColor(colors.black)
|
term.setBackgroundColor(_colors.backgroundColor)
|
||||||
return line
|
return line
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -593,8 +589,9 @@ local function shellRead(history)
|
|||||||
elseif ie.code == 'enter' then
|
elseif ie.code == 'enter' then
|
||||||
break
|
break
|
||||||
|
|
||||||
elseif ie.code == 'up' or ie.code == 'down' then
|
elseif ie.code == 'up' or ie.code == 'control-p' or
|
||||||
if ie.code == 'up' then
|
ie.code == 'down' or ie.code == 'control-n' then
|
||||||
|
if ie.code == 'up' or ie.code == 'control-p' then
|
||||||
entry.value = history:back() or ''
|
entry.value = history:back() or ''
|
||||||
else
|
else
|
||||||
entry.value = history:forward() or ''
|
entry.value = history:forward() or ''
|
||||||
@ -634,6 +631,9 @@ end
|
|||||||
|
|
||||||
local history = History.load('usr/.shell_history', 25)
|
local history = History.load('usr/.shell_history', 25)
|
||||||
|
|
||||||
|
term.setBackgroundColor(_colors.backgroundColor)
|
||||||
|
term.clear()
|
||||||
|
|
||||||
while not bExit do
|
while not bExit do
|
||||||
if config.displayDirectory then
|
if config.displayDirectory then
|
||||||
term.setTextColour(_colors.directoryTextColor)
|
term.setTextColour(_colors.directoryTextColor)
|
||||||
@ -644,7 +644,7 @@ while not bExit do
|
|||||||
term.setBackgroundColor(_colors.promptBackgroundColor)
|
term.setBackgroundColor(_colors.promptBackgroundColor)
|
||||||
term.write("$ " )
|
term.write("$ " )
|
||||||
term.setTextColour(_colors.commandTextColor)
|
term.setTextColour(_colors.commandTextColor)
|
||||||
term.setBackgroundColor(colors.black)
|
term.setBackgroundColor(_colors.backgroundColor)
|
||||||
local sLine = shellRead(history)
|
local sLine = shellRead(history)
|
||||||
if bExit then -- terminated
|
if bExit then -- terminated
|
||||||
break
|
break
|
||||||
|
@ -27,16 +27,16 @@ if _G.http.websocket then
|
|||||||
event = 'update_key',
|
event = 'update_key',
|
||||||
},
|
},
|
||||||
labelText = UI.TextArea {
|
labelText = UI.TextArea {
|
||||||
x = 2, ex = -2, y = 6,
|
x = 3, ex = -3, y = 6,
|
||||||
textColor = colors.yellow,
|
textColor = colors.yellow,
|
||||||
marginRight = 0,
|
marginLeft = 0, marginRight = 0,
|
||||||
value = string.format(
|
value = string.format(
|
||||||
[[Use a non-changing cloud key. Note that only a single computer can use this session at one time.
|
[[Use a non-changing cloud key. Note that only a single computer can use this session at one time.
|
||||||
To obtain a key, visit:
|
To obtain a key, visit:
|
||||||
%shttps://cloud-catcher.squiddev.cc%s then bookmark:
|
%shttps://cloud-catcher.squiddev.cc%s then bookmark:
|
||||||
%shttps://cloud-catcher.squiddev.cc/?id=%sKEY
|
%shttps://cloud-catcher.squiddev.cc/?id=KEY
|
||||||
]],
|
]],
|
||||||
Ansi.white, Ansi.reset, Ansi.white, Ansi.white),
|
Ansi.white, Ansi.reset, Ansi.white),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
136
sys/apps/system/colors.lua
Normal file
136
sys/apps/system/colors.lua
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
local Config = require('config')
|
||||||
|
local UI = require('ui')
|
||||||
|
local Util = require('util')
|
||||||
|
|
||||||
|
local colors = _G.colors
|
||||||
|
local os = _G.os
|
||||||
|
|
||||||
|
local config = Config.load('shellprompt')
|
||||||
|
|
||||||
|
local allColors = { }
|
||||||
|
for k,v in pairs(colors) do
|
||||||
|
if type(v) == 'number' then
|
||||||
|
table.insert(allColors, { name = k, value = v })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local defaults = {
|
||||||
|
textColor = colors.white,
|
||||||
|
commandTextColor = colors.yellow,
|
||||||
|
directoryTextColor = colors.orange,
|
||||||
|
directoryBackgroundColor = colors.black,
|
||||||
|
promptTextColor = colors.blue,
|
||||||
|
promptBackgroundColor = colors.black,
|
||||||
|
directoryColor = colors.green,
|
||||||
|
fileColor = colors.white,
|
||||||
|
backgroundColor = colors.black,
|
||||||
|
}
|
||||||
|
local _colors = config.color or Util.shallowCopy(defaults)
|
||||||
|
|
||||||
|
local allSettings = { }
|
||||||
|
for k, v in pairs(defaults) do
|
||||||
|
table.insert(allSettings, { name = k })
|
||||||
|
end
|
||||||
|
|
||||||
|
local tab = UI.Tab {
|
||||||
|
tabTitle = 'Shell',
|
||||||
|
description = 'Shell option',
|
||||||
|
grid1 = UI.ScrollingGrid {
|
||||||
|
y = 2, ey = -10, x = 3, ex = -16,
|
||||||
|
disableHeader = true,
|
||||||
|
columns = { { key = 'name' } },
|
||||||
|
values = allSettings,
|
||||||
|
sortColumn = 'name',
|
||||||
|
},
|
||||||
|
grid2 = UI.ScrollingGrid {
|
||||||
|
y = 2, ey = -10, x = -14, ex = -3,
|
||||||
|
disableHeader = true,
|
||||||
|
columns = { { key = 'name' } },
|
||||||
|
values = allColors,
|
||||||
|
sortColumn = 'name',
|
||||||
|
},
|
||||||
|
directoryLabel = UI.Text {
|
||||||
|
x = 2, y = -2,
|
||||||
|
value = 'Display directory',
|
||||||
|
},
|
||||||
|
directory = UI.Checkbox {
|
||||||
|
x = 20, y = -2,
|
||||||
|
value = config.displayDirectory
|
||||||
|
},
|
||||||
|
reset = UI.Button {
|
||||||
|
x = -18, y = -2,
|
||||||
|
text = 'Reset',
|
||||||
|
event = 'reset',
|
||||||
|
},
|
||||||
|
button = UI.Button {
|
||||||
|
x = -9, y = -2,
|
||||||
|
text = 'Update',
|
||||||
|
event = 'update',
|
||||||
|
},
|
||||||
|
display = UI.Window {
|
||||||
|
x = 3, ex = -3, y = -8, height = 5,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
function tab.grid2:getRowTextColor(row)
|
||||||
|
local selected = tab.grid1:getSelected()
|
||||||
|
if _colors[selected.name] == row.value then
|
||||||
|
return colors.yellow
|
||||||
|
end
|
||||||
|
return UI.Grid.getRowTextColor(self, row)
|
||||||
|
end
|
||||||
|
|
||||||
|
function tab.display:draw()
|
||||||
|
self:clear(_colors.backgroundColor)
|
||||||
|
local offset = 0
|
||||||
|
if config.displayDirectory then
|
||||||
|
self:write(1, 1,
|
||||||
|
'==' .. os.getComputerLabel() .. ':/dir/etc',
|
||||||
|
_colors.directoryBackgroundColor, _colors.directoryTextColor)
|
||||||
|
offset = 1
|
||||||
|
end
|
||||||
|
|
||||||
|
self:write(1, 1 + offset, '$ ',
|
||||||
|
_colors.promptBackgroundColor, _colors.promptTextColor)
|
||||||
|
|
||||||
|
self:write(3, 1 + offset, 'ls /',
|
||||||
|
_colors.backgroundColor, _colors.commandTextColor)
|
||||||
|
|
||||||
|
self:write(1, 2 + offset, 'sys usr',
|
||||||
|
_colors.backgroundColor, _colors.directoryColor)
|
||||||
|
|
||||||
|
self:write(1, 3 + offset, 'startup',
|
||||||
|
_colors.backgroundColor, _colors.fileColor)
|
||||||
|
end
|
||||||
|
|
||||||
|
function tab:eventHandler(event)
|
||||||
|
if event.type =='checkbox_change' then
|
||||||
|
config.displayDirectory = not not event.checked
|
||||||
|
self.display:draw()
|
||||||
|
|
||||||
|
elseif event.type == 'grid_focus_row' and event.element == self.grid1 then
|
||||||
|
self.grid2:draw()
|
||||||
|
|
||||||
|
elseif event.type == 'grid_select' and event.element == self.grid2 then
|
||||||
|
_colors[tab.grid1:getSelected().name] = event.selected.value
|
||||||
|
self.display:draw()
|
||||||
|
self.grid2:draw()
|
||||||
|
|
||||||
|
elseif event.type == 'reset' then
|
||||||
|
config.color = defaults
|
||||||
|
config.displayDirectory = true
|
||||||
|
self.directory.value = true
|
||||||
|
_colors = Util.shallowCopy(defaults)
|
||||||
|
|
||||||
|
Config.update('shellprompt', config)
|
||||||
|
self:draw()
|
||||||
|
|
||||||
|
elseif event.type == 'update' then
|
||||||
|
config.color = _colors
|
||||||
|
Config.update('shellprompt', config)
|
||||||
|
|
||||||
|
end
|
||||||
|
return UI.Tab.eventHandler(self, event)
|
||||||
|
end
|
||||||
|
|
||||||
|
return tab
|
81
sys/apps/system/launcher.lua
Normal file
81
sys/apps/system/launcher.lua
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
local Config = require('config')
|
||||||
|
local UI = require('ui')
|
||||||
|
|
||||||
|
local colors = _G.colors
|
||||||
|
local fs = _G.fs
|
||||||
|
|
||||||
|
local config = Config.load('multishell')
|
||||||
|
|
||||||
|
local tab = UI.Tab {
|
||||||
|
tabTitle = 'Launcher',
|
||||||
|
description = 'Set the application launcher',
|
||||||
|
launcherLabel = UI.Text {
|
||||||
|
x = 3, y = 2,
|
||||||
|
value = 'Launcher',
|
||||||
|
},
|
||||||
|
launcher = UI.Chooser {
|
||||||
|
x = 13, y = 2, width = 12,
|
||||||
|
choices = {
|
||||||
|
{ name = 'Overview', value = 'sys/apps/Overview.lua' },
|
||||||
|
{ name = 'Shell', value = 'sys/apps/shell.lua' },
|
||||||
|
{ name = 'Custom', value = 'custom' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
custom = UI.TextEntry {
|
||||||
|
x = 13, ex = -3, y = 3,
|
||||||
|
limit = 128,
|
||||||
|
shadowText = 'File name',
|
||||||
|
},
|
||||||
|
button = UI.Button {
|
||||||
|
x = 3, y = 5,
|
||||||
|
text = 'Update',
|
||||||
|
event = 'update',
|
||||||
|
},
|
||||||
|
labelText = UI.TextArea {
|
||||||
|
x = 3, ex = -3, y = 7,
|
||||||
|
textColor = colors.yellow,
|
||||||
|
value = 'Choose an application launcher',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
function tab:enable()
|
||||||
|
local launcher = config.launcher and 'custom' or 'sys/apps/Overview.lua'
|
||||||
|
|
||||||
|
for _, v in pairs(self.launcher.choices) do
|
||||||
|
if v.value == config.launcher then
|
||||||
|
launcher = v.value
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
UI.Tab.enable(self)
|
||||||
|
|
||||||
|
self.launcher.value = launcher
|
||||||
|
self.custom.enabled = launcher == 'custom'
|
||||||
|
end
|
||||||
|
|
||||||
|
function tab:eventHandler(event)
|
||||||
|
if event.type == 'choice_change' then
|
||||||
|
self.custom.enabled = event.value == 'custom'
|
||||||
|
self:draw()
|
||||||
|
|
||||||
|
elseif event.type == 'update' then
|
||||||
|
local launcher
|
||||||
|
|
||||||
|
if self.launcher.value ~= 'custom' then
|
||||||
|
launcher = self.launcher.value
|
||||||
|
elseif fs.exists(self.custom.value) and not fs.isDir(self.custom.value) then
|
||||||
|
launcher = self.custom.value
|
||||||
|
end
|
||||||
|
|
||||||
|
if launcher then
|
||||||
|
config.launcher = launcher
|
||||||
|
Config.update('multishell', config)
|
||||||
|
self:emit({ type = 'success_message', message = 'Updated' })
|
||||||
|
else
|
||||||
|
self:emit({ type = 'error_message', message = 'Invalid file' })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return tab
|
@ -20,7 +20,7 @@ local tab = UI.Tab {
|
|||||||
disableHeader = true,
|
disableHeader = true,
|
||||||
columns = { { key = 'value' } },
|
columns = { { key = 'value' } },
|
||||||
autospace = true,
|
autospace = true,
|
||||||
sort = 'index',
|
sortColumn = 'index',
|
||||||
help = 'double-click to remove, shift-arrow to move',
|
help = 'double-click to remove, shift-arrow to move',
|
||||||
accelerators = {
|
accelerators = {
|
||||||
delete = 'remove',
|
delete = 'remove',
|
||||||
|
@ -20,7 +20,7 @@ local tab = UI.Tab {
|
|||||||
disableHeader = true,
|
disableHeader = true,
|
||||||
columns = { { key = 'value' } },
|
columns = { { key = 'value' } },
|
||||||
autospace = true,
|
autospace = true,
|
||||||
sort = 'index',
|
sortColumn = 'index',
|
||||||
help = 'double-click to remove, shift-arrow to move',
|
help = 'double-click to remove, shift-arrow to move',
|
||||||
accelerators = {
|
accelerators = {
|
||||||
delete = 'remove',
|
delete = 'remove',
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
iconExt = "\031f\128\0313\152\131\131\132\031f\128\
|
iconExt = "\031f\128\0313\152\131\131\132\031f\128\
|
||||||
\0313\139\159\129\0303\031f\159\129\139\
|
\0313\139\159\129\0303\031f\159\129\139\
|
||||||
\031f\128\0313\136\0303\031f\143\143\030f\0313\134\031f\128",
|
\031f\128\0313\136\0303\031f\143\143\030f\0313\134\031f\128",
|
||||||
run = "update",
|
run = "update update",
|
||||||
},
|
},
|
||||||
c47ae15370cfe1ed2781eedc1dc2547d12d9e972 = {
|
c47ae15370cfe1ed2781eedc1dc2547d12d9e972 = {
|
||||||
title = "Help",
|
title = "Help",
|
||||||
|
@ -75,7 +75,7 @@ end)
|
|||||||
local modifiers = Util.transpose {
|
local modifiers = Util.transpose {
|
||||||
keys.leftCtrl, keys.rightCtrl,
|
keys.leftCtrl, keys.rightCtrl,
|
||||||
keys.leftShift, keys.rightShift,
|
keys.leftShift, keys.rightShift,
|
||||||
--keys.leftAlt, keys.rightAlt,
|
keys.leftAlt, keys.rightAlt,
|
||||||
}
|
}
|
||||||
|
|
||||||
kernel.hook({ 'key', 'key_up', 'char', 'paste' }, function(event, eventData)
|
kernel.hook({ 'key', 'key_up', 'char', 'paste' }, function(event, eventData)
|
||||||
|
@ -44,6 +44,6 @@ end
|
|||||||
shell.setPath(table.concat(path, ':'))
|
shell.setPath(table.concat(path, ':'))
|
||||||
|
|
||||||
_G.LUA_PATH = config.lua_path
|
_G.LUA_PATH = config.lua_path
|
||||||
_G.settings.set('require.path', config.lua_path)
|
_G.settings.set('mbs.shell.require_path', config.lua_path)
|
||||||
|
|
||||||
fs.loadTab('usr/config/fstab')
|
fs.loadTab('usr/config/fstab')
|
||||||
|
@ -332,11 +332,15 @@ kernel.hook('mouse_scroll', function(_, eventData)
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
kernel.hook('kernel_ready', function()
|
kernel.hook('kernel_ready', function()
|
||||||
|
local env = Util.shallowCopy(shell.getEnv())
|
||||||
|
_G.requireInjector(env)
|
||||||
|
|
||||||
overviewId = multishell.openTab({
|
overviewId = multishell.openTab({
|
||||||
path = 'sys/apps/Overview.lua',
|
path = config.launcher or 'sys/apps/Overview.lua',
|
||||||
isOverview = true,
|
isOverview = true,
|
||||||
focused = true,
|
focused = true,
|
||||||
title = '+',
|
title = '+',
|
||||||
|
env = env,
|
||||||
})
|
})
|
||||||
|
|
||||||
multishell.openTab({
|
multishell.openTab({
|
||||||
|
Loading…
Reference in New Issue
Block a user