Compare commits

...

20 Commits

Author SHA1 Message Date
sammy 6bb2a2f8c8
chore: make login message use less lines in code 2021-05-01 16:28:43 -04:00
sammy 8242e0bfc9
fix: use lunacolors instead of ansikit 2021-05-01 16:18:11 -04:00
sammy 69883c6b73
docs: add --recursive flag to git clone 2021-05-01 16:07:39 -04:00
sammy 4d38b913f1
feat: add lunacolors library 2021-05-01 16:05:02 -04:00
sammy 32dea836d5
fix!: remove format function from ansikit
BREAKING CHANGE: this function has been moved to
Lunacolors. Hilbish users will now be using that
separate library for colors, while ansikit will be for
other terminal codes and things
2021-05-01 16:01:42 -04:00
sammy 6e3f1e1b97
fix: add additional lua import path 2021-05-01 15:56:08 -04:00
sammy c43aab6a60
fix: make appendPath expand ~ to home dir 2021-05-01 15:35:43 -04:00
sammy 9934ba417f
chore: bump to 0.4 2021-05-01 14:57:20 -04:00
sammy a75100d15d
feat: add _user variable
this will probably change to a better global var in the
future, but it's `_user` now.
this provides a simple, guaranteed way of getting the
current user's name
$USER (in?)correctly shows the previous user when
`su` is used, _user will always be root in this case
2021-05-01 14:51:57 -04:00
sammy 60b1b50bb3
feat: add multiline hook (resolves #19) 2021-05-01 14:25:58 -04:00
sammy f00063beaa
chore: bump version 2021-05-01 14:17:33 -04:00
sammy 7f8d8db53e
fix: errors and make login rc run before config 2021-05-01 14:17:14 -04:00
sammy 38f1d62598
feat: make hilbish act like a login shell
when a user logs in with hilbish as the user shell,
or -l/--login is passed
resolves #37
2021-05-01 14:08:42 -04:00
sammy e580112e1b
refactor: use lua.Check<Type> where possible (resolves #40) 2021-05-01 13:42:15 -04:00
sammy d2a44c70c0
chore: remove redundant module renaming 2021-05-01 13:38:01 -04:00
sammy 447775f8c4
chore: bump version 2021-05-01 13:33:05 -04:00
sammy 338b45227c
chore: merge from master 2021-05-01 13:32:09 -04:00
sammy 80029cfff3
feat: make cd builtin work with env variables (resolves #43) 2021-05-01 13:31:51 -04:00
Brandon Wright d653a9c349
fix: newline near contributors imgs (#45) 2021-05-01 12:05:54 -05:00
sammy 9b3f8e818c
style: add space between binary op 2021-05-01 11:55:09 -04:00
11 changed files with 73 additions and 78 deletions

3
.gitmodules vendored 100644
View File

@ -0,0 +1,3 @@
[submodule "libs/lunacolors"]
path = libs/lunacolors
url = https://github.com/Hilbis/Lunacolors

View File

@ -1,16 +1,15 @@
-- Default Hilbish config -- Default Hilbish config
ansikit = require 'ansikit' lunacolors = require 'lunacolors'
bait = require 'bait' bait = require 'bait'
function doPrompt(fail) function doPrompt(fail)
prompt(ansikit.format( prompt(lunacolors.format(
'{blue}%u {cyan}%d ' .. (fail and '{red}' or '{green}') .. '{reset} ' '{blue}%u {cyan}%d ' .. (fail and '{red}' or '{green}') .. ' '
)) ))
end end
print(ansikit.format('Welcome to {magenta}Hilbish{reset}, {cyan}' .. print(lunacolors.format('Welcome to {magenta}Hilbish{reset}, {cyan}' .. _user ..
os.getenv 'USER' .. '{reset}.\n' .. '{reset}.\n' .. 'The nice lil shell for {blue}Lua{reset} fanatics!\n'))
'The nice lil shell for {blue}Lua{reset} fanatics!\n'))
doPrompt() doPrompt()

View File

@ -52,7 +52,7 @@ sudo zypper install readline-devel
### Install ### Install
```sh ```sh
git clone https://github.com/Hilbis/Hilbish git clone --recursive https://github.com/Hilbis/Hilbish
cd Hilbish cd Hilbish
make build make build
sudo make install sudo make install
@ -80,6 +80,7 @@ Make sure to read [CONTRIBUTING.md](CONTRIBUTING.md) before getting started.
### Special Thanks To ### Special Thanks To
Everyone here who has contributed: Everyone here who has contributed:
<a href="https://github.com/Hilbis/Hilbish/graphs/contributors"> <a href="https://github.com/Hilbis/Hilbish/graphs/contributors">
<img src="https://contrib.rocks/image?repo=Hilbis/Hilbish" /> <img src="https://contrib.rocks/image?repo=Hilbis/Hilbish" />
</a> </a>

View File

@ -29,8 +29,8 @@ func (c *Commander) Loader(L *lua.LState) int {
} }
func (c *Commander) register(L *lua.LState) int { func (c *Commander) register(L *lua.LState) int {
cmdName := L.ToString(1) cmdName := L.CheckString(1)
cmd := L.ToFunction(2) cmd := L.CheckFunction(2)
c.Events.Emit("commandRegister", cmdName, cmd) c.Events.Emit("commandRegister", cmdName, cmd)

View File

@ -4,8 +4,8 @@ import (
"os" "os"
"strings" "strings"
lua "github.com/yuin/gopher-lua" "github.com/yuin/gopher-lua"
luar "layeh.com/gopher-luar" "layeh.com/gopher-luar"
) )
func Loader(L *lua.LState) int { func Loader(L *lua.LState) int {
@ -27,7 +27,7 @@ var exports = map[string]lua.LGFunction{
} }
func cd(L *lua.LState) int { func cd(L *lua.LState) int {
path := L.ToString(1) path := L.CheckString(1)
err := os.Chdir(strings.TrimSpace(path)) err := os.Chdir(strings.TrimSpace(path))
if err != nil { if err != nil {
@ -41,7 +41,7 @@ func cd(L *lua.LState) int {
} }
func mkdir(L *lua.LState) int { func mkdir(L *lua.LState) int {
dirname := L.ToString(1) dirname := L.CheckString(1)
// TODO: handle error here // TODO: handle error here
os.Mkdir(strings.TrimSpace(dirname), 0744) os.Mkdir(strings.TrimSpace(dirname), 0744)
@ -50,7 +50,7 @@ func mkdir(L *lua.LState) int {
} }
func stat(L *lua.LState) int { func stat(L *lua.LState) int {
path := L.ToString(1) path := L.CheckString(1)
// TODO: handle error here // TODO: handle error here
pathinfo, _ := os.Stat(path) pathinfo, _ := os.Stat(path)

View File

@ -61,49 +61,6 @@ ansikit.cursorUp = function(y)
return ansikit.printCSI(y, 'A') return ansikit.printCSI(y, 'A')
end end
ansikit.format = function(text)
local colors = {
-- TODO: write codes manually instead of using functions
-- less function calls = faster ????????
reset = {'{reset}', ansikit.getCSI(0)},
bold = {'{bold}', ansikit.getCSI(1)},
dim = {'{dim}', ansikit.getCSI(2)},
italic = {'{italic}', ansikit.getCSI(3)},
underline = {'{underline}', ansikit.getCSI(4)},
invert = {'{invert}', ansikit.getCSI(7)},
bold_off = {'{bold-off}', ansikit.getCSI(22)},
underline_off = {'{underline-off}', ansikit.getCSI(24)},
black = {'{black}', ansikit.getCSI(30)},
red = {'{red}', ansikit.getCSI(31)},
green = {'{green}', ansikit.getCSI(32)},
yellow = {'{yellow}', ansikit.getCSI(33)},
blue = {'{blue}', ansikit.getCSI(34)},
magenta = {'{magenta}', ansikit.getCSI(35)},
cyan = {'{cyan}', ansikit.getCSI(36)},
white = {'{white}', ansikit.getCSI(37)},
red_bg = {'{red-bg}', ansikit.getCSI(41)},
green_bg = {'{green-bg}', ansikit.getCSI(42)},
yellow_bg = {'{green-bg}', ansikit.getCSI(43)},
blue_bg = {'{blue-bg}', ansikit.getCSI(44)},
magenta_bg = {'{magenta-bg}', ansikit.getCSI(45)},
cyan_bg = {'{cyan-bg}', ansikit.getCSI(46)},
white_bg = {'{white-bg}', ansikit.getCSI(47)},
gray = {'{gray}', ansikit.getCSI(90)},
bright_red = {'{bright-red}', ansikit.getCSI(91)},
bright_green = {'{bright-green}', ansikit.getCSI(92)},
bright_yellow = {'{bright-yellow}', ansikit.getCSI(93)},
bright_blue = {'{bright-blue}', ansikit.getCSI(94)},
bright_magenta = {'{bright-magenta}', ansikit.getCSI(95)},
bright_cyan = {'{bright-cyan}', ansikit.getCSI(96)}
}
for k, v in pairs(colors) do
text = text:gsub(v[1], v[2])
end
return text
end
ansikit.getCode = function(code, terminate) ansikit.getCode = function(code, terminate)
return string.char(0x001b) .. code .. return string.char(0x001b) .. code ..
(terminate and string.char(0x001b) .. '\\' or '') (terminate and string.char(0x001b) .. '\\' or '')

1
libs/lunacolors 160000

@ -0,0 +1 @@
Subproject commit 004bca95d6e848f03e237c46127286f8f064bebc

39
lua.go
View File

@ -2,10 +2,12 @@ package main
import ( import (
"fmt" "fmt"
"os"
"strings"
"hilbish/golibs/bait" "hilbish/golibs/bait"
"hilbish/golibs/commander" "hilbish/golibs/commander"
"hilbish/golibs/fs" "hilbish/golibs/fs"
"os"
"github.com/yuin/gopher-lua" "github.com/yuin/gopher-lua"
) )
@ -17,12 +19,13 @@ prompt(ansikit.format(
)) ))
` `
func LuaInit(confpath string) { func LuaInit() {
l = lua.NewState() l = lua.NewState()
l.OpenLibs() l.OpenLibs()
l.SetGlobal("_ver", lua.LString(version)) l.SetGlobal("_ver", lua.LString(version))
l.SetGlobal("_user", lua.LString(curuser.Username))
l.SetGlobal("prompt", l.NewFunction(hshprompt)) l.SetGlobal("prompt", l.NewFunction(hshprompt))
l.SetGlobal("multiprompt", l.NewFunction(hshmlprompt)) l.SetGlobal("multiprompt", l.NewFunction(hshmlprompt))
@ -53,6 +56,7 @@ func LuaInit(confpath string) {
l.DoString(`package.path = package.path l.DoString(`package.path = package.path
.. ';./libs/?/init.lua;./?/init.lua;./?/?.lua' .. ';./libs/?/init.lua;./?/init.lua;./?/?.lua'
.. ';/usr/share/hilbish/libs/?/init.lua;' .. ';/usr/share/hilbish/libs/?/init.lua;'
.. ';/usr/share/hilbish/libs/?/?.lua;'
.. os.getenv 'HOME' .. '/.local/share/hilbish/libs/?/init.lua;' .. os.getenv 'HOME' .. '/.local/share/hilbish/libs/?/init.lua;'
.. os.getenv 'HOME' .. '/.local/share/hilbish/libs/?/?.lua;' .. os.getenv 'HOME' .. '/.local/share/hilbish/libs/?/?.lua;'
.. os.getenv 'HOME' .. '/.local/share/hilbish/libs/?.lua' .. os.getenv 'HOME' .. '/.local/share/hilbish/libs/?.lua'
@ -66,12 +70,12 @@ func LuaInit(confpath string) {
"Missing preload file, builtins may be missing.") "Missing preload file, builtins may be missing.")
} }
} }
}
// Run config func RunConfig(confpath string) {
if !interactive { if !interactive {
return return
} }
err = l.DoFile(confpath) err := l.DoFile(confpath)
if err != nil { if err != nil {
fmt.Fprintln(os.Stderr, err, fmt.Fprintln(os.Stderr, err,
"\nAn error has occured while loading your config! Falling back to minimal default config.\n") "\nAn error has occured while loading your config! Falling back to minimal default config.\n")
@ -80,21 +84,35 @@ func LuaInit(confpath string) {
} }
} }
func RunLogin() {
if _, err := os.Stat(homedir + "/.hprofile.lua"); os.IsNotExist(err) {
return
}
if !login {
return
}
err := l.DoFile(homedir + "/.hprofile.lua")
if err != nil {
fmt.Fprintln(os.Stderr, err,
"\nAn error has occured while loading your login config!n")
}
}
func hshprompt(L *lua.LState) int { func hshprompt(L *lua.LState) int {
prompt = L.ToString(1) prompt = L.CheckString(1)
return 0 return 0
} }
func hshmlprompt(L *lua.LState) int { func hshmlprompt(L *lua.LState) int {
multilinePrompt = L.ToString(1) multilinePrompt = L.CheckString(1)
return 0 return 0
} }
func hshalias(L *lua.LState) int { func hshalias(L *lua.LState) int {
alias := L.ToString(1) alias := L.CheckString(1)
source := L.ToString(2) source := L.CheckString(2)
aliases[alias] = source aliases[alias] = source
@ -102,7 +120,8 @@ func hshalias(L *lua.LState) int {
} }
func hshappendPath(L *lua.LState) int { func hshappendPath(L *lua.LState) int {
path := L.ToString(1) path := L.CheckString(1)
path = strings.Replace(path, "~", curuser.HomeDir, 1)
os.Setenv("PATH", os.Getenv("PATH") + ":" + path) os.Setenv("PATH", os.Getenv("PATH") + ":" + path)

33
main.go
View File

@ -4,9 +4,10 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
"strings"
"os/signal" "os/signal"
"os/user" "os/user"
"strings" "path/filepath"
"hilbish/golibs/bait" "hilbish/golibs/bait"
@ -16,26 +17,29 @@ import (
"golang.org/x/term" "golang.org/x/term"
) )
const version = "0.4.0-dev.6" const version = "0.4.0"
var ( var (
l *lua.LState l *lua.LState
// User's prompt, this will get set when lua side is initialized prompt string // User's prompt, this will get set when lua side is initialized
prompt string
multilinePrompt = "> " multilinePrompt = "> "
commands = map[string]bool{} commands = map[string]bool{}
aliases = map[string]string{} aliases = map[string]string{}
hooks bait.Bait
homedir string homedir string
running bool curuser *user.User
running bool // Is a command currently running
hooks bait.Bait
interactive bool interactive bool
login bool // Are we the login shell?
) )
func main() { func main() {
homedir, _ = os.UserHomeDir() homedir, _ = os.UserHomeDir()
curuser, _ = user.Current()
defaultconfpath := homedir + "/.hilbishrc.lua" defaultconfpath := homedir + "/.hilbishrc.lua"
// parser := argparse.NewParser("hilbish", "A shell for lua and flower lovers") // parser := argparse.NewParser("hilbish", "A shell for lua and flower lovers")
@ -49,6 +53,7 @@ func main() {
_ = getopt.BoolLong("interactive", 'i', "Force Hilbish to be an interactive shell") _ = getopt.BoolLong("interactive", 'i', "Force Hilbish to be an interactive shell")
getopt.Parse() getopt.Parse()
loginshflag := getopt.Lookup('l').Seen()
interactiveflag := getopt.Lookup('i').Seen() interactiveflag := getopt.Lookup('i').Seen()
if *cmdflag == "" || interactiveflag { if *cmdflag == "" || interactiveflag {
@ -59,6 +64,11 @@ func main() {
interactive = false interactive = false
} }
// first arg, first character
if loginshflag || os.Args[0][0] == '-' {
login = true
}
if *verflag { if *verflag {
fmt.Printf("Hilbish v%s\n", version) fmt.Printf("Hilbish v%s\n", version)
os.Exit(0) os.Exit(0)
@ -94,7 +104,9 @@ func main() {
} }
go HandleSignals() go HandleSignals()
LuaInit(*configflag) LuaInit()
RunLogin()
RunConfig(*configflag)
readline.Completer = readline.FilenameCompleter readline.Completer = readline.FilenameCompleter
readline.LoadHistory(homedir + "/.hilbish-history") readline.LoadHistory(homedir + "/.hilbish-history")
@ -148,6 +160,7 @@ func main() {
} }
func ContinuePrompt(prev string) (string, error) { func ContinuePrompt(prev string) (string, error) {
hooks.Em.Emit("multiline", nil)
cont, err := readline.String(multilinePrompt) cont, err := readline.String(multilinePrompt)
if err != nil { if err != nil {
fmt.Println("") fmt.Println("")
@ -160,16 +173,16 @@ func ContinuePrompt(prev string) (string, error) {
// This semi cursed function formats our prompt (obviously) // This semi cursed function formats our prompt (obviously)
func fmtPrompt() string { func fmtPrompt() string {
user, _ := user.Current()
host, _ := os.Hostname() host, _ := os.Hostname()
cwd, _ := os.Getwd() cwd, _ := os.Getwd()
cwd = strings.Replace(cwd, user.HomeDir, "~", 1) cwd = strings.Replace(cwd, curuser.HomeDir, "~", 1)
args := []string{ args := []string{
"d", cwd, "d", cwd,
"D", filepath.Base(cwd),
"h", host, "h", host,
"u", user.Username, "u", curuser.Username,
} }
for i, v := range args { for i, v := range args {

View File

@ -12,6 +12,8 @@ commander.register('cd', function (args)
for i = 1, #args do for i = 1, #args do
path = path .. tostring(args[i]) .. ' ' path = path .. tostring(args[i]) .. ' '
end end
path = path:gsub('$%$','\0'):gsub('${([%w_]+)}', os.getenv)
:gsub('$([%w_]+)', os.getenv):gsub('%z','$')
local ok, err = pcall(function() fs.cd(path) end) local ok, err = pcall(function() fs.cd(path) end)
if not ok then if not ok then