2021-03-21 16:41:23 +00:00
|
|
|
-- The preload file initializes everything else for our shell
|
2022-03-06 18:45:06 +00:00
|
|
|
local ansikit = require 'ansikit'
|
2021-03-31 03:58:12 +00:00
|
|
|
local bait = require 'bait'
|
2021-12-04 21:50:04 +00:00
|
|
|
local commander = require 'commander'
|
|
|
|
local fs = require 'fs'
|
|
|
|
local lunacolors = require 'lunacolors'
|
2022-01-29 21:43:12 +00:00
|
|
|
local _ = require 'succulent' -- Function additions
|
2021-06-10 10:29:35 +00:00
|
|
|
local oldDir = hilbish.cwd()
|
2021-03-21 16:41:23 +00:00
|
|
|
|
2021-05-29 03:10:23 +00:00
|
|
|
local shlvl = tonumber(os.getenv 'SHLVL')
|
2022-04-04 10:40:02 +00:00
|
|
|
if shlvl ~= nil then os.setenv('SHLVL', tostring(shlvl + 1)) else os.setenv('SHLVL', '0') end
|
2021-05-29 03:10:23 +00:00
|
|
|
|
2021-05-19 01:04:49 +00:00
|
|
|
-- Builtins
|
2021-10-17 22:39:26 +00:00
|
|
|
local recentDirs = {}
|
2021-03-31 17:46:22 +00:00
|
|
|
commander.register('cd', function (args)
|
|
|
|
if #args > 0 then
|
2021-10-17 21:55:41 +00:00
|
|
|
local path = table.concat(args, ' '):gsub('$%$','\0'):gsub('${([%w_]+)}', os.getenv)
|
2021-10-08 13:49:57 +00:00
|
|
|
:gsub('$([%w_]+)', os.getenv):gsub('%z','$'):gsub('^%s*(.-)%s*$', '%1')
|
2021-03-31 17:46:22 +00:00
|
|
|
|
2021-05-27 22:23:15 +00:00
|
|
|
if path == '-' then
|
2021-06-10 10:29:35 +00:00
|
|
|
path = oldDir
|
2021-05-27 23:06:45 +00:00
|
|
|
print(path)
|
2021-05-27 22:23:15 +00:00
|
|
|
end
|
2021-06-10 10:29:35 +00:00
|
|
|
oldDir = hilbish.cwd()
|
2021-05-27 23:06:45 +00:00
|
|
|
|
2021-03-31 17:46:22 +00:00
|
|
|
local ok, err = pcall(function() fs.cd(path) end)
|
2021-03-31 03:58:12 +00:00
|
|
|
if not ok then
|
2021-10-17 21:55:41 +00:00
|
|
|
print(err:sub(17))
|
|
|
|
return 1
|
2021-05-11 22:55:22 +00:00
|
|
|
end
|
2021-06-14 22:11:07 +00:00
|
|
|
bait.throw('cd', path)
|
2021-10-17 22:39:26 +00:00
|
|
|
|
|
|
|
-- add to table of recent dirs
|
|
|
|
recentDirs[11] = nil
|
2022-02-24 01:16:16 +00:00
|
|
|
if recentDirs[#recentDirs - 1] ~= path then
|
|
|
|
table.insert(recentDirs, 1, path)
|
|
|
|
end
|
2021-10-17 22:39:26 +00:00
|
|
|
|
2021-03-31 03:59:59 +00:00
|
|
|
return
|
2021-03-21 16:41:23 +00:00
|
|
|
end
|
2021-06-14 22:12:12 +00:00
|
|
|
fs.cd(hilbish.home)
|
|
|
|
bait.throw('cd', hilbish.home)
|
2021-12-07 20:13:05 +00:00
|
|
|
|
|
|
|
table.insert(recentDirs, 1, hilbish.home)
|
|
|
|
recentDirs[11] = nil
|
2021-03-21 16:41:23 +00:00
|
|
|
end)
|
2021-04-03 20:08:04 +00:00
|
|
|
|
2021-04-05 19:21:44 +00:00
|
|
|
commander.register('exit', function()
|
2022-03-06 14:23:32 +00:00
|
|
|
bait.throw('hilbish.exit')
|
2021-04-05 19:21:44 +00:00
|
|
|
os.exit(0)
|
|
|
|
end)
|
|
|
|
|
2021-10-16 19:42:55 +00:00
|
|
|
commander.register('doc', function(args)
|
|
|
|
local moddocPath = hilbish.dataDir .. '/docs/'
|
2021-11-22 23:59:28 +00:00
|
|
|
local modDocFormat = [[
|
|
|
|
%s
|
|
|
|
%s
|
|
|
|
# Functions
|
|
|
|
]]
|
|
|
|
|
2021-10-16 19:42:55 +00:00
|
|
|
if #args > 0 then
|
2021-11-22 21:36:32 +00:00
|
|
|
local mod = args[1]
|
2021-10-16 19:42:55 +00:00
|
|
|
|
|
|
|
local f = io.open(moddocPath .. mod .. '.txt', 'rb')
|
2021-11-22 21:36:32 +00:00
|
|
|
local funcdocs = nil
|
|
|
|
if not f then
|
|
|
|
-- assume subdir
|
|
|
|
-- dataDir/docs/<mod>/<mod>.txt
|
|
|
|
moddocPath = moddocPath .. mod .. '/'
|
|
|
|
local subdocName = args[2]
|
|
|
|
if not subdocName then
|
|
|
|
subdocName = 'index'
|
|
|
|
end
|
|
|
|
f = io.open(moddocPath .. subdocName .. '.txt', 'rb')
|
2021-11-23 00:20:22 +00:00
|
|
|
if not f then
|
|
|
|
print('No documentation found for ' .. mod .. '.')
|
|
|
|
return
|
|
|
|
end
|
2021-11-22 21:36:32 +00:00
|
|
|
funcdocs = f:read '*a'
|
2021-12-07 20:24:55 +00:00
|
|
|
local moddocs = table.filter(fs.readdir(moddocPath), function(f) return f ~= 'index.txt' end)
|
|
|
|
local subdocs = table.map(moddocs, function(fname)
|
2021-12-04 21:53:34 +00:00
|
|
|
return lunacolors.underline(lunacolors.blue(string.gsub(fname, '.txt', '')))
|
2021-11-22 21:36:32 +00:00
|
|
|
end)
|
|
|
|
if subdocName == 'index' then
|
|
|
|
funcdocs = funcdocs .. '\nSubdocs: ' .. table.concat(subdocs, ', ')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-11-22 23:29:26 +00:00
|
|
|
if not funcdocs then
|
|
|
|
funcdocs = f:read '*a'
|
|
|
|
end
|
2021-11-22 21:36:32 +00:00
|
|
|
local desc = ''
|
|
|
|
local ok = pcall(require, mod)
|
2021-10-16 19:42:55 +00:00
|
|
|
local backtickOccurence = 0
|
2021-11-22 23:59:28 +00:00
|
|
|
local formattedFuncs = lunacolors.format(funcdocs:sub(1, #funcdocs - 1):gsub('`', function()
|
2021-10-16 19:42:55 +00:00
|
|
|
backtickOccurence = backtickOccurence + 1
|
|
|
|
if backtickOccurence % 2 == 0 then
|
|
|
|
return '{reset}'
|
|
|
|
else
|
2021-10-17 21:23:35 +00:00
|
|
|
return '{underline}{green}'
|
2021-10-16 19:42:55 +00:00
|
|
|
end
|
2021-11-22 23:59:28 +00:00
|
|
|
end))
|
|
|
|
|
2022-02-24 22:19:54 +00:00
|
|
|
if ok then
|
2021-11-23 00:20:57 +00:00
|
|
|
local props = {}
|
|
|
|
local propstr = ''
|
2022-02-24 22:19:54 +00:00
|
|
|
local modDesc = ''
|
|
|
|
local modmt = getmetatable(require(mod))
|
|
|
|
modDesc = modmt.__doc
|
|
|
|
if modmt.__docProp then
|
|
|
|
-- not all modules have docs for properties
|
|
|
|
props = table.map(modmt.__docProp, function(v, k)
|
|
|
|
return lunacolors.underline(lunacolors.blue(k)) .. ' > ' .. v
|
|
|
|
end)
|
2021-11-23 00:20:57 +00:00
|
|
|
end
|
|
|
|
if #props > 0 then
|
|
|
|
propstr = '\n# Properties\n' .. table.concat(props, '\n') .. '\n'
|
|
|
|
end
|
|
|
|
desc = string.format(modDocFormat, modDesc, propstr)
|
2021-11-22 23:59:28 +00:00
|
|
|
end
|
|
|
|
print(desc .. formattedFuncs)
|
2021-10-16 19:42:55 +00:00
|
|
|
f:close()
|
|
|
|
|
|
|
|
return
|
|
|
|
end
|
2021-10-17 22:09:42 +00:00
|
|
|
local modules = table.map(fs.readdir(moddocPath), function(f)
|
2021-11-22 21:36:32 +00:00
|
|
|
return lunacolors.underline(lunacolors.blue(string.gsub(f, '.txt', '')))
|
2021-10-17 22:09:42 +00:00
|
|
|
end)
|
2021-10-16 19:42:55 +00:00
|
|
|
|
|
|
|
io.write [[
|
|
|
|
Welcome to Hilbish's doc tool! Here you can find documentation for builtin
|
|
|
|
functions and other things.
|
|
|
|
|
2021-11-22 21:36:32 +00:00
|
|
|
Usage: doc <section> [subdoc]
|
|
|
|
A section is a module or a literal section and a subdoc is a subsection for it.
|
2021-10-16 19:42:55 +00:00
|
|
|
|
2021-11-22 21:36:32 +00:00
|
|
|
Available sections: ]]
|
2021-10-16 19:42:55 +00:00
|
|
|
|
2021-10-17 22:10:06 +00:00
|
|
|
print(table.concat(modules, ', '))
|
2021-10-16 19:42:55 +00:00
|
|
|
end)
|
|
|
|
|
2022-03-06 18:45:06 +00:00
|
|
|
local helpTexts = {
|
|
|
|
[[
|
|
|
|
Hello there! Welcome to Hilbish, the comfy and nice little shell for
|
|
|
|
Lua users and fans. Hilbish is configured with Lua, and its
|
|
|
|
scripts are also in Lua. It also runs both Lua and shell script when
|
|
|
|
interactive (aka normal usage).
|
|
|
|
]],
|
|
|
|
[[
|
|
|
|
What does that mean for you, the user? It means that if you prefer to
|
|
|
|
use Lua for scripting instead of shell script but still have ordinary
|
|
|
|
shell usage for interactive use.
|
|
|
|
]],
|
|
|
|
[[
|
|
|
|
If this is your first time using Hilbish and Lua, check out the
|
|
|
|
Programming in Lua book here: https://www.lua.org/pil
|
|
|
|
After (or if you already know Lua) check out the doc command.
|
|
|
|
It is an in shell tool for documentation about Hilbish provided
|
|
|
|
functions and modules.
|
|
|
|
]],
|
|
|
|
[[
|
|
|
|
If you've updated from a pre-1.0 version (0.7.1 as an example)
|
|
|
|
you'll want to move your config from ~/.hilbishrc.lua to
|
|
|
|
]] ..
|
|
|
|
hilbish.userDir.config .. '/hilbish/init.lua' ..
|
|
|
|
[[
|
|
|
|
|
|
|
|
and also change all global functions (prompt, alias) to be
|
|
|
|
in the hilbish module (hilbish.prompt, hilbish.alias as examples).
|
|
|
|
|
2022-03-19 13:50:51 +00:00
|
|
|
And if this is your first time (most likely), you can copy a config
|
|
|
|
from ]] .. hilbish.dataDir,
|
|
|
|
[[
|
2022-03-06 18:45:06 +00:00
|
|
|
Since 1.0 is a big release, you'll want to check the changelog
|
|
|
|
at https://github.com/Rosettea/Hilbish/releases/tag/v1.0.0
|
|
|
|
to find more breaking changes.
|
|
|
|
]]
|
|
|
|
}
|
|
|
|
commander.register('guide', function()
|
|
|
|
ansikit.clear()
|
|
|
|
ansikit.cursorTo(0, 0)
|
|
|
|
for _, text in ipairs(helpTexts) do
|
|
|
|
print(text)
|
|
|
|
local out = hilbish.read('Hit enter to continue ')
|
|
|
|
ansikit.clear()
|
|
|
|
ansikit.cursorTo(0, 0)
|
|
|
|
if not out then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
end
|
|
|
|
print 'Hope you enjoy using Hilbish!'
|
|
|
|
end)
|
|
|
|
|
2021-04-03 20:08:04 +00:00
|
|
|
do
|
|
|
|
local virt_G = { }
|
2021-06-09 22:41:37 +00:00
|
|
|
|
2021-04-03 20:08:04 +00:00
|
|
|
setmetatable(_G, {
|
2021-06-09 22:41:37 +00:00
|
|
|
__index = function (_, key)
|
2021-04-03 20:08:04 +00:00
|
|
|
local got_virt = virt_G[key]
|
|
|
|
if got_virt ~= nil then
|
|
|
|
return got_virt
|
|
|
|
end
|
2021-06-09 22:41:37 +00:00
|
|
|
|
2021-04-03 20:08:04 +00:00
|
|
|
virt_G[key] = os.getenv(key)
|
|
|
|
return virt_G[key]
|
|
|
|
end,
|
2021-06-09 22:41:37 +00:00
|
|
|
|
|
|
|
__newindex = function (_, key, value)
|
2021-04-03 20:08:04 +00:00
|
|
|
if type(value) == 'string' then
|
|
|
|
os.setenv(key, value)
|
|
|
|
virt_G[key] = value
|
|
|
|
else
|
|
|
|
if type(virt_G[key]) == 'string' then
|
|
|
|
os.setenv(key, '')
|
|
|
|
end
|
|
|
|
virt_G[key] = value
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
})
|
2021-06-09 22:41:37 +00:00
|
|
|
|
2021-04-03 20:08:04 +00:00
|
|
|
bait.catch('command.exit', function ()
|
|
|
|
for key, value in pairs(virt_G) do
|
|
|
|
if type(value) == 'string' then
|
|
|
|
virt_G[key] = os.getenv(key)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end)
|
|
|
|
end
|
2021-05-01 05:08:20 +00:00
|
|
|
|
2021-10-17 22:39:26 +00:00
|
|
|
commander.register('cdr', function(args)
|
|
|
|
if not args[1] then
|
|
|
|
print(lunacolors.format [[
|
|
|
|
cdr: change directory to one which has been recently visied
|
|
|
|
|
|
|
|
usage: cdr <index>
|
|
|
|
|
|
|
|
to get a list of recent directories, use {green}{underline}cdr list{reset}]])
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
if args[1] == 'list' then
|
|
|
|
if #recentDirs == 0 then
|
|
|
|
print 'No directories have been visited.'
|
|
|
|
return 1
|
|
|
|
end
|
|
|
|
print(table.concat(recentDirs, '\n'))
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
local index = tonumber(args[1])
|
|
|
|
if not index then
|
|
|
|
print(string.format('received %s as index, which isn\'t a number', index))
|
|
|
|
return 1
|
|
|
|
end
|
|
|
|
|
|
|
|
if not recentDirs[index] then
|
|
|
|
print(string.format('no recent directory found at index %s', index))
|
|
|
|
return 1
|
|
|
|
end
|
|
|
|
|
|
|
|
fs.cd(recentDirs[index])
|
|
|
|
end)
|
|
|
|
|
2021-05-19 01:04:49 +00:00
|
|
|
-- Hook handles
|
|
|
|
bait.catch('command.not-found', function(cmd)
|
|
|
|
print(string.format('hilbish: %s not found', cmd))
|
|
|
|
end)
|
|
|
|
|
2022-03-17 23:29:27 +00:00
|
|
|
bait.catch('command.not-executable', function(cmd)
|
|
|
|
print(string.format('hilbish: %s: not executable', cmd))
|
2021-11-21 23:45:44 +00:00
|
|
|
end)
|
|
|
|
|