diff --git a/openos/.package b/openos/.package deleted file mode 100644 index b248f01..0000000 --- a/openos/.package +++ /dev/null @@ -1,7 +0,0 @@ -{ - title = 'Shell utilities', - repository = 'kepler155c/opus-apps/{{OPUS_BRANCH}}/openos', - description = [[Experimental! - Utilties for shell: grep, cat, touch, etc ]], - licence = 'MIT', -} diff --git a/openos/tree.lua b/openos/tree.lua deleted file mode 100644 index 1d37799..0000000 --- a/openos/tree.lua +++ /dev/null @@ -1,331 +0,0 @@ -local computer = require("openos.computer") -local shell = require("openos.shell") -local fs = require("openos.filesystem") -local tx = require("openos.transforms") -local text = require("openos.text") - -local args, opts = shell.parse(...) - -local function die(...) - io.stderr:write(...) - os.exit(1) -end - -do -- handle cli - if opts.help then - print([[Usage: tree [OPTION]... [FILE]... - -a, --all do not ignore entries starting with . - --full-time with -l, print time in full iso format - -h, --human-readable with -l, print human readable sizes - --si likewise, but use powers of 1000 not 1024 - --level=LEVEL descend only LEVEL directories deep - --color=WHEN WHEN can be - auto - colorize output only if writing to a tty, - always - always colorize output, - never - never colorize output; (default: auto) - -l use a long listing format - -f print the full path prefix for each file - -i do not print indentation lines - -p append "/" indicator to directories - -Q, --quote quote filenames with double quotes - -r, --reverse reverse order while sorting - -S sort by file size - -t sort by modification type, newest first - -X sort alphabetically by entry extension - -C do not count files and directories - -R count root directories like other files - --help print this help and exit]]) - return 0 - end - - if #args == 0 then - table.insert(args, ".") - end - - opts.level = tonumber(opts.level) or math.huge - if opts.level < 1 then - die("Invalid level, must be greater than 0") - end - - opts.color = opts.color or "auto" - if opts.color == "auto" then - opts.color = io.stdout.tty and "always" or "never" - end - - if opts.color ~= "always" and opts.color ~= "never" then - die("Invalid value for --color=WHEN option; WHEN should be auto, always or never") - end -end - -local lastYield = computer.uptime() -local function yieldopt() - if computer.uptime() - lastYield > 2 then - lastYield = computer.uptime() - os.sleep(0) - end -end - -local function peekable(iterator, state, var1) - local nextItem = {iterator(state, var1)} - - return setmetatable({ - peek = function() - return table.unpack(nextItem) - end - }, { - __call = coroutine.wrap(function() - while true do - local item = nextItem - nextItem = {iterator(state, nextItem[1])} - coroutine.yield(table.unpack(item)) - if nextItem[1] == nil then break end - end - end) - }) -end - -local function filter(entry) - return opts.a or entry:sub(1, 1) ~= "." -end - -local function stat(path) - local st = {} - st.path = path - st.name = fs.name(path) or "/" - st.sortName = st.name:gsub("^%.","") - st.time = fs.lastModified(path) - st.isLink = fs.isLink(path) - st.isDirectory = fs.isDirectory(path) - st.size = st.isLink and 0 or fs.size(path) - st.extension = st.name:match("(%.[^.]+)$") or "" - st.fs = fs.get(path) - return st -end - -local colorize -if opts.color == "always" then - -- from /lib/core/full_ls.lua - local colors = tx.foreach(text.split(os.getenv("LS_COLORS") or "", {":"}, true), function(e) - local parts = text.split(e, {"="}, true) - return parts[2], parts[1] - end) - - function colorize(stat) - return stat.isLink and colors.ln or - stat.isDirectory and colors.di or - colors["*" .. stat.extension] or - colors.fi - end -end - -local function list(path) - return coroutine.wrap(function() - local l = {} - for entry in fs.list(path) do - if filter(entry) then - table.insert(l, stat(fs.concat(path, entry))) - end - end - - if opts.S then - table.sort(l, function(a, b) - return a.size < b.size - end) - elseif opts.t then - table.sort(l, function(a, b) - return a.time < b.time - end) - elseif opts.X then - table.sort(l, function(a, b) - return a.extension < b.extension - end) - else - table.sort(l, function(a, b) - return a.sortName < b.sortName - end) - end - - for i = opts.r and #l or 1, opts.r and 1 or #l, opts.r and -1 or 1 do - coroutine.yield(l[i]) - end - end) -end - -local function digRoot(rootPath) - coroutine.yield(stat(rootPath), {}) - - if not fs.isDirectory(rootPath) then - return - end - local iterStack = {peekable(list(rootPath))} - local pathStack = {rootPath} - local levelStack = {not not iterStack[#iterStack]:peek()} - - - repeat - local entry = iterStack[#iterStack]() - - if entry then - levelStack[#levelStack] = not not iterStack[#iterStack]:peek() - - local path = fs.concat(fs.concat(table.unpack(pathStack)), entry.name) - - coroutine.yield(entry, levelStack) - - if entry.isDirectory and opts.level > #levelStack then - table.insert(iterStack, peekable(list(path))) - table.insert(pathStack, entry.name) - table.insert(levelStack, not not iterStack[#iterStack]:peek()) - end - else - table.remove(iterStack) - table.remove(pathStack) - table.remove(levelStack) - end - until #iterStack == 0 -end - -local function dig(roots) - return coroutine.wrap(function() - for _, root in ipairs(roots) do - digRoot(root) - end - end) -end - -local function nod(n) -- from /lib/core/full_ls.lua - return n and (tostring(n):gsub("(%.[0-9]+)0+$","%1")) or "0" -end - -local function formatFSize(size) -- from /lib/core/full_ls.lua - if not opts.h and not opts["human-readable"] and not opts.si then - return tostring(size) - end - - local sizes = {"", "K", "M", "G"} - local unit = 1 - local power = opts.si and 1000 or 1024 - - while size > power and unit < #sizes do - unit = unit + 1 - size = size / power - end - - return nod(math.floor(size*10)/10)..sizes[unit] -end - -local function pad(txt) -- from /lib/core/full_ls.lua - txt = tostring(txt) - return #txt >= 2 and txt or "0" .. txt -end - -local function formatTime(epochms) -- from /lib/core/full_ls.lua - local month_names = {"January","February","March","April","May","June", - "July","August","September","October","November","December"} - - if epochms == 0 then return "" end - - local d = os.date("*t", epochms) - local day, hour, min, sec = nod(d.day), pad(nod(d.hour)), pad(nod(d.min)), pad(nod(d.sec)) - - if opts["full-time"] then - return string.format("%s-%s-%s %s:%s:%s ", d.year, pad(nod(d.month)), pad(day), hour, min, sec) - else - return string.format("%s %+2s %+2s:%+2s ", month_names[d.month]:sub(1,3), day, hour, pad(min)) - end -end - -local function writeEntry(entry, levelStack) - for i, hasNext in ipairs(levelStack) do - if opts.i then break end - - if i == #levelStack then - if hasNext then - io.write("├── ") - else - io.write("└── ") - end - else - if hasNext then - io.write("│   ") - else - io.write(" ") - end - end - end - - if opts.l then - io.write("[") - - io.write(entry.isDirectory and "d" or entry.isLink and "l" or "f", "-") - io.write("r", entry.fs.isReadOnly() and "-" or "w", " ") - - io.write(formatFSize(entry.size), " ") - - io.write(formatTime(entry.time)) - io.write("] ") - end - - if opts.Q then io.write('"') end - - if opts.color == "always" then - io.write("\27[" .. colorize(entry) .. "m") - end - - if opts.f then - io.write(entry.path) - else - io.write(entry.name) - end - - if opts.color == "always" then - io.write("\27[0m") - end - - if opts.p and entry.isDirectory then - io.write("/") - end - - if opts.Q then io.write('"') end - io.write("\n") -end - -local function writeCount(dirs, files) - io.write("\n") - io.write(dirs, " director", dirs == 1 and "y" or "ies") - io.write(", ") - io.write(files, " file", files == 1 and "" or "s") - io.write("\n") -end - -local dirs, files = 0, 0 - -local roots = {} -for _, arg in ipairs(args) do - local path = shell.resolve(arg) - local real, reason = fs.realPath(path) - if not real then - die("cannot access ", path, ": ", reason or "unknown error") - elseif not fs.exists(path) then - die("cannot access ", path, ":", "No such file or directory") - else - table.insert(roots, real) - end -end - -for entry, levelStack in dig(roots) do - if opts.R or #levelStack > 0 then - if entry.isDirectory then - dirs = dirs + 1 - else - files = files + 1 - end - end - writeEntry(entry, levelStack) - yieldopt() -end - -if not opts.C then - writeCount(dirs, files) -end - diff --git a/shellex/.package b/shellex/.package new file mode 100644 index 0000000..be27178 --- /dev/null +++ b/shellex/.package @@ -0,0 +1,7 @@ +{ + title = 'Shell utilities', + repository = 'kepler155c/opus-apps/{{OPUS_BRANCH}}/shellex', + description = [[Experimental! + Linux style shell commands: grep, cat, touch, df, etc ]], + licence = 'MIT', +} diff --git a/openos/apis/computer.lua b/shellex/apis/computer.lua similarity index 100% rename from openos/apis/computer.lua rename to shellex/apis/computer.lua diff --git a/openos/apis/filesystem.lua b/shellex/apis/filesystem.lua similarity index 100% rename from openos/apis/filesystem.lua rename to shellex/apis/filesystem.lua diff --git a/shellex/apis/glob.lua b/shellex/apis/glob.lua new file mode 100644 index 0000000..a622229 --- /dev/null +++ b/shellex/apis/glob.lua @@ -0,0 +1,50 @@ +local GtoP = require('shellex.globtopattern') + +local Glob = { } + +local fs = _G.fs + +local function splitpath(path) + local parts = { } + for match in string.gmatch(path, "[^/]+") do + table.insert(parts, match) + end + return parts +end + +function Glob.matches(path, spec) + local t = { } + local ss = splitpath(spec) + local abs = string.sub(spec, 1, 1) == '/' + + local function dirMatches(dir, i) + local files = fs.list(dir) + local s = GtoP.globtopattern(ss[i]) + + for _, f in pairs(files) do + if f:match(s) then + local fp = fs.combine(dir, f) + if not ss[i + 1] then + table.insert(t, '/' .. fp) + elseif ss[i + 1] and fs.isDir(fp) then + dirMatches(fp, i + 1) + end + end + end + end + + path = '/' .. fs.combine('', path) -- normalize + + dirMatches(abs and '' or path, 1) + + if not abs then + local len = path == '/' and #path + 1 or #path + 2 + for k, v in pairs(t) do + t[k] = v:sub(len) + end + end + + return t +end + +return Glob diff --git a/shellex/apis/globtopattern.lua b/shellex/apis/globtopattern.lua new file mode 100644 index 0000000..ea91145 --- /dev/null +++ b/shellex/apis/globtopattern.lua @@ -0,0 +1,119 @@ +-- see: https://github.com/davidm/lua-glob-pattern +local M = {_TYPE='module', _NAME='globtopattern', _VERSION='0.2.1.20120406'} + +function M.globtopattern(g) + -- Some useful references: + -- - apr_fnmatch in Apache APR. For example, + -- http://apr.apache.org/docs/apr/1.3/group__apr__fnmatch.html + -- which cites POSIX 1003.2-1992, section B.6. + + local p = "^" -- pattern being built + local i = 0 -- index in g + local c -- char at index i in g. + + -- unescape glob char + local function unescape() + if c == '\\' then + i = i + 1; c = g:sub(i,i) + if c == '' then + p = '[^]' + return false + end + end + return true + end + + -- escape pattern char + local function escape(c) + return c:match("^%w$") and c or '%' .. c + end + + -- Convert tokens at end of charset. + local function charset_end() + while 1 do + if c == '' then + p = '[^]' + return false + elseif c == ']' then + p = p .. ']' + break + else + if not unescape() then break end + local c1 = c + i = i + 1; c = g:sub(i,i) + if c == '' then + p = '[^]' + return false + elseif c == '-' then + i = i + 1; c = g:sub(i,i) + if c == '' then + p = '[^]' + return false + elseif c == ']' then + p = p .. escape(c1) .. '%-]' + break + else + if not unescape() then break end + p = p .. escape(c1) .. '-' .. escape(c) + end + elseif c == ']' then + p = p .. escape(c1) .. ']' + break + else + p = p .. escape(c1) + i = i - 1 -- put back + end + end + i = i + 1; c = g:sub(i,i) + end + return true + end + + -- Convert tokens in charset. + local function charset() + i = i + 1; c = g:sub(i,i) + if c == '' or c == ']' then + p = '[^]' + return false + elseif c == '^' or c == '!' then + i = i + 1; c = g:sub(i,i) + if c == ']' then + -- ignored + else + p = p .. '[^' + if not charset_end() then return false end + end + else + p = p .. '[' + if not charset_end() then return false end + end + return true + end + + -- Convert tokens. + while 1 do + i = i + 1; c = g:sub(i,i) + if c == '' then + p = p .. '$' + break + elseif c == '?' then + p = p .. '.' + elseif c == '*' then + p = p .. '.*' + elseif c == '[' then + if not charset() then break end + elseif c == '\\' then + i = i + 1; c = g:sub(i,i) + if c == '' then + p = p .. '\\$' + break + end + p = p .. escape(c) + else + p = p .. escape(c) + end + end + return p +end + +return M \ No newline at end of file diff --git a/openos/apis/keyboard.lua b/shellex/apis/keyboard.lua similarity index 100% rename from openos/apis/keyboard.lua rename to shellex/apis/keyboard.lua diff --git a/openos/apis/sh.lua b/shellex/apis/sh.lua similarity index 100% rename from openos/apis/sh.lua rename to shellex/apis/sh.lua diff --git a/openos/apis/shell.lua b/shellex/apis/shell.lua similarity index 100% rename from openos/apis/shell.lua rename to shellex/apis/shell.lua diff --git a/openos/apis/term.lua b/shellex/apis/term.lua similarity index 100% rename from openos/apis/term.lua rename to shellex/apis/term.lua diff --git a/openos/apis/text.lua b/shellex/apis/text.lua similarity index 99% rename from openos/apis/text.lua rename to shellex/apis/text.lua index 4a2b0fd..ce3f4f3 100644 --- a/openos/apis/text.lua +++ b/shellex/apis/text.lua @@ -1,5 +1,5 @@ -local unicode = require("openos.unicode") -local tx = require("openos.transforms") +local unicode = require("shellex.unicode") +local tx = require("shellex.transforms") local text = {} text.internal = {} diff --git a/openos/apis/transfer.lua b/shellex/apis/transfer.lua similarity index 85% rename from openos/apis/transfer.lua rename to shellex/apis/transfer.lua index bd3868a..8a89d30 100644 --- a/openos/apis/transfer.lua +++ b/shellex/apis/transfer.lua @@ -1,6 +1,7 @@ -local fs = require("openos.filesystem") -local shell = require("openos.shell") -local text = require("openos.text") +local fs = require("shellex.filesystem") +local glob = require('shellex.glob') +local shell = require("shellex.shell") +local text = require("shellex.text") local lib = {} local function perr(ops, format, ...) @@ -236,28 +237,31 @@ function lib.batch(args, options) end local originalToIsDir = fs.isDirectory(ok) - for _, fromArg in ipairs(args) do - -- a "contents of" copy is where src path ends in . or .. - -- a source path ending with . is not sufficient - could be the source filename - local contents_of - contents_of, ok = contents_check(fromArg, options, true) - if ok then - -- we do not append fromPath name to toPath in case of contents_of copy - local toPath = toArg - if contents_of and options.cmd == "mv" then - perr(options, "invalid move path '%s'", fromArg) - else - if not contents_of and originalToIsDir then - local fromName = fs.name(fromArg) - if fromName then - toPath = toPath .. "/" .. fromName + for _, arg in ipairs(args) do + local files = glob.matches(shell.getWorkingDirectory(), arg) + for _, fromArg in pairs(files) do + -- a "contents of" copy is where src path ends in . or .. + -- a source path ending with . is not sufficient - could be the source filename + local contents_of + contents_of, ok = contents_check(fromArg, options, true) + if ok then + -- we do not append fromPath name to toPath in case of contents_of copy + local toPath = toArg + if contents_of and options.cmd == "mv" then + perr(options, "invalid move path '%s'", fromArg) + else + if not contents_of and originalToIsDir then + local fromName = fs.name(fromArg) + if fromName then + toPath = toPath .. "/" .. fromName + end end - end - local result, reason = lib.recurse(fromArg, toPath, options, origin, true) + local result, reason = lib.recurse(fromArg, toPath, options, origin, true) - if not result then - perr(options, reason) + if not result then + perr(options, reason) + end end end end diff --git a/openos/apis/transforms.lua b/shellex/apis/transforms.lua similarity index 99% rename from openos/apis/transforms.lua rename to shellex/apis/transforms.lua index d2ee40d..f9dc1cc 100644 --- a/openos/apis/transforms.lua +++ b/shellex/apis/transforms.lua @@ -1,4 +1,3 @@ - local lib={} lib.internal={} diff --git a/openos/apis/tty.lua b/shellex/apis/tty.lua similarity index 100% rename from openos/apis/tty.lua rename to shellex/apis/tty.lua diff --git a/openos/apis/unicode.lua b/shellex/apis/unicode.lua similarity index 100% rename from openos/apis/unicode.lua rename to shellex/apis/unicode.lua diff --git a/openos/autorun/startup.lua b/shellex/autorun/startup.lua similarity index 100% rename from openos/autorun/startup.lua rename to shellex/autorun/startup.lua diff --git a/openos/cat.lua b/shellex/cat.lua similarity index 87% rename from openos/cat.lua rename to shellex/cat.lua index de1a293..50245d8 100644 --- a/openos/cat.lua +++ b/shellex/cat.lua @@ -1,5 +1,5 @@ -local shell = require("openos.shell") -local fs = require("openos.filesystem") +local shell = require("shellex.shell") +local fs = require("shellex.filesystem") local args = shell.parse(...) local ec = 0 diff --git a/openos/cp.lua b/shellex/cp.lua similarity index 91% rename from openos/cp.lua rename to shellex/cp.lua index f59c15c..ea502a0 100644 --- a/openos/cp.lua +++ b/shellex/cp.lua @@ -1,5 +1,5 @@ -local shell = require("openos.shell") -local transfer = require("openos.transfer") +local shell = require("shellex.shell") +local transfer = require("shellex.transfer") local args, options = shell.parse(...) options.h = options.h or options.help diff --git a/openos/df.lua b/shellex/df.lua similarity index 93% rename from openos/df.lua rename to shellex/df.lua index 192dda4..c7b3580 100644 --- a/openos/df.lua +++ b/shellex/df.lua @@ -1,6 +1,6 @@ -local fs = require("openos.filesystem") -local shell = require("openos.shell") -local text = require("openos.text") +local fs = require("shellex.filesystem") +local shell = require("shellex.shell") +local text = require("shellex.text") local args, options = shell.parse(...) diff --git a/openos/dmesg.lua b/shellex/dmesg.lua similarity index 96% rename from openos/dmesg.lua rename to shellex/dmesg.lua index 6e944f5..96203f2 100644 --- a/openos/dmesg.lua +++ b/shellex/dmesg.lua @@ -1,4 +1,4 @@ -local tty = require("openos.tty") +local tty = require("shellex.tty") local args = {...} local gpu = tty.gpu() diff --git a/openos/du.lua b/shellex/du.lua similarity index 79% rename from openos/du.lua rename to shellex/du.lua index 692b08a..4bdbea8 100644 --- a/openos/du.lua +++ b/shellex/du.lua @@ -1,5 +1,6 @@ -local shell = require("openos.shell") -local fs = require("openos.filesystem") +local fs = require("shellex.filesystem") +local glob = require('shellex.glob') +local shell = require("shellex.shell") local args, options = shell.parse(...) if #args == 0 then @@ -107,22 +108,24 @@ local function visitor(rpath) end for _,arg in ipairs(args) do - local path = shell.resolve(arg) - - if not fs.exists(path) then - io.stderr:write(string.format("du: cannot access '%s': no such file or directory\n", arg)) - return 1 - else - if fs.isDirectory(path) then - local total = visitor(arg) - - if bSummary then - printSize(total, arg) - end - elseif fs.isLink(path) then - printSize(0, arg) + local files = glob.matches(shell.getWorkingDirectory(), arg) + for _, v in pairs(files) do + local path = shell.resolve(v) + if not fs.exists(path) then + io.stderr:write(string.format("du: cannot access '%s': no such file or directory\n", v)) + return 1 else - printSize(fs.size(path), arg) + if fs.isDirectory(path) then + local total = visitor(v) + + if bSummary then + printSize(total, v) + end + elseif fs.isLink(path) then + printSize(0, v) + else + printSize(fs.size(path), v) + end end end end diff --git a/openos/find.lua b/shellex/find.lua similarity index 96% rename from openos/find.lua rename to shellex/find.lua index d8c4972..b4695e2 100644 --- a/openos/find.lua +++ b/shellex/find.lua @@ -1,6 +1,6 @@ -local shell = require("openos.shell") -local fs = require("openos.filesystem") -local text = require("openos.text") +local shell = require("shellex.shell") +local fs = require("shellex.filesystem") +local text = require("shellex.text") local USAGE = [===[Usage: find [path] [--type=[dfs]] [--[i]name=EXPR] diff --git a/openos/grep.lua b/shellex/grep.lua similarity index 94% rename from openos/grep.lua rename to shellex/grep.lua index f758660..f4cb39c 100644 --- a/openos/grep.lua +++ b/shellex/grep.lua @@ -6,10 +6,11 @@ https://raw.githubusercontent.com/OpenPrograms/Wobbo-Programs/master/grep/grep.l -- POSIX grep for OpenComputers -- one difference is that this version uses Lua regex, not POSIX regex. -local fs = require("openos.filesystem") -local shell = require("openos.shell") -local tty = require("openos.tty") -local computer = require("openos.computer") +local computer = require("shellex.computer") +local fs = require("shellex.filesystem") +local glob = require('shellex.glob') +local shell = require("shellex.shell") +local tty = require("shellex.tty") -- Process the command line arguments @@ -28,8 +29,14 @@ for more information, run: man grep ]]) end -local PATTERNS = {args[1]} -local FILES = {select(2, table.unpack(args))} +local PATTERNS = { table.remove(args, 1) } +local FILES = { } +for _, arg in pairs(args) do + local files = glob.matches(shell.getWorkingDirectory(), arg) + for _, v in pairs(files) do + table.insert(FILES, v) + end +end local LABEL_COLOR = 0xb000b0 local LINE_NUM_COLOR = 0x00FF00 @@ -167,7 +174,7 @@ end if search_recursively then local files = {} for _,arg in ipairs(FILES) do - if fs.isDirectory(arg) then + if fs.isDirectory(shell.resolve(arg)) then getAllFiles(arg, files) else files[#files+1]=arg diff --git a/openos/head.lua b/shellex/head.lua similarity index 97% rename from openos/head.lua rename to shellex/head.lua index 7925f7d..0cd41a2 100644 --- a/openos/head.lua +++ b/shellex/head.lua @@ -1,5 +1,4 @@ -local shell = require("openos.shell") -local fs = require("openos.filesystem") +local shell = require("shellex.shell") local args, options = shell.parse(...) local error_code = 0 diff --git a/openos/hostname.lua b/shellex/hostname.lua similarity index 87% rename from openos/hostname.lua rename to shellex/hostname.lua index ae1060d..8999e3b 100644 --- a/openos/hostname.lua +++ b/shellex/hostname.lua @@ -1,6 +1,6 @@ local os = _G.os -local shell = require("openos.shell") +local shell = require("shellex.shell") local args = shell.parse(...) local hostname = args[1] diff --git a/openos/less.lua b/shellex/less.lua similarity index 94% rename from openos/less.lua rename to shellex/less.lua index 9bf882f..bc5d390 100644 --- a/openos/less.lua +++ b/shellex/less.lua @@ -1,7 +1,7 @@ -local keys = require("openos.keyboard").keys -local shell = require("openos.shell") -local unicode = require("openos.unicode") -local term = require("openos.term") -- using term for negative scroll feature +local keys = require("shellex.keyboard").keys +local shell = require("shellex.shell") +local unicode = require("shellex.unicode") +local term = require("shellex.term") -- using term for negative scroll feature local args, ops = shell.parse(...) if #args > 1 then diff --git a/openos/ln.lua b/shellex/ln.lua similarity index 90% rename from openos/ln.lua rename to shellex/ln.lua index 0dbc0fa..7b5e8c3 100644 --- a/openos/ln.lua +++ b/shellex/ln.lua @@ -1,5 +1,5 @@ -local fs = require("openos.filesystem") -local shell = require("openos.shell") +local fs = require("shellex.filesystem") +local shell = require("shellex.shell") local args = shell.parse(...) if #args == 0 then diff --git a/openos/ls.lua b/shellex/ls.lua similarity index 93% rename from openos/ls.lua rename to shellex/ls.lua index 083f76f..ec00d26 100644 --- a/openos/ls.lua +++ b/shellex/ls.lua @@ -1,9 +1,10 @@ -local fs = require("openos.filesystem") -local shell = require("openos.shell") -local tty = require("openos.tty") -local unicode = require("openos.unicode") -local tx = require("openos.transforms") -local text = require("openos.text") +local fs = require("shellex.filesystem") +local glob = require('shellex.glob') +local shell = require("shellex.shell") +local tty = require("shellex.tty") +local unicode = require("shellex.unicode") +local tx = require("shellex.transforms") +local text = require("shellex.text") local dirsArg, ops = shell.parse(...) @@ -42,7 +43,6 @@ local function stat(names, index) end local info = {} info.key = name -info._path = name info.path = name:sub(1, 1) == "/" and "" or names.path info.full_path = fs.concat(info.path, name) info.isDir = fs.isDirectory(info.full_path) @@ -248,7 +248,6 @@ local function display(names) local info = stat(names, index) local file_type = info.isLink and 'l' or info.isDir and 'd' or 'f' local link_target = info.isLink and string.format(" -> %s", info.link:gsub("/+$", "") .. (info.isDir and "/" or "")) or "" -_G._p = info local write_mode = info.fs.isReadOnly() and '-' or 'w' local size = formatSize(info.size) local format = "%s-r%s %+"..tostring(max_size_width)..'s ' @@ -345,6 +344,7 @@ local function displayDirList(dirs) end end end +--[[ local dir_set, file_set = {}, {path=shell.getWorkingDirectory()} for _,dir in ipairs(dirsArg) do local path = shell.resolve(dir) @@ -360,6 +360,23 @@ for _,dir in ipairs(dirsArg) do table.insert(file_set, dir) end end +]] +local dir_set, file_set = {}, {path=shell.getWorkingDirectory()} +for _,dir in ipairs(dirsArg) do + local path = shell.resolve(dir) + if fs.isDirectory(path) then + table.insert(dir_set, dir) + else + local files = glob.matches(shell.getWorkingDirectory(), dir) + for _, v in pairs(files) do + table.insert(file_set, v) + end + if #files == 0 then + local access_msg = "cannot access " .. tostring(dir) .. ": " + perr(access_msg .. "No such file or directory") + end + end +end io.output():setvbuf("line") diff --git a/openos/mv.lua b/shellex/mv.lua similarity index 90% rename from openos/mv.lua rename to shellex/mv.lua index a50acc9..b70a417 100644 --- a/openos/mv.lua +++ b/shellex/mv.lua @@ -1,5 +1,5 @@ -local shell = require("openos.shell") -local transfer = require("openos.transfer") +local shell = require("shellex.shell") +local transfer = require("shellex.transfer") local args, options = shell.parse(...) options.h = options.h or options.help diff --git a/openos/rm.lua b/shellex/rm.lua similarity index 90% rename from openos/rm.lua rename to shellex/rm.lua index fa7ed17..b019c1e 100644 --- a/openos/rm.lua +++ b/shellex/rm.lua @@ -1,5 +1,6 @@ -local fs = require("openos.filesystem") -local shell = require("openos.shell") +local fs = require("shellex.filesystem") +local glob = require('shellex.glob') +local shell = require("shellex.shell") local function usage() print("Usage: rm [options] [ [...]]"..[[ @@ -40,14 +41,14 @@ local function pout(...) end local metas = {} +local remove -- promptLevel 3 done before fs.exists -- promptLevel 1 asks for each, displaying fs.exists on hit as it visits local function _path(m) return shell.resolve(m.rel) end -local function _link(m) return fs.isLink(_path(m)) end -local function _exists(m) return _link(m) or fs.exists(_path(m)) end -local function _dir(m) return not _link(m) and fs.isDirectory(_path(m)) end +local function _exists(m) return fs.exists(_path(m)) end +local function _dir(m) return fs.isDirectory(_path(m)) end local function _readonly(m) return not _exists(m) or fs.get(_path(m)).isReadOnly() end local function _empty(m) return _exists(m) and _dir(m) and (fs.list(_path(m))==nil) end @@ -94,7 +95,7 @@ local function remove_all(parent) return all_ok end -local function remove(meta) +remove = function(meta) if not remove_all(meta) then return false end @@ -140,7 +141,10 @@ local function remove(meta) end for _,arg in ipairs(args) do - metas[#metas+1] = createMeta(arg, arg) + local files = glob.matches(shell.getWorkingDirectory(), arg) + for _, v in pairs(files) do + metas[#metas+1] = createMeta(v, v) + end end if promptLevel == 3 and #metas > 3 then diff --git a/openos/rmdir.lua b/shellex/rmdir.lua similarity index 95% rename from openos/rmdir.lua rename to shellex/rmdir.lua index 1a11c27..21d3130 100644 --- a/openos/rmdir.lua +++ b/shellex/rmdir.lua @@ -1,6 +1,6 @@ -local shell = require("openos.shell") -local fs = require("openos.filesystem") -local text = require("openos.text") +local shell = require("shellex.shell") +local fs = require("shellex.filesystem") +local text = require("shellex.text") local args, options = shell.parse(...) diff --git a/openos/time.lua b/shellex/time.lua similarity index 85% rename from openos/time.lua rename to shellex/time.lua index 0b9fa79..7abfb2b 100644 --- a/openos/time.lua +++ b/shellex/time.lua @@ -1,5 +1,5 @@ -local computer = require('openos.computer') -local sh = require('openos.sh') +local computer = require('shellex.computer') +local sh = require('shellex.sh') local real_before, cpu_before = computer.uptime(), os.clock() local cmd_result = 0 diff --git a/openos/touch.lua b/shellex/touch.lua similarity index 93% rename from openos/touch.lua rename to shellex/touch.lua index 8f4f094..ff5a84f 100644 --- a/openos/touch.lua +++ b/shellex/touch.lua @@ -1,6 +1,6 @@ --[[Lua implementation of the UN*X touch command--]] -local shell = require("openos.shell") -local fs = require("openos.filesystem") +local shell = require("shellex.shell") +local fs = require("shellex.filesystem") local args, options = shell.parse(...) diff --git a/openos/which.lua b/shellex/which.lua similarity index 91% rename from openos/which.lua rename to shellex/which.lua index fed369c..828ddc2 100644 --- a/openos/which.lua +++ b/shellex/which.lua @@ -1,4 +1,4 @@ -local shell = require("openos.shell") +local shell = require("shellex.shell") local args = shell.parse(...) if #args == 0 then