mirror of
https://github.com/Hilbis/Hilbish
synced 2025-07-09 04:22:03 +00:00
major rewrite which changes the library hilbish uses for it's lua vm this one implements lua 5.4, and since that's a major version bump, it's a breaking change. introduced here also is a fix for `hilbish.login` not being the right value * refactor: start work on lua 5.4 lots of commented out code ive found a go lua library which implements lua 5.4 and found an opportunity to start working on it. this commit basically removes everything and just leaves enough for the shell to be "usable" and able to start. there are no builtins or libraries (besides the `hilbish` global) * fix: call cont next in prompt function this continues execution of lua, very obvious fixes an issue with code stopping at the prompt function * fix: handle errors in user config * fix: handle panic in lua input if it is incorrect * feat: implement bait * refactor: use util funcs to run lua where possible * refactor: move arg handle function to util * feat: implement commander * feat: implement fs * feat: add hilbish module functions used by prelude * chore: use custom fork of golua * fix: make sure args to setenv are strings in prelude * feat: implement completions * chore: remove comment * feat: implement terminal * feat: implement hilbish.interval * chore: update lunacolors * chore: update golua * feat: implement aliases * feat: add input mode * feat: implement runner mode * style: use comma separated cases instead of fallthrough * feat: implement syntax highlight and hints * chore: add comments to document util functions * chore: fix dofile comment doc * refactor: make loader functions for go modules unexported * feat: implement job management * feat: add hilbish properties * feat: implement all hilbish module functions * feat: implement history interface * feat: add completion interface * feat: add module description docs * feat: implement os interface * refactor: use hlalias for add function in hilbish.alias interface * feat: make it so hilbish.run can return command output * fix: set hilbish.exitCode to last command exit code * fix(ansikit): flush on io.write * fix: deregister commander if return isnt number * feat: run script when provided path * fix: read file manually in DoFile to avoid shebang * chore: add comment for reason of unreading byte * fix: remove prelude error printing * fix: add names at chunk load for context in errors * fix: add newline at the beginning of file buffer when there is shebang this makes the line count in error messages line up properly * fix: remove extra newline after error
273 lines
6.8 KiB
Lua
273 lines
6.8 KiB
Lua
-- The preload file initializes everything else for our shell
|
|
local ansikit = require 'ansikit'
|
|
local bait = require 'bait'
|
|
local commander = require 'commander'
|
|
local fs = require 'fs'
|
|
local lunacolors = require 'lunacolors'
|
|
local _ = require 'succulent' -- Function additions
|
|
local oldDir = hilbish.cwd()
|
|
|
|
local shlvl = tonumber(os.getenv 'SHLVL')
|
|
if shlvl ~= nil then os.setenv('SHLVL', tostring(shlvl + 1)) else os.setenv('SHLVL', '0') end
|
|
|
|
-- Builtins
|
|
local recentDirs = {}
|
|
commander.register('cd', function (args)
|
|
if #args > 0 then
|
|
local path = table.concat(args, ' '):gsub('$%$','\0'):gsub('${([%w_]+)}', os.getenv)
|
|
:gsub('$([%w_]+)', os.getenv):gsub('%z','$'):gsub('^%s*(.-)%s*$', '%1')
|
|
|
|
if path == '-' then
|
|
path = oldDir
|
|
print(path)
|
|
end
|
|
oldDir = hilbish.cwd()
|
|
|
|
local ok, err = pcall(function() fs.cd(path) end)
|
|
if not ok then
|
|
print(err:sub(17))
|
|
return 1
|
|
end
|
|
bait.throw('cd', path)
|
|
|
|
-- add to table of recent dirs
|
|
recentDirs[11] = nil
|
|
if recentDirs[#recentDirs - 1] ~= path then
|
|
table.insert(recentDirs, 1, path)
|
|
end
|
|
|
|
return
|
|
end
|
|
fs.cd(hilbish.home)
|
|
bait.throw('cd', hilbish.home)
|
|
|
|
table.insert(recentDirs, 1, hilbish.home)
|
|
recentDirs[11] = nil
|
|
end)
|
|
|
|
commander.register('exit', function()
|
|
bait.throw('hilbish.exit')
|
|
os.exit(0)
|
|
end)
|
|
|
|
commander.register('doc', function(args)
|
|
local moddocPath = hilbish.dataDir .. '/docs/'
|
|
local modDocFormat = [[
|
|
%s
|
|
%s
|
|
# Functions
|
|
]]
|
|
|
|
if #args > 0 then
|
|
local mod = args[1]
|
|
|
|
local f = io.open(moddocPath .. mod .. '.txt', 'rb')
|
|
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')
|
|
if not f then
|
|
print('No documentation found for ' .. mod .. '.')
|
|
return
|
|
end
|
|
funcdocs = f:read '*a'
|
|
local moddocs = table.filter(fs.readdir(moddocPath), function(f) return f ~= 'index.txt' end)
|
|
local subdocs = table.map(moddocs, function(fname)
|
|
return lunacolors.underline(lunacolors.blue(string.gsub(fname, '.txt', '')))
|
|
end)
|
|
if subdocName == 'index' then
|
|
funcdocs = funcdocs .. '\nSubdocs: ' .. table.concat(subdocs, ', ')
|
|
end
|
|
end
|
|
|
|
if not funcdocs then
|
|
funcdocs = f:read '*a'
|
|
end
|
|
local desc = ''
|
|
local ok = pcall(require, mod)
|
|
local backtickOccurence = 0
|
|
local formattedFuncs = lunacolors.format(funcdocs:sub(1, #funcdocs - 1):gsub('`', function()
|
|
backtickOccurence = backtickOccurence + 1
|
|
if backtickOccurence % 2 == 0 then
|
|
return '{reset}'
|
|
else
|
|
return '{underline}{green}'
|
|
end
|
|
end))
|
|
|
|
if ok then
|
|
local props = {}
|
|
local propstr = ''
|
|
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)
|
|
end
|
|
if #props > 0 then
|
|
propstr = '\n# Properties\n' .. table.concat(props, '\n') .. '\n'
|
|
end
|
|
desc = string.format(modDocFormat, modDesc, propstr)
|
|
end
|
|
print(desc .. formattedFuncs)
|
|
f:close()
|
|
|
|
return
|
|
end
|
|
local modules = table.map(fs.readdir(moddocPath), function(f)
|
|
return lunacolors.underline(lunacolors.blue(string.gsub(f, '.txt', '')))
|
|
end)
|
|
|
|
io.write [[
|
|
Welcome to Hilbish's doc tool! Here you can find documentation for builtin
|
|
functions and other things.
|
|
|
|
Usage: doc <section> [subdoc]
|
|
A section is a module or a literal section and a subdoc is a subsection for it.
|
|
|
|
Available sections: ]]
|
|
|
|
print(table.concat(modules, ', '))
|
|
end)
|
|
|
|
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).
|
|
|
|
And if this is your first time (most likely), you can copy a config
|
|
from ]] .. hilbish.dataDir,
|
|
[[
|
|
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)
|
|
|
|
do
|
|
local virt_G = { }
|
|
|
|
setmetatable(_G, {
|
|
__index = function (_, key)
|
|
local got_virt = virt_G[key]
|
|
if got_virt ~= nil then
|
|
return got_virt
|
|
end
|
|
|
|
virt_G[key] = os.getenv(key)
|
|
return virt_G[key]
|
|
end,
|
|
|
|
__newindex = function (_, key, value)
|
|
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,
|
|
})
|
|
|
|
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
|
|
|
|
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)
|
|
|
|
-- Hook handles
|
|
bait.catch('command.not-found', function(cmd)
|
|
print(string.format('hilbish: %s not found', cmd))
|
|
end)
|
|
|
|
bait.catch('command.not-executable', function(cmd)
|
|
print(string.format('hilbish: %s: not executable', cmd))
|
|
end)
|
|
|