refactor: make initial changes for snail lib (shell interp)

snail
sammyette 2024-12-28 21:43:33 -04:00
parent 4743222044
commit 0b0821f410
Signed by: sammyette
GPG Key ID: 904FC49417B44DCD
13 changed files with 52 additions and 71 deletions

4
api.go
View File

@ -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
View File

@ -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)
}

View File

@ -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
}

View File

4
job.go
View File

@ -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

View File

@ -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")

View File

@ -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")
}

View File

@ -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()

View File

@ -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)

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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 {