global clipboard plus directory sizes in Files

This commit is contained in:
kepler155c@gmail.com 2017-05-12 01:12:58 -04:00
parent e287958faa
commit ae3ee946e4
8 changed files with 192 additions and 56 deletions

View File

@ -2,6 +2,7 @@ require = requireInjector(getfenv(1))
local Util = require('util')
local Event = require('event')
local UI = require('ui')
local Config = require('config')
local cleanEnv = Util.shallowCopy(getfenv(1))
cleanEnv.require = nil
@ -9,10 +10,16 @@ cleanEnv.require = nil
multishell.setTitle(multishell.getCurrent(), 'Files')
UI:configure('Files', ...)
local config = {
showHidden = false,
showDirSizes = false,
}
Config.load('Files', config)
local copied = { }
local marked = { }
local directories = { }
local hidden = true
local cutMode = false
function formatSize(size)
@ -60,6 +67,7 @@ local Browser = UI.Page {
buttons = {
{ text = 'Refresh r', event = 'refresh' },
{ text = 'Hidden ^h', event = 'toggle_hidden' },
{ text = 'Dir Size ^s', event = 'toggle_dirSize' },
UI.Text { },
}
},
@ -200,12 +208,18 @@ function Browser:updateDirectory(dir)
dir.totalSize = dir.totalSize + file.size
file.fsize = formatSize(file.size)
else
if config.showDirSizes then
file.size = fs.getSize(file.fullName, true)
dir.totalSize = dir.totalSize + file.size
file.fsize = formatSize(file.size)
end
file.flags = 'D'
end
if file.isReadOnly then
file.flags = file.flags .. 'R'
end
if not hidden or file.name:sub(1, 1) ~= '.' then
if config.showHidden or file.name:sub(1, 1) ~= '.' then
dir.files[file.fullName] = file
end
end
@ -277,15 +291,27 @@ function Browser:eventHandler(event)
self:setStatus('Refreshed')
elseif event.type == 'toggle_hidden' then
hidden = not hidden
config.showHidden = not config.showHidden
Config.update('Files', config)
self:updateDirectory(self.dir)
self.grid:draw()
if hidden then
if not config.showHidden then
self:setStatus('Hiding hidden')
else
self:setStatus('Displaying hidden')
end
elseif event.type == 'toggle_dirSize' then
config.showDirSizes = not config.showDirSizes
Config.update('Files', config)
self:updateDirectory(self.dir)
self.grid:draw()
if config.showDirSizes then
self:setStatus('Displaying dir sizes')
end
elseif event.type == 'mark' and file then
file.marked = not file.marked
if file.marked then

View File

@ -258,6 +258,10 @@ function page.grid:eventHandler(event)
elseif event.type == 'grid_select' then
page:setPrompt(commandAppend(), true)
page:executeStatement(commandAppend())
elseif event.type == 'copy' then
if entry then
clipboard.setData(entry.rawValue)
end
else
return UI.Grid.eventHandler(self, event)
end

View File

