mirror of
				https://github.com/sammy-ette/Hilbish
				synced 2025-08-10 02:52:03 +00:00 
			
		
		
		
	Compare commits
	
		
			No commits in common. "40c2933a95c1ad2f0d75f145754151939149c937" and "bbf5a93ca0acf2872f319c63818aedbe408d4f1e" have entirely different histories.
		
	
	
		
			40c2933a95
			...
			bbf5a93ca0
		
	
		
							
								
								
									
										16
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @ -56,7 +56,6 @@ having and using multiple runners. | |||||||
|   - `fs.basename(path)` gets the basename of path |   - `fs.basename(path)` gets the basename of path | ||||||
|   - `fs.dir(path)` gets the directory part of path |   - `fs.dir(path)` gets the directory part of path | ||||||
|   - `fs.glob(pattern)` globs files and directories based on patterns |   - `fs.glob(pattern)` globs files and directories based on patterns | ||||||
|   - `fs.join(dirs...)` joins directories by OS dir separator |  | ||||||
| - .. and 2 properties | - .. and 2 properties | ||||||
|   - `fs.pathSep` is the separator for filesystem paths and directories |   - `fs.pathSep` is the separator for filesystem paths and directories | ||||||
|   - `fs.pathListSep` is the separator for $PATH env entries |   - `fs.pathListSep` is the separator for $PATH env entries | ||||||
| @ -66,10 +65,7 @@ will be ran on startup | |||||||
| - Message of the day on startup (`hilbish.motd`), mainly intended as quick | - Message of the day on startup (`hilbish.motd`), mainly intended as quick | ||||||
| small news pieces for releases. It is printed by default. To disable it, | small news pieces for releases. It is printed by default. To disable it, | ||||||
| set `hilbish.opts.motd` to false. | set `hilbish.opts.motd` to false. | ||||||
| - `history` opt has been added and is true by default. Setting it to false |  | ||||||
| disables commands being added to history. |  | ||||||
| - `hilbish.rawInput` hook for input from the readline library | - `hilbish.rawInput` hook for input from the readline library | ||||||
| - Completion of files in quotes |  | ||||||
| 
 | 
 | ||||||
