refactor: (re)organize and change prelude path and structure

prelude is no longer. it is now nature.
organized the single file prelude into multiple
source files and renamed it to nature. this is coming
after thought that it can turn into a general hilbish
lua core, with user facing modules as well.

this introduces the `nature.dirs` module, to interact
and get recently changed to directories and last/old
cwd.
insensitive-tab^2
TorchedSammy 2022-04-22 23:56:57 -04:00
parent f003249632
commit 9e596dc271
Signed by: sammyette
GPG Key ID: 904FC49417B44DCD
15 changed files with 369 additions and 270 deletions

View File

@ -15,7 +15,7 @@ build:
install:
install -v -d "$(DESTDIR)$(BINDIR)/" && install -m 0755 -v hilbish "$(DESTDIR)$(BINDIR)/hilbish"
mkdir -p "$(DESTDIR)$(LIBDIR)"
cp -r libs docs emmyLuaDocs prelude .hilbishrc.lua "$(DESTDIR)$(LIBDIR)"
cp -r libs docs emmyLuaDocs nature .hilbishrc.lua "$(DESTDIR)$(LIBDIR)"
grep -qxF "$(DESTDIR)$(BINDIR)/hilbish" /etc/shells || echo "$(DESTDIR)$(BINDIR)/hilbish" >> /etc/shells
uninstall:

2
lua.go
View File

@ -54,7 +54,7 @@ func luaInit() {
fmt.Fprintln(os.Stderr, "Could not add preload paths! Libraries will be missing. This shouldn't happen.")
}
err = util.DoFile(l, "prelude/init.lua")
err = util.DoFile(l, "nature/init.lua")
if err != nil {
err = util.DoFile(l, preloadPath)
if err != nil {

View File

@ -0,0 +1,35 @@
local bait = require 'bait'
local commander = require 'commander'
local fs = require 'fs'
local dirs = require 'nature.dirs'
dirs.old = hilbish.cwd()
commander.register('cd', function (args)
if #args > 1 then
print("cd: too many arguments")
return 1
elseif #args > 0 then
local path = args[1]:gsub('$%$','\0'):gsub('${([%w_]+)}', os.getenv)
:gsub('$([%w_]+)', os.getenv):gsub('%z','$'):gsub('^%s*(.-)%s*$', '%1')
if path == '-' then
path = dirs.old
print(path)
end
dirs.setOld(hilbish.cwd())
dirs.push(path)
local ok, err = pcall(function() fs.cd(path) end)
if not ok then
print(err)
return 1
end
bait.throw('cd', path)
return
end
fs.cd(hilbish.home)
bait.throw('cd', hilbish.home)
dirs.addRecent(hilbish.home)
end)

View File

@ -0,0 +1,39 @@
local commander = require 'commander'
local fs = require 'fs'
local lunacolors = require 'lunacolors'
local dirs = require 'nature.dirs'
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
local recentDirs = dirs.recentDirs
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 dirs.recent(index) then
print(string.format('No recent directory found at index %s.', index))
return 1
end
fs.cd(dirs.recent(index))
end)

View File

@ -0,0 +1,93 @@
local commander = require 'commander'
local fs = require 'fs'
local lunacolors = require 'lunacolors'
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: ]]
io.flush()
print(table.concat(modules, ', '))
end)

View File

@ -0,0 +1,7 @@
local bait = require 'bait'
local commander = require 'commander'
commander.register('exit', function()
bait.throw('hilbish.exit')
os.exit(0)
end)

View File

@ -0,0 +1,54 @@
local ansikit = require 'ansikit'
local commander = require 'commander'
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)

View File

@ -0,0 +1,6 @@
-- Add command builtins
require 'nature.commands.cd'
require 'nature.commands.cdr'
require 'nature.commands.doc'
require 'nature.commands.exit'
require 'nature.commands.guide'

75
nature/dirs.lua 100644
View File