@ -29,15 +29,36 @@ local fileInfo
local dirty = { y = 1, ey = h }
local mark = { anchor, active, continue }
local keyboard
local clipboard = { size, internal }
local searchPattern
local undo = { chain = { }, pointer = 0 }
local complete = { }
if _G.__CLIPBOARD then
clipboard = _G.__CLIPBOARD
else
_G.__CLIPBOARD = clipboard
if not clipboard then
_G.clipboard = { internal, data }
clipboard.shim = true
function clipboard.setData(data)
clipboard.data = data
if data then
clipboard.useInternal(true)
end
end
function clipboard.getText()
if clipboard.data then
return Util.tostring(clipboard.data)
end
end
function clipboard.isInternal()
return clipboard.internal
end
function clipboard.useInternal(mode)
if mode ~= clipboard.mode then
clipboard.internal = mode
end
end
end
local color = {
@ -363,7 +384,7 @@ local function redraw()
if not (w < 32 and #sStatus > 0) then
local clipboardIndicator = 'S'
if clipboard.internal then
if clipboard.isInternal() then
clipboardIndicator = 'I'
end
@ -1016,8 +1037,10 @@ local __actions = {
end,
toggle_clipboard = function()
clipboard.internal = not clipboard.internal
if clipboard.internal then
if clipboard.shim then
clipboard.setInternal(not clipboard.internal)
end
if clipboard.isInternal() then
setStatus('Using internal clipboard')
else
setStatus('Using system clipboard')
@ -1025,10 +1048,11 @@ local __actions = {
end,
copy_marked = function()
clipboard.lines, clipboard.size =
local text, size =
actions.copyText(mark.x, mark.y, mark.ex, mark.ey)
setStatus('%d chars copied', clipboard.size)
clipboard.internal = true
clipboard.setData(text)
setStatus('%d chars copied', size)
clipboard.useInternal(true)
end,
cut = function()
@ -1049,16 +1073,14 @@ local __actions = {
if mark.active then
actions.delete()
end
if clipboard.internal then
if clipboard.lines then
actions.insertText(x, y, clipboard.lines)
setStatus('%d chars added', clipboard.size)
else
setStatus('Internal clipboard empty')
end
else
if clipboard.isInternal() then
text = clipboard.getText()
end
if text then
actions.insertText(x, y, text)
setStatus('%d chars added', #text)
else
setStatus('Clipboard empty')
end
end,

View File

@ -42,7 +42,6 @@ function socketClass:read(timeout)
local e, id = os.pullEvent()
if e == 'transport_' .. self.sport then
data, distance = transport.read(self)
if data then
os.cancelTimer(timerId)
@ -74,7 +73,6 @@ function socketClass:ping()
transport.write(self, {
type = 'PING',
seq = self.wseq,
data = data,
})
return true
end

View File

@ -128,9 +128,27 @@ function Manager:init(args)
end
end)
Event.addHandler('mouse_drag', function(h, button, x, y)
if self.target then
local event = self:pointToChild(self.target, x, y)
-- revisit - should send out scroll_up and scroll_down events
-- let the element convert them to up / down
self:inputEvent(event.element,
{ type = 'mouse_drag', button = button, x = event.x, y = event.y })
self.currentPage:sync()
end
end)
Event.addHandler('paste', function(h, text)
self:emitEvent({ type = 'paste', text = text })
self.currentPage:sync()
if clipboard.isInternal() then
text = clipboard.getData()
end
if text and type(text) == 'string' then
self:emitEvent({ type = 'paste', text = text })
self.currentPage:sync()
end
end)
Event.addHandler('char', function(h, ch)
@ -431,7 +449,7 @@ end
function Manager:getDefaults(element, args)
local defaults = Util.deepCopy(element.defaults)
if args then
Util.merge(defaults, args)
Manager.setProperties(defaults, args)
end
return defaults
end
@ -1449,6 +1467,18 @@ UI.Grid.defaults = {
inverseSortIndicator = '^',
values = { },
columns = { },
accelerators = {
enter = 'key_enter',
[ 'control-c' ] = 'copy',
down = 'scroll_down',
up = 'scroll_up',
home = 'scroll_top',
[ 'end' ] = 'scroll_bottom',
pageUp = 'scroll_pageUp',
[ 'control-b' ] = 'scroll_pageUp',
pageDown = 'scroll_pageDown',
[ 'control-f' ] = 'scroll_pageDown',
},
}
function UI.Grid:init(args)
local defaults = UI:getDefaults(UI.Grid, args)
@ -1772,34 +1802,37 @@ function UI.Grid:eventHandler(event)
if row > 0 and row <= Util.size(self.values) then
self:setIndex(row)
if event.type == 'mouse_doubleclick' then
self:emit({ type = 'key', key = 'enter' })
self:emit({ type = 'key_enter' })
end
return true
end
elseif event.type == 'key' then
if event.key == 'enter' then
if self.selected then
self:emit({ type = 'grid_select', selected = self.selected })
end
return true
elseif event.key == 'down' then
self:setIndex(self.index + 1)
elseif event.key == 'up' then
self:setIndex(self.index - 1)
elseif event.key == 'control-b' or event.key == 'pageUp' then
self:setIndex(self.index - self.pageSize)
elseif event.key == 'control-f' or event.key == 'pageDown' then
self:setIndex(self.index + self.pageSize)
elseif event.key == 'home' then
self:setIndex(1)
elseif event.key == 'end' then
self:setIndex(Util.size(self.values))
else
return false
return false
elseif event.type == 'scroll_down' then
self:setIndex(self.index + 1)
elseif event.type == 'scroll_up' then
self:setIndex(self.index - 1)
elseif event.type == 'scroll_top' then
self:setIndex(1)
elseif event.type == 'scroll_bottom' then
self:setIndex(Util.size(self.values))
elseif event.type == 'scroll_pageUp' then
self:setIndex(self.index - self.pageSize)
elseif event.type == 'scroll_pageDown' then
self:setIndex(self.index + self.pageSize)
elseif event.type == 'key_enter' then
if self.selected then
self:emit({ type = 'grid_select', selected = self.selected })
end
return true
elseif event.type == 'copy' then
if self.selected then
clipboard.setData(Util.tostring(self.selected))
clipboard.useInternal(true)
end
else
return false
end
return false
return true
end
--[[-- ScrollingGrid --]]--
@ -2776,6 +2809,9 @@ UI.TextEntry.defaults = {
height = 1,
limit = 6,
pos = 0,
accelerators = {
[ 'control-c' ] = 'copy',
}
}
function UI.TextEntry:init(args)
local defaults = UI:getDefaults(UI.TextEntry, args)
@ -2910,6 +2946,9 @@ function UI.TextEntry:eventHandler(event)
end
return true
elseif event.type == 'copy' then
clipboard.setData(self.value)
elseif event.type == 'paste' then
local input = tostring(self.value)
local text = event.text

View File

@ -0,0 +1,33 @@
_G.clipboard = { internal, data }
function clipboard.getData()
return clipboard.data
end
function clipboard.setData(data)
clipboard.data = data
if data then
clipboard.useInternal(true)
end
end
function clipboard.getText()
if clipboard.data then
return Util.tostring(clipboard.data)
end
end
function clipboard.isInternal()
return clipboard.internal
end
function clipboard.useInternal(mode)
if mode ~= clipboard.mode then
clipboard.internal = mode
os.queueEvent('clipboard_mode', mode)
end
end
multishell.addHotkey(20, function()
clipboard.useInternal(not clipboard.isInternal())
end)

View File

@ -66,7 +66,23 @@ function nativefs.list(node, dir, full)
return files
end
function nativefs.getSize(node, dir)
function nativefs.getSize(node, dir, recursive)
if recursive and fs.native.isDir(dir) then
local function sum(dir)
local total = 0
local files = fs.native.list(dir)
for _,f in ipairs(files) do
local fullName = fs.combine(dir, f)
if fs.native.isDir(fullName) then
total = total + sum(fullName)
else
total = total + fs.native.getSize(fullName)
end
end
return total
end
return sum(dir)
end
if node.mountPoint == dir and node.nodes then
return 0
end

View File

@ -5,8 +5,6 @@
* write acknowledgements
* background read buffering
]]--
require = requireInjector(getfenv(1))
local Logger = require('logger')
multishell.setTitle(multishell.getCurrent(), 'Net transport')
@ -53,7 +51,7 @@ while true do
if e == 'timer' then
local socket = transport.timers[timerId]
if socket and socket.connected then
Logger.log('transport', 'timeout - closing socket ' .. socket.sport)
print('transport timeout - closing socket ' .. socket.sport)
socket:close()
transport.timers[timerId] = nil
end
@ -84,7 +82,7 @@ while true do
elseif msg.type == 'DATA' and msg.data then
if msg.seq ~= socket.rseq then
Logger.log('transport', 'seq error - closing socket ' .. socket.sport)
print('transport seq error - closing socket ' .. socket.sport)
socket:close()
else
socket.rseq = socket.rseq + 1