mirror of https://github.com/Hilbis/Hilbish
refactor: make initial changes for snail lib (shell interp)
parent
4743222044
commit
0b0821f410
4
api.go
4
api.go
|
@ -508,7 +508,7 @@ func hlexec(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
}
|
||||
cmdArgs, _ := splitInput(cmd)
|
||||
if runtime.GOOS != "windows" {
|
||||
cmdPath, err := exec.LookPath(cmdArgs[0])
|
||||
cmdPath, err := util.LookPath(cmdArgs[0])
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
// if we get here, cmdPath will be nothing
|
||||
|
@ -706,7 +706,7 @@ func hlwhich(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
return c.PushingNext1(t.Runtime, rt.StringValue(cmd)), nil
|
||||
}
|
||||
|
||||
path, err := exec.LookPath(cmd)
|
||||
path, err := util.LookPath(cmd)
|
||||
if err != nil {
|
||||
return c.Next(), nil
|
||||
}
|
||||
|
|
45
exec.go
45
exec.go
|
@ -411,7 +411,7 @@ func execHandle(bg bool) interp.ExecHandlerFunc {
|
|||
return interp.NewExitStatus(exitcode)
|
||||
}
|
||||
|
||||
path, err := lookpath(args[0])
|
||||
path, err := util.LookPath(args[0])
|
||||
if err == errNotExec {
|
||||
return execError{
|
||||
typ: "not-executable",
|
||||
|
@ -524,41 +524,14 @@ func handleExecErr(err error) (exit uint8) {
|
|||
|
||||
return
|
||||
}
|
||||
func lookpath(file string) (string, error) { // custom lookpath function so we know if a command is found *and* is executable
|
||||
var skip []string
|
||||
if runtime.GOOS == "windows" {
|
||||
skip = []string{"./", "../", "~/", "C:"}
|
||||
} else {
|
||||
skip = []string{"./", "/", "../", "~/"}
|
||||
}
|
||||
for _, s := range skip {
|
||||
if strings.HasPrefix(file, s) {
|
||||
return file, findExecutable(file, false, false)
|
||||
}
|
||||
}
|
||||
for _, dir := range filepath.SplitList(os.Getenv("PATH")) {
|
||||
path := filepath.Join(dir, file)
|
||||
err := findExecutable(path, true, false)
|
||||
if err == errNotExec {
|
||||
return "", err
|
||||
} else if err == nil {
|
||||
return path, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", os.ErrNotExist
|
||||
}
|
||||
|
||||
func splitInput(input string) ([]string, string) {
|
||||
// end my suffering
|
||||
// TODO: refactor this garbage
|
||||
quoted := false
|
||||
startlastcmd := false
|
||||
lastcmddone := false
|
||||
cmdArgs := []string{}
|
||||
sb := &strings.Builder{}
|
||||
cmdstr := &strings.Builder{}
|
||||
lastcmd := "" //readline.GetHistory(readline.HistorySize() - 1)
|
||||
|
||||
for _, r := range input {
|
||||
if r == '"' {
|
||||
|
@ -574,22 +547,6 @@ func splitInput(input string) ([]string, string) {
|
|||
// if not quoted and there's a space then add to cmdargs
|
||||
cmdArgs = append(cmdArgs, sb.String())
|
||||
sb.Reset()
|
||||
} else if !quoted && r == '^' && startlastcmd && !lastcmddone {
|
||||
// if ^ is found, isnt in quotes and is
|
||||
// the second occurence of the character and is
|
||||
// the first time "^^" has been used
|
||||
cmdstr.WriteString(lastcmd)
|
||||
sb.WriteString(lastcmd)
|
||||
|
||||
startlastcmd = !startlastcmd
|
||||
lastcmddone = !lastcmddone
|
||||
|
||||
continue
|
||||
} else if !quoted && r == '^' && !lastcmddone {
|
||||
// if ^ is found, isnt in quotes and is the
|
||||
// first time of starting "^^"
|
||||
startlastcmd = !startlastcmd
|
||||
continue
|
||||
} else {
|
||||
sb.WriteRune(r)
|
||||
}
|
||||
|
|
|
@ -110,12 +110,10 @@ func (f *fs) fcd(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
}
|
||||
path = util.ExpandHome(strings.TrimSpace(path))
|
||||
|
||||
abspath, _ := filepath.Abs(path)
|
||||
err = os.Chdir(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
interp.Dir(abspath)(f.runner)
|
||||
|
||||
return c.Next(), err
|
||||
}
|
||||
|
|
4
job.go
4
job.go
|
@ -56,8 +56,8 @@ func (j *job) start() error {
|
|||
}
|
||||
j.setHandle(&cmd)
|
||||
}
|
||||
// bgProcAttr is defined in execfile_<os>.go, it holds a procattr struct
|
||||
// in a simple explanation, it makes signals from hilbish (sigint)
|
||||
// bgProcAttr is defined in job_<os>.go, it holds a procattr struct
|
||||
// in a simple explanation, it makes signals from hilbish (like sigint)
|
||||
// not go to it (child process)
|
||||
j.handle.SysProcAttr = bgProcAttr
|
||||
// reset output buffers
|
||||
|
|
|
@ -10,6 +10,10 @@ import (
|
|||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
var bgProcAttr *syscall.SysProcAttr = &syscall.SysProcAttr{
|
||||
Setpgid: true,
|
||||
}
|
||||
|
||||
func (j *job) foreground() error {
|
||||
if jobs.foreground {
|
||||
return errors.New("(another) job already foregrounded")
|
||||
|
|
|
@ -4,8 +4,13 @@ package main
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
var bgProcAttr *syscall.SysProcAttr = &syscall.SysProcAttr{
|
||||
CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP,
|
||||
}
|
||||
|
||||
func (j *job) foreground() error {
|
||||
return errors.New("not supported on windows")
|
||||
}
|
||||
|
|
2
main.go
2
main.go
|
@ -38,11 +38,9 @@ var (
|
|||
cmds *commander.Commander
|
||||
defaultConfPath string
|
||||
defaultHistPath string
|
||||
runner *interp.Runner
|
||||
)
|
||||
|
||||
func main() {
|
||||
runner, _ = interp.New()
|
||||
curuser, _ = user.Current()
|
||||
homedir := curuser.HomeDir
|
||||
confDir, _ = os.UserConfigDir()
|
||||
|
|
|
@ -3,8 +3,9 @@ local commander = require 'commander'
|
|||
local fs = require 'fs'
|
||||
local dirs = require 'nature.dirs'
|
||||
|
||||
dirs.old = hilbish.cwd()
|
||||
commander.register('cd', function (args, sinks)
|
||||
local oldPath = hilbish.cwd()
|
||||
|
||||
if #args > 1 then
|
||||
sinks.out:writeln("cd: too many arguments")
|
||||
return 1
|
||||
|
@ -16,13 +17,10 @@ commander.register('cd', function (args, sinks)
|
|||
sinks.out:writeln(path)
|
||||
end
|
||||
|
||||
dirs.setOld(hilbish.cwd())
|
||||
dirs.push(path)
|
||||
|
||||
local ok, err = pcall(function() fs.cd(path) end)
|
||||
if not ok then
|
||||
sinks.out:writeln(err)
|
||||
return 1
|
||||
end
|
||||
bait.throw('cd', path)
|
||||
bait.throw('hilbish.cd', fs.abs(path), oldPath)
|
||||
end)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
-- @module dirs
|
||||
local bait = require 'bait'
|
||||
local fs = require 'fs'
|
||||
|
||||
local dirs = {}
|
||||
|
@ -73,4 +74,9 @@ function dirs.setOld(d)
|
|||
dirs.old = d
|
||||
end
|
||||
|
||||
bait.catch('hilbish.cd', function(path, oldPath)
|
||||
dirs.setOld(oldPath)
|
||||
dirs.push(path)
|
||||
end)
|
||||
|
||||
return dirs
|
||||
|
|
25
util/util.go
25
util/util.go
|
@ -141,3 +141,28 @@ func AbbrevHome(path string) string {
|
|||
|
||||
return path
|
||||
}
|
||||
|
||||
func LookPath(file string) (string, error) { // custom lookpath function so we know if a command is found *and* is executable
|
||||
var skip []string
|
||||
if runtime.GOOS == "windows" {
|
||||
skip = []string{"./", "../", "~/", "C:"}
|
||||
} else {
|
||||
skip = []string{"./", "/", "../", "~/"}
|
||||
}
|
||||
for _, s := range skip {
|
||||
if strings.HasPrefix(file, s) {
|
||||
return file, findExecutable(file, false, false)
|
||||
}
|
||||
}
|
||||
for _, dir := range filepath.SplitList(os.Getenv("PATH")) {
|
||||
path := filepath.Join(dir, file)
|
||||
err := findExecutable(path, true, false)
|
||||
if err == errNotExec {
|
||||
return "", err
|
||||
} else if err == nil {
|
||||
return path, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", os.ErrNotExist
|
||||
}
|
||||
|
|
|
@ -1,17 +1,12 @@
|
|||
//go:build unix
|
||||
|
||||
package main
|
||||
package util
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
var bgProcAttr *syscall.SysProcAttr = &syscall.SysProcAttr{
|
||||
Setpgid: true,
|
||||
}
|
||||
|
||||
func findExecutable(path string, inPath, dirs bool) error {
|
||||
func FindExecutable(path string, inPath, dirs bool) error {
|
||||
f, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return err
|
|
@ -1,18 +1,13 @@
|
|||
//go:build windows
|
||||
|
||||
package main
|
||||
package util
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
var bgProcAttr *syscall.SysProcAttr = &syscall.SysProcAttr{
|
||||
CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP,
|
||||
}
|
||||
|
||||
func findExecutable(path string, inPath, dirs bool) error {
|
||||
func FindExecutable(path string, inPath, dirs bool) error {
|
||||
nameExt := filepath.Ext(path)
|
||||
pathExts := filepath.SplitList(os.Getenv("PATHEXT"))
|
||||
if inPath {
|
Loading…
Reference in New Issue