Compare commits

...

48 Commits

Author SHA1 Message Date
TorchedSammy fe8372379c
fix: make user dataDir on non linux the config dir 2021-12-14 09:41:47 -04:00
TorchedSammy 2e4bea8292
refactor!: replace hilbish.xdg with hilbish.userDir
"xdg" is basically a linux specific thing and it acted linux specific also.
so replace that with a more portable and general "userDir" table

config is for the user's config directory and also defaults to xdg vars on linux.
data is a directory to store data, mostly for scripts.
on other oses beside linux, it is just the config directory for now
2021-12-13 20:13:17 -04:00
TorchedSammy b920f7d7b1
docs: change the description for the hilbish module 2021-12-13 17:32:55 -04:00
TorchedSammy bcfbb20685
fix: dont export lua init 2021-12-08 23:31:48 -04:00
TorchedSammy 4dadfb0874
docs(contributing): fix sentence in making pr section 2021-12-08 23:04:30 -04:00
TorchedSammy 970fe43413
chore: remove newline between replace directives in module file 2021-12-07 18:01:39 -04:00
TorchedSammy 11aaa0cd36
feat: accept a function in complete
the `complete` function will now also accept a nested function in the table
for you to have more fine control over what is suggested and easily
filter specific things
2021-12-07 17:58:56 -04:00
TorchedSammy 6bff669abe
docs(bait): document catchOnce 2021-12-07 17:41:41 -04:00
TorchedSammy c6edbc20af
style: dont explicitly set exitcode to 0 since its the default value 2021-12-07 17:27:07 -04:00
TorchedSammy 82b4fa5e7c
fix(docgen): revert "fix(docgen): trim trailing space from doc comments"
This reverts commit 3f1f698511.
removes the newlines, dont do this for now
2021-12-07 17:08:25 -04:00
TorchedSammy 3f1f698511
fix(docgen): trim trailing space from doc comments 2021-12-07 16:57:53 -04:00
TorchedSammy 3421f286f2
fix: remove index subdoc (resolves #84) 2021-12-07 16:24:55 -04:00
TorchedSammy bfc141f655
fix: add home to recent dirs when visited (cd with no args) 2021-12-07 16:13:05 -04:00
TorchedSammy 2f809e398c
fix: use fork of go readline 2021-12-06 20:56:04 -04:00
TorchedSammy 2ede1a195f
chore: remove test completion code 2021-12-06 20:52:49 -04:00
TorchedSammy 6653fa2e03
feat: add new readline lib
this is an almost 100% working readline implementation
in go, will add tab completion in another commit
2021-12-06 20:48:16 -04:00
TorchedSammy 5c6310b1ca
refactor: dont export functions and types 2021-12-06 17:21:31 -04:00
TorchedSammy 369ddcc100
chore: use correct version of hilbiline 2021-12-06 17:19:22 -04:00
TorchedSammy eaaf17a792
fix: make table for `args` instead of using luar 2021-12-06 16:32:42 -04:00
TorchedSammy f60f61e616
style: remove new line 2021-12-06 16:26:51 -04:00
TorchedSammy 28fcdb3122
fix: take care of readline segfault, update deps 2021-12-06 16:24:25 -04:00
TorchedSammy 4e2e8ddf94
fix: revert "fix: resize if terminal has been resized during running command and fix readline segfault"
This reverts commit d270e8f66b.
causes breakage
2021-12-06 16:07:23 -04:00
TorchedSammy d270e8f66b
fix: resize if terminal has been resized during running command and fix readline segfault 2021-12-06 15:53:51 -04:00
TorchedSammy 6ac4aa50b3
fix: check if interactive when handling signals 2021-12-06 15:45:35 -04:00
TorchedSammy 2a71fb0075
fix!: change xdg config file to init.lua 2021-12-06 15:42:04 -04:00
TorchedSammy 51b1219003
feat(bait): add catchOnce function 2021-12-04 17:59:19 -04:00
TorchedSammy dd45766bae
style: dont redeclare function param, just assign 2021-12-04 17:56:45 -04:00
TorchedSammy 144e158473
chore: remove unused function param 2021-12-04 17:56:11 -04:00
TorchedSammy dedb8cbf76
chore: make typ a local 2021-12-04 17:54:04 -04:00
TorchedSammy 284d4e01a3
chore: rename f to fname in subdoc map (doesnt redefine f) 2021-12-04 17:53:34 -04:00
TorchedSammy 3d36786cc7
chore: remove redundant returns 2021-12-04 17:53:10 -04:00
TorchedSammy 074c5f6766
fix: require lunacolors in preload 2021-12-04 17:50:04 -04:00
TorchedSammy 2e21af4d6b
refactor: use curuser to get homedir everywhere 2021-12-01 18:31:04 -04:00
TorchedSammy effd028658
fix: substitution of home dir to ~ when names in path match it
fixes edge cases like `/mnt/home/user`
2021-12-01 18:30:03 -04:00
TorchedSammy 4a517bde5e
fix: remove handler when error in hook occurs 2021-12-01 17:35:12 -04:00
TorchedSammy 6a526dbbe4
fix: dont panic when error in bait hook occurs 2021-12-01 17:30:06 -04:00
TorchedSammy 3568b62219
style: use decl and assign operator instead of var and = 2021-12-01 17:29:14 -04:00
TorchedSammy 34778a4bdf
fix!: default SHLVL to 0 instead of 1 2021-11-28 23:19:14 -04:00
TorchedSammy ce0b2ab955
fix: dont print extra new line on ctrl+d in continue prompt 2021-11-28 10:44:02 -05:00
TorchedSammy 9261253b63
fix: stop interval if error occurs 2021-11-28 09:29:17 -05:00
TorchedSammy f6aaf85cca
fix: make minimal config actually minimal and not require lunacolors 2021-11-27 22:51:32 -05:00
TorchedSammy 12910ba724
fix: add docs for hilbish.xdg 2021-11-25 22:24:35 -05:00
TorchedSammy e8a69d36bb
fix: executable tab completion 2021-11-23 19:09:07 -05:00
TorchedSammy c329d21e7d
chore: make changelogs and bump for 0.7.1 2021-11-22 22:54:20 -05:00
TorchedSammy 4aafddfdb1
fix: tab complete absolute path binaries properly 2021-11-22 22:52:14 -05:00
TorchedSammy 80dcfc362b
fix: allow non absolute paths to be executed
this is a regression introduced in 06272778f8
2021-11-22 22:49:23 -05:00
TorchedSammy 4127396892
docs: add docs for new functions 2021-11-22 22:04:30 -05:00
TorchedSammy 7ab81a61df
fix: dont trim trailing space for completion field 2021-11-22 21:52:58 -05:00
20 changed files with 337 additions and 172 deletions

View File

@ -2,6 +2,11 @@
This is the changelog for the Hilbish shell made in Go and Lua. This is the changelog for the Hilbish shell made in Go and Lua.
## [0.7.1] - 2021-11-22
### Fixed
- Tab complete absolute paths to binaries properly
- Allow execution of absolute paths to binaries (https://github.com/Rosettea/Hilbish/commit/06272778f85dad04e0e7abffc78a5b9b0cebd067 regression)
## [0.7.0] - 2021-11-22 ## [0.7.0] - 2021-11-22
### Added ### Added
- `hilbish.interactive` and `hilbish.login` properties to figure out if Hilbish is interactive or a login shell, respectively. - `hilbish.interactive` and `hilbish.login` properties to figure out if Hilbish is interactive or a login shell, respectively.
@ -284,6 +289,7 @@ This input for example will prompt for more input to complete:
First "stable" release of Hilbish. First "stable" release of Hilbish.
[0.7.1]: https://github.com/Rosettea/Hilbish/compare/v0.7.0...v0.7.1
[0.7.0]: https://github.com/Rosettea/Hilbish/compare/v0.6.1...v0.7.0 [0.7.0]: https://github.com/Rosettea/Hilbish/compare/v0.6.1...v0.7.0
[0.6.1]: https://github.com/Rosettea/Hilbish/compare/v0.6.0...v0.6.1 [0.6.1]: https://github.com/Rosettea/Hilbish/compare/v0.6.0...v0.6.1
[0.6.0]: https://github.com/Rosettea/Hilbish/compare/v0.5.1...v0.6.0 [0.6.0]: https://github.com/Rosettea/Hilbish/compare/v0.5.1...v0.6.0

View File

@ -31,9 +31,9 @@ the README.md and PR request.
2. Say in the pull request details the changes to the shell, 2. Say in the pull request details the changes to the shell,
this includes useful file locations and breaking changes. this includes useful file locations and breaking changes.
3. The versioning scheme we use is [SemVer](http://semver.org/) and the 3. We use [SemVer](http://semver.org/) for versioning and
commit scheme we use is [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)
[Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/). for commit messages.
Please document any backwards incompatible changes and be sure to name Please document any backwards incompatible changes and be sure to name
your commits correctly. your commits correctly.

View File

@ -1,4 +1,6 @@
catch(name, cb) > Catches a hook with `name`. Runs the `cb` when it is thrown catch(name, cb) > Catches a hook with `name`. Runs the `cb` when it is thrown
catchOnce(name, cb) > Same as catch, but only runs the `cb` once and then removes the hook
throw(name, ...args) > Throws a hook with `name` with the provided `args` throw(name, ...args) > Throws a hook with `name` with the provided `args`

View File

@ -2,6 +2,12 @@ alias(cmd, orig) > Sets an alias of `orig` to `cmd`
appendPath(dir) > Appends `dir` to $PATH appendPath(dir) > Appends `dir` to $PATH
complete(scope, cb) > Registers a completion handler for `scope`.
A `scope` is currently only expected to be `command.<cmd>`,
replacing <cmd> with the name of the command (for example `command.git`).
`cb` must be a function that returns a table of the entries to complete.
Nested tables will be used as sub-completions.
exec(cmd) > Replaces running hilbish with `cmd` exec(cmd) > Replaces running hilbish with `cmd`
goro(fn) > Puts `fn` in a goroutine goro(fn) > Puts `fn` in a goroutine
@ -10,6 +16,8 @@ interval(cb, time) > Runs the `cb` function every `time` milliseconds
multiprompt(str) > Changes the continued line prompt to `str` multiprompt(str) > Changes the continued line prompt to `str`
prependPath(dir) > Prepends `dir` to $PATH
prompt(str) > Changes the shell prompt to `str` prompt(str) > Changes the shell prompt to `str`
There are a few verbs that can be used in the prompt text. There are a few verbs that can be used in the prompt text.
These will be formatted and replaced with the appropriate values. These will be formatted and replaced with the appropriate values.

19
go.mod
View File

@ -3,16 +3,23 @@ module hilbish
go 1.16 go 1.16
require ( require (
github.com/Rosettea/Hilbiline v0.0.0-20210603231612-80054dac3650 github.com/Rosettea/Hilbiline v0.0.0-20210624011007-8088a2d84b65
github.com/Rosettea/readline v0.0.0-20211122152601-6d95ce44b7ed github.com/Rosettea/readline v0.0.0-20211206201906-5570232ed3b3
github.com/bobappleyard/readline v0.0.0-20150707195538-7e300e02d38e
github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9 github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9
github.com/creack/goselect v0.1.2 // indirect
github.com/creack/termios v0.0.0-20160714173321-88d0029e36a1 // indirect
github.com/kr/pty v1.1.8 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/maxlandon/readline v0.1.0-beta.0.20211027085530-2b76cabb8036
github.com/pborman/ansi v1.0.0 // indirect
github.com/pborman/getopt v1.1.0 github.com/pborman/getopt v1.1.0
github.com/yuin/gopher-lua v0.0.0-20210529063254-f4c35e4016d9 github.com/yuin/gopher-lua v0.0.0-20210529063254-f4c35e4016d9
golang.org/x/term v0.0.0-20210916214954-140adaaadfaf golang.org/x/sys v0.0.0-20211205182925-97ca703d548d // indirect
layeh.com/gopher-luar v1.0.8 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
mvdan.cc/sh/v3 v3.3.0 layeh.com/gopher-luar v1.0.10
mvdan.cc/sh/v3 v3.4.1
) )
replace mvdan.cc/sh/v3 => github.com/Rosettea/sh/v3 v3.4.0-0.dev.0.20211022004519-f67a49cb50f5 replace mvdan.cc/sh/v3 => github.com/Rosettea/sh/v3 v3.4.0-0.dev.0.20211022004519-f67a49cb50f5
replace github.com/maxlandon/readline => github.com/Rosettea/readline-1 v0.1.0-beta.0.20211207003625-341c7985ad7d

66
go.sum
View File

@ -1,35 +1,53 @@
github.com/Rosettea/Hilbiline v0.0.0-20210603231612-80054dac3650 h1:nzFJUdJU8UJ1DA8mSQp4eoBtQyOJyecekVWusjfQsqE= github.com/Rosettea/Hilbiline v0.0.0-20210624011007-8088a2d84b65 h1:z6alP313nLg1U/V3bKSd6849L/A2LxDSwKv4CPqqzDk=
github.com/Rosettea/Hilbiline v0.0.0-20210603231612-80054dac3650/go.mod h1:/FFZ4cgR6TXXYaskRUxyLIYdfG0PS4BPtWjWRQms754= github.com/Rosettea/Hilbiline v0.0.0-20210624011007-8088a2d84b65/go.mod h1:/FFZ4cgR6TXXYaskRUxyLIYdfG0PS4BPtWjWRQms754=
github.com/Rosettea/readline v0.0.0-20211122152601-6d95ce44b7ed h1:sGsGPG+b5h9OR1GjM0PiM4iemB9hmi0o8cg2YRSRKko= github.com/Rosettea/Hilbiline v0.0.0-20210710124707-aa6e3ff34cb2 h1:6f1umn6mkodpGf6rK9LZjr4Gut2uS+b8QLoFBFTeOE8=
github.com/Rosettea/readline v0.0.0-20211122152601-6d95ce44b7ed/go.mod h1:OH+WJSCks0t2ISvaCFUT4ZxNGr4Etq4ju9JE/UxH/5o= github.com/Rosettea/Hilbiline v0.0.0-20210710124707-aa6e3ff34cb2/go.mod h1:0J2+sRC+d4a3swcH20sVlFvYUEXASvGTHJnVTTI4S9w=
github.com/Rosettea/sh/v3 v3.3.0 h1:0/xmOfzpy46gB1I2oPj8QwdYvyJzpdF5STcgNPRQHcI= github.com/Rosettea/readline v0.0.0-20211206201906-5570232ed3b3 h1:y+BeaQipF8CuIIkIjvGO7TWlA03t9Nlq+m+cSwXEJ7I=
github.com/Rosettea/sh/v3 v3.3.0/go.mod h1:dh3avhLDhJJ/MJKzbak6FYn+DJKUWk7Fb6Dh5mGdv6Y= github.com/Rosettea/readline v0.0.0-20211206201906-5570232ed3b3/go.mod h1:OH+WJSCks0t2ISvaCFUT4ZxNGr4Etq4ju9JE/UxH/5o=
github.com/Rosettea/readline-1 v0.1.0-beta.0.20211207003625-341c7985ad7d h1:KBttN41h/tPahmpaZavviwQ8q4rCkt5CD0HdVmfgPVA=
github.com/Rosettea/readline-1 v0.1.0-beta.0.20211207003625-341c7985ad7d/go.mod h1:QiUAvbhg8PzCA4hlafCUl0bKD/0VmcocM4AjqtszAJs=
github.com/Rosettea/sh/v3 v3.4.0-0.dev.0.20211022004519-f67a49cb50f5 h1:ygwVRX8gf5MHA0VzSgOdscCEoAJLjM8joEotfQPgAd0= github.com/Rosettea/sh/v3 v3.4.0-0.dev.0.20211022004519-f67a49cb50f5 h1:ygwVRX8gf5MHA0VzSgOdscCEoAJLjM8joEotfQPgAd0=
github.com/Rosettea/sh/v3 v3.4.0-0.dev.0.20211022004519-f67a49cb50f5/go.mod h1:R09vh/04ILvP2Gj8/Z9Jd0Dh0ZIvaucowMEs6abQpWs= github.com/Rosettea/sh/v3 v3.4.0-0.dev.0.20211022004519-f67a49cb50f5/go.mod h1:R09vh/04ILvP2Gj8/Z9Jd0Dh0ZIvaucowMEs6abQpWs=
github.com/bobappleyard/readline v0.0.0-20150707195538-7e300e02d38e h1:4G8AYOOwZdDWOiJR6D6JXaFmj5BDS7c5D5PyqsG/+Hg= github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=
github.com/bobappleyard/readline v0.0.0-20150707195538-7e300e02d38e/go.mod h1:fmqtV+Wqx0uFYLN1F4VhjZdtT56Dr8c3yA7nALFsw/Q= github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9 h1:xz6Nv3zcwO2Lila35hcb0QloCQsc38Al13RNEzWRpX4= github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9 h1:xz6Nv3zcwO2Lila35hcb0QloCQsc38Al13RNEzWRpX4=
github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9/go.mod h1:2wSM9zJkl1UQEFZgSd68NfCgRz1VL1jzy/RjCg+ULrs= github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9/go.mod h1:2wSM9zJkl1UQEFZgSd68NfCgRz1VL1jzy/RjCg+ULrs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0=
github.com/creack/goselect v0.1.2/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= github.com/creack/pty v1.1.15 h1:cKRCLMj3Ddm54bKSpemfQ8AtYFBhAI2MPmdys22fBdc=
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.15/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/creack/pty v1.1.15/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/google/renameio v1.0.1-0.20210406141108-81588dbe0453/go.mod h1:t/HQoYBZSsWSNK35C6CO/TpPLDVWvxOHboWUAweKUpk= github.com/creack/termios v0.0.0-20160714173321-88d0029e36a1 h1:3ZFknr3UZk2E18CuCeA0NMRk226zM/slMEFOmJTtJjI=
github.com/creack/termios v0.0.0-20160714173321-88d0029e36a1/go.mod h1:141QqpYDZtzU1VJMRHPU6ZWkn9K5cE6X8elajH9hJk4=
github.com/evilsocket/islazy v1.10.6 h1:MFq000a1ByoumoJWlytqg0qon0KlBeUfPsDjY0hK0bo=
github.com/evilsocket/islazy v1.10.6/go.mod h1:OrwQGYg3DuZvXUfmH+KIZDjwTCbrjy48T24TUpGqVVw=
github.com/google/renameio v1.0.1/go.mod h1:t/HQoYBZSsWSNK35C6CO/TpPLDVWvxOHboWUAweKUpk= github.com/google/renameio v1.0.1/go.mod h1:t/HQoYBZSsWSNK35C6CO/TpPLDVWvxOHboWUAweKUpk=
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.8 h1:AkaSdXYQOWeaO3neb8EM634ahkXXe3jYbVh/F9lq+GI=
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/maxlandon/readline v0.1.0-beta.0.20211027085530-2b76cabb8036 h1:wJMb6UBj7BSW8dquwo7Hyli7SQ2QmjT4L0xKgIyWy08=
github.com/maxlandon/readline v0.1.0-beta.0.20211027085530-2b76cabb8036/go.mod h1:Yzn6jb/68429mQI+aAVOD9yPFnpl2ZYwWien8gBnupo=
github.com/olekukonko/ts v0.0.0-20171002115256-78ecb04241c0 h1:LiZB1h0GIcudcDci2bxbqI6DXV8bF8POAnArqvRrIyw=
github.com/olekukonko/ts v0.0.0-20171002115256-78ecb04241c0/go.mod h1:F/7q8/HZz+TXjlsoZQQKVYvXTZaFH4QRa3y+j1p7MS0=
github.com/pborman/ansi v1.0.0 h1:OqjHMhvlSuCCV5JT07yqPuJPQzQl+WXsiZ14gZsqOrQ=
github.com/pborman/ansi v1.0.0/go.mod h1:SgWzwMAx1X/Ez7i90VqF8LRiQtx52pWDiQP+x3iGnzw=
github.com/pborman/getopt v1.1.0 h1:eJ3aFZroQqq0bWmraivjQNt6Dmm5M0h2JcDW38/Azb0= github.com/pborman/getopt v1.1.0 h1:eJ3aFZroQqq0bWmraivjQNt6Dmm5M0h2JcDW38/Azb0=
github.com/pborman/getopt v1.1.0/go.mod h1:FxXoW1Re00sQG/+KIkuSqRL/LwQgSkv7uyac+STFsbk= github.com/pborman/getopt v1.1.0/go.mod h1:FxXoW1Re00sQG/+KIkuSqRL/LwQgSkv7uyac+STFsbk=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
@ -37,7 +55,7 @@ github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.7.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.1-0.20210923151022-86f73c517451 h1:d1PiN4RxzIFXCJTvRkvSkKqwtRAl5ZV4lATKtQI0B7I=
github.com/rogpeppe/go-internal v1.8.1-0.20210923151022-86f73c517451/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rogpeppe/go-internal v1.8.1-0.20210923151022-86f73c517451/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
github.com/yuin/gopher-lua v0.0.0-20190206043414-8bfc7677f583/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ= github.com/yuin/gopher-lua v0.0.0-20190206043414-8bfc7677f583/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ=
github.com/yuin/gopher-lua v0.0.0-20210529063254-f4c35e4016d9 h1:k/gmLsJDWwWqbLCur2yWnJzwQEKRcAHXo6seXGuSwWw= github.com/yuin/gopher-lua v0.0.0-20210529063254-f4c35e4016d9 h1:k/gmLsJDWwWqbLCur2yWnJzwQEKRcAHXo6seXGuSwWw=
@ -45,23 +63,21 @@ github.com/yuin/gopher-lua v0.0.0-20210529063254-f4c35e4016d9/go.mod h1:E1AXubJB
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210414055047-fe65e336abe0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210414055047-fe65e336abe0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210603125802-9665404d3644 h1:CA1DEQ4NdKphKeL70tvsWNdT5oFh1lOjihRcEDROi0I=
golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210925032602-92d5a993a665 h1:QOQNt6vCjMpXE7JSK5VvAzJC1byuN3FgTNSBwf+CJgI= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210925032602-92d5a993a665/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210925032602-92d5a993a665/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d h1:FjkYO/PPp4Wi0EAUOVLxePm7qVW4r4ctbWpURyuOD0E=
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20210406210042-72f3dc4e9b72/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210406210042-72f3dc4e9b72/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210503060354-a79de5458b56 h1:b8jxX3zqjpqb2LklXPzKSGJhzyxCOZSz8ncv8Nv+y7w=
golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY=
golang.org/x/term v0.0.0-20210916214954-140adaaadfaf h1:Ihq/mm/suC88gF8WFcVwk+OV6Tq+wyA1O0E5UEvDglI=
golang.org/x/term v0.0.0-20210916214954-140adaaadfaf/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210916214954-140adaaadfaf/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
layeh.com/gopher-luar v1.0.8 h1:Uqws1Z6T0vK6pZ7ehNNurLLSFcz7+E0EOHVM4FNiMQs= layeh.com/gopher-luar v1.0.10 h1:55b0mpBhN9XSshEd2Nz6WsbYXctyBT35azk4POQNSXo=
layeh.com/gopher-luar v1.0.8/go.mod h1:TPnIVCZ2RJBndm7ohXyaqfhzjlZ+OA2SZR/YwL8tECk= layeh.com/gopher-luar v1.0.10/go.mod h1:TPnIVCZ2RJBndm7ohXyaqfhzjlZ+OA2SZR/YwL8tECk=
mvdan.cc/editorconfig v0.2.0/go.mod h1:lvnnD3BNdBYkhq+B4uBuFFKatfp02eB6HixDvEz91C0= mvdan.cc/editorconfig v0.2.0/go.mod h1:lvnnD3BNdBYkhq+B4uBuFFKatfp02eB6HixDvEz91C0=
mvdan.cc/sh/v3 v3.3.0 h1:ujzElMnry63f4I5sjPFxzo6xia+gwsHZM0yyauuyZ6k=
mvdan.cc/sh/v3 v3.3.0/go.mod h1:dh3avhLDhJJ/MJKzbak6FYn+DJKUWk7Fb6Dh5mGdv6Y=

View File

@ -1,6 +1,7 @@
package bait package bait
import ( import (
"fmt"
"hilbish/util" "hilbish/util"
"github.com/chuckpreslar/emission" "github.com/chuckpreslar/emission"
@ -13,8 +14,13 @@ type Bait struct{
} }
func New() Bait { func New() Bait {
emitter := emission.NewEmitter()
emitter.RecoverWith(func(hookname, hookfunc interface{}, err error) {
emitter.Off(hookname, hookfunc)
fmt.Println(err)
})
return Bait{ return Bait{
Em: emission.NewEmitter(), Em: emitter,
} }
} }
@ -32,6 +38,7 @@ failed, etc. To find all available hooks, see doc hooks.`)
L.SetField(mod, "throw", luar.New(L, b.bthrow)) L.SetField(mod, "throw", luar.New(L, b.bthrow))
L.SetField(mod, "catch", luar.New(L, b.bcatch)) L.SetField(mod, "catch", luar.New(L, b.bcatch))
L.SetField(mod, "catchOnce", luar.New(L, b.bcatchOnce))
L.Push(mod) L.Push(mod)
@ -49,3 +56,9 @@ func (b *Bait) bthrow(name string, args ...interface{}) {
func (b *Bait) bcatch(name string, catcher func(...interface{})) { func (b *Bait) bcatch(name string, catcher func(...interface{})) {
b.Em.On(name, catcher) b.Em.On(name, catcher)
} }
// catchOnce(name, cb)
// Same as catch, but only runs the `cb` once and then removes the hook
func (b *Bait) bcatchOnce(name string, catcher func(...interface{})) {
b.Em.Once(name, catcher)
}

View File

@ -18,7 +18,7 @@ func New() Commander {
} }
func (c *Commander) Loader(L *lua.LState) int { func (c *Commander) Loader(L *lua.LState) int {
var exports = map[string]lua.LGFunction{ exports := map[string]lua.LGFunction{
"register": c.cregister, "register": c.cregister,
"deregister": c.cderegister, "deregister": c.cderegister,
} }

View File

@ -5,6 +5,7 @@ package main
import ( import (
"os" "os"
"path/filepath"
"runtime" "runtime"
"strings" "strings"
@ -22,7 +23,7 @@ var exports = map[string]lua.LGFunction {
"read": hlread, "read": hlread,
} }
func HilbishLoader(L *lua.LState) int { func hilbishLoader(L *lua.LState) int {
mod := L.SetFuncs(L.NewTable(), exports) mod := L.SetFuncs(L.NewTable(), exports)
host, _ := os.Hostname() host, _ := os.Hostname()
@ -35,26 +36,37 @@ func HilbishLoader(L *lua.LState) int {
util.SetField(L, mod, "ver", lua.LString(version), "Hilbish version") util.SetField(L, mod, "ver", lua.LString(version), "Hilbish version")
util.SetField(L, mod, "user", lua.LString(username), "Username of user") util.SetField(L, mod, "user", lua.LString(username), "Username of user")
util.SetField(L, mod, "host", lua.LString(host), "Host name of the machine") util.SetField(L, mod, "host", lua.LString(host), "Host name of the machine")
util.SetField(L, mod, "home", lua.LString(homedir), "Home directory of the user") util.SetField(L, mod, "home", lua.LString(curuser.HomeDir), "Home directory of the user")
util.SetField(L, mod, "dataDir", lua.LString(dataDir), "Directory for Hilbish's data files") util.SetField(L, mod, "dataDir", lua.LString(dataDir), "Directory for Hilbish's data files")
util.SetField(L, mod, "interactive", lua.LBool(interactive), "If this is an interactive shell") util.SetField(L, mod, "interactive", lua.LBool(interactive), "If this is an interactive shell")
util.SetField(L, mod, "login", lua.LBool(interactive), "Whether this is a login shell") util.SetField(L, mod, "login", lua.LBool(interactive), "Whether this is a login shell")
xdg := L.NewTable() hshuser := L.NewTable()
L.SetField(xdg, "config", lua.LString(confDir)) userConfigDir, _ := os.UserConfigDir()
L.SetField(xdg, "data", lua.LString(getenv("XDG_DATA_HOME", homedir + "/.local/share"))) userDataDir := ""
L.SetField(mod, "xdg", xdg) // i honestly dont know what directories to use for this
switch runtime.GOOS {
case "linux":
userDataDir = getenv("XDG_DATA_HOME", curuser.HomeDir + "/.local/share")
default:
userDataDir = filepath.Join(userConfigDir)
}
util.Document(L, mod, "A miscellaneous sort of \"core\" API for things that relate to the shell itself and others.") util.SetField(L, hshuser, "config", lua.LString(userConfigDir), "User's config directory")
util.SetField(L, hshuser, "data", lua.LString(userDataDir), "XDG data directory")
util.Document(L, hshuser, "User directories to store configs and/or modules.")
L.SetField(mod, "userDir", hshuser)
util.Document(L, mod, "Hilbish's core API, containing submodules and functions which relate to the shell itself.")
L.Push(mod) L.Push(mod)
return 1 return 1
} }
// run(cmd) // run(cmd)
// Runs `cmd` in Hilbish's sh interpreter // Runs `cmd` in Hilbish's sh interpreter.
func hlrun(L *lua.LState) int { func hlrun(L *lua.LState) int {
var exitcode uint8 = 0 var exitcode uint8
cmd := L.CheckString(1) cmd := L.CheckString(1)
err := execCommand(cmd) err := execCommand(cmd)
@ -73,7 +85,14 @@ func hlrun(L *lua.LState) int {
func hlflag(L *lua.LState) int { func hlflag(L *lua.LState) int {
flagchar := L.CheckString(1) flagchar := L.CheckString(1)
L.Push(lua.LBool(getopt.Lookup([]rune(flagchar)[0]).Seen())) flag := getopt.Lookup([]rune(flagchar)[0])
if flag == nil {
L.Push(lua.LNil)
return 1
}
passed := flag.Seen()
L.Push(lua.LBool(passed))
return 1 return 1
} }
@ -102,7 +121,7 @@ func getenv(key, fallback string) string {
// Returns `input`, will be nil if ctrl + d is pressed, or an error occurs (which shouldn't happen) // Returns `input`, will be nil if ctrl + d is pressed, or an error occurs (which shouldn't happen)
func hlread(L *lua.LState) int { func hlread(L *lua.LState) int {
luaprompt := L.CheckString(1) luaprompt := L.CheckString(1)
lualr := NewLineReader(luaprompt) lualr := newLineReader(luaprompt)
input, err := lualr.Read() input, err := lualr.Read()
if err != nil { if err != nil {

View File

@ -5,11 +5,11 @@ local lunacolors = require 'lunacolors'
local ansikit = {} local ansikit = {}
ansikit.clear = function(scrollback) ansikit.clear = function(scrollback)
typ = (scrollback and 3 or 2) local typ = (scrollback and 3 or 2)
return ansikit.printCSI(typ, 'J') return ansikit.printCSI(typ, 'J')
end end
ansikit.clearFromPos = function(scrollback) ansikit.clearFromPos = function()
return ansikit.printCSI(0, 'J') return ansikit.printCSI(0, 'J')
end end
@ -79,7 +79,7 @@ end
ansikit.link = function(url, text) ansikit.link = function(url, text)
if not url then error 'ansikit: missing url for hyperlink' end if not url then error 'ansikit: missing url for hyperlink' end
local text = (text and text or 'link') text = (text and text or 'link')
return lunacolors.blue('\27]8;;' .. url .. '\27\\' .. text .. '\27]8;;\27\\\n') return lunacolors.blue('\27]8;;' .. url .. '\27\\' .. text .. '\27]8;;\27\\\n')
end end

23
lua.go
View File

@ -17,14 +17,9 @@ import (
"layeh.com/gopher-luar" "layeh.com/gopher-luar"
) )
var minimalconf = ` var minimalconf = `prompt '& '`
lunacolors = require 'lunacolors'
prompt(lunacolors.format(
'{blue}%u {cyan}%d {green}{reset} '
))
`
func LuaInit() { func luaInit() {
l = lua.NewState() l = lua.NewState()
l.OpenLibs() l.OpenLibs()
@ -39,7 +34,7 @@ func LuaInit() {
l.SetGlobal("interval", l.NewFunction(hshinterval)) l.SetGlobal("interval", l.NewFunction(hshinterval))
// yes this is stupid, i know // yes this is stupid, i know
l.PreloadModule("hilbish", HilbishLoader) l.PreloadModule("hilbish", hilbishLoader)
l.DoString("hilbish = require 'hilbish'") l.DoString("hilbish = require 'hilbish'")
// Add fs and terminal module module to Lua // Add fs and terminal module module to Lua
@ -80,7 +75,7 @@ func LuaInit() {
} }
} }
} }
func RunConfig(confpath string) { func runConfig(confpath string) {
if !interactive { if !interactive {
return return
} }
@ -93,14 +88,14 @@ func RunConfig(confpath string) {
} }
} }
func RunLogin() { func runLogin() {
if _, err := os.Stat(homedir + "/.hprofile.lua"); os.IsNotExist(err) { if _, err := os.Stat(curuser.HomeDir + "/.hprofile.lua"); os.IsNotExist(err) {
return return
} }
if !login { if !login {
return return
} }
err := l.DoFile(homedir + "/.hprofile.lua") err := l.DoFile(curuser.HomeDir + "/.hprofile.lua")
if err != nil { if err != nil {
fmt.Fprintln(os.Stderr, err, fmt.Fprintln(os.Stderr, err,
"\nAn error has occured while loading your login config!n") "\nAn error has occured while loading your login config!n")
@ -206,8 +201,8 @@ func hshinterval(L *lua.LState) int {
NRet: 0, NRet: 0,
Protect: true, Protect: true,
}); err != nil { }); err != nil {
fmt.Fprintln(os.Stderr, fmt.Fprintln(os.Stderr, "Error in interval function:\n\n", err)
"Error in interval function:\n\n", err) stop <- lua.LTrue // stop the interval
} }
case <-stop: case <-stop:
ticker.Stop() ticker.Stop()

55
main.go
View File

@ -17,18 +17,16 @@ import (
"github.com/pborman/getopt" "github.com/pborman/getopt"
"github.com/yuin/gopher-lua" "github.com/yuin/gopher-lua"
"golang.org/x/term" "golang.org/x/term"
"layeh.com/gopher-luar"
) )
var ( var (
l *lua.LState l *lua.LState
lr *LineReader lr *lineReader
commands = map[string]*lua.LFunction{} commands = map[string]*lua.LFunction{}
aliases = map[string]string{} aliases = map[string]string{}
luaCompletions = map[string]*lua.LFunction{} luaCompletions = map[string]*lua.LFunction{}
homedir string
confDir string confDir string
curuser *user.User curuser *user.User
@ -38,9 +36,9 @@ var (
) )
func main() { func main() {
homedir, _ = os.UserHomeDir()
confDir = getenv("XDG_CONFIG_HOME", homedir + "/.config")
curuser, _ = user.Current() curuser, _ = user.Current()
homedir := curuser.HomeDir
confDir = getenv("XDG_CONFIG_HOME", homedir + "/.config")
preloadPath = strings.Replace(preloadPath, "~", homedir, 1) preloadPath = strings.Replace(preloadPath, "~", homedir, 1)
sampleConfPath = strings.Replace(sampleConfPath, "~", homedir, 1) sampleConfPath = strings.Replace(sampleConfPath, "~", homedir, 1)
@ -49,7 +47,7 @@ func main() {
if _, err := os.Stat(filepath.Join(confDir, "hilbish")); os.IsNotExist(err) { if _, err := os.Stat(filepath.Join(confDir, "hilbish")); os.IsNotExist(err) {
defaultConfPath = filepath.Join(homedir, "/.hilbishrc.lua") defaultConfPath = filepath.Join(homedir, "/.hilbishrc.lua")
} else { } else {
defaultConfPath = filepath.Join(confDir, "hilbish", "hilbishrc.lua") defaultConfPath = filepath.Join(confDir, "hilbish", "init.lua")
} }
} else { } else {
// else do ~ substitution // else do ~ substitution
@ -140,26 +138,29 @@ func main() {
} }
} }
go HandleSignals() go handleSignals()
LuaInit() luaInit()
RunLogin() runLogin()
RunConfig(*configflag) runConfig(*configflag)
lr = NewLineReader("")
if fileInfo, _ := os.Stdin.Stat(); (fileInfo.Mode() & os.ModeCharDevice) == 0 { if fileInfo, _ := os.Stdin.Stat(); (fileInfo.Mode() & os.ModeCharDevice) == 0 {
scanner := bufio.NewScanner(bufio.NewReader(os.Stdin)) scanner := bufio.NewScanner(bufio.NewReader(os.Stdin))
for scanner.Scan() { for scanner.Scan() {
RunInput(scanner.Text()) runInput(scanner.Text())
} }
} }
if *cmdflag != "" { if *cmdflag != "" {
RunInput(*cmdflag) runInput(*cmdflag)
} }
if getopt.NArgs() > 0 { if getopt.NArgs() > 0 {
l.SetGlobal("args", luar.New(l, getopt.Args())) luaArgs := l.NewTable()
for _, arg := range getopt.Args() {
luaArgs.Append(lua.LString(arg))
}
l.SetGlobal("args", luaArgs)
err := l.DoFile(getopt.Arg(0)) err := l.DoFile(getopt.Arg(0))
if err != nil { if err != nil {
fmt.Fprintln(os.Stderr, err) fmt.Fprintln(os.Stderr, err)
@ -168,6 +169,7 @@ func main() {
os.Exit(0) os.Exit(0)
} }
lr = newLineReader("")
input: input:
for interactive { for interactive {
running = false running = false
@ -192,7 +194,7 @@ input:
if strings.HasSuffix(input, "\\") { if strings.HasSuffix(input, "\\") {
for { for {
input, err = ContinuePrompt(strings.TrimSuffix(input, "\\")) input, err = continuePrompt(strings.TrimSuffix(input, "\\"))
if err != nil { if err != nil {
goto input // continue inside nested loop goto input // continue inside nested loop
} }
@ -201,9 +203,8 @@ input:
} }
} }
} }
running = true handleHistory(input)
HandleHistory(input) runInput(input)
RunInput(input)
termwidth, _, err := term.GetSize(0) termwidth, _, err := term.GetSize(0)
if err != nil { if err != nil {
@ -213,12 +214,11 @@ input:
} }
} }
func ContinuePrompt(prev string) (string, error) { func continuePrompt(prev string) (string, error) {
hooks.Em.Emit("multiline", nil) hooks.Em.Emit("multiline", nil)
lr.SetPrompt(multilinePrompt) lr.SetPrompt(multilinePrompt)
cont, err := lr.Read() cont, err := lr.Read()
if err != nil { if err != nil {
fmt.Println("")
return "", err return "", err
} }
cont = strings.TrimSpace(cont) cont = strings.TrimSpace(cont)
@ -231,7 +231,9 @@ func fmtPrompt() string {
host, _ := os.Hostname() host, _ := os.Hostname()
cwd, _ := os.Getwd() cwd, _ := os.Getwd()
cwd = strings.Replace(cwd, curuser.HomeDir, "~", 1) if strings.HasPrefix(cwd, curuser.HomeDir) {
cwd = "~" + strings.TrimPrefix(cwd, curuser.HomeDir)
}
username := curuser.Username username := curuser.Username
// this will be baked into binary since GOOS is a constant // this will be baked into binary since GOOS is a constant
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
@ -257,8 +259,7 @@ func fmtPrompt() string {
return nprompt return nprompt
} }
// do i even have to say func handleSignals() {
func HandleSignals() {
c := make(chan os.Signal) c := make(chan os.Signal)
signal.Notify(c, os.Interrupt, syscall.SIGWINCH) signal.Notify(c, os.Interrupt, syscall.SIGWINCH)
@ -266,19 +267,19 @@ func HandleSignals() {
switch s { switch s {
case os.Interrupt: case os.Interrupt:
hooks.Em.Emit("signals.sigint") hooks.Em.Emit("signals.sigint")
if !running { if !running && interactive {
lr.ClearInput() lr.ClearInput()
} }
case syscall.SIGWINCH: case syscall.SIGWINCH:
hooks.Em.Emit("signals.resize") hooks.Em.Emit("signals.resize")
if !running { if !running && interactive {
lr.Resize() lr.Resize()
} }
} }
} }
} }
func HandleHistory(cmd string) { func handleHistory(cmd string) {
lr.AddHistory(cmd) lr.AddHistory(cmd)
// TODO: load history again (history shared between sessions like this ye) // TODO: load history again (history shared between sessions like this ye)
} }

View File

@ -1,13 +1,13 @@
-- The preload file initializes everything else for our shell -- The preload file initializes everything else for our shell
local fs = require 'fs'
local commander = require 'commander'
local bait = require 'bait' local bait = require 'bait'
require 'succulent' -- Function additions local commander = require 'commander'
local fs = require 'fs'
local lunacolors = require 'lunacolors'
local _ require 'succulent' -- Function additions
local oldDir = hilbish.cwd() local oldDir = hilbish.cwd()
local shlvl = tonumber(os.getenv 'SHLVL') local shlvl = tonumber(os.getenv 'SHLVL')
if shlvl ~= nil then os.setenv('SHLVL', shlvl + 1) else os.setenv('SHLVL', 1) end if shlvl ~= nil then os.setenv('SHLVL', shlvl + 1) else os.setenv('SHLVL', 0) end
-- Builtins -- Builtins
local recentDirs = {} local recentDirs = {}
@ -38,7 +38,8 @@ commander.register('cd', function (args)
fs.cd(hilbish.home) fs.cd(hilbish.home)
bait.throw('cd', hilbish.home) bait.throw('cd', hilbish.home)
return table.insert(recentDirs, 1, hilbish.home)
recentDirs[11] = nil
end) end)
commander.register('exit', function() commander.register('exit', function()
@ -74,8 +75,9 @@ These are the global Hilbish functions that are always available and not part of
return return
end end
funcdocs = f:read '*a' funcdocs = f:read '*a'
local subdocs = table.map(fs.readdir(moddocPath), function(f) local moddocs = table.filter(fs.readdir(moddocPath), function(f) return f ~= 'index.txt' end)
return lunacolors.underline(lunacolors.blue(string.gsub(f, '.txt', ''))) local subdocs = table.map(moddocs, function(fname)
return lunacolors.underline(lunacolors.blue(string.gsub(fname, '.txt', '')))
end) end)
if subdocName == 'index' then if subdocName == 'index' then
funcdocs = funcdocs .. '\nSubdocs: ' .. table.concat(subdocs, ', ') funcdocs = funcdocs .. '\nSubdocs: ' .. table.concat(subdocs, ', ')
@ -135,8 +137,6 @@ A section is a module or a literal section and a subdoc is a subsection for it.
Available sections: ]] Available sections: ]]
print(table.concat(modules, ', ')) print(table.concat(modules, ', '))
return
end) end)
do do
@ -207,7 +207,6 @@ to get a list of recent directories, use {green}{underline}cdr list{reset}]])
end end
fs.cd(recentDirs[index]) fs.cd(recentDirs[index])
return
end) end)
-- Hook handles -- Hook handles

119
rl.go
View File

@ -1,5 +1,5 @@
//go:build !hilbiline //go:build !hilbiline && !goreadline
// +build !hilbiline // +build !hilbiline,!goreadline
package main package main
@ -16,18 +16,23 @@ import (
"github.com/yuin/gopher-lua" "github.com/yuin/gopher-lua"
) )
type LineReader struct { type lineReader struct {
Prompt string Prompt string
} }
func NewLineReader(prompt string) *LineReader { func newLineReader(prompt string) *lineReader {
readline.Init()
readline.Completer = func(query string, ctx string) []string { readline.Completer = func(query string, ctx string) []string {
var completions []string var completions []string
// trim whitespace from ctx // trim whitespace from ctx
ctx = strings.TrimLeft(ctx, " ") ctx = strings.TrimLeft(ctx, " ")
fields, ctx := splitInput(ctx) if len(ctx) == 0 {
return []string{}
}
fields := strings.Split(ctx, " ")
if len(fields) == 0 { if len(fields) == 0 {
return nil return []string{}
} }
for aliases[fields[0]] != "" { for aliases[fields[0]] != "" {
@ -44,37 +49,23 @@ func NewLineReader(prompt string) *LineReader {
} }
if len(fields) == 1 { if len(fields) == 1 {
prefixes := []string{"./", "../"} prefixes := []string{"./", "../", "/", "~/"}
for _, prefix := range prefixes { for _, prefix := range prefixes {
if strings.HasPrefix(query, prefix) { if strings.HasPrefix(fields[0], prefix) {
if matches, err := filepath.Glob(query + "*"); err == nil { fileCompletions := append(completions, readline.FilenameCompleter(query, ctx)...)
for _, match := range matches { // filter out executables
if info, err := os.Stat(match); err == nil && info.Mode().Perm() & 0100 == 0 { for _, f := range fileCompletions {
continue name := strings.Replace(f, "~", curuser.HomeDir, 1)
} if info, err := os.Stat(name); err == nil && info.Mode().Perm() & 0100 == 0 {
name := filepath.Base(match) continue
completions = append(completions, name)
}
}
if len(completions) == 1 {
// we have add the base dir of query since the completion entries are basename
// why? so readline will display just that
// and we want to complete the full path when its the only completion entry
// query will be incomplete so adding it will be broken
// also Dir doesn't have a trailing slash so we need to filepath join
// to account to windows
// AND ANOTHER THING is it returns . if the arg is ./ and Join will
// ignore that so we have to check and just add the prefix instead
if prefix != "./" {
completions[0] = filepath.Join(filepath.Dir(query), completions[0])
} else {
completions[0] = prefix + completions[0]
} }
completions = append(completions, f)
} }
return completions return completions
} }
} }
// filter out executables, but in path
for _, dir := range filepath.SplitList(os.Getenv("PATH")) { for _, dir := range filepath.SplitList(os.Getenv("PATH")) {
// print dir to stderr for debugging // print dir to stderr for debugging
// search for an executable which matches our query string // search for an executable which matches our query string
@ -116,7 +107,6 @@ func NewLineReader(prompt string) *LineReader {
if cmpTbl, ok := luacompleteTable.(*lua.LTable); ok { if cmpTbl, ok := luacompleteTable.(*lua.LTable); ok {
cmpTbl.ForEach(func(key lua.LValue, value lua.LValue) { cmpTbl.ForEach(func(key lua.LValue, value lua.LValue) {
// print key and value to stderr for debugging
// if key is a number (index), we just check and complete that // if key is a number (index), we just check and complete that
if key.Type() == lua.LTNumber { if key.Type() == lua.LTNumber {
// if we have only 2 fields then this is fine // if we have only 2 fields then this is fine
@ -137,18 +127,53 @@ func NewLineReader(prompt string) *LineReader {
if key.String() == fields[1] { if key.String() == fields[1] {
// if value is a table, we need to iterate over it // if value is a table, we need to iterate over it
// and add each value to completions // and add each value to completions
valueTbl := value.(*lua.LTable) // check if value is either a table or function
valueTbl.ForEach(func(key lua.LValue, value lua.LValue) { if value.Type() == lua.LTTable {
val := value.String() valueTbl := value.(*lua.LTable)
if val == "<file>" { valueTbl.ForEach(func(key lua.LValue, value lua.LValue) {
// complete files val := value.String()
completions = append(completions, readline.FilenameCompleter(query, ctx)...) if val == "<file>" {
} else { // complete files
if strings.HasPrefix(val, query) { completions = append(completions, readline.FilenameCompleter(query, ctx)...)
completions = append(completions, val) } else {
if strings.HasPrefix(val, query) {
completions = append(completions, val)
}
} }
})
} else if value.Type() == lua.LTFunction {
// if value is a function, we need to call it
// and add each value to completions
// completionsCtx is the context we pass to the function,
// removing 2 fields from the fields array
completionsCtx := strings.Join(fields[2:], " ")
err := l.CallByParam(lua.P{
Fn: value,
NRet: 1,
Protect: true,
}, lua.LString(query), lua.LString(completionsCtx))
if err != nil {
return
} }
})
luacompleteTable := l.Get(-1)
l.Pop(1)
// just check if its actually a table and add it to the completions
if cmpTbl, ok := luacompleteTable.(*lua.LTable); ok {
cmpTbl.ForEach(func(key lua.LValue, value lua.LValue) {
val := value.String()
if strings.HasPrefix(val, query) {
completions = append(completions, val)
}
})
}
} else {
// throw lua error
// complete.cmdname: error message...
l.RaiseError("complete." + fields[0] + ": completion value is not a table or function")
}
} }
} }
} }
@ -164,30 +189,30 @@ func NewLineReader(prompt string) *LineReader {
} }
readline.LoadHistory(defaultHistPath) readline.LoadHistory(defaultHistPath)
return &LineReader{ return &lineReader{
Prompt: prompt, Prompt: prompt,
} }
} }
func (lr *LineReader) Read() (string, error) { func (lr *lineReader) Read() (string, error) {
hooks.Em.Emit("command.precmd", nil) hooks.Em.Emit("command.precmd", nil)
return readline.String(lr.Prompt) return readline.String(lr.Prompt)
} }
func (lr *LineReader) SetPrompt(prompt string) { func (lr *lineReader) SetPrompt(prompt string) {
lr.Prompt = prompt lr.Prompt = prompt
} }
func (lr *LineReader) AddHistory(cmd string) { func (lr *lineReader) AddHistory(cmd string) {
readline.AddHistory(cmd) readline.AddHistory(cmd)
readline.SaveHistory(defaultHistPath) readline.SaveHistory(defaultHistPath)
} }
func (lr *LineReader) ClearInput() { func (lr *lineReader) ClearInput() {
readline.ReplaceLine("", 0) readline.ReplaceLine("", 0)
readline.RefreshLine() readline.RefreshLine()
} }
func (lr *LineReader) Resize() { func (lr *lineReader) Resize() {
readline.Resize() readline.Resize()
} }

View File

@ -1,4 +1,4 @@
// +build hilbiline // +build hilbiline,!goreadline
package main package main
@ -8,36 +8,36 @@ package main
import "github.com/Rosettea/Hilbiline" import "github.com/Rosettea/Hilbiline"
type LineReader struct { type lineReader struct {
hl *hilbiline.HilbilineState hl *hilbiline.HilbilineState
} }
// other gophers might hate this naming but this is local, shut up // other gophers might hate this naming but this is local, shut up
func NewLineReader(prompt string) *LineReader { func newLineReader(prompt string) *lineReader {
hl := hilbiline.New(prompt) hl := hilbiline.New(prompt)
return &LineReader{ return &lineReader{
&hl, &hl,
} }
} }
func (lr *LineReader) Read() (string, error) { func (lr *lineReader) Read() (string, error) {
return lr.hl.Read() return lr.hl.Read()
} }
func (lr *LineReader) SetPrompt(prompt string) { func (lr *lineReader) SetPrompt(prompt string) {
lr.hl.SetPrompt(prompt) lr.hl.SetPrompt(prompt)
} }
func (lr *LineReader) AddHistory(cmd string) { func (lr *lineReader) AddHistory(cmd string) {
return return
} }
func (lr *LineReader) ClearInput() { func (lr *lineReader) ClearInput() {
return return
} }
func (lr *LineReader) Resize() { func (lr *lineReader) Resize() {
return return
} }

65
rl_readline-go.go 100644
View File

@ -0,0 +1,65 @@
// +build goreadline,!hilbiline
package main
// Here we define a generic interface for readline and hilbiline,
// making them interchangable during build time
// this is hilbiline's, as is obvious by the filename
import (
"io"
"strings"
"fmt"
"github.com/maxlandon/readline"
)
type lineReader struct {
rl *readline.Instance
}
// other gophers might hate this naming but this is local, shut up
func newLineReader(prompt string) *lineReader {
rl := readline.NewInstance()
rl.Multiline = true
return &lineReader{
rl,
}
}
func (lr *lineReader) Read() (string, error) {
s, err := lr.rl.Readline()
// this is so dumb
if err == readline.EOF {
return "", io.EOF
}
return s, err // might get another error
}
func (lr *lineReader) SetPrompt(prompt string) {
halfPrompt := strings.Split(prompt, "\n")
if len(halfPrompt) > 1 {
lr.rl.SetPrompt(strings.Join(halfPrompt[:len(halfPrompt) - 1], "\n"))
lr.rl.MultilinePrompt = halfPrompt[len(halfPrompt) - 1:][0]
} else {
// print cursor up ansi code
fmt.Printf("\033[1A")
lr.rl.SetPrompt("")
lr.rl.MultilinePrompt = halfPrompt[len(halfPrompt) - 1:][0]
}
}
func (lr *lineReader) AddHistory(cmd string) {
return
}
func (lr *lineReader) ClearInput() {
return
}
func (lr *lineReader) Resize() {
return
}

View File

@ -14,7 +14,8 @@ import (
"mvdan.cc/sh/v3/syntax" "mvdan.cc/sh/v3/syntax"
) )
func RunInput(input string) { func runInput(input string) {
running = true
cmdArgs, cmdString := splitInput(input) cmdArgs, cmdString := splitInput(input)
// If alias was found, use command alias // If alias was found, use command alias
@ -60,7 +61,7 @@ func RunInput(input string) {
// If input is incomplete, start multiline prompting // If input is incomplete, start multiline prompting
if syntax.IsIncomplete(err) { if syntax.IsIncomplete(err) {
for { for {
cmdString, err = ContinuePrompt(strings.TrimSuffix(cmdString, "\\")) cmdString, err = continuePrompt(strings.TrimSuffix(cmdString, "\\"))
if err != nil { if err != nil {
break break
} }
@ -132,7 +133,7 @@ func execCommand(cmd string) error {
} }
luaexitcode := l.Get(-1) luaexitcode := l.Get(-1)
var exitcode uint8 = 0 var exitcode uint8
l.Pop(1) l.Pop(1)
@ -166,6 +167,13 @@ func execCommand(cmd string) error {
// custom lookpath function so we know if a command is found *and* has execute permission // custom lookpath function so we know if a command is found *and* has execute permission
func lookpath(file string) error { func lookpath(file string) error {
skip := []string{"./", "/", "../", "~/"}
for _, s := range skip {
if strings.HasPrefix(file, s) {
err := findExecutable(file)
return err
}
}
for _, dir := range filepath.SplitList(os.Getenv("PATH")) { for _, dir := range filepath.SplitList(os.Getenv("PATH")) {
path := filepath.Join(dir, file) path := filepath.Join(dir, file)
err := findExecutable(path) err := findExecutable(path)

View File

@ -2,7 +2,7 @@ package main
// String vars that are free to be changed at compile time // String vars that are free to be changed at compile time
var ( var (
version = "v0.7.0" version = "v0.7.1"
defaultConfDir = "" // ~ will be substituted for home, path for user's default config defaultConfDir = "" // ~ will be substituted for home, path for user's default config
defaultHistDir = "" defaultHistDir = ""
commonRequirePaths = "';./libs/?/init.lua;./?/init.lua;./?/?.lua'" commonRequirePaths = "';./libs/?/init.lua;./?/init.lua;./?/?.lua'"

View File

@ -8,12 +8,12 @@ var (
.. hilbish.dataDir .. '/libs/?/init.lua;' .. hilbish.dataDir .. '/libs/?/init.lua;'
.. hilbish.dataDir .. '/libs/?/?.lua;'` + linuxUserPaths .. hilbish.dataDir .. '/libs/?/?.lua;'` + linuxUserPaths
linuxUserPaths = ` linuxUserPaths = `
.. hilbish.xdg.data .. '/hilbish/libs/?/init.lua;' .. hilbish.userDir.data .. '/hilbish/libs/?/init.lua;'
.. hilbish.xdg.data .. '/hilbish/libs/?/?.lua;' .. hilbish.userDir.data .. '/hilbish/libs/?/?.lua;'
.. hilbish.xdg.data .. '/hilbish/libs/?.lua;' .. hilbish.userDir.data .. '/hilbish/libs/?.lua;'
.. hilbish.xdg.config .. '/hilbish/?/init.lua;' .. hilbish.userDir.config .. '/hilbish/?/init.lua;'
.. hilbish.xdg.config .. '/hilbish/?/?.lua;' .. hilbish.userDir.config .. '/hilbish/?/?.lua;'
.. hilbish.xdg.config .. '/hilbish/?.lua'` .. hilbish.userDir.config .. '/hilbish/?.lua'`
dataDir = "/usr/share/hilbish" dataDir = "/usr/share/hilbish"
preloadPath = dataDir + "/preload.lua" preloadPath = dataDir + "/preload.lua"
sampleConfPath = dataDir + "/.hilbishrc.lua" // Path to default/sample config sampleConfPath = dataDir + "/.hilbishrc.lua" // Path to default/sample config

View File

@ -4,9 +4,10 @@ package main
// 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.home .. '\\Appdata\\Roaming\\Hilbish\\libs\\?\\init.lua;' .. hilbish.user.config .. '\\Hilbish\\libs\\?\\init.lua;'
.. hilbish.home .. '\\Appdata\\Roaming\\Hilbish\\libs\\?\\?.lua;'` .. hilbish.user.config .. '\\Hilbish\\libs\\?\\?.lua;'
.. hilbish.user.config .. '\\Hilbish\\libs\\?.lua;'`
dataDir = "~\\Appdata\\Roaming\\Hilbish" // ~ and \ gonna cry? dataDir = "~\\Appdata\\Roaming\\Hilbish" // ~ and \ gonna cry?
preloadPath = dataDir + "\\preload.lua" preloadPath = dataDir + "\\preload.lua"
sampleConfPath = dataDir + "\\hilbishrc.lua" // Path to default/sample config sampleConfPath = dataDir + "\\hilbishrc.lua" // Path to default/sample config