mirror of
				https://github.com/kepler155c/opus
				synced 2025-10-31 15:43:00 +00:00 
			
		
		
		
	debugger support
This commit is contained in:
		| @@ -7,47 +7,47 @@ local shell = _ENV.shell | ||||
| local URL = 'https://raw.githubusercontent.com/kepler155c/opus/%s/.opus_version' | ||||
|  | ||||
| if fs.exists('.opus_version') then | ||||
|     local f = fs.open('.opus_version', 'r') | ||||
|     local date = f.readLine() | ||||
|     f.close() | ||||
|     date = type(date) == 'string' and Util.split(date)[1] | ||||
| 	local f = fs.open('.opus_version', 'r') | ||||
| 	local date = f.readLine() | ||||
| 	f.close() | ||||
| 	date = type(date) == 'string' and Util.split(date)[1] | ||||
|  | ||||
|     local today = os.date('%j') | ||||
|     local config = Config.load('version', { | ||||
|         packages = date, | ||||
|         checked = today, | ||||
|     }) | ||||
| 	local today = os.date('%j') | ||||
| 	local config = Config.load('version', { | ||||
| 		packages = date, | ||||
| 		checked = today, | ||||
| 	}) | ||||
|  | ||||
|     -- check if packages need an update | ||||
|     if date ~= config.packages then | ||||
|         config.packages = date | ||||
|         Config.update('version', config) | ||||
|         print('Updating packages') | ||||
|         shell.run('package updateall') | ||||
|         os.reboot() | ||||
|     end | ||||
| 	-- check if packages need an update | ||||
| 	if date ~= config.packages then | ||||
| 		config.packages = date | ||||
| 		Config.update('version', config) | ||||
| 		print('Updating packages') | ||||
| 		shell.run('package updateall') | ||||
| 		os.reboot() | ||||
| 	end | ||||
|  | ||||
|     if type(date) == 'string' and #date > 0 then | ||||
|         if config.checked ~= today then | ||||
|             config.checked = today | ||||
|             Config.update('version', config) | ||||
|             print('Checking for new version') | ||||
|             pcall(function() | ||||
|                 local c = Util.httpGet(string.format(URL, _G.OPUS_BRANCH)) | ||||
|                 if c then | ||||
|                     local lines = Util.split(c) | ||||
|                     local revdate = table.remove(lines, 1) | ||||
|                     if date ~= revdate and config.skip ~= revdate then | ||||
|                         config.current = revdate | ||||
|                         config.details = table.concat(lines, '\n') | ||||
|                         Config.update('version', config) | ||||
|                         print('New version available') | ||||
|                         if _ENV.multishell then | ||||
|                             shell.openForegroundTab('sys/apps/Version.lua') | ||||
|                         end | ||||
|                     end | ||||
|                 end | ||||
|             end) | ||||
|         end | ||||
|     end | ||||
| 	if type(date) == 'string' and #date > 0 then | ||||
| 		if config.checked ~= today then | ||||
| 			config.checked = today | ||||
| 			Config.update('version', config) | ||||
| 			print('Checking for new version') | ||||
| 			pcall(function() | ||||
| 				local c = Util.httpGet(string.format(URL, _G.OPUS_BRANCH)) | ||||
| 				if c then | ||||
| 					local lines = Util.split(c) | ||||
| 					local revdate = table.remove(lines, 1) | ||||
| 					if date ~= revdate and config.skip ~= revdate then | ||||
| 						config.current = revdate | ||||
| 						config.details = table.concat(lines, '\n') | ||||
| 						Config.update('version', config) | ||||
| 						print('New version available') | ||||
| 						if _ENV.multishell then | ||||
| 							shell.openForegroundTab('sys/apps/Version.lua') | ||||
| 						end | ||||
| 					end | ||||
| 				end | ||||
| 			end) | ||||
| 		end | ||||
| 	end | ||||
| end | ||||
|   | ||||
| @@ -1,5 +1,20 @@ | ||||
| local fs = _G.fs | ||||
|  | ||||
| -- override bios function to include the actual filename | ||||
| function _G.loadfile(filename, env) | ||||
|     -- Support the previous `loadfile(filename, env)` form instead. | ||||
|     if type(mode) == "table" and env == nil then | ||||
|         mode, env = nil, mode | ||||
|     end | ||||
|  | ||||
|     local file = fs.open(filename, "r") | ||||
|     if not file then return nil, "File not found" end | ||||
|  | ||||
|     local func, err = load(file.readAll(), '@' .. filename, mode, env) | ||||
|     file.close() | ||||
|     return func, err | ||||
| end | ||||
|  | ||||
| local sandboxEnv = setmetatable({ }, { __index = _G }) | ||||
| for k,v in pairs(_ENV) do | ||||
| 	sandboxEnv[k] = v | ||||
|   | ||||
| @@ -42,5 +42,5 @@ end | ||||
|  | ||||
| -- non-standard - will raise error instead | ||||
| os.exit = function(code) | ||||
| 	error('Terminated with ' .. code) | ||||
| 	error(code) | ||||
| end | ||||
|   | ||||
| @@ -7,41 +7,41 @@ local sub   = string.sub | ||||
| -- https://rosettacode.org/wiki/Jaro_distance (ported to lua) | ||||
| return function(s1, s2) | ||||
| 	local l1, l2 = #s1, #s2; | ||||
|     if l1 == 0 then | ||||
| 	if l1 == 0 then | ||||
| 		return l2 == 0 and 1.0 or 0.0 | ||||
| 	end | ||||
|  | ||||
| 	local match_distance = max(floor(max(l1, l2) / 2) - 1, 0) | ||||
|     local s1_matches = { } | ||||
|     local s2_matches = { } | ||||
|     local matches = 0 | ||||
| 	local s1_matches = { } | ||||
| 	local s2_matches = { } | ||||
| 	local matches = 0 | ||||
|  | ||||
| 	for i = 1, l1 do | ||||
|         local _end = min(i + match_distance + 1, l2) | ||||
| 		local _end = min(i + match_distance + 1, l2) | ||||
| 		for k = max(1, i - match_distance), _end do | ||||
|             if not s2_matches[k] and sub(s1, i, i) == sub(s2, k, k) then | ||||
|                 s1_matches[i] = true | ||||
|                 s2_matches[k] = true | ||||
|                 matches = matches + 1 | ||||
|                 break | ||||
| 			if not s2_matches[k] and sub(s1, i, i) == sub(s2, k, k) then | ||||
| 				s1_matches[i] = true | ||||
| 				s2_matches[k] = true | ||||
| 				matches = matches + 1 | ||||
| 				break | ||||
| 			end | ||||
| 		end | ||||
| 	end | ||||
|     if matches == 0 then | ||||
| 	if matches == 0 then | ||||
| 		return 0.0 | ||||
| 	end | ||||
|  | ||||
|     local t = 0.0 | ||||
|     local k = 1 | ||||
| 	local t = 0.0 | ||||
| 	local k = 1 | ||||
| 	for i = 1, l1 do | ||||
|         if s1_matches[i] then | ||||
| 		if s1_matches[i] then | ||||
| 			while not s2_matches[k] do | ||||
| 				k = k + 1 | ||||
| 			end | ||||
| 			if sub(s1, i, i) ~= sub(s2, k, k) then | ||||
| 				t = t + 0.5 | ||||
| 			end | ||||
|             k = k + 1 | ||||
| 			k = k + 1 | ||||
| 		end | ||||
| 	end | ||||
|  | ||||
| @@ -51,6 +51,6 @@ return function(s1, s2) | ||||
| 		b = b + .5 | ||||
| 	end | ||||
|  | ||||
|     local m = matches | ||||
|     return (m / l1 + m / l2 + (m - t) / m) / 3.0 + b | ||||
| 	local m = matches | ||||
| 	return (m / l1 + m / l2 + (m - t) / m) / 3.0 + b | ||||
| end | ||||
|   | ||||
| @@ -12,6 +12,10 @@ local function traceback(x) | ||||
| 		return x | ||||
| 	end | ||||
|  | ||||
| 	if x and x:match(':%d+: 0$') then | ||||
| 		return x | ||||
| 	end | ||||
|  | ||||
| 	if debug_traceback then | ||||
| 		-- The parens are important, as they prevent a tail call occuring, meaning | ||||
| 		-- the stack level is preserved. This ensures the code behaves identically | ||||
| @@ -65,7 +69,7 @@ local function trim_traceback(stack) | ||||
| 	local t = { } | ||||
| 	for _, line in pairs(trace) do | ||||
| 		if not matchesFilter(line) then | ||||
| 			line = line:gsub("in function", "in") | ||||
| 			line = line:gsub("in function", "in"):gsub('%w+/', '') | ||||
| 			table.insert(t, line) | ||||
| 		end | ||||
| 	end | ||||
| @@ -84,9 +88,15 @@ return function (fn, ...) | ||||
| 	if not res[1] and res[2] ~= nil then | ||||
| 		local err, trace = trim_traceback(res[2]) | ||||
|  | ||||
| 		_G._syslog('\n' .. err .. '\n' .. 'stack traceback:') | ||||
| 		for _, v in ipairs(trace) do | ||||
| 			_G._syslog(v) | ||||
| 		if #trace > 0 then | ||||
| 			_G._syslog('\n' .. err .. '\n' .. 'stack traceback:') | ||||
| 			for _, v in ipairs(trace) do | ||||
| 				_G._syslog(v) | ||||
| 			end | ||||
| 		end | ||||
|  | ||||
| 		if err:match(':%d+: 0$') then | ||||
| 			return true | ||||
| 		end | ||||
|  | ||||
| 		return res[1], err, trace | ||||
|   | ||||
							
								
								
									
										107
									
								
								sys/modules/opus/ui/components/QuickSelect.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								sys/modules/opus/ui/components/QuickSelect.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,107 @@ | ||||
