From 0b0821f410ebc9eda9c71a052a570ea8c55b3185 Mon Sep 17 00:00:00 2001 From: sammyette Date: Sat, 28 Dec 2024 21:43:33 -0400 Subject: [PATCH] refactor: make initial changes for snail lib (shell interp) --- api.go | 4 +- exec.go | 45 +-------------------- golibs/fs/fs.go | 2 - golibs/terminal/snail.go | 0 job.go | 4 +- job_unix.go | 4 ++ job_windows.go | 5 +++ main.go | 2 - nature/commands/cd.lua | 8 ++-- nature/dirs.lua | 6 +++ util/util.go | 25 ++++++++++++ execfile_unix.go => util/util_unix.go | 9 +---- execfile_windows.go => util/util_windows.go | 9 +---- 13 files changed, 52 insertions(+), 71 deletions(-) create mode 100644 golibs/terminal/snail.go rename execfile_unix.go => util/util_unix.go (61%) rename execfile_windows.go => util/util_windows.go (74%) diff --git a/api.go b/api.go index 43e361a..8c2e6e4 100644 --- a/api.go +++ b/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 } diff --git a/exec.go b/exec.go index 7f8e37b..01a5dfa 100644 --- a/exec.go +++ b/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) } diff --git a/golibs/fs/fs.go b/golibs/fs/fs.go index 002be90..1c0589e 100644 --- a/golibs/fs/fs.go +++ b/golibs/fs/fs.go @@ -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 } diff --git a/golibs/terminal/snail.go b/golibs/terminal/snail.go new file mode 100644 index 0000000..e69de29 diff --git a/job.go b/job.go index f5bd6f2..bb16e92 100644 --- a/job.go +++ b/job.go @@ -56,8 +56,8 @@ func (j *job) start() error { } j.setHandle(&cmd) } - // bgProcAttr is defined in execfile_.go, it holds a procattr struct - // in a simple explanation, it makes signals from hilbish (sigint) + // bgProcAttr is defined in job_.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 diff --git a/job_unix.go b/job_unix.go index 0a038b1..2caa4ae 100644 --- a/job_unix.go +++ b/job_unix.go @@ -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") diff --git a/job_windows.go b/job_windows.go index 26818b5..1ac4646 100644 --- a/job_windows.go +++ b/job_windows.go @@ -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") } diff --git a/main.go b/main.go index 1bddfc4..af7a22a 100644 --- a/main.go +++ b/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() diff --git a/nature/commands/cd.lua b/nature/commands/cd.lua index 7cfe4a2..0efbb3f 100644 --- a/nature/commands/cd.lua +++ b/nature/commands/cd.lua @@ -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) diff --git a/nature/dirs.lua b/nature/dirs.lua index 328b4b7..2efad63 100644 --- a/nature/dirs.lua +++ b/nature/dirs.lua @@ -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 diff --git a/util/util.go b/util/util.go index 0fcd4b0..e60f66e 100644 --- a/util/util.go +++ b/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 +} diff --git a/execfile_unix.go b/util/util_unix.go similarity index 61% rename from execfile_unix.go rename to util/util_unix.go index 82c738b..9fa6a6c 100644 --- a/execfile_unix.go +++ b/util/util_unix.go @@ -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 diff --git a/execfile_windows.go b/util/util_windows.go similarity index 74% rename from execfile_windows.go rename to util/util_windows.go index 3d6ef61..4eb50c8 100644 --- a/execfile_windows.go +++ b/util/util_windows.go @@ -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 {