| ### Changed | ### Changed | ||||||
| - **Breaking Change:** Upgraded to Lua 5.4. | - **Breaking Change:** Upgraded to Lua 5.4. | ||||||
| @ -92,10 +88,6 @@ of a dot. (ie. `job.stop()` -> `job:stop()`) | |||||||
| - All `fs` module functions which take paths now implicitly expand ~ to home. | - All `fs` module functions which take paths now implicitly expand ~ to home. | ||||||
| - **Breaking Change:** `hilbish.greeting` has been moved to an opt (`hilbish.opts.greeting`) and is | - **Breaking Change:** `hilbish.greeting` has been moved to an opt (`hilbish.opts.greeting`) and is | ||||||
| always printed by default. To disable it, set the opt to false. | always printed by default. To disable it, set the opt to false. | ||||||
| - History is now fetched from Lua, which means users can override `hilbish.history` |  | ||||||
| methods to make it act how they want. |  | ||||||
| - `guide` has been removed. See the [website](https://rosettea.github.io/Hilbish/) |  | ||||||
| for general tips and documentation |  | ||||||
| 
 | 
 | ||||||
| ### Fixed | ### Fixed | ||||||
| - If in Vim replace mode, input at the end of the line inserts instead of | - If in Vim replace mode, input at the end of the line inserts instead of | ||||||
| @ -130,14 +122,6 @@ for explanation. | |||||||
| Lua `job.stop` function. | Lua `job.stop` function. | ||||||
| - Jobs are always started in sh exec handler now instead of only successful start. | - Jobs are always started in sh exec handler now instead of only successful start. | ||||||
| - SIGTERM is handled properly now, which means stopping jobs and timers. | - SIGTERM is handled properly now, which means stopping jobs and timers. | ||||||
| - Fix panic on trailing newline on pasted multiline text. |  | ||||||
| - Completions will no longer be refreshed if the prompt refreshes while the |  | ||||||
| menu is open. |  | ||||||
| - Print error on search fail instead of panicking |  | ||||||
| - Windows related fixes: |  | ||||||
|   - `hilbish.dataDir` now has tilde (`~`) expanded. |  | ||||||
|   - Arrow keys now work on Windows terminals. |  | ||||||
|   - Escape codes now work. |  | ||||||
| 
 | 
 | ||||||
| ## [1.2.0] - 2022-03-17 | ## [1.2.0] - 2022-03-17 | ||||||
| ### Added | ### Added | ||||||
|  | |||||||
| @ -11,9 +11,6 @@ filepath.Dir | |||||||
| glob(pattern) > Glob all files and directories that match the pattern. | glob(pattern) > Glob all files and directories that match the pattern. | ||||||
| For the rules, see Go's filepath.Glob | For the rules, see Go's filepath.Glob | ||||||
| 
 | 
 | ||||||
| join(paths...) > Takes paths and joins them together with the OS's |  | ||||||
| directory separator (forward or backward slash). |  | ||||||
| 
 |  | ||||||
| mkdir(name, recursive) > Makes a directory called `name`. If `recursive` is true, it will create its parent directories. | mkdir(name, recursive) > Makes a directory called `name`. If `recursive` is true, it will create its parent directories. | ||||||
| 
 | 
 | ||||||
| readdir(dir) > Returns a table of files in `dir` | readdir(dir) > Returns a table of files in `dir` | ||||||
|  | |||||||
| @ -22,10 +22,6 @@ function fs.dir() end | |||||||
| --- For the rules, see Go's filepath.Glob | --- For the rules, see Go's filepath.Glob | ||||||
| function fs.glob() end | function fs.glob() end | ||||||
| 
 | 
 | ||||||
| --- Takes paths and joins them together with the OS's |  | ||||||
| --- directory separator (forward or backward slash). |  | ||||||
| function fs.join() end |  | ||||||
| 
 |  | ||||||
| --- Makes a directory called `name`. If `recursive` is true, it will create its parent directories. | --- Makes a directory called `name`. If `recursive` is true, it will create its parent directories. | ||||||
| --- @param name string | --- @param name string | ||||||
| --- @param recursive boolean | --- @param recursive boolean | ||||||
|  | |||||||
							
								
								
									
										6
									
								
								exec.go
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								exec.go
									
									
									
									
									
								
							| @ -540,9 +540,13 @@ func splitInput(input string) ([]string, string) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func cmdFinish(code uint8, cmdstr string, private bool) { | func cmdFinish(code uint8, cmdstr string, private bool) { | ||||||
|  | 	// if input has space at the beginning, dont put in history | ||||||
|  | 	if interactive && !private { | ||||||
|  | 		handleHistory(cmdstr) | ||||||
|  | 	} | ||||||
| 	util.SetField(l, hshMod, "exitCode", rt.IntValue(int64(code)), "Exit code of last exected command") | 	util.SetField(l, hshMod, "exitCode", rt.IntValue(int64(code)), "Exit code of last exected command") | ||||||
| 	// using AsValue (to convert to lua type) on an interface which is an int | 	// using AsValue (to convert to lua type) on an interface which is an int | ||||||
| 	// results in it being unknown in lua .... ???? | 	// results in it being unknown in lua .... ???? | ||||||
| 	// so we allow the hook handler to take lua runtime Values | 	// so we allow the hook handler to take lua runtime Values | ||||||
| 	hooks.Em.Emit("command.exit", rt.IntValue(int64(code)), cmdstr, private) | 	hooks.Em.Emit("command.exit", rt.IntValue(int64(code)), cmdstr) | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,7 +1,6 @@ | |||||||
| package fs | package fs | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"fmt" |  | ||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"os" | 	"os" | ||||||
| @ -28,7 +27,6 @@ func loaderFunc(rtm *rt.Runtime) (rt.Value, func()) { | |||||||
| 		"basename": util.LuaExport{fbasename, 1, false}, | 		"basename": util.LuaExport{fbasename, 1, false}, | ||||||
| 		"dir": util.LuaExport{fdir, 1, false}, | 		"dir": util.LuaExport{fdir, 1, false}, | ||||||
| 		"glob": util.LuaExport{fglob, 1, false}, | 		"glob": util.LuaExport{fglob, 1, false}, | ||||||
| 		"join": util.LuaExport{fjoin, 0, true}, |  | ||||||
| 	} | 	} | ||||||
| 	mod := rt.NewTable() | 	mod := rt.NewTable() | ||||||
| 	util.SetExports(rtm, mod, exports) | 	util.SetExports(rtm, mod, exports) | ||||||
| @ -218,21 +216,3 @@ func fglob(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { | |||||||
| 	 | 	 | ||||||
| 	return c.PushingNext(t.Runtime, rt.TableValue(luaMatches)), nil | 	return c.PushingNext(t.Runtime, rt.TableValue(luaMatches)), nil | ||||||
| } | } | ||||||
| 
 |  | ||||||
| // join(paths...) |  | ||||||
| // Takes paths and joins them together with the OS's |  | ||||||
| // directory separator (forward or backward slash). |  | ||||||
| func fjoin(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { |  | ||||||
| 	strs := make([]string, len(c.Etc())) |  | ||||||
| 	for i, v := range c.Etc() { |  | ||||||
| 		if v.Type() != rt.StringType { |  | ||||||
| 			// +2; go indexes of 0 and first arg from above |  | ||||||
| 			return nil, fmt.Errorf("bad argument #%d to run (expected string, got %s)", i + 1, v.TypeName()) |  | ||||||
| 		} |  | ||||||
| 		strs[i] = v.AsString() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	res := filepath.Join(strs...) |  | ||||||
| 
 |  | ||||||
| 	return c.PushingNext(t.Runtime, rt.StringValue(res)), nil |  | ||||||
| } |  | ||||||
|  | |||||||
							
								
								
									
										56
									
								
								history.go
									
									
									
									
									
								
							
							
						
						
									
										56
									
								
								history.go
									
									
									
									
									
								
							| @ -4,69 +4,21 @@ import ( | |||||||
| 	"errors" | 	"errors" | ||||||
| 	"io/fs" | 	"io/fs" | ||||||
| 	"os" | 	"os" | ||||||
| 	"path/filepath" |  | ||||||
| 	"strings" | 	"strings" | ||||||
| 
 |  | ||||||
| 	rt "github.com/arnodel/golua/runtime" |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type luaHistory struct {} |  | ||||||
| 
 |  | ||||||
| func (h *luaHistory) Write(line string) (int, error) { |  | ||||||
| 	histWrite := hshMod.Get(rt.StringValue("history")).AsTable().Get(rt.StringValue("add")) |  | ||||||
| 	ln, err := rt.Call1(l.MainThread(), histWrite, rt.StringValue(line)) |  | ||||||
| 
 |  | ||||||
| 	var num int64 |  | ||||||
| 	if ln.Type() == rt.IntType { |  | ||||||
| 		num = ln.AsInt() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return int(num), err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (h *luaHistory) GetLine(idx int) (string, error) { |  | ||||||
| 	histGet := hshMod.Get(rt.StringValue("history")).AsTable().Get(rt.StringValue("get")) |  | ||||||
| 	lcmd, err := rt.Call1(l.MainThread(), histGet, rt.IntValue(int64(idx))) |  | ||||||
| 
 |  | ||||||
| 	var cmd string |  | ||||||
| 	if lcmd.Type() == rt.StringType { |  | ||||||
| 		cmd = lcmd.AsString() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return cmd, err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (h *luaHistory) Len() int { |  | ||||||
| 	histSize := hshMod.Get(rt.StringValue("history")).AsTable().Get(rt.StringValue("size")) |  | ||||||
| 	ln, _ := rt.Call1(l.MainThread(), histSize) |  | ||||||
| 
 |  | ||||||
| 	var num int64 |  | ||||||
| 	if ln.Type() == rt.IntType { |  | ||||||
| 		num = ln.AsInt() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return int(num) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (h *luaHistory) Dump() interface{} { |  | ||||||
| 	// hilbish.history interface already has all function, this isnt used in readline |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type fileHistory struct { | type fileHistory struct { | ||||||
| 	items []string | 	items []string | ||||||
| 	f *os.File | 	f *os.File | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func newFileHistory(path string) *fileHistory { | func newFileHistory() *fileHistory { | ||||||
| 	dir := filepath.Dir(path) | 	err := os.MkdirAll(defaultHistDir, 0755) | ||||||
| 
 |  | ||||||
| 	err := os.MkdirAll(dir, 0755) |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		panic(err) | 		panic(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	data, err := os.ReadFile(path) | 	data, err := os.ReadFile(defaultHistPath) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if !errors.Is(err, fs.ErrNotExist) { | 		if !errors.Is(err, fs.ErrNotExist) { | ||||||
| 			panic(err) | 			panic(err) | ||||||
| @ -81,7 +33,7 @@ func newFileHistory(path string) *fileHistory { | |||||||
| 		} | 		} | ||||||
| 		itms = append(itms, l) | 		itms = append(itms, l) | ||||||
| 	} | 	} | ||||||
| 	f, err := os.OpenFile(path, os.O_APPEND | os.O_WRONLY | os.O_CREATE, 0755) | 	f, err := os.OpenFile(defaultHistPath, os.O_APPEND | os.O_WRONLY | os.O_CREATE, 0755) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		panic(err) | 		panic(err) | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -5,13 +5,7 @@ package main | |||||||
| import "golang.org/x/sys/windows" | import "golang.org/x/sys/windows" | ||||||
| 
 | 
 | ||||||
| func init() { | func init() { | ||||||
| 	// vt output (escape codes) | 	var mode uint32 | ||||||
| 	var outMode uint32 | 	windows.GetConsoleMode(windows.Stdout, &mode) | ||||||
| 	windows.GetConsoleMode(windows.Stdout, &outMode) | 	windows.SetConsoleMode(windows.Stdout, mode | windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING) | ||||||
| 	windows.SetConsoleMode(windows.Stdout, outMode | windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING) |  | ||||||
| 
 |  | ||||||
| 	// vt input |  | ||||||
| 	var inMode uint32 |  | ||||||
| 	windows.GetConsoleMode(windows.Stdin, &inMode) |  | ||||||
| 	windows.SetConsoleMode(windows.Stdin, inMode | windows.ENABLE_VIRTUAL_TERMINAL_INPUT) |  | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										4
									
								
								lua.go
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								lua.go
									
									
									
									
									
								
							| @ -12,16 +12,12 @@ import ( | |||||||
| 
 | 
 | ||||||
| 	rt "github.com/arnodel/golua/runtime" | 	rt "github.com/arnodel/golua/runtime" | ||||||
| 	"github.com/arnodel/golua/lib" | 	"github.com/arnodel/golua/lib" | ||||||
| 	"github.com/arnodel/golua/lib/debuglib" |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var minimalconf = `hilbish.prompt '& '` | var minimalconf = `hilbish.prompt '& '` | ||||||
| 
 | 
 | ||||||
| func luaInit() { | func luaInit() { | ||||||
| 	l = rt.New(os.Stdout) | 	l = rt.New(os.Stdout) | ||||||
| 	l.PushContext(rt.RuntimeContextDef{ |  | ||||||
| 		MessageHandler: debuglib.Traceback, |  | ||||||
| 	}) |  | ||||||
| 	lib.LoadAll(l) | 	lib.LoadAll(l) | ||||||
| 
 | 
 | ||||||
| 	lib.LoadLibs(l, hilbishLoader) | 	lib.LoadLibs(l, hilbishLoader) | ||||||
|  | |||||||
							
								
								
									
										5
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								main.go
									
									
									
									
									
								
							| @ -269,6 +269,11 @@ func fmtPrompt(prompt string) string { | |||||||
| 	return nprompt | 	return nprompt | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func handleHistory(cmd string) { | ||||||
|  | 	lr.AddHistory(cmd) | ||||||
|  | 	// TODO: load history again (history shared between sessions like this ye) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func removeDupes(slice []string) []string { | func removeDupes(slice []string) []string { | ||||||
| 	all := make(map[string]bool) | 	all := make(map[string]bool) | ||||||
| 	newSlice := []string{} | 	newSlice := []string{} | ||||||
|  | |||||||
							
								
								
									
										54
									
								
								nature/commands/guide.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								nature/commands/guide.lua
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,54 @@ | |||||||
|  | local ansikit = require 'ansikit' | ||||||
|  | local commander = require 'commander' | ||||||
|  | 
 | ||||||
|  | local helpTexts = { | ||||||
|  | [[ | ||||||
|  | Hello there! Welcome to Hilbish, the comfy and nice little shell for | ||||||
|  | Lua users and fans. Hilbish is configured with Lua, and its | ||||||
|  | scripts are also in Lua. It also runs both Lua and shell script when | ||||||
|  | interactive (aka normal usage). | ||||||
|  | ]], | ||||||
|  | [[ | ||||||
|  | What does that mean for you, the user? It means that if you prefer to | ||||||
|  | use Lua for scripting instead of shell script but still have ordinary | ||||||
|  | shell usage for interactive use. | ||||||
|  | ]], | ||||||
|  | [[ | ||||||
|  | If this is your first time using Hilbish and Lua, check out the | ||||||
|  | Programming in Lua book here: https://www.lua.org/pil | ||||||
|  | After (or if you already know Lua) check out the doc command. | ||||||
|  | It is an in shell tool for documentation about Hilbish provided | ||||||
|  | functions and modules. | ||||||
|  | ]], | ||||||
|  | [[ | ||||||
|  | If you've updated from a pre-1.0 version (0.7.1 as an example) | ||||||
|  | you'll want to move your config from ~/.hilbishrc.lua to | ||||||
|  | ]] .. | ||||||
|  | hilbish.userDir.config .. '/hilbish/init.lua' .. | ||||||
|  | [[ | ||||||
|  | 
 | ||||||
|  | and also change all global functions (prompt, alias) to be | ||||||
|  | in the hilbish module (hilbish.prompt, hilbish.alias as examples). | ||||||
|  | 
 | ||||||
|  | And if this is your first time (most likely), you can copy a config | ||||||
|  | from ]] .. hilbish.dataDir, | ||||||
|  | [[ | ||||||
|  | Since 1.0 is a big release, you'll want to check the changelog | ||||||
|  | at https://github.com/Rosettea/Hilbish/releases/tag/v1.0.0 | ||||||
|  | to find more breaking changes. | ||||||
|  | ]] | ||||||
|  | } | ||||||
|  | commander.register('guide', function() | ||||||
|  | 	ansikit.clear() | ||||||
|  | 	ansikit.cursorTo(0, 0) | ||||||
|  | 	for _, text in ipairs(helpTexts) do | ||||||
|  | 		print(text) | ||||||
|  | 		local out = hilbish.read('Hit enter to continue ') | ||||||
|  | 		ansikit.clear() | ||||||
|  | 		ansikit.cursorTo(0, 0) | ||||||
|  | 		if not out then | ||||||
|  | 			return | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  | 	print 'Hope you enjoy using Hilbish!' | ||||||
|  | end) | ||||||
| @ -3,6 +3,7 @@ require 'nature.commands.cd' | |||||||
| require 'nature.commands.cdr' | require 'nature.commands.cdr' | ||||||
| require 'nature.commands.doc' | require 'nature.commands.doc' | ||||||
| require 'nature.commands.exit' | require 'nature.commands.exit' | ||||||
|  | require 'nature.commands.guide' | ||||||
| require 'nature.commands.disown' | require 'nature.commands.disown' | ||||||
| require 'nature.commands.fg' | require 'nature.commands.fg' | ||||||
| require 'nature.commands.bg' | require 'nature.commands.bg' | ||||||
|  | |||||||
| @ -1,5 +0,0 @@ | |||||||
| local bait = require 'bait' |  | ||||||
| 
 |  | ||||||
| bait.catch('command.exit', function(_, cmd, priv) |  | ||||||
| 	if not priv and hilbish.opts.history then hilbish.history.add(cmd) end |  | ||||||
| end) |  | ||||||
| @ -21,7 +21,6 @@ end | |||||||
| 
 | 
 | ||||||
| local defaultOpts = { | local defaultOpts = { | ||||||
| 	autocd = false, | 	autocd = false, | ||||||
| 	history = true, |  | ||||||
| 	greeting = string.format([[Welcome to {magenta}Hilbish{reset}, {cyan}%s{reset}. | 	greeting = string.format([[Welcome to {magenta}Hilbish{reset}, {cyan}%s{reset}. | ||||||
| The nice lil shell for {blue}Lua{reset} fanatics! | The nice lil shell for {blue}Lua{reset} fanatics! | ||||||
| ]], hilbish.user), | ]], hilbish.user), | ||||||
|  | |||||||
| @ -88,7 +88,7 @@ func (g *CompletionGroup) updateTabFind(rl *Instance) { | |||||||
| 	if rl.searchMode != HistoryFind { | 	if rl.searchMode != HistoryFind { | ||||||
| 		g.Suggestions = g.filterSuggestions(rl) | 		g.Suggestions = g.filterSuggestions(rl) | ||||||
| 	} else { | 	} else { | ||||||
| 		g.Suggestions = rl.HistorySearcher(string(rl.tfLine), g.Suggestions) | 		g.Suggestions = rl.HistorySearcher(string(rl.tfLine)) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Finally, the group computes its new printing settings | 	// Finally, the group computes its new printing settings | ||||||
|  | |||||||
| @ -201,7 +201,7 @@ type Instance struct { | |||||||
| 
 | 
 | ||||||
| 	RawInputCallback func([]rune) // called on all input | 	RawInputCallback func([]rune) // called on all input | ||||||
| 
 | 
 | ||||||
| 	HistorySearcher func(string, []string) []string | 	HistorySearcher func(string) []string | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NewInstance is used to create a readline instance and initialise it with sane defaults. | // NewInstance is used to create a readline instance and initialise it with sane defaults. | ||||||
| @ -231,13 +231,9 @@ func NewInstance() *Instance { | |||||||
| 	rl.evtKeyPress = make(map[string]func(string, []rune, int) *EventReturn) | 	rl.evtKeyPress = make(map[string]func(string, []rune, int) *EventReturn) | ||||||
| 	rl.TempDirectory = os.TempDir() | 	rl.TempDirectory = os.TempDir() | ||||||
| 
 | 
 | ||||||
| 	rl.HistorySearcher = func(filter string, suggestions []string) []string { | 	rl.HistorySearcher = func(filter string) []string { | ||||||
| 		grp := CompletionGroup{ | 		grps := rl.completeHistory() | ||||||
| 			DisplayType: TabDisplayMap, | 		return grps[0].filterSuggestions(rl) | ||||||
| 			MaxLength:   10, |  | ||||||
| 			Suggestions: suggestions, |  | ||||||
| 		} |  | ||||||
| 		return grp.filterSuggestions(rl) |  | ||||||
| 	} | 	} | ||||||
| 	// Registers | 	// Registers | ||||||
| 	rl.initRegisters() | 	rl.initRegisters() | ||||||
|  | |||||||
| @ -94,9 +94,7 @@ func (rl *Instance) Readline() (string, error) { | |||||||
| 
 | 
 | ||||||
| 		rl.skipStdinRead = false | 		rl.skipStdinRead = false | ||||||
| 		r := []rune(string(b)) | 		r := []rune(string(b)) | ||||||
| 		if rl.RawInputCallback != nil { | 		rl.RawInputCallback(r[:i]) | ||||||
| 			rl.RawInputCallback(r[:i]) |  | ||||||
| 		} |  | ||||||
| 
 | 
 | ||||||
| 		if isMultiline(r[:i]) || len(rl.multiline) > 0 { | 		if isMultiline(r[:i]) || len(rl.multiline) > 0 { | ||||||
| 			rl.multiline = append(rl.multiline, b[:i]...) | 			rl.multiline = append(rl.multiline, b[:i]...) | ||||||
|  | |||||||
							
								
								
									
										75
									
								
								rl.go
									
									
									
									
									
								
							
							
						
						
									
										75
									
								
								rl.go
									
									
									
									
									
								
							| @ -13,74 +13,29 @@ import ( | |||||||
| 
 | 
 | ||||||
| type lineReader struct { | type lineReader struct { | ||||||
| 	rl *readline.Instance | 	rl *readline.Instance | ||||||
| 	fileHist *fileHistory |  | ||||||
| } | } | ||||||
|  | var fileHist *fileHistory | ||||||
| var hinter *rt.Closure | var hinter *rt.Closure | ||||||
| var highlighter *rt.Closure | var highlighter *rt.Closure | ||||||
| 
 | 
 | ||||||
| func newLineReader(prompt string, noHist bool) *lineReader { | func newLineReader(prompt string, noHist bool) *lineReader { | ||||||
| 	rl := readline.NewInstance() | 	rl := readline.NewInstance() | ||||||
| 	lr := &lineReader{ |  | ||||||
| 		rl: rl, |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// we don't mind hilbish.read rl instances having completion, | 	// we don't mind hilbish.read rl instances having completion, | ||||||
| 	// but it cant have shared history | 	// but it cant have shared history | ||||||
| 	if !noHist { | 	if !noHist { | ||||||
| 		lr.fileHist = newFileHistory(defaultHistPath) | 		fileHist = newFileHistory() | ||||||
| 		rl.SetHistoryCtrlR("History", &luaHistory{}) | 		rl.SetHistoryCtrlR("History", fileHist) | ||||||
| 		rl.HistoryAutoWrite = false | 		rl.HistoryAutoWrite = false | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	oldSearcher := rl.HistorySearcher | 	oldSearcher := rl.HistorySearcher | ||||||
| 	rl.HistorySearcher = func(query string, suggestions []string) []string { | 	rl.HistorySearcher = func(filter string) []string { | ||||||
| 		return oldSearcher(query, suggestions) |  | ||||||
| 		searcherBool := hshMod.Get(rt.StringValue("opts")).AsTable().Get(rt.StringValue("searcher")) |  | ||||||
| 		if b, _ := searcherBool.TryBool(); !b { |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		searcherHandler := hshMod.Get(rt.StringValue("history")).AsTable().Get(rt.StringValue("searcher")) | 		searcherHandler := hshMod.Get(rt.StringValue("history")).AsTable().Get(rt.StringValue("searcher")) | ||||||
| 		entries := []string{} |  | ||||||
| 		if searcherHandler == rt.NilValue { | 		if searcherHandler == rt.NilValue { | ||||||
| 			// if no searcher, just do a simple filter function | 			return oldSearcher(filter) | ||||||
| 			filter := hshMod.Get(rt.StringValue("history")).AsTable().Get(rt.StringValue("filter")) |  | ||||||
| 			if filter == rt.NilValue { |  | ||||||
| 				return oldSearcher(query, suggestions) |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			histAll := hshMod.Get(rt.StringValue("history")).AsTable().Get(rt.StringValue("all")) |  | ||||||
| 			cmds, err := rt.Call1(l.MainThread(), histAll) |  | ||||||
| 			if err != nil || cmds.Type() != rt.TableType { |  | ||||||
| 				return entries |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			util.ForEach(cmds.AsTable(), func(k rt.Value, cmd rt.Value) { |  | ||||||
| 				if k.Type() != rt.IntType && cmd.Type() != rt.StringType { |  | ||||||
| 					return |  | ||||||
| 				} |  | ||||||
| 
 |  | ||||||
| 				ret, err := rt.Call1(l.MainThread(), filter, rt.StringValue(query), cmd) |  | ||||||
| 				if err != nil { |  | ||||||
| 					return // TODO: true to stop for each (implement in util) |  | ||||||
| 				} |  | ||||||
| 				if ret.Type() != rt.BoolType { |  | ||||||
| 					return // just skip normally |  | ||||||
| 				} |  | ||||||
| 
 |  | ||||||
| 				if ret.AsBool() { |  | ||||||
| 					entries = append(entries, cmd.AsString()) |  | ||||||
| 				} |  | ||||||
| 			}) |  | ||||||
| 
 |  | ||||||
| 			return entries |  | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		luaSuggs := rt.NewTable() | 		ret, err := rt.Call1(l.MainThread(), searcherHandler, rt.StringValue(filter)) | ||||||
| 		for i, sug := range suggestions { | 		entries := []string{} | ||||||
| 			luaSuggs.Set(rt.IntValue(int64(i + 1)), rt.StringValue(sug)) |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		ret, err := rt.Call1(l.MainThread(), searcherHandler, rt.StringValue(query), luaSuggs) |  | ||||||
| 		if err == nil && ret.Type() == rt.TableType { | 		if err == nil && ret.Type() == rt.TableType { | ||||||
| 			util.ForEach(ret.AsTable(), func(k rt.Value, v rt.Value) { | 			util.ForEach(ret.AsTable(), func(k rt.Value, v rt.Value) { | ||||||
| 				if k.Type() == rt.IntType && v.Type() == rt.StringType { | 				if k.Type() == rt.IntType && v.Type() == rt.StringType { | ||||||
| @ -235,7 +190,9 @@ func newLineReader(prompt string, noHist bool) *lineReader { | |||||||
| 		return pfx, compGroups | 		return pfx, compGroups | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return lr | 	return &lineReader{ | ||||||
|  | 		rl, | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (lr *lineReader) Read() (string, error) { | func (lr *lineReader) Read() (string, error) { | ||||||
| @ -274,7 +231,7 @@ func (lr *lineReader) SetRightPrompt(p string) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (lr *lineReader) AddHistory(cmd string) { | func (lr *lineReader) AddHistory(cmd string) { | ||||||
| 	lr.fileHist.Write(cmd) | 	fileHist.Write(cmd) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (lr *lineReader) ClearInput() { | func (lr *lineReader) ClearInput() { | ||||||
| @ -315,7 +272,7 @@ func (lr *lineReader) luaAddHistory(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (lr *lineReader) luaSize(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { | func (lr *lineReader) luaSize(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { | ||||||
| 	return c.PushingNext1(t.Runtime, rt.IntValue(int64(lr.fileHist.Len()))), nil | 	return c.PushingNext1(t.Runtime, rt.IntValue(int64(fileHist.Len()))), nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (lr *lineReader) luaGetHistory(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { | func (lr *lineReader) luaGetHistory(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { | ||||||
| @ -327,17 +284,17 @@ func (lr *lineReader) luaGetHistory(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) | |||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	cmd, _ := lr.fileHist.GetLine(int(idx)) | 	cmd, _ := fileHist.GetLine(int(idx)) | ||||||
| 
 | 
 | ||||||
| 	return c.PushingNext1(t.Runtime, rt.StringValue(cmd)), nil | 	return c.PushingNext1(t.Runtime, rt.StringValue(cmd)), nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (lr *lineReader) luaAllHistory(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { | func (lr *lineReader) luaAllHistory(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { | ||||||
| 	tbl := rt.NewTable() | 	tbl := rt.NewTable() | ||||||
| 	size := lr.fileHist.Len() | 	size := fileHist.Len() | ||||||
| 
 | 
 | ||||||
| 	for i := 1; i < size; i++ { | 	for i := 1; i < size; i++ { | ||||||
| 		cmd, _ := lr.fileHist.GetLine(i) | 		cmd, _ := fileHist.GetLine(i) | ||||||
| 		tbl.Set(rt.IntValue(int64(i)), rt.StringValue(cmd)) | 		tbl.Set(rt.IntValue(int64(i)), rt.StringValue(cmd)) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -345,6 +302,6 @@ func (lr *lineReader) luaAllHistory(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (lr *lineReader) luaClearHistory(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { | func (lr *lineReader) luaClearHistory(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { | ||||||
| 	lr.fileHist.clear() | 	fileHist.clear() | ||||||
| 	return c.Next(), nil | 	return c.Next(), nil | ||||||
| } | } | ||||||
|  | |||||||
| @ -2,15 +2,13 @@ | |||||||
| 
 | 
 | ||||||
| package main | package main | ||||||
| 
 | 
 | ||||||
| import "hilbish/util" |  | ||||||
| 
 |  | ||||||
| // String vars that are free to be changed at compile time | // String vars that are free to be changed at compile time | ||||||
| var ( | var ( | ||||||
| 	requirePaths = commonRequirePaths + `.. ';' | 	requirePaths = commonRequirePaths + `.. ';' | ||||||
| 	.. hilbish.userDir.config .. '\\Hilbish\\libs\\?\\init.lua;' | 	.. hilbish.userDir.config .. '\\Hilbish\\libs\\?\\init.lua;' | ||||||
| 	.. hilbish.userDir.config .. '\\Hilbish\\libs\\?\\?.lua;' | 	.. hilbish.userDir.config .. '\\Hilbish\\libs\\?\\?.lua;' | ||||||
| 	.. hilbish.userDir.config .. '\\Hilbish\\libs\\?.lua;'` | 	.. hilbish.userDir.config .. '\\Hilbish\\libs\\?.lua;'` | ||||||
| 	dataDir = util.ExpandHome("~\\Appdata\\Roaming\\Hilbish") // ~ and \ gonna cry? | 	dataDir = "~\\Appdata\\Roaming\\Hilbish" // ~ and \ gonna cry? | ||||||
| 	preloadPath = dataDir + "\\nature\\init.lua" | 	preloadPath = dataDir + "\\nature\\init.lua" | ||||||
| 	sampleConfPath = dataDir + "\\hilbishrc.lua" // Path to default/sample config | 	sampleConfPath = dataDir + "\\hilbishrc.lua" // Path to default/sample config | ||||||
| 	defaultConfDir = "" | 	defaultConfDir = "" | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user