Compare commits

..

No commits in common. "fe8372379c650d5a5a98688daadc4e8772ffd7d7" and "65435572d4d329997931401b4a627061ccadcd17" have entirely different histories.

20 changed files with 172 additions and 337 deletions

View File

@ -2,11 +2,6 @@
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.
@ -289,7 +284,6 @@ 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. We use [SemVer](http://semver.org/) for versioning and 3. The versioning scheme we use is [SemVer](http://semver.org/) and the
[Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) commit scheme we use is
for commit messages. [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).
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,6 +1,4 @@
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,12 +2,6 @@ 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
@ -16,8 +10,6 @@ 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,23 +3,16 @@ module hilbish
go 1.16 go 1.16
require ( require (
github.com/Rosettea/Hilbiline v0.0.0-20210624011007-8088a2d84b65 github.com/Rosettea/Hilbiline v0.0.0-20210603231612-80054dac3650
github.com/Rosettea/readline v0.0.0-20211206201906-5570232ed3b3 github.com/Rosettea/readline v0.0.0-20211122152601-6d95ce44b7ed
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/sys v0.0.0-20211205182925-97ca703d548d // indirect golang.org/x/term v0.0.0-20210916214954-140adaaadfaf
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 layeh.com/gopher-luar v1.0.8
layeh.com/gopher-luar v1.0.10 mvdan.cc/sh/v3 v3.3.0
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,53 +1,35 @@
github.com/Rosettea/Hilbiline v0.0.0-20210624011007-8088a2d84b65 h1:z6alP313nLg1U/V3bKSd6849L/A2LxDSwKv4CPqqzDk= github.com/Rosettea/Hilbiline v0.0.0-20210603231612-80054dac3650 h1:nzFJUdJU8UJ1DA8mSQp4eoBtQyOJyecekVWusjfQsqE=
github.com/Rosettea/Hilbiline v0.0.0-20210624011007-8088a2d84b65/go.mod h1:/FFZ4cgR6TXXYaskRUxyLIYdfG0PS4BPtWjWRQms754= github.com/Rosettea/Hilbiline v0.0.0-20210603231612-80054dac3650/go.mod h1:/FFZ4cgR6TXXYaskRUxyLIYdfG0PS4BPtWjWRQms754=
github.com/Rosettea/Hilbiline v0.0.0-20210710124707-aa6e3ff34cb2 h1:6f1umn6mkodpGf6rK9LZjr4Gut2uS+b8QLoFBFTeOE8= github.com/Rosettea/readline v0.0.0-20211122152601-6d95ce44b7ed h1:sGsGPG+b5h9OR1GjM0PiM4iemB9hmi0o8cg2YRSRKko=
github.com/Rosettea/Hilbiline v0.0.0-20210710124707-aa6e3ff34cb2/go.mod h1:0J2+sRC+d4a3swcH20sVlFvYUEXASvGTHJnVTTI4S9w= github.com/Rosettea/readline v0.0.0-20211122152601-6d95ce44b7ed/go.mod h1:OH+WJSCks0t2ISvaCFUT4ZxNGr4Etq4ju9JE/UxH/5o=
github.com/Rosettea/readline v0.0.0-20211206201906-5570232ed3b3 h1:y+BeaQipF8CuIIkIjvGO7TWlA03t9Nlq+m+cSwXEJ7I= github.com/Rosettea/sh/v3 v3.3.0 h1:0/xmOfzpy46gB1I2oPj8QwdYvyJzpdF5STcgNPRQHcI=
github.com/Rosettea/readline v0.0.0-20211206201906-5570232ed3b3/go.mod h1:OH+WJSCks0t2ISvaCFUT4ZxNGr4Etq4ju9JE/UxH/5o= github.com/Rosettea/sh/v3 v3.3.0/go.mod h1:dh3avhLDhJJ/MJKzbak6FYn+DJKUWk7Fb6Dh5mGdv6Y=
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/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8= github.com/bobappleyard/readline v0.0.0-20150707195538-7e300e02d38e h1:4G8AYOOwZdDWOiJR6D6JXaFmj5BDS7c5D5PyqsG/+Hg=
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo= github.com/bobappleyard/readline v0.0.0-20150707195538-7e300e02d38e/go.mod h1:fmqtV+Wqx0uFYLN1F4VhjZdtT56Dr8c3yA7nALFsw/Q=
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.15 h1:cKRCLMj3Ddm54bKSpemfQ8AtYFBhAI2MPmdys22fBdc= github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
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/creack/termios v0.0.0-20160714173321-88d0029e36a1 h1:3ZFknr3UZk2E18CuCeA0NMRk226zM/slMEFOmJTtJjI= 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/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.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
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=
@ -55,7 +37,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.8.1-0.20210923151022-86f73c517451 h1:d1PiN4RxzIFXCJTvRkvSkKqwtRAl5ZV4lATKtQI0B7I= github.com/rogpeppe/go-internal v1.7.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
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=
@ -63,21 +45,23 @@ 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-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210925032602-92d5a993a665 h1:QOQNt6vCjMpXE7JSK5VvAzJC1byuN3FgTNSBwf+CJgI=
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.10 h1:55b0mpBhN9XSshEd2Nz6WsbYXctyBT35azk4POQNSXo= layeh.com/gopher-luar v1.0.8 h1:Uqws1Z6T0vK6pZ7ehNNurLLSFcz7+E0EOHVM4FNiMQs=
layeh.com/gopher-luar v1.0.10/go.mod h1:TPnIVCZ2RJBndm7ohXyaqfhzjlZ+OA2SZR/YwL8tECk= layeh.com/gopher-luar v1.0.8/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,7 +1,6 @@
package bait package bait
import ( import (
"fmt"
"hilbish/util" "hilbish/util"
"github.com/chuckpreslar/emission" "github.com/chuckpreslar/emission"
@ -14,13 +13,8 @@ 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: emitter, Em: emission.NewEmitter(),
} }
} }
@ -38,7 +32,6 @@ 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)
@ -56,9 +49,3 @@ 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 {
exports := map[string]lua.LGFunction{ var exports = map[string]lua.LGFunction{
"register": c.cregister, "register": c.cregister,
"deregister": c.cderegister, "deregister": c.cderegister,
} }

View File

@ -5,7 +5,6 @@ package main
import ( import (
"os" "os"
"path/filepath"
"runtime" "runtime"
"strings" "strings"
@ -23,7 +22,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()
@ -36,37 +35,26 @@ 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(curuser.HomeDir), "Home directory of the user") util.SetField(L, mod, "home", lua.LString(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")
hshuser := L.NewTable() xdg := L.NewTable()
userConfigDir, _ := os.UserConfigDir() L.SetField(xdg, "config", lua.LString(confDir))
userDataDir := "" L.SetField(xdg, "data", lua.LString(getenv("XDG_DATA_HOME", homedir + "/.local/share")))
// i honestly dont know what directories to use for this L.SetField(mod, "xdg", xdg)
switch runtime.GOOS {
case "linux":
userDataDir = getenv("XDG_DATA_HOME", curuser.HomeDir + "/.local/share")
default:
userDataDir = filepath.Join(userConfigDir)
}
util.SetField(L, hshuser, "config", lua.LString(userConfigDir), "User's config directory") util.Document(L, mod, "A miscellaneous sort of \"core\" API for things that relate to the shell itself and others.")
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 var exitcode uint8 = 0
cmd := L.CheckString(1) cmd := L.CheckString(1)
err := execCommand(cmd) err := execCommand(cmd)
@ -85,14 +73,7 @@ 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)
flag := getopt.Lookup([]rune(flagchar)[0]) L.Push(lua.LBool(getopt.Lookup([]rune(flagchar)[0]).Seen()))
if flag == nil {
L.Push(lua.LNil)
return 1
}
passed := flag.Seen()
L.Push(lua.LBool(passed))
return 1 return 1
} }
@ -121,7 +102,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)
local typ = (scrollback and 3 or 2) typ = (scrollback and 3 or 2)
return ansikit.printCSI(typ, 'J') return ansikit.printCSI(typ, 'J')
end end
ansikit.clearFromPos = function() ansikit.clearFromPos = function(scrollback)
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
text = (text and text or 'link') local 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,9 +17,14 @@ import (
"layeh.com/gopher-luar" "layeh.com/gopher-luar"
) )
var minimalconf = `prompt '& '` var minimalconf = `
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()
@ -34,7 +39,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
@ -75,7 +80,7 @@ func luaInit() {
} }
} }
} }
func runConfig(confpath string) { func RunConfig(confpath string) {
if !interactive { if !interactive {
return return
} }
@ -88,14 +93,14 @@ func runConfig(confpath string) {
} }
} }
func runLogin() { func RunLogin() {
if _, err := os.Stat(curuser.HomeDir + "/.hprofile.lua"); os.IsNotExist(err) { if _, err := os.Stat(homedir + "/.hprofile.lua"); os.IsNotExist(err) {
return return
} }
if !login { if !login {
return return
} }
err := l.DoFile(curuser.HomeDir + "/.hprofile.lua") err := l.DoFile(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")
@ -201,8 +206,8 @@ func hshinterval(L *lua.LState) int {
NRet: 0, NRet: 0,
Protect: true, Protect: true,
}); err != nil { }); err != nil {
fmt.Fprintln(os.Stderr, "Error in interval function:\n\n", err) fmt.Fprintln(os.Stderr,
stop <- lua.LTrue // stop the interval "Error in interval function:\n\n", err)
} }
case <-stop: case <-stop:
ticker.Stop() ticker.Stop()

55
main.go
View File

@ -17,16 +17,18 @@ 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
@ -36,9 +38,9 @@ var (
) )
func main() { func main() {
curuser, _ = user.Current() homedir, _ = os.UserHomeDir()
homedir := curuser.HomeDir
confDir = getenv("XDG_CONFIG_HOME", homedir + "/.config") confDir = getenv("XDG_CONFIG_HOME", homedir + "/.config")
curuser, _ = user.Current()
preloadPath = strings.Replace(preloadPath, "~", homedir, 1) preloadPath = strings.Replace(preloadPath, "~", homedir, 1)
sampleConfPath = strings.Replace(sampleConfPath, "~", homedir, 1) sampleConfPath = strings.Replace(sampleConfPath, "~", homedir, 1)
@ -47,7 +49,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", "init.lua") defaultConfPath = filepath.Join(confDir, "hilbish", "hilbishrc.lua")
} }
} else { } else {
// else do ~ substitution // else do ~ substitution
@ -138,29 +140,26 @@ 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 {
luaArgs := l.NewTable() l.SetGlobal("args", luar.New(l, getopt.Args()))
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)
@ -169,7 +168,6 @@ func main() {
os.Exit(0) os.Exit(0)
} }
lr = newLineReader("")
input: input:
for interactive { for interactive {
running = false running = false
@ -194,7 +192,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
} }
@ -203,8 +201,9 @@ input:
} }
} }
} }
handleHistory(input) running = true
runInput(input) HandleHistory(input)
RunInput(input)
termwidth, _, err := term.GetSize(0) termwidth, _, err := term.GetSize(0)
if err != nil { if err != nil {
@ -214,11 +213,12 @@ 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,9 +231,7 @@ func fmtPrompt() string {
host, _ := os.Hostname() host, _ := os.Hostname()
cwd, _ := os.Getwd() cwd, _ := os.Getwd()
if strings.HasPrefix(cwd, curuser.HomeDir) { cwd = strings.Replace(cwd, curuser.HomeDir, "~", 1)
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" {
@ -259,7 +257,8 @@ func fmtPrompt() string {
return nprompt return nprompt
} }
func handleSignals() { // do i even have to say
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)
@ -267,19 +266,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 && interactive { if !running {
lr.ClearInput() lr.ClearInput()
} }
case syscall.SIGWINCH: case syscall.SIGWINCH:
hooks.Em.Emit("signals.resize") hooks.Em.Emit("signals.resize")
if !running && interactive { if !running {
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 bait = require 'bait'
local commander = require 'commander'
local fs = require 'fs' local fs = require 'fs'
local lunacolors = require 'lunacolors' local commander = require 'commander'
local _ require 'succulent' -- Function additions local bait = require 'bait'
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', 0) end if shlvl ~= nil then os.setenv('SHLVL', shlvl + 1) else os.setenv('SHLVL', 1) end
-- Builtins -- Builtins
local recentDirs = {} local recentDirs = {}
@ -38,8 +38,7 @@ commander.register('cd', function (args)
fs.cd(hilbish.home) fs.cd(hilbish.home)
bait.throw('cd', hilbish.home) bait.throw('cd', hilbish.home)
table.insert(recentDirs, 1, hilbish.home) return
recentDirs[11] = nil
end) end)
commander.register('exit', function() commander.register('exit', function()
@ -75,9 +74,8 @@ 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 moddocs = table.filter(fs.readdir(moddocPath), function(f) return f ~= 'index.txt' end) local subdocs = table.map(fs.readdir(moddocPath), function(f)
local subdocs = table.map(moddocs, function(fname) return lunacolors.underline(lunacolors.blue(string.gsub(f, '.txt', '')))
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, ', ')
@ -137,6 +135,8 @@ 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,6 +207,7 @@ 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 && !goreadline //go:build !hilbiline
// +build !hilbiline,!goreadline // +build !hilbiline
package main package main
@ -16,23 +16,18 @@ 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, " ")
if len(ctx) == 0 { fields, ctx := splitInput(ctx)
return []string{}
}
fields := strings.Split(ctx, " ")
if len(fields) == 0 { if len(fields) == 0 {
return []string{} return nil
} }
for aliases[fields[0]] != "" { for aliases[fields[0]] != "" {
@ -49,23 +44,37 @@ 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(fields[0], prefix) { if strings.HasPrefix(query, prefix) {
fileCompletions := append(completions, readline.FilenameCompleter(query, ctx)...) if matches, err := filepath.Glob(query + "*"); err == nil {
// filter out executables for _, match := range matches {
for _, f := range fileCompletions { if info, err := os.Stat(match); err == nil && info.Mode().Perm() & 0100 == 0 {
name := strings.Replace(f, "~", curuser.HomeDir, 1) continue
if info, err := os.Stat(name); err == nil && info.Mode().Perm() & 0100 == 0 { }
continue name := filepath.Base(match)
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
@ -107,6 +116,7 @@ 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
@ -127,53 +137,18 @@ 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
// check if value is either a table or function valueTbl := value.(*lua.LTable)
if value.Type() == lua.LTTable { valueTbl.ForEach(func(key lua.LValue, value lua.LValue) {
valueTbl := value.(*lua.LTable) val := value.String()
valueTbl.ForEach(func(key lua.LValue, value lua.LValue) { if val == "<file>" {
val := value.String() // complete files
if val == "<file>" { completions = append(completions, readline.FilenameCompleter(query, ctx)...)
// complete files } else {
completions = append(completions, readline.FilenameCompleter(query, ctx)...) if strings.HasPrefix(val, query) {
} else { completions = append(completions, val)
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")
}
} }
} }
} }
@ -189,30 +164,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,!goreadline // +build hilbiline
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
} }

View File

@ -1,65 +0,0 @@
// +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,8 +14,7 @@ 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
@ -61,7 +60,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
} }
@ -133,7 +132,7 @@ func execCommand(cmd string) error {
} }
luaexitcode := l.Get(-1) luaexitcode := l.Get(-1)
var exitcode uint8 var exitcode uint8 = 0
l.Pop(1) l.Pop(1)
@ -167,13 +166,6 @@ 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.1" version = "v0.7.0"
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.userDir.data .. '/hilbish/libs/?/init.lua;' .. hilbish.xdg.data .. '/hilbish/libs/?/init.lua;'
.. hilbish.userDir.data .. '/hilbish/libs/?/?.lua;' .. hilbish.xdg.data .. '/hilbish/libs/?/?.lua;'
.. hilbish.userDir.data .. '/hilbish/libs/?.lua;' .. hilbish.xdg.data .. '/hilbish/libs/?.lua;'
.. hilbish.userDir.config .. '/hilbish/?/init.lua;' .. hilbish.xdg.config .. '/hilbish/?/init.lua;'
.. hilbish.userDir.config .. '/hilbish/?/?.lua;' .. hilbish.xdg.config .. '/hilbish/?/?.lua;'
.. hilbish.userDir.config .. '/hilbish/?.lua'` .. hilbish.xdg.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,10 +4,9 @@ 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.user.config .. '\\Hilbish\\libs\\?\\init.lua;' .. hilbish.home .. '\\Appdata\\Roaming\\Hilbish\\libs\\?\\init.lua;'
.. hilbish.user.config .. '\\Hilbish\\libs\\?\\?.lua;' .. hilbish.home .. '\\Appdata\\Roaming\\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