| local class = require('opus.class') | ||||
| local fuzzy = require('opus.fuzzy') | ||||
| local UI    = require('opus.ui') | ||||
|  | ||||
| local fs      = _G.fs | ||||
| local _insert = table.insert | ||||
|  | ||||
| UI.QuickSelect = class(UI.Window) | ||||
| UI.QuickSelect.defaults = { | ||||
| 	UIElement = 'QuickSelect', | ||||
| } | ||||
| function UI.QuickSelect:postInit() | ||||
| 	self.filterEntry = UI.TextEntry { | ||||
| 		x = 2, y = 2, ex = -2, | ||||
| 		shadowText = 'File name', | ||||
| 		accelerators = { | ||||
| 			[ 'enter' ] = 'accept', | ||||
| 			[ 'up' ] = 'grid_up', | ||||
| 			[ 'down' ] = 'grid_down', | ||||
| 		}, | ||||
| 	} | ||||
| 	self.grid = UI.ScrollingGrid { | ||||
| 		x = 2, y = 3, ex = -2, ey = -4, | ||||
| 		disableHeader = true, | ||||
| 		columns = { | ||||
| 			{ key = 'name' }, | ||||
| 			{ key = 'dir', textColor = 'lightGray' }, | ||||
| 		}, | ||||
| 		accelerators = { | ||||
| 			grid_select = 'accept', | ||||
| 		}, | ||||
| 	} | ||||
| 	self.cancel = UI.Button { | ||||
| 		x = -9, y = -2, | ||||
| 		text = 'Cancel', | ||||
| 		event = 'select_cancel', | ||||
| 	} | ||||
| end | ||||
|  | ||||
| function UI.QuickSelect:draw() | ||||
| 	self:fillArea(1, 1, self.width, self.height, string.rep('\127', self.width), 'black', 'gray') | ||||
| 	self:drawChildren() | ||||
| end | ||||
|  | ||||
| function UI.QuickSelect:applyFilter(filter) | ||||
| 	if filter then | ||||
| 		filter = filter:lower() | ||||
| 		self.grid.sortColumn = 'score' | ||||
|  | ||||
| 		for _,v in pairs(self.grid.values) do | ||||
| 			v.score = -fuzzy(v.lname, filter) | ||||
| 		end | ||||
| 	else | ||||
| 		self.grid.sortColumn = 'lname' | ||||
| 	end | ||||
|  | ||||
| 	self.grid:update() | ||||
| 	self.grid:setIndex(1) | ||||
| end | ||||
|  | ||||
| function UI.QuickSelect:enable() | ||||
| 	self.grid.values = { } | ||||
| 	local function recurse(dir) | ||||
| 		local files = fs.list(dir) | ||||
| 		for _,f in ipairs(files) do | ||||
| 			local fullName = fs.combine(dir, f) | ||||
| 			if fs.native.isDir(fullName) then -- skip virtual dirs | ||||
| 				if f ~= '.git' then recurse(fullName) end | ||||
| 			else | ||||
| 				_insert(self.grid.values, { | ||||
| 					name = f, | ||||
| 					dir = dir, | ||||
| 					lname = f:lower(), | ||||
| 					fullName = fullName, | ||||
| 				}) | ||||
| 			end | ||||
| 		end | ||||
| 	end | ||||
| 	recurse('') | ||||
| 	self:applyFilter() | ||||
| 	self.filterEntry:reset() | ||||
| 	UI.Window.enable(self) | ||||
| end | ||||
|  | ||||
| function UI.QuickSelect:eventHandler(event) | ||||
| 	if event.type == 'grid_up' then | ||||
| 		self.grid:emit({ type = 'scroll_up' }) | ||||
| 		return true | ||||
|  | ||||
| 	elseif event.type == 'grid_down' then | ||||
| 		self.grid:emit({ type = 'scroll_down' }) | ||||
| 		return true | ||||
|  | ||||
| 	elseif event.type == 'accept' then | ||||
| 		local sel = self.grid:getSelected() | ||||
| 		if sel then | ||||
| 			self:emit({ type = 'select_file', file = sel.fullName, element = self }) | ||||
| 		end | ||||
| 		return true | ||||
|  | ||||
| 	elseif event.type == 'text_change' then | ||||
| 		self:applyFilter(event.text) | ||||
| 		self.grid:draw() | ||||
| 		return true | ||||
|  | ||||
| 	end | ||||
| end | ||||
		Reference in New Issue
	
	Block a user
	 kepler155c@gmail.com
					kepler155c@gmail.com