From ae3ee946e45dfb0abbb0f133c3208febf3d2e22e Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Fri, 12 May 2017 01:12:58 -0400 Subject: [PATCH] global clipboard plus directory sizes in Files --- apps/Files.lua | 34 ++++++++++++-- apps/Lua.lua | 4 ++ apps/edit.lua | 60 ++++++++++++++++-------- sys/apis/socket.lua | 2 - sys/apis/ui.lua | 91 +++++++++++++++++++++++++----------- sys/extensions/clipboard.lua | 33 +++++++++++++ sys/extensions/vfs.lua | 18 ++++++- sys/services/transort.lua | 6 +-- 8 files changed, 192 insertions(+), 56 deletions(-) create mode 100644 sys/extensions/clipboard.lua diff --git a/apps/Files.lua b/apps/Files.lua index 28ca3e9..88553fb 100644 --- a/apps/Files.lua +++ b/apps/Files.lua @@ -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 diff --git a/apps/Lua.lua b/apps/Lua.lua index 255164f..246231e 100644 --- a/apps/Lua.lua +++ b/apps/Lua.lua @@ -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 diff --git a/apps/edit.lua b/apps/edit.lua index 0c02df7..a3e5086 100644 --- a/apps/edit.lua +++ b/apps/edit.lua @@ -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, diff --git a/sys/apis/socket.lua b/sys/apis/socket.lua index cb55ed8..49a473f 100644 --- a/sys/apis/socket.lua +++ b/sys/apis/socket.lua @@ -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 diff --git a/sys/apis/ui.lua b/sys/apis/ui.lua index 24317a3..a838bcb 100644 --- a/sys/apis/ui.lua +++ b/sys/apis/ui.lua @@ -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 diff --git a/sys/extensions/clipboard.lua b/sys/extensions/clipboard.lua new file mode 100644 index 0000000..51ff2fa --- /dev/null +++ b/sys/extensions/clipboard.lua @@ -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) diff --git a/sys/extensions/vfs.lua b/sys/extensions/vfs.lua index 3c14558..339a14d 100644 --- a/sys/extensions/vfs.lua +++ b/sys/extensions/vfs.lua @@ -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 diff --git a/sys/services/transort.lua b/sys/services/transort.lua index 7b9e849..9bb1273 100644 --- a/sys/services/transort.lua +++ b/sys/services/transort.lua @@ -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