mirror of
				https://github.com/sammy-ette/Hilbish
				synced 2025-08-10 02:52:03 +00:00 
			
		
		
		
	Compare commits
	
		
			No commits in common. "b8e3d4d8e623d1204ce50c2970ac5e896556776a" and "9491e3e67f9dd7a1112049690b512bd5356f975b" have entirely different histories.
		
	
	
		
			b8e3d4d8e6
			...
			9491e3e67f
		
	
		
							
								
								
									
										29
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @ -1,33 +1,5 @@ | ||||
| # 🎀 Changelog | ||||
| 
 | ||||
| ## Unreleased | ||||
| ### Added | ||||
| - `fs.pipe` function to get a pair of connected files (a pipe). | ||||
| - Added an alternative 2nd parameter to `hilbish.run`, which is `streams`. | ||||
| `streams` is a table of input and output streams to run the command with. | ||||
| It uses these 3 keys: | ||||
|   - `input` as standard input for the command | ||||
|   - `out` as standard output | ||||
|   - `err` as standard error | ||||
| 
 | ||||
| Here is a minimal example of the new usage which allows users to now pipe commands | ||||
| directly via Lua functions: | ||||
|    | ||||
| ```lua | ||||
| local fs = require 'fs' | ||||
| local pr, pw = fs.pipe() | ||||
| hilbish.run('ls -l', { | ||||
| 	stdout = pw, | ||||
| 	stderr = pw, | ||||
| }) | ||||
| 
 | ||||
| pw:close() | ||||
| 
 | ||||
| hilbish.run('wc -l', { | ||||
| 	stdin = pr | ||||
| }) | ||||
| ``` | ||||
| 
 | ||||
| ## [2.2.3] - 2024-04-27 | ||||
| ### Fixed | ||||
| - Highligher and hinter work now, since it was regressed from the previous minor release. | ||||
| @ -744,7 +716,6 @@ This input for example will prompt for more input to complete: | ||||
| 
 | ||||
| First "stable" release of Hilbish. | ||||
| 
 | ||||