@ -0,0 +1,75 @@
local fs = require 'fs'
local dirs = {}
--- Last (current working) directory. Separate from recentDirs mainly for
--- easier use.
dirs.old = ''
--- Table of recent directories. For use, look at public functions.
dirs.recentDirs = {}
--- Size of the recentDirs table.
dirs.recentSize = 10
--- Get (and remove) a `num` of entries from recent directories.
--- @param num number
--- @param remove boolean Whether to remove items
function dirRecents(num, remove)
num = num or 1
local entries = {}
if #dirs.recentDirs ~= 0 then
for i = 1, num do
local idx = remove and 1 or i
if not dirs.recentDirs[idx] then break end
table.insert(entries, dirs.recentDirs[idx])
if remove then table.remove(dirs.recentDirs, 1) end
end
end
if #entries == 1 then
return entries[1]
end
return entries
end
--- Look at `num` amount of recent directories, starting from the latest.
--- @param num? number
function dirs.peak(num)
return dirRecents(num)
end
--- Add `d` to the recent directories.
function dirs.push(d)
dirs.recentDirs[dirs.recentSize + 1] = nil
if dirs.recentDirs[#dirs.recentDirs - 1] ~= d then
ok, d = pcall(fs.abs, d)
assert(ok, 'could not turn "' .. d .. '"into an absolute path')
table.insert(dirs.recentDirs, 1, d)
end
end
--- Remove `num` amount of dirs from the recent directories.
--- @param num number
function dirs.pop(num)
return dirRecents(num, true)
end
--- Get entry from recent directories.
--- @param idx number
function dirs.recent(idx)
return dirs.recentDirs[idx]
end
--- Sets the old directory.
--- @param d string
function dirs.setOld(d)
ok, d = pcall(fs.abs, d)
assert(ok, 'could not turn "' .. d .. '"into an absolute path')
os.setenv('OLDPWD', d)
dirs.old = d
end
return dirs

11
nature/hooks.lua 100644
View File

@ -0,0 +1,11 @@
local bait = require 'bait'
-- 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)

44
nature/init.lua 100644
View File

@ -0,0 +1,44 @@
-- Prelude initializes everything else for our shell
local _ = require 'succulent' -- Function additions
package.path = package.path .. ';' .. hilbish.dataDir .. '/?/init.lua'
.. ';' .. hilbish.dataDir .. '/?/?.lua'
require 'nature.hooks'
require 'nature.commands'
local shlvl = tonumber(os.getenv 'SHLVL')
if shlvl ~= nil then
os.setenv('SHLVL', tostring(shlvl + 1))
else
os.setenv('SHLVL', '0')
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,
})
end

View File

@ -1,265 +0,0 @@
-- 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: ]]
io.flush()
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,
})
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)

View File

@ -15,7 +15,7 @@ var (
.. hilbish.userDir.config .. '/hilbish/?/?.lua;'
.. hilbish.userDir.config .. '/hilbish/?.lua'`
dataDir = "/usr/local/share/hilbish"
preloadPath = dataDir + "/prelude/init.lua"
preloadPath = dataDir + "/nature/init.lua"
sampleConfPath = dataDir + "/.hilbishrc.lua" // Path to default/sample config
defaultConfDir = getenv("XDG_CONFIG_HOME", "~/.config")
)

View File

@ -15,7 +15,7 @@ var (
.. hilbish.userDir.config .. '/hilbish/?/?.lua;'
.. hilbish.userDir.config .. '/hilbish/?.lua'`
dataDir = "/usr/share/hilbish"
preloadPath = dataDir + "/prelude/init.lua"
preloadPath = dataDir + "/nature/init.lua"
sampleConfPath = dataDir + "/.hilbishrc.lua" // Path to default/sample config
defaultConfDir = ""
)

View File

@ -9,7 +9,7 @@ var (
.. hilbish.userDir.config .. '\\Hilbish\\libs\\?\\?.lua;'
.. hilbish.userDir.config .. '\\Hilbish\\libs\\?.lua;'`
dataDir = "~\\Appdata\\Roaming\\Hilbish" // ~ and \ gonna cry?
preloadPath = dataDir + "\\prelude\\init.lua"
preloadPath = dataDir + "\\nature\\init.lua"
sampleConfPath = dataDir + "\\hilbishrc.lua" // Path to default/sample config
defaultConfDir = ""
)