redo input translation + shift-paste
This commit is contained in:
205
apps/edit.lua
205
apps/edit.lua
@@ -5,6 +5,7 @@ local multishell = _ENV.multishell
|
|||||||
local os = _G.os
|
local os = _G.os
|
||||||
local shell = _ENV.shell
|
local shell = _ENV.shell
|
||||||
local term = _G.term
|
local term = _G.term
|
||||||
|
local textutils = _G.textutils
|
||||||
|
|
||||||
shell.setCompletionFunction(shell.getRunningProgram(), function(_, index, text)
|
shell.setCompletionFunction(shell.getRunningProgram(), function(_, index, text)
|
||||||
if index == 1 then
|
if index == 1 then
|
||||||
@@ -38,10 +39,11 @@ local bRunning = true
|
|||||||
local sStatus = ""
|
local sStatus = ""
|
||||||
local isError
|
local isError
|
||||||
local fileInfo
|
local fileInfo
|
||||||
|
local lastAction
|
||||||
|
|
||||||
local dirty = { y = 1, ey = h }
|
local dirty = { y = 1, ey = h }
|
||||||
local mark = { }
|
local mark = { }
|
||||||
local keyboard
|
--local input
|
||||||
local searchPattern
|
local searchPattern
|
||||||
local undo = { chain = { }, pointer = 0 }
|
local undo = { chain = { }, pointer = 0 }
|
||||||
local complete = { }
|
local complete = { }
|
||||||
@@ -56,9 +58,6 @@ if not multishell or not multishell.hook then -- is this OpusOS ?
|
|||||||
|
|
||||||
function clipboard.setData(data)
|
function clipboard.setData(data)
|
||||||
clipboard.data = data
|
clipboard.data = data
|
||||||
if data then
|
|
||||||
clipboard.useInternal(true)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function clipboard.getText()
|
function clipboard.getText()
|
||||||
@@ -67,16 +66,6 @@ if not multishell or not multishell.hook then -- is this OpusOS ?
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function clipboard.isInternal()
|
|
||||||
return clipboard.internal
|
|
||||||
end
|
|
||||||
|
|
||||||
function clipboard.useInternal(mode)
|
|
||||||
if mode ~= clipboard.mode then
|
|
||||||
clipboard.internal = mode
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
_G.clipboard = clipboard
|
_G.clipboard = clipboard
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -154,8 +143,7 @@ local keyMapping = {
|
|||||||
-- copy/paste
|
-- copy/paste
|
||||||
[ 'control-x' ] = 'cut',
|
[ 'control-x' ] = 'cut',
|
||||||
[ 'control-c' ] = 'copy',
|
[ 'control-c' ] = 'copy',
|
||||||
[ 'control-v' ] = 'paste',
|
[ 'shift-paste' ] = 'paste_internal',
|
||||||
[ 'control-m' ] = 'toggle_clipboard',
|
|
||||||
|
|
||||||
-- file
|
-- file
|
||||||
[ 'control-s' ] = 'save',
|
[ 'control-s' ] = 'save',
|
||||||
@@ -403,21 +391,13 @@ local function redraw()
|
|||||||
end
|
end
|
||||||
|
|
||||||
if not (w < 32 and #sStatus > 0) then
|
if not (w < 32 and #sStatus > 0) then
|
||||||
local clipboardIndicator = ''
|
|
||||||
if clipboard then
|
|
||||||
clipboardIndicator = 'S'
|
|
||||||
if clipboard.isInternal() then
|
|
||||||
clipboardIndicator = 'I'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local modifiedIndicator = ' '
|
local modifiedIndicator = ' '
|
||||||
if undo.chain[1] then
|
if undo.chain[1] then
|
||||||
modifiedIndicator = '*'
|
modifiedIndicator = '*'
|
||||||
end
|
end
|
||||||
|
|
||||||
local str = string.format(' %d:%d %s%s',
|
local str = string.format(' %d:%d %s',
|
||||||
y, x, clipboardIndicator, modifiedIndicator)
|
y, x, modifiedIndicator)
|
||||||
term.setTextColor(color.highlightColor)
|
term.setTextColor(color.highlightColor)
|
||||||
term.setBackgroundColor(colors.gray)
|
term.setBackgroundColor(colors.gray)
|
||||||
term.setCursorPos(w - #str + 1, h)
|
term.setCursorPos(w - #str + 1, h)
|
||||||
@@ -460,7 +440,7 @@ local function hacky_read()
|
|||||||
return cx, 1
|
return cx, 1
|
||||||
end
|
end
|
||||||
|
|
||||||
local s, m = pcall(function() return read() end)
|
local s, m = pcall(function() return _G.read() end)
|
||||||
term.setCursorPos = _oldSetCursorPos
|
term.setCursorPos = _oldSetCursorPos
|
||||||
term.getCursorPos = _oldGetCursorPos
|
term.getCursorPos = _oldGetCursorPos
|
||||||
if s then
|
if s then
|
||||||
@@ -483,7 +463,7 @@ local __actions = {
|
|||||||
term.write(prompt)
|
term.write(prompt)
|
||||||
local str = hacky_read()
|
local str = hacky_read()
|
||||||
term.setCursorBlink(true)
|
term.setCursorBlink(true)
|
||||||
keyboard.shift, keyboard.control = false, false
|
--keyboard.shift, keyboard.control = false, false
|
||||||
term.setCursorPos(x - scrollX, y - scrollY)
|
term.setCursorPos(x - scrollX, y - scrollY)
|
||||||
actions.dirty_line(scrollY + h)
|
actions.dirty_line(scrollY + h)
|
||||||
return str
|
return str
|
||||||
@@ -523,7 +503,7 @@ local __actions = {
|
|||||||
end,
|
end,
|
||||||
|
|
||||||
autocomplete = function()
|
autocomplete = function()
|
||||||
if keyboard.lastAction ~= 'autocomplete' or not complete.results then
|
if lastAction ~= 'autocomplete' or not complete.results then
|
||||||
local sLine = tLines[y]:sub(1, x - 1)
|
local sLine = tLines[y]:sub(1, x - 1)
|
||||||
local nStartPos = sLine:find("[a-zA-Z0-9_%.]+$")
|
local nStartPos = sLine:find("[a-zA-Z0-9_%.]+$")
|
||||||
if nStartPos then
|
if nStartPos then
|
||||||
@@ -1046,27 +1026,14 @@ local __actions = {
|
|||||||
actions.insertText(x, y, ch)
|
actions.insertText(x, y, ch)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
toggle_clipboard = function()
|
|
||||||
if clipboard then
|
|
||||||
clipboard.setInternal(not clipboard.internal)
|
|
||||||
if clipboard.isInternal() then
|
|
||||||
setStatus('Using internal clipboard')
|
|
||||||
else
|
|
||||||
setStatus('Using system clipboard')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
mark.continue = mark.active
|
|
||||||
end,
|
|
||||||
|
|
||||||
copy_marked = function()
|
copy_marked = function()
|
||||||
local text, size = actions.copyText(mark.x, mark.y, mark.ex, mark.ey)
|
local text = actions.copyText(mark.x, mark.y, mark.ex, mark.ey)
|
||||||
if clipboard then
|
if clipboard then
|
||||||
clipboard.setData(text)
|
clipboard.setData(text)
|
||||||
clipboard.useInternal(true)
|
|
||||||
else
|
else
|
||||||
os.queueEvent('clipboard_copy', text)
|
os.queueEvent('clipboard_copy', text)
|
||||||
end
|
end
|
||||||
setStatus('%d chars copied', size)
|
setStatus('shift-^v to paste')
|
||||||
end,
|
end,
|
||||||
|
|
||||||
cut = function()
|
cut = function()
|
||||||
@@ -1087,9 +1054,6 @@ local __actions = {
|
|||||||
if mark.active then
|
if mark.active then
|
||||||
actions.delete()
|
actions.delete()
|
||||||
end
|
end
|
||||||
if clipboard and clipboard.isInternal() then
|
|
||||||
text = clipboard.getText()
|
|
||||||
end
|
|
||||||
if text then
|
if text then
|
||||||
actions.insertText(x, y, text)
|
actions.insertText(x, y, text)
|
||||||
setStatus('%d chars added', #text)
|
setStatus('%d chars added', #text)
|
||||||
@@ -1098,6 +1062,12 @@ local __actions = {
|
|||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
paste_internal = function()
|
||||||
|
if clipboard then
|
||||||
|
actions.paste(clipboard.getText())
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
go_to = function(cx, cy)
|
go_to = function(cx, cy)
|
||||||
y = math.min(math.max(cy, 1), #tLines)
|
y = math.min(math.max(cy, 1), #tLines)
|
||||||
x = math.min(math.max(cx, 1), #tLines[y] + 1)
|
x = math.min(math.max(cx, 1), #tLines[y] + 1)
|
||||||
@@ -1129,100 +1099,99 @@ load(sPath)
|
|||||||
term.setCursorBlink(true)
|
term.setCursorBlink(true)
|
||||||
redraw()
|
redraw()
|
||||||
|
|
||||||
keyboard = { }
|
local modifiers = {
|
||||||
|
[1] = keys.leftCtrl,
|
||||||
|
[2] = keys.rightCtrl,
|
||||||
|
[3] = keys.leftShift,
|
||||||
|
[4] = keys.rightShift,
|
||||||
|
}
|
||||||
|
|
||||||
function keyboard:translate(event, code)
|
local input = {
|
||||||
if event == 'key' then
|
pressed = { },
|
||||||
local ch = keys.getName(code)
|
}
|
||||||
if ch then
|
|
||||||
|
|
||||||
if code == keys.leftCtrl or code == keys.rightCtrl then
|
function input:toCode(code)
|
||||||
if not self.control then
|
|
||||||
self.control = true
|
|
||||||
self.combo = false
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if code == keys.leftShift or code == keys.rightShift then
|
local ch = self.ch or keys.getName(code)
|
||||||
if not self.shift then
|
local result = { }
|
||||||
self.shift = true
|
|
||||||
self.combo = false
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.shift then
|
if self.pressed[keys.leftCtrl] or self.pressed[keys.rightCtrl] then
|
||||||
if #ch > 1 then
|
table.insert(result, 'control')
|
||||||
ch = 'shift-' .. ch
|
end
|
||||||
elseif self.control then
|
|
||||||
-- will create control-X
|
|
||||||
-- better than shift-control-x
|
|
||||||
ch = ch:upper()
|
|
||||||
end
|
|
||||||
self.combo = true
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.control then
|
if self.pressed[keys.leftShift] or self.pressed[keys.rightShift] then
|
||||||
ch = 'control-' .. ch
|
if modifiers[code] or #ch > 1 then
|
||||||
self.combo = true
|
table.insert(result, 'shift')
|
||||||
-- even return numbers such as
|
|
||||||
-- control-seven
|
|
||||||
return ch
|
|
||||||
end
|
|
||||||
|
|
||||||
-- filter out characters that will be processed in
|
|
||||||
-- the subsequent char event
|
|
||||||
if ch and #ch > 1 and (code < 2 or code > 11) then
|
|
||||||
return ch
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif event == 'key_up' then
|
|
||||||
|
|
||||||
if code == keys.leftCtrl or code == keys.rightCtrl then
|
|
||||||
self.control = false
|
|
||||||
elseif code == keys.leftShift or code == keys.rightShift then
|
|
||||||
self.shift = false
|
|
||||||
else
|
else
|
||||||
return
|
ch = ch:upper()
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- only send through the shift / control event if it wasn't
|
if not modifiers[code] then
|
||||||
-- used in combination with another event
|
table.insert(result, ch)
|
||||||
if not self.combo then
|
end
|
||||||
return keys.getName(code)
|
|
||||||
|
return table.concat(result, '-')
|
||||||
|
end
|
||||||
|
|
||||||
|
function input:translate(event, code, heldDown)
|
||||||
|
if event == 'key' then
|
||||||
|
if heldDown then
|
||||||
|
if not modifiers[code] then
|
||||||
|
self.fired = input:toCode(code)
|
||||||
|
return self.fired
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self.fired = nil
|
||||||
|
self.ch = nil
|
||||||
|
self.pressed[code] = true
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif event == 'char' then
|
elseif event == 'char' then
|
||||||
if not self.control then
|
self.ch = code
|
||||||
self.combo = true
|
|
||||||
return event
|
elseif event == 'key_up' then
|
||||||
|
if not self.fired then
|
||||||
|
if self.pressed[code] then
|
||||||
|
self.fired = input:toCode(code)
|
||||||
|
self.pressed[code] = nil
|
||||||
|
return self.fired
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
self.pressed[code] = nil
|
||||||
|
|
||||||
elseif event == 'mouse_click' then
|
elseif event == 'mouse_click' then
|
||||||
|
|
||||||
local buttons = { 'mouse_click', 'mouse_rightclick', 'mouse_doubleclick' }
|
local buttons = { 'mouse_click', 'mouse_rightclick', 'mouse_doubleclick' }
|
||||||
|
self.ch = buttons[code]
|
||||||
self.combo = true
|
self.fired = input:toCode(0)
|
||||||
if self.shift then
|
return self.fired
|
||||||
return 'shift-' .. buttons[code]
|
|
||||||
end
|
|
||||||
return buttons[code]
|
|
||||||
|
|
||||||
elseif event == "mouse_scroll" then
|
elseif event == "mouse_scroll" then
|
||||||
local directions = {
|
local directions = {
|
||||||
[ -1 ] = 'scrollUp',
|
[ -1 ] = 'scrollUp',
|
||||||
[ 1 ] = 'scrollDown'
|
[ 1 ] = 'scrollDown'
|
||||||
}
|
}
|
||||||
return directions[code]
|
self.ch = directions[code]
|
||||||
|
self.fired = input:toCode(0)
|
||||||
|
return self.fired
|
||||||
|
|
||||||
elseif event == 'paste' then
|
elseif event == 'paste' then
|
||||||
self.combo = true
|
self.ch = 'paste'
|
||||||
return event
|
self.pressed[keys.leftCtrl] = nil
|
||||||
|
self.pressed[keys.rightCtrl] = nil
|
||||||
|
if clipboard then
|
||||||
|
self.fired = input:toCode(0)
|
||||||
|
else
|
||||||
|
self.fired = 'paste'
|
||||||
|
end
|
||||||
|
return self.fired
|
||||||
|
|
||||||
elseif event == 'mouse_drag' then
|
elseif event == 'mouse_drag' then
|
||||||
return event
|
self.ch = 'mouse_drag'
|
||||||
|
self.fired = input:toCode(0)
|
||||||
|
return self.fired
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1234,7 +1203,7 @@ while bRunning do
|
|||||||
action = 'exit'
|
action = 'exit'
|
||||||
elseif sEvent == "mouse_click" or sEvent == 'mouse_drag' then
|
elseif sEvent == "mouse_click" or sEvent == 'mouse_drag' then
|
||||||
if param3 < h or sEvent == 'mouse_drag' then
|
if param3 < h or sEvent == 'mouse_drag' then
|
||||||
local ch = keyboard:translate(sEvent, param)
|
local ch = input:translate(sEvent, param)
|
||||||
if ch then
|
if ch then
|
||||||
action = keyMapping[ch]
|
action = keyMapping[ch]
|
||||||
param = param2 + scrollX
|
param = param2 + scrollX
|
||||||
@@ -1242,7 +1211,7 @@ while bRunning do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
local ch = keyboard:translate(sEvent, param)
|
local ch = input:translate(sEvent, param)
|
||||||
if ch then
|
if ch then
|
||||||
action = keyMapping[ch]
|
action = keyMapping[ch]
|
||||||
end
|
end
|
||||||
@@ -1258,7 +1227,7 @@ while bRunning do
|
|||||||
|
|
||||||
actions[action](param, param2)
|
actions[action](param, param2)
|
||||||
if action ~= 'menu' then
|
if action ~= 'menu' then
|
||||||
keyboard.lastAction = action
|
lastAction = action
|
||||||
end
|
end
|
||||||
|
|
||||||
if x ~= lastPos.x or y ~= lastPos.y then
|
if x ~= lastPos.x or y ~= lastPos.y then
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ end
|
|||||||
|
|
||||||
local tabId = multishell.getCurrent()
|
local tabId = multishell.getCurrent()
|
||||||
|
|
||||||
multishell.addHotkey(25, function()
|
multishell.addHotkey('control-p', function()
|
||||||
os.queueEvent('recorder_stop')
|
os.queueEvent('recorder_stop')
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@@ -185,7 +185,7 @@ while true do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
multishell.removeHotkey(25)
|
multishell.removeHotkey('control-p')
|
||||||
|
|
||||||
for k,fn in pairs(oldTerm) do
|
for k,fn in pairs(oldTerm) do
|
||||||
multishell.term[k] = fn
|
multishell.term[k] = fn
|
||||||
|
|||||||
Reference in New Issue
Block a user