mirror of
				https://github.com/sammy-ette/Hilbish
				synced 2025-08-10 02:52:03 +00:00 
			
		
		
		
	Compare commits
	
		
			4 Commits
		
	
	
		
			8fdde4aa58
			...
			1fd99a78cc
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					1fd99a78cc | ||
| 
						 | 
					e50ee0b511 | ||
| 
						 | 
					f43ff7d03c | ||
| 
						 | 
					3bcff3e350 | 
							
								
								
									
										13
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								CHANGELOG.md
									
									
									
									
									
								
							@ -23,6 +23,17 @@ is for everything/anything as opposed to just adding a single command completion
 | 
				
			|||||||
[#122](https://github.com/Rosettea/Hilbish/issues/122)
 | 
					[#122](https://github.com/Rosettea/Hilbish/issues/122)
 | 
				
			||||||
- `fs.abs(path)` to get absolute path.
 | 
					- `fs.abs(path)` to get absolute path.
 | 
				
			||||||
- Nature module (`doc nature`)
 | 
					- Nature module (`doc nature`)
 | 
				
			||||||
 | 
					- `hilbish.jobs.add(cmdstr, args, execPath)` to add a job to the job table.
 | 
				
			||||||
 | 
					`cmdstr` would be user input, `args` is the args for the command (includes arg0)
 | 
				
			||||||
 | 
					and `execPath` is absolute path to command executable
 | 
				
			||||||
 | 
					- `job.add` hook is thrown when a job is added. acts as a unique hook for
 | 
				
			||||||
 | 
					jobs
 | 
				
			||||||
 | 
					- `hilbish.jobs.disown(id)` and `disown` builtin to disown a job. `disown`
 | 
				
			||||||
 | 
					without arguments will disown the last job.
 | 
				
			||||||
 | 
					- `hilbish.jobs.last()` returns the last added job.
 | 
				
			||||||
 | 
					- Job output (stdout/stderr) can now be obtained via the `stdout` and `stderr`
 | 
				
			||||||
 | 
					fields on a job object.
 | 
				
			||||||
 | 
					- Documentation for jobs is now available via `doc jobs`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Changed
 | 
					### Changed
 | 
				
			||||||
- **Breaking Change:** Upgraded to Lua 5.4.
 | 
					- **Breaking Change:** Upgraded to Lua 5.4.
 | 
				
			||||||
@ -57,6 +68,8 @@ certain color rules.
 | 
				
			|||||||
- Cursor position with CJK characters. ([#145](https://github.com/Rosettea/Hilbish/pull/145))
 | 
					- Cursor position with CJK characters. ([#145](https://github.com/Rosettea/Hilbish/pull/145))
 | 
				
			||||||
- Files with same name as parent folder in completions getting cut off [#136](https://github.com/Rosettea/Hilbish/issues/136))
 | 
					- Files with same name as parent folder in completions getting cut off [#136](https://github.com/Rosettea/Hilbish/issues/136))
 | 
				
			||||||
- `hilbish.which` now works with commanders and aliases.
 | 
					- `hilbish.which` now works with commanders and aliases.
 | 
				
			||||||
 | 
					- Background jobs no longer take stdin so they do not interfere with shell
 | 
				
			||||||
 | 
					input.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## [1.2.0] - 2022-03-17
 | 
					## [1.2.0] - 2022-03-17
 | 
				
			||||||
### Added
 | 
					### Added
 | 
				
			||||||
 | 
				
			|||||||
@ -1,11 +1,5 @@
 | 
				
			|||||||
Note: A `job` is a table with the following keys:
 | 
					Note: `job` refers to a job object. YOu can check `doc jobs` for more
 | 
				
			||||||
- cmd: command string
 | 
					detail.
 | 
				
			||||||
- running: boolean whether the job is running
 | 
					 | 
				
			||||||
- id: unique id for the job
 | 
					 | 
				
			||||||
- pid: process id for the job
 | 
					 | 
				
			||||||
- exitCode: exit code of the job
 | 
					 | 
				
			||||||
In ordinary cases you'd prefer to use the id instead of pid. The id is unique to
 | 
					 | 
				
			||||||
Hilbish and is how you get jobs with the `hilbish.jobs` interface.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
+ `job.start` -> job > Thrown when a new background job starts.
 | 
					+ `job.start` -> job > Thrown when a new background job starts.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										40
									
								
								docs/jobs.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								docs/jobs.txt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,40 @@
 | 
				
			|||||||
 | 
					Hilbish has pretty standard job control. It's missing one or two things,
 | 
				
			||||||
 | 
					but works well. One thing which is different from other shells
 | 
				
			||||||
 | 
					(besides Hilbish) itself is the API for jobs, and of course it's in Lua.
 | 
				
			||||||
 | 
					You can add jobs, stop and delete (disown) them and even get output.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Job Interface
 | 
				
			||||||
 | 
					The job interface refers to `hilbish.jobs`.
 | 
				
			||||||
 | 
					## Functions
 | 
				
			||||||
 | 
					(Note that in the list here, they're called from `hilbish.jobs`, so
 | 
				
			||||||
 | 
					a listing of `foo` would mean `hilbish.jobs.foo`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `all()` -> {jobs}: Returns a table of all jobs.
 | 
				
			||||||
 | 
					- `last()` -> job: Returns the last added job.
 | 
				
			||||||
 | 
					- `get(id)` -> job: Get a job by its ID.
 | 
				
			||||||
 | 
					- `add(cmdstr, args, execPath)` -> job: Adds a new job to the job table.
 | 
				
			||||||
 | 
					Note that this does not run the command; You have to start it manually.
 | 
				
			||||||
 | 
					`cmdstr` is the user's input for the job, `args` is a table of arguments
 | 
				
			||||||
 | 
					for the command. It includes arg0 (don't set it as entry 0 in the table)
 | 
				
			||||||
 | 
					and `execPath` is an absolute path for the command executable.
 | 
				
			||||||
 | 
					- `disown(id)`: Removes a job by ID from the job table.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Job Object
 | 
				
			||||||
 | 
					A job object on the Lua side is a table with some functions.
 | 
				
			||||||
 | 
					On the under side it represents a job in the job table.
 | 
				
			||||||
 | 
					You can still have a job object for a disowned job,
 | 
				
			||||||
 | 
					it just won't be *working* anywhere. :^)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Properties
 | 
				
			||||||
 | 
					- `cmd`: command string
 | 
				
			||||||
 | 
					- `running`: boolean whether the job is running
 | 
				
			||||||
 | 
					- `id`: unique id for the job
 | 
				
			||||||
 | 
					- `pid`: process id for the job
 | 
				
			||||||
 | 
					- `exitCode`: exit code of the job
 | 
				
			||||||
 | 
					In ordinary cases you'd prefer to use the `id` instead of `pid`.
 | 
				
			||||||
 | 
					The `id` is unique to Hilbish and is how you get jobs with the
 | 
				
			||||||
 | 
					`hilbish.jobs` interface. It may also not describe the job entirely.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Functions
 | 
				
			||||||
 | 
					- `stop()`: Stops the job.
 | 
				
			||||||
 | 
					- `start()`: Starts the job.
 | 
				
			||||||
							
								
								
									
										51
									
								
								job.go
									
									
									
									
									
								
							
							
						
						
									
										51
									
								
								job.go
									
									
									
									
									
								
							@ -1,6 +1,7 @@
 | 
				
			|||||||
package main
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
@ -27,9 +28,10 @@ type job struct {
 | 
				
			|||||||
	// would just be so itll be the same binary command always (path changes)
 | 
						// would just be so itll be the same binary command always (path changes)
 | 
				
			||||||
	path string
 | 
						path string
 | 
				
			||||||
	handle *exec.Cmd
 | 
						handle *exec.Cmd
 | 
				
			||||||
	stdin io.Reader
 | 
						cmdout io.Writer
 | 
				
			||||||
	stdout io.Writer
 | 
						cmderr io.Writer
 | 
				
			||||||
	stderr io.Writer
 | 
						stdout *bytes.Buffer
 | 
				
			||||||
 | 
						stderr *bytes.Buffer
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (j *job) start() error {
 | 
					func (j *job) start() error {
 | 
				
			||||||
@ -38,13 +40,19 @@ func (j *job) start() error {
 | 
				
			|||||||
		cmd := exec.Cmd{
 | 
							cmd := exec.Cmd{
 | 
				
			||||||
			Path: j.path,
 | 
								Path: j.path,
 | 
				
			||||||
			Args: j.args,
 | 
								Args: j.args,
 | 
				
			||||||
			Stdin: j.stdin,
 | 
					 | 
				
			||||||
			Stdout: j.stdout,
 | 
					 | 
				
			||||||
			Stderr: j.stderr,
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		j.setHandle(&cmd)
 | 
							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)
 | 
				
			||||||
 | 
						// not go to it (child process)
 | 
				
			||||||
	j.handle.SysProcAttr = bgProcAttr
 | 
						j.handle.SysProcAttr = bgProcAttr
 | 
				
			||||||
 | 
						// reset output buffers
 | 
				
			||||||
 | 
						j.stdout.Reset()
 | 
				
			||||||
 | 
						j.stderr.Reset()
 | 
				
			||||||
 | 
						// make cmd write to both standard output and output buffers for lua access
 | 
				
			||||||
 | 
						j.handle.Stdout = io.MultiWriter(j.cmdout, j.stdout)
 | 
				
			||||||
 | 
						j.handle.Stderr = io.MultiWriter(j.cmderr, j.stderr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if !j.once {
 | 
						if !j.once {
 | 
				
			||||||
		j.once = true
 | 
							j.once = true
 | 
				
			||||||
@ -82,9 +90,12 @@ func (j *job) setHandle(handle *exec.Cmd) {
 | 
				
			|||||||
	j.handle = handle
 | 
						j.handle = handle
 | 
				
			||||||
	j.args = handle.Args
 | 
						j.args = handle.Args
 | 
				
			||||||
	j.path = handle.Path
 | 
						j.path = handle.Path
 | 
				
			||||||
	j.stdin = handle.Stdin
 | 
						if handle.Stdout != nil {
 | 
				
			||||||
	j.stdout = handle.Stdout
 | 
							j.cmdout = handle.Stdout
 | 
				
			||||||
	j.stderr = handle.Stderr
 | 
						}
 | 
				
			||||||
 | 
						if handle.Stderr != nil {
 | 
				
			||||||
 | 
							j.cmderr = handle.Stderr
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (j *job) getProc() *os.Process {
 | 
					func (j *job) getProc() *os.Process {
 | 
				
			||||||
@ -109,6 +120,8 @@ func (j *job) lua() rt.Value {
 | 
				
			|||||||
	luaJob.Set(rt.StringValue("id"), rt.IntValue(int64(j.id)))
 | 
						luaJob.Set(rt.StringValue("id"), rt.IntValue(int64(j.id)))
 | 
				
			||||||
	luaJob.Set(rt.StringValue("pid"), rt.IntValue(int64(j.pid)))
 | 
						luaJob.Set(rt.StringValue("pid"), rt.IntValue(int64(j.pid)))
 | 
				
			||||||
	luaJob.Set(rt.StringValue("exitCode"), rt.IntValue(int64(j.exitCode)))
 | 
						luaJob.Set(rt.StringValue("exitCode"), rt.IntValue(int64(j.exitCode)))
 | 
				
			||||||
 | 
						luaJob.Set(rt.StringValue("stdout"), rt.StringValue(string(j.stdout.Bytes())))
 | 
				
			||||||
 | 
						luaJob.Set(rt.StringValue("stderr"), rt.StringValue(string(j.stderr.Bytes())))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return rt.TableValue(luaJob)
 | 
						return rt.TableValue(luaJob)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -158,9 +171,10 @@ func (j *jobHandler) add(cmd string, args []string, path string) *job {
 | 
				
			|||||||
		id: j.latestID,
 | 
							id: j.latestID,
 | 
				
			||||||
		args: args,
 | 
							args: args,
 | 
				
			||||||
		path: path,
 | 
							path: path,
 | 
				
			||||||
		stdin: os.Stdin,
 | 
							cmdout: os.Stdout,
 | 
				
			||||||
		stdout: os.Stdout,
 | 
							cmderr: os.Stderr,
 | 
				
			||||||
		stderr: os.Stderr,
 | 
							stdout: &bytes.Buffer{},
 | 
				
			||||||
 | 
							stderr: &bytes.Buffer{},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	j.jobs[j.latestID] = jb
 | 
						j.jobs[j.latestID] = jb
 | 
				
			||||||
	hooks.Em.Emit("job.add", jb.lua())
 | 
						hooks.Em.Emit("job.add", jb.lua())
 | 
				
			||||||
@ -208,7 +222,7 @@ func (j *jobHandler) loader(rtm *rt.Runtime) *rt.Table {
 | 
				
			|||||||
		"all": {j.luaAllJobs, 0, false},
 | 
							"all": {j.luaAllJobs, 0, false},
 | 
				
			||||||
		"last": {j.luaLastJob, 0, false},
 | 
							"last": {j.luaLastJob, 0, false},
 | 
				
			||||||
		"get": {j.luaGetJob, 1, false},
 | 
							"get": {j.luaGetJob, 1, false},
 | 
				
			||||||
		"add": {j.luaAddJob, 2, false},
 | 
							"add": {j.luaAddJob, 3, false},
 | 
				
			||||||
		"disown": {j.luaDisownJob, 1, false},
 | 
							"disown": {j.luaDisownJob, 1, false},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -239,7 +253,7 @@ func (j *jobHandler) luaGetJob(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (j *jobHandler) luaAddJob(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
 | 
					func (j *jobHandler) luaAddJob(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
 | 
				
			||||||
	if err := c.CheckNArgs(2); err != nil {
 | 
						if err := c.CheckNArgs(3); err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	cmd, err := c.StringArg(0)
 | 
						cmd, err := c.StringArg(0)
 | 
				
			||||||
@ -250,6 +264,10 @@ func (j *jobHandler) luaAddJob(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						execPath, err := c.StringArg(2)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var args []string
 | 
						var args []string
 | 
				
			||||||
	util.ForEach(largs, func(k rt.Value, v rt.Value) {
 | 
						util.ForEach(largs, func(k rt.Value, v rt.Value) {
 | 
				
			||||||
@ -257,8 +275,8 @@ func (j *jobHandler) luaAddJob(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
 | 
				
			|||||||
			args = append(args, v.AsString())
 | 
								args = append(args, v.AsString())
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	// TODO: change to lookpath for args[0]
 | 
					
 | 
				
			||||||
	jb := j.add(cmd, args, args[0])
 | 
						jb := j.add(cmd, args, execPath)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return c.PushingNext1(t.Runtime, jb.lua()), nil
 | 
						return c.PushingNext1(t.Runtime, jb.lua()), nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -303,4 +321,3 @@ func (j *jobHandler) luaLastJob(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	return c.PushingNext1(t.Runtime, job.lua()), nil
 | 
						return c.PushingNext1(t.Runtime, job.lua()), nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user