| [2.2.3]: https://github.com/Rosettea/Hilbish/compare/v2.2.2...v2.2.3 | ||||
| [2.2.2]: https://github.com/Rosettea/Hilbish/compare/v2.2.1...v2.2.2 | ||||
| [2.2.1]: https://github.com/Rosettea/Hilbish/compare/v2.2.0...v2.2.1 | ||||
| [2.2.0]: https://github.com/Rosettea/Hilbish/compare/v2.1.0...v2.2.0 | ||||
|  | ||||
							
								
								
									
										90
									
								
								api.go
									
									
									
									
									
								
							
							
						
						
									
										90
									
								
								api.go
									
									
									
									
									
								
							| @ -16,7 +16,6 @@ import ( | ||||
| 	"bytes" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"os" | ||||
| 	"os/exec" | ||||
| 	"runtime" | ||||
| @ -154,62 +153,11 @@ func unsetVimMode() { | ||||
| 	util.SetField(l, hshMod, "vimMode", rt.NilValue) | ||||
| } | ||||
| 
 | ||||
| func handleStream(v rt.Value, strms *streams, errStream bool) error { | ||||
| 	ud, ok := v.TryUserData() | ||||
| 	if !ok { | ||||
| 		return errors.New("expected metatable argument") | ||||
| 	} | ||||
| 
 | ||||
| 	val := ud.Value() | ||||
| 	var varstrm io.Writer | ||||
| 	if f, ok := val.(*iolib.File); ok { | ||||
| 		varstrm = f.Handle() | ||||
| 	} | ||||
| 
 | ||||
| 	if f, ok := val.(*sink); ok { | ||||
| 		varstrm = f.writer | ||||
| 	} | ||||
| 
 | ||||
| 	if varstrm == nil { | ||||
| 		return errors.New("expected either a sink or file") | ||||
| 	} | ||||
| 
 | ||||
| 	if errStream { | ||||
| 		strms.stderr = varstrm | ||||
| 	} else { | ||||
| 		strms.stdout = varstrm | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // run(cmd, streams) -> exitCode (number), stdout (string), stderr (string) | ||||
| // Runs `cmd` in Hilbish's shell script interpreter. | ||||
| // The `streams` parameter specifies the output and input streams the command should use. | ||||
| // For example, to write command output to a sink. | ||||
| // As a table, the caller can directly specify the standard output, error, and input | ||||
| // streams of the command with the table keys `out`, `err`, and `input` respectively. | ||||
| // As a boolean, it specifies whether the command should use standard output or return its output streams. | ||||
| // #param cmd string | ||||
| // #param streams table|boolean | ||||
| // #param returnOut boolean If this is true, the function will return the standard output and error of the command instead of printing it. | ||||
| // #returns number, string, string | ||||
| // #example | ||||
| /* | ||||
| // This code is the same as `ls -l | wc -l` | ||||
| local fs = require 'fs' | ||||
| local pr, pw = fs.pipe() | ||||
| hilbish.run('ls -l', { | ||||
| 	stdout = pw, | ||||
| 	stderr = pw, | ||||
| }) | ||||
| 
 | ||||
| pw:close() | ||||
| 
 | ||||
| hilbish.run('wc -l', { | ||||
| 	stdin = pr | ||||
| }) | ||||
| */ | ||||
| // #example | ||||
| func hlrun(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { | ||||
| 	// TODO: ON BREAKING RELEASE, DO NOT ACCEPT `streams` AS A BOOLEAN. | ||||
| 	if err := c.Check1Arg(); err != nil { | ||||
| @ -220,7 +168,7 @@ func hlrun(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	strms := &streams{} | ||||
| 	var strms *streams | ||||
| 	var terminalOut bool | ||||
| 	if len(c.Etc()) != 0 { | ||||
| 		tout := c.Etc()[0] | ||||
| @ -233,31 +181,35 @@ func hlrun(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { | ||||
| 				return nil, errors.New("bad argument to run (expected boolean or table, got " + tout.TypeName() + ")") | ||||
| 			} | ||||
| 
 | ||||
| 			handleStream(luastreams.Get(rt.StringValue("out")), strms, false) | ||||
| 			handleStream(luastreams.Get(rt.StringValue("err")), strms, true) | ||||
| 			var stdoutStream, stderrStream *iolib.File | ||||
| 
 | ||||
| 			stdinstrm := luastreams.Get(rt.StringValue("input")) | ||||
| 			if !stdinstrm.IsNil() { | ||||
| 				ud, ok := stdinstrm.TryUserData() | ||||
| 			stdoutstrm := luastreams.Get(rt.StringValue("stdout")) | ||||
| 			if !stdoutstrm.IsNil() { | ||||
| 				f, ok := iolib.ValueToFile(stdoutstrm) | ||||
| 				if !ok { | ||||
| 					return nil, errors.New("bad type as run stdin stream (expected userdata as either sink or file, got " + stdinstrm.TypeName() + ")") | ||||
| 					return nil, errors.New("bad argument to run streams table (expected file, got " + stdoutstrm.TypeName() + ")") | ||||
| 				} | ||||
| 
 | ||||
| 				val := ud.Value() | ||||
| 				var varstrm io.Reader | ||||
| 				if f, ok := val.(*iolib.File); ok { | ||||
| 					varstrm = f.Handle() | ||||
| 				stdoutStream = f | ||||
| 			} | ||||
| 
 | ||||
| 				if f, ok := val.(*sink); ok { | ||||
| 					varstrm = f.reader | ||||
| 			stderrstrm := luastreams.Get(rt.StringValue("stderr")) | ||||
| 			if !stderrstrm.IsNil() { | ||||
| 				f, ok := iolib.ValueToFile(stderrstrm) | ||||
| 				if !ok { | ||||
| 					return nil, errors.New("bad argument to run streams table (expected file, got " + stderrstrm.TypeName() + ")") | ||||
| 				} | ||||
| 
 | ||||
| 				if varstrm == nil { | ||||
| 					return nil, errors.New("bad type as run stdin stream (expected userdata as either sink or file)") | ||||
| 				stderrStream = f | ||||
| 			} | ||||
| 
 | ||||
| 				strms.stdin = varstrm | ||||
| 			strms = &streams{} | ||||
| 			if stdoutStream != nil { | ||||
| 				strms.stdout = stdoutStream.Handle() | ||||
| 			} | ||||
| 
 | ||||
| 			if stderrStream != nil { | ||||
| 				strms.stderr = stderrStream.Handle() | ||||
| 			} | ||||
| 		} else { | ||||
| 			if !terminalOut { | ||||
|  | ||||
| @ -488,12 +488,8 @@ func main() { | ||||
| 					} | ||||
| 
 | ||||
| 					mdTable.SetContent(i - diff, 0, fmt.Sprintf(`<a href="#%s">%s</a>`, dps.FuncName, dps.FuncSig)) | ||||
| 					if len(dps.Doc) == 0 { | ||||
| 						fmt.Printf("WARNING! Function %s on module %s has no documentation!\n", dps.FuncName, modname) | ||||
| 					} else { | ||||
| 					mdTable.SetContent(i - diff, 1, dps.Doc[0]) | ||||
| 				} | ||||
| 				} | ||||
| 				f.WriteString(mdTable.String()) | ||||
| 				f.WriteString("\n") | ||||
| 			} | ||||
|  | ||||
| @ -26,11 +26,8 @@ In this example, a command with the name of `hello` is created | ||||
| that will print `Hello world!` to output. One question you may | ||||
| have is: What is the `sinks` parameter? | ||||
| 
 | ||||
| The `sinks` parameter is a table with 3 keys: `input`, `out`, and `err`. | ||||
| There is an `in` alias to `input`, but it requires using the string accessor syntax (`sinks['in']`) | ||||
| as `in` is also a Lua keyword, so `input` is preferred for use. | ||||
| All of them are a <a href="/Hilbish/docs/api/hilbish/#sink" style="text-decoration: none;">Sink</a>. | ||||
| In the future, `sinks.in` will be removed. | ||||
| The `sinks` parameter is a table with 3 keys: `in`, `out`, | ||||
| and `err`. All of them are a <a href="/Hilbish/docs/api/hilbish/#sink" style="text-decoration: none;">Sink</a>. | ||||
| 
 | ||||
| - `in` is the standard input. | ||||
| You may use the read functions on this sink to get input from the user. | ||||
|  | ||||
| @ -23,7 +23,6 @@ library offers more functions and will work on any operating system Hilbish does | ||||
| |<a href="#glob">glob(pattern) -> matches (table)</a>|Match all files based on the provided `pattern`.| | ||||
| |<a href="#join">join(...path) -> string</a>|Takes any list of paths and joins them based on the operating system's path separator.| | ||||
| |<a href="#mkdir">mkdir(name, recursive)</a>|Creates a new directory with the provided `name`.| | ||||
| |<a href="#pipe">fpipe() -> File, File</a>|Returns a pair of connected files, also known as a pipe.| | ||||
| |<a href="#readdir">readdir(path) -> table[string]</a>|Returns a list of all files and directories in the provided path.| | ||||
| |<a href="#stat">stat(path) -> {}</a>|Returns the information about a given `path`.| | ||||
| 
 | ||||
| @ -184,22 +183,6 @@ fs.mkdir('./foo/bar', true) | ||||
| ``` | ||||
| </div> | ||||
| 
 | ||||
| <hr> | ||||
| <div id='pipe'> | ||||
| <h4 class='heading'> | ||||
| fs.fpipe() -> File, File | ||||
| <a href="#pipe" class='heading-link'> | ||||
| 	<i class="fas fa-paperclip"></i> | ||||
| </a> | ||||
| </h4> | ||||
| 
 | ||||
| Returns a pair of connected files, also known as a pipe.   | ||||
| The type returned is a Lua file, same as returned from `io` functions.   | ||||
| 
 | ||||
| #### Parameters | ||||
| This function has no parameters.   | ||||
| </div> | ||||
| 
 | ||||
| <hr> | ||||
| <div id='readdir'> | ||||
| <h4 class='heading'> | ||||
|  | ||||
| @ -28,7 +28,7 @@ interfaces and functions which directly relate to shell functionality. | ||||
| |<a href="#prependPath">prependPath(dir)</a>|Prepends `dir` to $PATH.| | ||||
| |<a href="#prompt">prompt(str, typ)</a>|Changes the shell prompt to the provided string.| | ||||
| |<a href="#read">read(prompt) -> input (string)</a>|Read input from the user, using Hilbish's line editor/input reader.| | ||||
| |<a href="#run">run(cmd, streams) -> exitCode (number), stdout (string), stderr (string)</a>|Runs `cmd` in Hilbish's shell script interpreter.| | ||||
| |<a href="#run">run(cmd, returnOut) -> exitCode (number), stdout (string), stderr (string)</a>|Runs `cmd` in Hilbish's shell script interpreter.| | ||||
| |<a href="#runnerMode">runnerMode(mode)</a>|Sets the execution/runner mode for interactive Hilbish.| | ||||
| |<a href="#timeout">timeout(cb, time) -> @Timer</a>|Executed the `cb` function after a period of `time`.| | ||||
| |<a href="#which">which(name) -> string</a>|Checks if `name` is a valid command.| | ||||
| @ -413,25 +413,20 @@ Text to print before input, can be empty. | ||||
| <hr> | ||||
| <div id='run'> | ||||
| <h4 class='heading'> | ||||
| hilbish.run(cmd, streams) -> exitCode (number), stdout (string), stderr (string) | ||||
| hilbish.run(cmd, returnOut) -> exitCode (number), stdout (string), stderr (string) | ||||
| <a href="#run" class='heading-link'> | ||||
| 	<i class="fas fa-paperclip"></i> | ||||
| </a> | ||||
| </h4> | ||||
| 
 | ||||
| Runs `cmd` in Hilbish's shell script interpreter.   | ||||
| Specifies the output and input streams the command should use.   | ||||
| For example, to write command output to a sink.   | ||||
| As a table, the caller can directly specify the standard output, error, and input   | ||||
| streams of the command with the table keys `out`, `err`, and `input` respectively.   | ||||
| As a boolean, it specifies whether the command should use standard output or return its output streams.   | ||||
| 
 | ||||
| #### Parameters | ||||
| `string` **`cmd`**   | ||||
| 
 | ||||
| 
 | ||||
| `table|boolean` **`streams`**   | ||||
| 
 | ||||
| `boolean` **`returnOut`**   | ||||
| If this is true, the function will return the standard output and error of the command instead of printing it. | ||||
| 
 | ||||
| </div> | ||||
| 
 | ||||
|  | ||||
| @ -34,10 +34,6 @@ function fs.join(...path) end | ||||
| ---  | ||||
| function fs.mkdir(name, recursive) end | ||||
| 
 | ||||
| --- Returns a pair of connected files, also known as a pipe. | ||||
| --- The type returned is a Lua file, same as returned from `io` functions. | ||||
| function fs.fpipe() end | ||||
| 
 | ||||
| --- Returns a list of all files and directories in the provided path. | ||||
| function fs.readdir(path) end | ||||
| 
 | ||||
|  | ||||
| @ -132,12 +132,7 @@ function hilbish.prompt(str, typ) end | ||||
| function hilbish.read(prompt) end | ||||
| 
 | ||||
| --- Runs `cmd` in Hilbish's shell script interpreter. | ||||
| --- Specifies the output and input streams the command should use. | ||||
| --- For example, to write command output to a sink. | ||||
| --- As a table, the caller can directly specify the standard output, error, and input | ||||
| --- streams of the command with the table keys `out`, `err`, and `input` respectively. | ||||
| --- As a boolean, it specifies whether the command should use standard output or return its output streams. | ||||
| function hilbish.run(cmd, streams) end | ||||
| function hilbish.run(cmd, returnOut) end | ||||
| 
 | ||||
| --- Sets the execution/runner mode for interactive Hilbish. | ||||
| --- This determines whether Hilbish wll try to run input as Lua | ||||
|  | ||||
							
								
								
									
										7
									
								
								exec.go
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								exec.go
									
									
									
									
									
								
							| @ -283,11 +283,7 @@ func execCommand(cmd string, strms *streams) (io.Writer, io.Writer, error) { | ||||
| 		strms.stderr = os.Stderr | ||||
| 	} | ||||
| 
 | ||||
| 	if strms.stdin == nil { | ||||
| 		strms.stdin = os.Stdin | ||||
| 	} | ||||
| 
 | ||||
| 	interp.StdIO(strms.stdin, strms.stdout, strms.stderr)(runner) | ||||
| 	interp.StdIO(os.Stdin, strms.stdout, strms.stderr)(runner) | ||||
| 
 | ||||
| 	buf := new(bytes.Buffer) | ||||
| 	printer := syntax.NewPrinter() | ||||
| @ -349,7 +345,6 @@ func execHandle(bg bool) interp.ExecHandlerFunc { | ||||
| 
 | ||||
| 			sinks := rt.NewTable() | ||||
| 			sinks.Set(rt.StringValue("in"), rt.UserDataValue(stdin.ud)) | ||||
| 			sinks.Set(rt.StringValue("input"), rt.UserDataValue(stdin.ud)) | ||||
| 			sinks.Set(rt.StringValue("out"), rt.UserDataValue(stdout.ud)) | ||||
| 			sinks.Set(rt.StringValue("err"), rt.UserDataValue(stderr.ud)) | ||||
| 
 | ||||
|  | ||||
| @ -17,11 +17,8 @@ In this example, a command with the name of `hello` is created | ||||
| that will print `Hello world!` to output. One question you may | ||||
| have is: What is the `sinks` parameter? | ||||
| 
 | ||||
| The `sinks` parameter is a table with 3 keys: `input`, `out`, and `err`. | ||||
| There is an `in` alias to `input`, but it requires using the string accessor syntax (`sinks['in']`) | ||||
| as `in` is also a Lua keyword, so `input` is preferred for use. | ||||
| All of them are a @Sink. | ||||
| In the future, `sinks.in` will be removed. | ||||
| The `sinks` parameter is a table with 3 keys: `in`, `out`, | ||||
| and `err`. All of them are a @Sink. | ||||
| 
 | ||||
| - `in` is the standard input. | ||||
| You may use the read functions on this sink to get input from the user. | ||||
|  | ||||
| @ -228,11 +228,6 @@ func fmkdir(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { | ||||
| 	return c.Next(), err | ||||
| } | ||||
| 
 | ||||
| // fpipe() -> File, File | ||||
| // Returns a pair of connected files, also known as a pipe. | ||||
| // The type returned is a Lua file, same as returned from `io` functions. | ||||
| // #returns File | ||||
| // #returns File | ||||
| func fpipe(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { | ||||
| 	rf, wf, err := os.Pipe() | ||||
| 	if err != nil { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user