Compare commits

..

14 Commits

Author SHA1 Message Date
TorchedSammy 123f8992b1
feat: add tab completion api
tab complete is better than it was before!
there is a new `complete` function which allows adding custom arguments
to complete specific functions.
hilbish will now also complete executables if it's the first input
argument (this also works with ./)
if no completion is added for a command, hilbish will just complete
files
2021-11-22 11:24:31 -05:00
TorchedSammy 77cc7fe24a
fix: only resize term if not running command 2021-11-22 10:41:27 -05:00
TorchedSammy 5a258ce68e
chore: bump version 2021-11-22 10:39:50 -05:00
TorchedSammy 35e648b7bc
style: remove extra whitespace 2021-11-21 18:50:35 -05:00
TorchedSammy 06272778f8
fix: say if no perms for executable instead of printing not found 2021-11-21 18:45:44 -05:00
sammyette 2f816c33cd
fix: revert "chore: update deps"
This reverts commit e06765abc3.
broke builds
2021-10-30 23:08:29 -04:00
sammyette 9b66547803
docs: change urls to use new org name 2021-10-30 20:03:59 -04:00
sammyette e06765abc3
chore: update deps 2021-10-30 20:01:07 -04:00
sammyette 2073752e7e
chore: merge from dev 2021-10-30 19:57:50 -04:00
sammyette 174d67c9e1
chore: bump version 2021-10-21 22:54:23 -04:00
sammyette c360ac7126
docs: add changelog for 0.6.1 2021-10-21 22:54:04 -04:00
sammyette f46d4c7024
docs: just remove the vertical split 2021-10-21 22:41:48 -04:00
sammyette d3c50aa227
docs: add newline before short description 2021-10-21 22:40:51 -04:00
sammyette 1ee8827c9c
docs: put short description above vertical split
this is the 420th commit! blaze it <o/
2021-10-21 22:38:20 -04:00
12 changed files with 247 additions and 35 deletions

View File

@ -2,8 +2,18 @@
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.
@ -24,13 +34,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)
@ -40,15 +50,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
@ -56,7 +66,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
@ -83,7 +93,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`
@ -100,7 +110,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
@ -111,7 +121,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
@ -125,7 +135,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
@ -239,6 +249,7 @@ 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/Hilbis/Hilbish/issues) Check [currently open issues](https://github.com/Rosettea/Hilbish/issues)
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. 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.
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/Hilbis/Hilbish/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22+) You can check out the [help wanted](https://github.com/Rosettea/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/Hilbis/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/Rosettea/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,10 +1,9 @@
<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> <img src="./assets/hilbish-text.png" width=256><br><br>
<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> </blockquote><br>
<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,6 +4,7 @@ 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,5 +1,7 @@
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,6 +58,8 @@ 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)
@ -210,3 +212,17 @@ 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,18 +5,19 @@ 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"
"layeh.com/gopher-luar"
"golang.org/x/term" "golang.org/x/term"
"layeh.com/gopher-luar"
) )
var ( var (
@ -25,6 +26,7 @@ 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
@ -258,15 +260,22 @@ 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) signal.Notify(c, os.Interrupt, syscall.SIGWINCH)
for range c { for s := 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,3 +166,7 @@ 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,3 +1,4 @@
//go:build !hilbiline
// +build !hilbiline // +build !hilbiline
package main package main
@ -6,15 +7,149 @@ package main
// making them interchangable during build time // making them interchangable during build time
// this is normal readline // this is normal readline
import "github.com/bobappleyard/readline" import (
"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 = readline.FilenameCompleter readline.Completer = func(query string, ctx string) []string {
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{
@ -41,3 +176,6 @@ func (lr *LineReader) ClearInput() {
readline.RefreshLine() readline.RefreshLine()
} }
func (lr *LineReader) Resize() {
readline.Resize()
}

View File

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

View File

@ -4,12 +4,12 @@ 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"
"mvdan.cc/sh/v3/syntax" "mvdan.cc/sh/v3/syntax"
) )
@ -95,7 +95,6 @@ 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
@ -142,7 +141,11 @@ func execCommand(cmd string) error {
return interp.NewExitStatus(exitcode) return interp.NewExitStatus(exitcode)
} }
if _, err := interp.LookPathDir(hc.Dir, hc.Env, args[0]); err != nil { err := lookpath(args[0])
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)
} }
@ -158,6 +161,31 @@ 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.6.0" version = "v0.7.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'"