better fuzzy matching + vfs type flag in Files

This commit is contained in:
kepler155c@gmail.com 2020-05-19 17:09:10 -06:00
parent b93d69c261
commit 985830fcfd
8 changed files with 115 additions and 66 deletions

View File

@ -77,8 +77,8 @@ local Browser = UI.Page {
grid = UI.ScrollingGrid {
columns = {
{ heading = 'Name', key = 'name' },
{ key = 'flags', width = 2 },
{ heading = 'Size', key = 'fsize', width = 5 },
{ key = 'flags', width = 3, textColor = 'lightGray' },
{ heading = 'Size', key = 'fsize', width = 5, textColor = 'yellow' },
},
sortColumn = 'name',
y = 2, ey = -2,
@ -211,7 +211,7 @@ function Browser:enable()
self:setFocus(self.grid)
end
function Browser.menuBar:getActive(menuItem)
function Browser.menuBar.getActive(_, menuItem)
local file = Browser.grid:getSelected()
if menuItem.flags == FILE then
return file and not file.isDir
@ -223,7 +223,7 @@ function Browser:setStatus(status, ...)
self.notification:info(string.format(status, ...))
end
function Browser:unmarkAll()
function Browser.unmarkAll()
for _,m in pairs(marked) do
m.marked = false
end
@ -263,10 +263,11 @@ function Browser:updateDirectory(dir)
dir.size = #files
for _, file in pairs(files) do
file.fullName = fs.combine(dir.name, file.name)
file.flags = ''
file.flags = file.fstype or ' '
if not file.isDir then
dir.totalSize = dir.totalSize + file.size
file.fsize = formatSize(file.size)
file.flags = file.flags .. ' '
else
if config.showDirSizes then
file.size = fs.getSize(file.fullName, true)
@ -274,11 +275,9 @@ function Browser:updateDirectory(dir)
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'
file.flags = file.flags .. 'D'
end
file.flags = file.flags .. (file.isReadOnly and 'R' or ' ')
if config.showHidden or file.name:sub(1, 1) ~= '.' then
dir.files[file.fullName] = file
end
@ -467,7 +466,7 @@ function Browser:eventHandler(event)
elseif event.type == 'paste' then
for _,m in pairs(copied) do
local s, m = pcall(function()
pcall(function()
if cutMode then
fs.move(m.fullName, fs.combine(self.dir.name, m.name))
else

View File

@ -1,3 +1,4 @@
local fuzzy = require('opus.fuzzy')
local UI = require('opus.ui')
local Util = require('opus.util')
@ -42,13 +43,13 @@ UI:addPage('main', UI.Page {
elseif event.type == 'text_change' then
if not event.text then
self.grid.values = topics
self.grid.sortColumn = 'lname'
else
self.grid.values = { }
for _,f in pairs(topics) do
if string.find(f.lname, event.text:lower()) then
table.insert(self.grid.values, f)
end
self.grid.sortColumn = 'score'
self.grid.inverseSort = false
local pattern = event.text:lower()
for _,v in pairs(self.grid.values) do
v.score = -fuzzy(v.lname, pattern)
end
end
self.grid:update()

View File

@ -41,7 +41,7 @@ local page = UI.Page {
},
description = UI.TextArea {
x = 16, y = 3, ey = -5,
marginRight = 0, marginLeft = 0,
marginRight = 2, marginLeft = 0,
},
action = UI.SlideOut {
titleBar = UI.TitleBar {
@ -140,9 +140,9 @@ function page:eventHandler(event)
elseif event.type == 'grid_focus_row' then
local manifest = event.selected.manifest
self.description.value = string.format('%s%s\n\n%s%s',
self.description:setValue(string.format('%s%s\n\n%s%s',
Ansi.yellow, manifest.title,
Ansi.white, manifest.description)
Ansi.white, manifest.description))
self.description:draw()
self:updateSelection(event.selected)

View File

@ -52,8 +52,8 @@ local function run(...)
loadFn = loadfile
end
local funkshun, err = loadFn(path, env)
if not funkshun then
local O_v_O, err = loadFn(path, env)
if not O_v_O then
error(err, -1)
end
@ -68,7 +68,7 @@ local function run(...)
}
env[ "arg" ] = { [0] = path, table.unpack(args) }
local r = { funkshun(table.unpack(args)) }
local r = { O_v_O(table.unpack(args)) }
tProgramStack[#tProgramStack] = nil

View File

@ -166,6 +166,13 @@ function fs.complete(partial, dir, includeFiles, includeSlash)
return fs.native.complete(partial, dir, includeFiles, includeSlash)
end
local displayFlags = {
urlfs = 'U',
linkfs = 'L',
ramfs = 'T',
netfs = 'N',
}
function fs.listEx(dir)
dir = fs.combine(dir, '')
local node = getNode(dir)
@ -176,20 +183,22 @@ function fs.listEx(dir)
local t = { }
local files = node.fs.list(node, dir)
pcall(function()
for _,f in ipairs(files) do
for _,f in ipairs(files) do
pcall(function()
local fullName = fs.combine(dir, f)
local n = fs.getNode(fullName)
local file = {
name = f,
isDir = fs.isDir(fullName),
isReadOnly = fs.isReadOnly(fullName),
fstype = n.mountPoint == fullName and displayFlags[n.fstype],
}
if not file.isDir then
file.size = fs.getSize(fullName)
end
table.insert(t, file)
end
end)
end)
end
return t
end

View File

@ -6,37 +6,41 @@ fs.loadTab('sys/etc/fstab')
-- add some Lua compatibility functions
function os.remove(a)
if fs.exists(a) then
local s = pcall(fs.delete, a)
return s and true or nil, a .. ': Unable to remove file'
local s = pcall(fs.delete, a)
return s and true or nil, a .. ': Unable to remove file'
end
return nil, a .. ': No such file or directory'
end
os.execute = function(cmd)
if not cmd then
return 1
end
local env = _G.getfenv(2)
if not cmd then
return env.shell and 1 or 0
end
local env = _G.getfenv(2)
local s, m = env.shell.run('sys/apps/shell.lua ' .. cmd)
if not env.shell then
return 0
end
if not s then
return 1, m
end
local s, m = env.shell.run('sys/apps/shell.lua ' .. cmd)
return 0
if not s then
return 1, m
end
return 0
end
os.tmpname = function()
local fname
repeat
fname = 'tmp/a' .. math.random(1, 32768)
until not fs.exists(fname)
local fname
repeat
fname = 'tmp/a' .. math.random(1, 32768)
until not fs.exists(fname)
return fname
return fname
end
-- non-standard - will raise error instead
os.exit = function(code)
error('Terminated with ' .. code)
error('Terminated with ' .. code)
end

View File

@ -13,7 +13,13 @@ table.insert(helpPaths, '/sys/help')
for name in pairs(Packages:installed()) do
local packageDir = fs.combine('packages', name)
local fstabPath = fs.combine(packageDir, 'etc/fstab')
if fs.exists(fstabPath) then
fs.loadTab(fstabPath)
end
table.insert(appPaths, 1, '/' .. packageDir)
local apiPath = fs.combine(packageDir, 'apis') -- TODO: rename dir to 'modules' (someday)
if fs.exists(apiPath) then
fs.mount(fs.combine('rom/modules/main', name), 'linkfs', apiPath)
@ -23,11 +29,6 @@ for name in pairs(Packages:installed()) do
if fs.exists(helpPath) then
table.insert(helpPaths, helpPath)
end
local fstabPath = fs.combine(packageDir, 'etc/fstab')
if fs.exists(fstabPath) then
fs.loadTab(fstabPath)
end
end
help.setPath(table.concat(helpPaths, ':'))

View File

@ -1,21 +1,56 @@
-- Based on Squid's fuzzy search
-- https://github.com/SquidDev-CC/artist/blob/vnext/artist/lib/match.lua
--
-- not very fuzzy anymore
local find = string.find
local floor = math.floor
local min = math.min
local max = math.max
local sub = string.sub
local SCORE_WEIGHT = 1000
local LEADING_LETTER_PENALTY = -30
local LEADING_LETTER_PENALTY_MAX = -90
local _find = string.find
local _max = math.max
return function(str, pattern)
local start = _find(str, pattern, 1, true)
if start then
-- All letters before the current one are considered leading, so add them to our penalty
return SCORE_WEIGHT
+ _max(LEADING_LETTER_PENALTY * (start - 1), LEADING_LETTER_PENALTY_MAX)
- (#str - #pattern)
-- https://rosettacode.org/wiki/Jaro_distance (ported to lua)
return function(s1, s2)
local l1, l2 = #s1, #s2;
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
for i = 1, l1 do
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
end
end
end
if matches == 0 then
return 0.0
end
local t = 0.0
local k = 1
for i = 1, l1 do
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
end
end
-- provide a major boost for exact matches
local b = 0.0
if find(s1, s2, 1, true) then
b = b + .5
end
local m = matches
return (m / l1 + m / l2 + (m - t) / m) / 3.0 + b
end