Compare commits

..

No commits in common. "123f8992b1b258bd649ea351ecb25ea9afc43dff" and "84ec3d085d1e7c77b5a22dff9bc4630d72968edf" have entirely different histories.

12 changed files with 35 additions and 247 deletions

View File

@ -2,18 +2,8 @@
This is the changelog for the Hilbish shell made in Go and Lua. This is the changelog for the Hilbish shell made in Go and Lua.
## [0.6.1] - 2021-10-21
### Fixed
- Require paths now use the `dataDir` variable so there is no need to change it anymore unless you want to add more paths
- Remove double slash in XDG data require paths
- Ctrl+C is handled properly when not interactive and won't result in a panic anymore
- Commanders are handled by the sh interpreter library only now, so they work with sh syntax
### Changed
- Error messages from `fs` functions now include the path provided
## [0.6.0] - 2021-10-17 ## [0.6.0] - 2021-10-17
### Added ## Added
- Hilbish will expand `~` in the preloadPath and samplePathConf variables. These are for compile time. - Hilbish will expand `~` in the preloadPath and samplePathConf variables. These are for compile time.
- On Windows, the hostname in `%u` has been removed. - On Windows, the hostname in `%u` has been removed.
- Made it easier to compile on Windows by adding Windows-tailored vars and paths. - Made it easier to compile on Windows by adding Windows-tailored vars and paths.
@ -34,13 +24,13 @@ This is the changelog for the Hilbish shell made in Go and Lua.
- The [Succulent](https://github.com/Rosettea/Succulent) library has been added. This includes more utility functions and expansions to the Lua standard library itself. - The [Succulent](https://github.com/Rosettea/Succulent) library has been added. This includes more utility functions and expansions to the Lua standard library itself.
- The command string is now passed to the `command.exit` hook - The command string is now passed to the `command.exit` hook
### Changed # Changed
- Hilbish won't print an extra newline at exit with ctrl + d - Hilbish won't print an extra newline at exit with ctrl + d
- `command.exit` with 0 exit code will now be thrown if input is nothing - `command.exit` with 0 exit code will now be thrown if input is nothing
- **Breaking Change:** `fs.stat` has been made better. It returns a proper table instead of userdata, and has fields instead of functions - **Breaking Change:** `fs.stat` has been made better. It returns a proper table instead of userdata, and has fields instead of functions
- It includes `name`, `mode` as a octal representation in a string, `isDir`, and `size` - It includes `name`, `mode` as a octal representation in a string, `isDir`, and `size`
### Fixed # Fixed
- `timeout()` is now blocking - `timeout()` is now blocking
- Directories with spaces in them can now be `cd`'d to - Directories with spaces in them can now be `cd`'d to
- An alias with the same name as the command will now not cause a freeze (#73) - An alias with the same name as the command will now not cause a freeze (#73)
@ -50,15 +40,15 @@ This is the changelog for the Hilbish shell made in Go and Lua.
## [0.5.1] - 2021-06-16 ## [0.5.1] - 2021-06-16
### Added ## Added
- Add `~/.config/hilbish` as a require path - Add `~/.config/hilbish` as a require path
### Changed ## Changed
- `cd` hook is only thrown after directory has actually changed - `cd` hook is only thrown after directory has actually changed
### Fixed ## Fixed
- Handle error in commander properly, preventing a panic from Lua - Handle error in commander properly, preventing a panic from Lua
@ -66,7 +56,7 @@ This is the changelog for the Hilbish shell made in Go and Lua.
An absolutely massive release. Probably the biggest yet, includes a bunch of fixes and new features and convenient additions to the Lua API. An absolutely massive release. Probably the biggest yet, includes a bunch of fixes and new features and convenient additions to the Lua API.
### Added ## Added
- `-n` flag, which checks Lua for syntax errors without running it - `-n` flag, which checks Lua for syntax errors without running it
- `exec(command)` function, acts like the `exec` builtin in sh - `exec(command)` function, acts like the `exec` builtin in sh
@ -93,7 +83,7 @@ When `false` is run, it will have the exit code of `1`, this is shorter/easier t
- `hilbish.home` is a crossplatform Lua alternative to get the home directory easily. - `hilbish.home` is a crossplatform Lua alternative to get the home directory easily.
- `commander.deregister(cmdName)` de-registers any command defined with commander. - `commander.deregister(cmdName)` de-registers any command defined with commander.
### Changed ## Changed
- **Breaking Change**: Move `_user` and `_ver` to a global `hilbish` table - **Breaking Change**: Move `_user` and `_ver` to a global `hilbish` table
- Accessing username and Hilbish version is now done with `hilbish.user` and `hilbish.ver` - Accessing username and Hilbish version is now done with `hilbish.user` and `hilbish.ver`
@ -110,7 +100,7 @@ When `false` is run, it will have the exit code of `1`, this is shorter/easier t
- Add input to history before alias expansion. Basically, this adds the actual alias to history instead of the aliased command. - Add input to history before alias expansion. Basically, this adds the actual alias to history instead of the aliased command.
- Global preload path, require paths, default config directory and sample config directory can now be changed at compile time to help support other systems. - Global preload path, require paths, default config directory and sample config directory can now be changed at compile time to help support other systems.
### Fixed ## Fixed
- `cd` now exits with code `1` instead of the error code if it occurs - `cd` now exits with code `1` instead of the error code if it occurs
- Don't append directory to $PATH with `appendPath` if its already there - Don't append directory to $PATH with `appendPath` if its already there
@ -121,7 +111,7 @@ When `false` is run, it will have the exit code of `1`, this is shorter/easier t
## [0.4.0] - 2021-05-01 ## [0.4.0] - 2021-05-01
### Added ## Added
- Ctrl C in the prompt now cancels/clear input (I've needed this for so long also) - Ctrl C in the prompt now cancels/clear input (I've needed this for so long also)
- Made Hilbish act like a login shell on login - Made Hilbish act like a login shell on login
- If Hilbish is the login shell, or the `-l`/`--login` flags are used, Hilbish will use an additional `~/.hprofile.lua` file, you can use this to set environment variables once on login - If Hilbish is the login shell, or the `-l`/`--login` flags are used, Hilbish will use an additional `~/.hprofile.lua` file, you can use this to set environment variables once on login
@ -135,7 +125,7 @@ When `false` is run, it will have the exit code of `1`, this is shorter/easier t
- `string.split(str, delimiter)` - `string.split(str, delimiter)`
- Added a `_user` variable to easily get current user's name - Added a `_user` variable to easily get current user's name
### Changed ## Changed
- **BREAKING Change**: [Lunacolors](https://github.com/Hilbis/Lunacolors) has replaced ansikit for formatting colors, which means the format function has been removed from ansikit and moved to Lunacolors. - **BREAKING Change**: [Lunacolors](https://github.com/Hilbis/Lunacolors) has replaced ansikit for formatting colors, which means the format function has been removed from ansikit and moved to Lunacolors.
- Users must replace ansikit with `lunacolors` in their config files - Users must replace ansikit with `lunacolors` in their config files
@ -249,7 +239,6 @@ This input for example will prompt for more input to complete:
First "stable" release of Hilbish. First "stable" release of Hilbish.
[0.6.1]: https://github.com/Rosettea/Hilbish/compare/v0.6.0...v0.6.1
[0.6.0]: https://github.com/Rosettea/Hilbish/compare/v0.5.1...v0.6.0 [0.6.0]: https://github.com/Rosettea/Hilbish/compare/v0.5.1...v0.6.0
[0.5.1]: https://github.com/Rosettea/Hilbish/compare/v0.5.0...v0.5.1 [0.5.1]: https://github.com/Rosettea/Hilbish/compare/v0.5.0...v0.5.1
[0.5.0]: https://github.com/Rosettea/Hilbish/compare/v0.4.0...v0.5.0 [0.5.0]: https://github.com/Rosettea/Hilbish/compare/v0.4.0...v0.5.0

View File

@ -10,8 +10,8 @@ a contribution. Be sure to read through it.
Use GitHub Issues to report any bugs or to request any features Use GitHub Issues to report any bugs or to request any features
that may be useful to *anyone* else. that may be useful to *anyone* else.
Check [currently open issues](https://github.com/Rosettea/Hilbish/issues) Check [currently open issues](https://github.com/Hilbis/Hilbish/issues)
and [closed ones](https://github.com/Rosettea/Hilbish/issues?q=is%3Aissue+is%3Aclosed) to make sure someone else hasn't already made the issue. and [closed ones](https://github.com/Hilbis/Hilbish/issues?q=is%3Aissue+is%3Aclosed) to make sure someone else hasn't already made the issue.
For bug reports, be sure to include: For bug reports, be sure to include:
- Hilbish Version (`hilbish -v`) - Hilbish Version (`hilbish -v`)
@ -40,8 +40,8 @@ your commits correctly.
4. Finally, make the pull request to the **dev** branch. 4. Finally, make the pull request to the **dev** branch.
## Finding Issues to Contribute to ## Finding Issues to Contribute to
You can check out the [help wanted](https://github.com/Rosettea/Hilbish/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22+) You can check out the [help wanted](https://github.com/Hilbis/Hilbish/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22+)
labels to figure out what we need your help working on. labels to figure out what we need your help working on.
The [up for grabs](https://github.com/Rosettea/Hilbish/issues?q=is%3Aissue+is%3Aopen+label%3A%22up+for+grabs%22+) labeled issues are low hanging fruit that should be The [up for grabs](https://github.com/Hilbis/Hilbish/issues?q=is%3Aissue+is%3Aopen+label%3A%22up+for+grabs%22+) labeled issues are low hanging fruit that should be
easy for anyone. You can use this to get started on contributing! easy for anyone. You can use this to get started on contributing!

View File

@ -1,9 +1,10 @@
<div align="center"> <div align="center">
<img src="./assets/hilbish-flower.png" width=128><br> <img src="./assets/hilbish-flower.png" width=128><br>
<img src="./assets/hilbish-text.png" width=256><br><br> <img src="./assets/hilbish-text.png" width=256>
<h1></h1>
<blockquote> <blockquote>
🌺 The flower shell. A comfy and nice little shell for Lua users and fans! 🌺 The flower shell. A comfy and nice little shell for Lua users and fans!
</blockquote><br> </blockquote>
<p align="center"> <p align="center">
<img alt="GitHub commit activity" src="https://img.shields.io/github/commit-activity/m/Rosettea/Hilbish?style=flat-square"> <img alt="GitHub commit activity" src="https://img.shields.io/github/commit-activity/m/Rosettea/Hilbish?style=flat-square">
<img alt="GitHub commits since latest release (by date)" src="https://img.shields.io/github/commits-since/Rosettea/Hilbish/latest?style=flat-square"> <img alt="GitHub commits since latest release (by date)" src="https://img.shields.io/github/commits-since/Rosettea/Hilbish/latest?style=flat-square">

1
go.mod
View File

@ -4,7 +4,6 @@ go 1.16
require ( require (
github.com/Rosettea/Hilbiline v0.0.0-20210603231612-80054dac3650 github.com/Rosettea/Hilbiline v0.0.0-20210603231612-80054dac3650
github.com/Rosettea/readline v0.0.0-20211122152601-6d95ce44b7ed
github.com/bobappleyard/readline v0.0.0-20150707195538-7e300e02d38e github.com/bobappleyard/readline v0.0.0-20150707195538-7e300e02d38e
github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9 github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9
github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect

2
go.sum
View File

@ -1,7 +1,5 @@
github.com/Rosettea/Hilbiline v0.0.0-20210603231612-80054dac3650 h1:nzFJUdJU8UJ1DA8mSQp4eoBtQyOJyecekVWusjfQsqE= github.com/Rosettea/Hilbiline v0.0.0-20210603231612-80054dac3650 h1:nzFJUdJU8UJ1DA8mSQp4eoBtQyOJyecekVWusjfQsqE=
github.com/Rosettea/Hilbiline v0.0.0-20210603231612-80054dac3650/go.mod h1:/FFZ4cgR6TXXYaskRUxyLIYdfG0PS4BPtWjWRQms754= github.com/Rosettea/Hilbiline v0.0.0-20210603231612-80054dac3650/go.mod h1:/FFZ4cgR6TXXYaskRUxyLIYdfG0PS4BPtWjWRQms754=
github.com/Rosettea/readline v0.0.0-20211122152601-6d95ce44b7ed h1:sGsGPG+b5h9OR1GjM0PiM4iemB9hmi0o8cg2YRSRKko=
github.com/Rosettea/readline v0.0.0-20211122152601-6d95ce44b7ed/go.mod h1:OH+WJSCks0t2ISvaCFUT4ZxNGr4Etq4ju9JE/UxH/5o=
github.com/Rosettea/sh/v3 v3.3.0 h1:0/xmOfzpy46gB1I2oPj8QwdYvyJzpdF5STcgNPRQHcI= github.com/Rosettea/sh/v3 v3.3.0 h1:0/xmOfzpy46gB1I2oPj8QwdYvyJzpdF5STcgNPRQHcI=
github.com/Rosettea/sh/v3 v3.3.0/go.mod h1:dh3avhLDhJJ/MJKzbak6FYn+DJKUWk7Fb6Dh5mGdv6Y= github.com/Rosettea/sh/v3 v3.3.0/go.mod h1:dh3avhLDhJJ/MJKzbak6FYn+DJKUWk7Fb6Dh5mGdv6Y=
github.com/Rosettea/sh/v3 v3.4.0-0.dev.0.20211022004519-f67a49cb50f5 h1:ygwVRX8gf5MHA0VzSgOdscCEoAJLjM8joEotfQPgAd0= github.com/Rosettea/sh/v3 v3.4.0-0.dev.0.20211022004519-f67a49cb50f5 h1:ygwVRX8gf5MHA0VzSgOdscCEoAJLjM8joEotfQPgAd0=

16
lua.go
View File

@ -58,8 +58,6 @@ func LuaInit() {
hooks = bait.New() hooks = bait.New()
l.PreloadModule("bait", hooks.Loader) l.PreloadModule("bait", hooks.Loader)
l.SetGlobal("complete", l.NewFunction(hshcomplete))
// Add more paths that Lua can require from // Add more paths that Lua can require from
l.DoString("package.path = package.path .. " + requirePaths) l.DoString("package.path = package.path .. " + requirePaths)
@ -212,17 +210,3 @@ func hshinterval(L *lua.LState) int {
return 1 return 1
} }
// complete(scope, cb)
// Registers a completion handler for `scope`.
// A `scope` is currently only expected to be `command.<cmd>`,
// replacing <cmd> with the name of the command (for example `command.git`).
// `cb` must be a function that returns a table of the entries to complete.
// Nested tables will be used as sub-completions.
func hshcomplete(L *lua.LState) int {
scope := L.CheckString(1)
cb := L.CheckFunction(2)
luaCompletions[scope] = cb
return 0
}

19
main.go
View File

@ -5,19 +5,18 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
"runtime"
"strings"
"os/signal" "os/signal"
"os/user" "os/user"
"path/filepath" "path/filepath"
"runtime"
"strings"
"syscall"
"hilbish/golibs/bait" "hilbish/golibs/bait"
"github.com/pborman/getopt" "github.com/pborman/getopt"
"github.com/yuin/gopher-lua" "github.com/yuin/gopher-lua"
"golang.org/x/term"
"layeh.com/gopher-luar" "layeh.com/gopher-luar"
"golang.org/x/term"
) )
var ( var (
@ -26,7 +25,6 @@ var (
commands = map[string]*lua.LFunction{} commands = map[string]*lua.LFunction{}
aliases = map[string]string{} aliases = map[string]string{}
luaCompletions = map[string]*lua.LFunction{}
homedir string homedir string
confDir string confDir string
@ -260,22 +258,15 @@ func fmtPrompt() string {
// do i even have to say // do i even have to say
func HandleSignals() { func HandleSignals() {
c := make(chan os.Signal) c := make(chan os.Signal)
signal.Notify(c, os.Interrupt, syscall.SIGWINCH) signal.Notify(c, os.Interrupt)
for s := range c { for range c {
switch s {
case os.Interrupt:
if !running { if !running {
if !interactive { if !interactive {
os.Exit(0) os.Exit(0)
} }
lr.ClearInput() lr.ClearInput()
} }
case syscall.SIGWINCH:
if !running {
lr.Resize()
}
}
} }
} }

View File

@ -166,7 +166,3 @@ bait.catch('command.not-found', function(cmd)
print(string.format('hilbish: %s not found', cmd)) print(string.format('hilbish: %s not found', cmd))
end) end)
bait.catch('command.no-perm', function(cmd)
print(string.format('hilbish: %s: no permission', cmd))
end)

144
rl.go
View File

@ -1,4 +1,3 @@
//go:build !hilbiline
// +build !hilbiline // +build !hilbiline
package main package main
@ -7,149 +6,15 @@ package main
// making them interchangable during build time // making them interchangable during build time
// this is normal readline // this is normal readline
import ( import "github.com/bobappleyard/readline"
"path/filepath"
"strings"
"os"
"github.com/Rosettea/readline"
"github.com/yuin/gopher-lua"
)
type LineReader struct { type LineReader struct {
Prompt string Prompt string
} }
// other gophers might hate this naming but this is local, shut up
func NewLineReader(prompt string) *LineReader { func NewLineReader(prompt string) *LineReader {
readline.Completer = func(query string, ctx string) []string { readline.Completer = readline.FilenameCompleter
var completions []string
// trim whitespace from ctx
ctx = strings.TrimLeft(ctx, " ")
fields := strings.Split(ctx, " ")
if len(fields) == 0 {
return nil
}
if len(fields) == 1 {
prefixes := []string{"./", "../"}
for _, prefix := range prefixes {
if strings.HasPrefix(query, prefix) {
if matches, err := filepath.Glob(query + "*"); err == nil {
for _, match := range matches {
if info, err := os.Stat(match); err == nil && info.Mode().Perm() & 0100 == 0 {
continue
}
name := filepath.Base(match)
completions = append(completions, name)
}
}
if len(completions) == 1 {
// we have add the base dir of query since the completion entries are basename
// why? so readline will display just that
// and we want to complete the full path when its the only completion entry
// query will be incomplete so adding it will be broken
// also Dir doesn't have a trailing slash so we need to filepath join
// to account to windows
// AND ANOTHER THING is it returns . if the arg is ./ and Join will
// ignore that so we have to check and just add the prefix instead
if prefix != "./" {
completions[0] = filepath.Join(filepath.Dir(query), completions[0])
} else {
completions[0] = prefix + completions[0]
}
}
return completions
}
}
for _, dir := range filepath.SplitList(os.Getenv("PATH")) {
// print dir to stderr for debugging
// search for an executable which matches our query string
if matches, err := filepath.Glob(filepath.Join(dir, query + "*")); err == nil {
// get basename from matches
for _, match := range matches {
// check if we have execute permissions for our match
if info, err := os.Stat(match); err == nil && info.Mode().Perm() & 0100 == 0 {
continue
}
// get basename from match
name := filepath.Base(match)
// print name to stderr for debugging
// add basename to completions
completions = append(completions, name)
}
}
}
// add lua registered commands to completions
for cmdName := range commands {
if strings.HasPrefix(cmdName, query) {
completions = append(completions, cmdName)
}
}
} else {
if completecb, ok := luaCompletions["command." + fields[0]]; ok {
err := l.CallByParam(lua.P{
Fn: completecb,
NRet: 1,
Protect: true,
})
if err != nil {
return []string{}
}
luacompleteTable := l.Get(-1)
l.Pop(1)
if cmpTbl, ok := luacompleteTable.(*lua.LTable); ok {
cmpTbl.ForEach(func(key lua.LValue, value lua.LValue) {
// print key and value to stderr for debugging
// if key is a number (index), we just check and complete that
if key.Type() == lua.LTNumber {
// if we have only 2 fields then this is fine
if len(fields) == 2 {
if strings.HasPrefix(value.String(), fields[1]) {
completions = append(completions, value.String())
}
}
} else if key.Type() == lua.LTString {
if len(fields) == 2 {
if strings.HasPrefix(key.String(), fields[1]) {
completions = append(completions, key.String())
}
} else {
// if we have more than 2 fields, we need to check if the key matches
// the current field and if it does, we need to check if the value is a string
// or table (nested sub completions)
if key.String() == fields[1] {
// if value is a table, we need to iterate over it
// and add each value to completions
valueTbl := value.(*lua.LTable)
valueTbl.ForEach(func(key lua.LValue, value lua.LValue) {
val := value.String()
if val == "<file>" {
// complete files
completions = append(completions, readline.FilenameCompleter(query, ctx)...)
} else {
if strings.HasPrefix(val, query) {
completions = append(completions, val)
}
}
})
}
}
}
})
}
}
if len(completions) == 0 {
completions = readline.FilenameCompleter(query, ctx)
}
}
return completions
}
readline.LoadHistory(defaultHistPath) readline.LoadHistory(defaultHistPath)
return &LineReader{ return &LineReader{
@ -176,6 +41,3 @@ func (lr *LineReader) ClearInput() {
readline.RefreshLine() readline.RefreshLine()
} }
func (lr *LineReader) Resize() {
readline.Resize()
}

View File

@ -37,7 +37,3 @@ func (lr *LineReader) ClearInput() {
return return
} }
func (lr *LineReader) Resize() {
return
}

View File

@ -4,10 +4,10 @@ import (
"context" "context"
"fmt" "fmt"
"os" "os"
"path/filepath"
"strings" "strings"
"time" "time"
// "github.com/bobappleyard/readline"
"github.com/yuin/gopher-lua" "github.com/yuin/gopher-lua"
// "github.com/yuin/gopher-lua/parse" // "github.com/yuin/gopher-lua/parse"
"mvdan.cc/sh/v3/interp" "mvdan.cc/sh/v3/interp"
@ -95,6 +95,7 @@ func execCommand(cmd string) error {
} }
exechandle := func(ctx context.Context, args []string) error { exechandle := func(ctx context.Context, args []string) error {
hc := interp.HandlerCtx(ctx)
_, argstring := splitInput(strings.Join(args, " ")) _, argstring := splitInput(strings.Join(args, " "))
// If alias was found, use command alias // If alias was found, use command alias
@ -141,11 +142,7 @@ func execCommand(cmd string) error {
return interp.NewExitStatus(exitcode) return interp.NewExitStatus(exitcode)
} }
err := lookpath(args[0]) if _, err := interp.LookPathDir(hc.Dir, hc.Env, args[0]); err != nil {
if err == os.ErrPermission {
hooks.Em.Emit("command.no-perm", args[0])
return interp.NewExitStatus(126)
} else if err != nil {
hooks.Em.Emit("command.not-found", args[0]) hooks.Em.Emit("command.not-found", args[0])
return interp.NewExitStatus(127) return interp.NewExitStatus(127)
} }
@ -161,31 +158,6 @@ func execCommand(cmd string) error {
return err return err
} }
// custom lookpath function so we know if a command is found *and* has execute permission
func lookpath(file string) error {
for _, dir := range filepath.SplitList(os.Getenv("PATH")) {
path := filepath.Join(dir, file)
err := findExecutable(path)
if err == os.ErrPermission {
return err
} else if err == nil {
return nil
}
}
return os.ErrNotExist
}
func findExecutable(name string) error {
f, err := os.Stat(name)
if err != nil {
return err
}
if m := f.Mode(); !m.IsDir() && m & 0111 != 0 {
return nil
}
return os.ErrPermission
}
func splitInput(input string) ([]string, string) { func splitInput(input string) ([]string, string) {
// end my suffering // end my suffering
// TODO: refactor this garbage // TODO: refactor this garbage

View File

@ -2,7 +2,7 @@ package main
// String vars that are free to be changed at compile time // String vars that are free to be changed at compile time
var ( var (
version = "v0.7.0" version = "v0.6.0"
defaultConfDir = "" // ~ will be substituted for home, path for user's default config defaultConfDir = "" // ~ will be substituted for home, path for user's default config
defaultHistDir = "" defaultHistDir = ""
commonRequirePaths = "';./libs/?/init.lua;./?/init.lua;./?/?.lua'" commonRequirePaths = "';./libs/?/init.lua;./?/init.lua;./?/?.lua'"