Compare commits

..

No commits in common. "babb870383217362b3977aa3750865748e769a18" and "b221921ab7e2214e4107a89d7e8b00fe3f31424b" have entirely different histories.

12 changed files with 320 additions and 161 deletions

View File

@ -6,17 +6,13 @@ on:
jobs: jobs:
build: build:
name: ${{ matrix.goos }}-${{ matrix.goarch }} name: ${{ matrix.build }}
runs-on: ubuntu-latest runs-on: ${{ matrix.os }}
strategy: strategy:
matrix: matrix:
goos: [linux, windows, darwin] include:
goarch: ["386", amd64, arm64] - build: linux-amd64
exclude: os: ubuntu-latest
- goarch: "386"
goos: darwin
- goarch: arm64
goos: windows
steps: steps:
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v2 uses: actions/checkout@v2
@ -25,11 +21,11 @@ jobs:
- name: Setup Go - name: Setup Go
uses: actions/setup-go@v2 uses: actions/setup-go@v2
with: with:
go-version: '1.17.7' go-version: '1.16.2'
- name: Build - name: Build
run: GOARCH=${{ matrix.goarch }} go build run: make hilbiline
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v2
with: with:
name: hilbish-${{ matrix.goos }}-${{ matrix.goarch }} name: hilbish-${{ matrix.build }}
path: hilbish path: hilbish

View File

@ -19,7 +19,6 @@ with Lua
- Home dir is now added to recent dirs (the case of cd with no arg) - Home dir is now added to recent dirs (the case of cd with no arg)
- `index` subdoc will no longer appear - `index` subdoc will no longer appear
- Alias expansion with quotes - Alias expansion with quotes
- Add full command to history in the case of incomplete input
### Changed ### Changed
- The minimal config is truly minimal now - The minimal config is truly minimal now

View File

@ -9,6 +9,9 @@ build:
dev: dev:
@go build -ldflags "-s -w -X main.version=$(shell git describe --tags)" @go build -ldflags "-s -w -X main.version=$(shell git describe --tags)"
hilbiline:
@go build -ldflags "-s -w -X main.version=$(shell git describe --tags)+hilbiline" -tags hilbiline
install: install:
@install -v -d "$(DESTDIR)$(BINDIR)/" && install -m 0755 -v hilbish "$(DESTDIR)$(BINDIR)/hilbish" @install -v -d "$(DESTDIR)$(BINDIR)/" && install -m 0755 -v hilbish "$(DESTDIR)$(BINDIR)/hilbish"
@mkdir -p "$(DESTDIR)$(LIBDIR)" @mkdir -p "$(DESTDIR)$(LIBDIR)"

2
api.go
View File

@ -88,7 +88,7 @@ The nice lil shell for {blue}Lua{reset} fanatics!
func hlrun(L *lua.LState) int { func hlrun(L *lua.LState) int {
var exitcode uint8 var exitcode uint8
cmd := L.CheckString(1) cmd := L.CheckString(1)
err := execCommand(cmd, cmd) err := execCommand(cmd)
if code, ok := interp.IsExitStatus(err); ok { if code, ok := interp.IsExitStatus(err); ok {
exitcode = code exitcode = code

View File

@ -1,59 +0,0 @@
package main
import (
"path/filepath"
"strings"
"os"
)
func fileComplete(query, ctx string, fields []string) []string {
var completions []string
prefixes := []string{"./", "../", "/", "~/"}
for _, prefix := range prefixes {
if strings.HasPrefix(query, prefix) {
completions, _ = matchPath(strings.Replace(query, "~", curuser.HomeDir, 1), query)
}
}
if len(completions) == 0 && len(fields) > 1 {
completions, _ = matchPath("./" + query, query)
}
return completions
}
func matchPath(path, pref string) ([]string, error) {
var entries []string
matches, err := filepath.Glob(path + "*")
if err == nil {
args := []string{
"\"", "\\\"",
"'", "\\'",
"`", "\\`",
" ", "\\ ",
"(", "\\(",
")", "\\)",
"[", "\\[",
"]", "\\]",
}
r := strings.NewReplacer(args...)
for _, match := range matches {
name := filepath.Base(match)
p := filepath.Base(pref)
if pref == "" {
p = ""
}
name = strings.TrimPrefix(name, p)
matchFull, _ := filepath.Abs(match)
if info, err := os.Stat(matchFull); err == nil && info.IsDir() {
name = name + string(os.PathSeparator)
}
name = r.Replace(name)
entries = append(entries, name)
}
}
return entries, err
}

26
exec.go
View File

@ -15,7 +15,7 @@ import (
"mvdan.cc/sh/v3/syntax" "mvdan.cc/sh/v3/syntax"
) )
func runInput(input, origInput string) { func runInput(input string) {
running = true running = true
cmdString := aliases.Resolve(input) cmdString := aliases.Resolve(input)
@ -39,12 +39,12 @@ func runInput(input, origInput string) {
err = l.PCall(0, lua.MultRet, nil) err = l.PCall(0, lua.MultRet, nil)
} }
if err == nil { if err == nil {
cmdFinish(0, cmdString, origInput) cmdFinish(0, cmdString)
return return
} }
// Last option: use sh interpreter // Last option: use sh interpreter
err = execCommand(cmdString, origInput) err = execCommand(cmdString)
if err != nil { if err != nil {
// If input is incomplete, start multiline prompting // If input is incomplete, start multiline prompting
if syntax.IsIncomplete(err) { if syntax.IsIncomplete(err) {
@ -53,31 +53,31 @@ func runInput(input, origInput string) {
if err != nil { if err != nil {
break break
} }
err = execCommand(cmdString, origInput) err = execCommand(cmdString)
if syntax.IsIncomplete(err) || strings.HasSuffix(input, "\\") { if syntax.IsIncomplete(err) || strings.HasSuffix(input, "\\") {
continue continue
} else if code, ok := interp.IsExitStatus(err); ok { } else if code, ok := interp.IsExitStatus(err); ok {
cmdFinish(code, cmdString, origInput) cmdFinish(code, cmdString)
} else if err != nil { } else if err != nil {
fmt.Fprintln(os.Stderr, err) fmt.Fprintln(os.Stderr, err)
cmdFinish(1, cmdString, origInput) cmdFinish(1, cmdString)
} }
break break
} }
} else { } else {
if code, ok := interp.IsExitStatus(err); ok { if code, ok := interp.IsExitStatus(err); ok {
cmdFinish(code, cmdString, origInput) cmdFinish(code, cmdString)
} else { } else {
fmt.Fprintln(os.Stderr, err) fmt.Fprintln(os.Stderr, err)
} }
} }
} else { } else {
cmdFinish(0, cmdString, origInput) cmdFinish(0, cmdString)
} }
} }
// Run command in sh interpreter // Run command in sh interpreter
func execCommand(cmd, old string) error { func execCommand(cmd string) error {
file, err := syntax.NewParser().Parse(strings.NewReader(cmd), "") file, err := syntax.NewParser().Parse(strings.NewReader(cmd), "")
if err != nil { if err != nil {
return err return err
@ -127,7 +127,7 @@ func execCommand(cmd, old string) error {
exitcode = uint8(code) exitcode = uint8(code)
} }
cmdFinish(exitcode, argstring, old) cmdFinish(exitcode, argstring)
return interp.NewExitStatus(exitcode) return interp.NewExitStatus(exitcode)
} }
@ -237,10 +237,6 @@ func splitInput(input string) ([]string, string) {
return cmdArgs, cmdstr.String() return cmdArgs, cmdstr.String()
} }
func cmdFinish(code uint8, cmdstr, oldInput string) { func cmdFinish(code uint8, cmdstr string) {
// if input has space at the beginning, dont put in history
if !strings.HasPrefix(oldInput, " ") || interactive {
handleHistory(cmdstr)
}
hooks.Em.Emit("command.exit", code, cmdstr) hooks.Em.Emit("command.exit", code, cmdstr)
} }

8
go.mod
View File

@ -3,8 +3,16 @@ module hilbish
go 1.16 go 1.16
require ( require (
github.com/Rosettea/Hilbiline v0.0.0-20210624011007-8088a2d84b65
github.com/Rosettea/readline v0.0.0-20211207004608-4afb088da503
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/maxlandon/readline v0.1.0-beta.0.20211027085530-2b76cabb8036 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-20220224120231-95c6836cb0e7 // indirect golang.org/x/sys v0.0.0-20220224120231-95c6836cb0e7 // indirect

29
go.sum
View File

@ -1,3 +1,9 @@
github.com/Rosettea/Hilbiline v0.0.0-20210624011007-8088a2d84b65 h1:z6alP313nLg1U/V3bKSd6849L/A2LxDSwKv4CPqqzDk=
github.com/Rosettea/Hilbiline v0.0.0-20210624011007-8088a2d84b65/go.mod h1:/FFZ4cgR6TXXYaskRUxyLIYdfG0PS4BPtWjWRQms754=
github.com/Rosettea/Hilbiline v0.0.0-20210710124707-aa6e3ff34cb2 h1:6f1umn6mkodpGf6rK9LZjr4Gut2uS+b8QLoFBFTeOE8=
github.com/Rosettea/Hilbiline v0.0.0-20210710124707-aa6e3ff34cb2/go.mod h1:0J2+sRC+d4a3swcH20sVlFvYUEXASvGTHJnVTTI4S9w=
github.com/Rosettea/readline v0.0.0-20211207004608-4afb088da503 h1:hA2kXBwY8SFH3+PT67CkoUjlMuRN08RSEtsKjwQ+of4=
github.com/Rosettea/readline v0.0.0-20211207004608-4afb088da503/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 h1:KBttN41h/tPahmpaZavviwQ8q4rCkt5CD0HdVmfgPVA=
github.com/Rosettea/readline-1 v0.1.0-beta.0.20211207003625-341c7985ad7d/go.mod h1:QiUAvbhg8PzCA4hlafCUl0bKD/0VmcocM4AjqtszAJs= 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=
@ -9,9 +15,14 @@ github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9/go.mod h1:2w
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.15 h1:cKRCLMj3Ddm54bKSpemfQ8AtYFBhAI2MPmdys22fBdc=
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/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 h1:MFq000a1ByoumoJWlytqg0qon0KlBeUfPsDjY0hK0bo=
github.com/evilsocket/islazy v1.10.6/go.mod h1:OrwQGYg3DuZvXUfmH+KIZDjwTCbrjy48T24TUpGqVVw= 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=
@ -20,16 +31,27 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
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/layeh/gopher-luar v1.0.10 h1:8NIv4MX1Arz96kK4buGK1D87DyDxKZyq6KKvJ2diHp0= github.com/layeh/gopher-luar v1.0.10 h1:8NIv4MX1Arz96kK4buGK1D87DyDxKZyq6KKvJ2diHp0=
github.com/layeh/gopher-luar v1.0.10/go.mod h1:TPnIVCZ2RJBndm7ohXyaqfhzjlZ+OA2SZR/YwL8tECk= github.com/layeh/gopher-luar v1.0.10/go.mod h1:TPnIVCZ2RJBndm7ohXyaqfhzjlZ+OA2SZR/YwL8tECk=
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.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/olekukonko/ts v0.0.0-20171002115256-78ecb04241c0 h1:LiZB1h0GIcudcDci2bxbqI6DXV8bF8POAnArqvRrIyw= 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/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=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
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=
@ -41,14 +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-20210320140829-1e4c9ba3b0c4/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-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/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-20220224120231-95c6836cb0e7 h1:BXxu8t6QN0G1uff4bzZzSkpsax8+ALqTGUtz08QrV00= golang.org/x/sys v0.0.0-20220224120231-95c6836cb0e7 h1:BXxu8t6QN0G1uff4bzZzSkpsax8+ALqTGUtz08QrV00=
golang.org/x/sys v0.0.0-20220224120231-95c6836cb0e7/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220224120231-95c6836cb0e7/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-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 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 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.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=

13
main.go
View File

@ -139,13 +139,12 @@ func main() {
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() {
text := scanner.Text() runInput(scanner.Text())
runInput(text, text)
} }
} }
if *cmdflag != "" { if *cmdflag != "" {
runInput(*cmdflag, *cmdflag) runInput(*cmdflag)
} }
if getopt.NArgs() > 0 { if getopt.NArgs() > 0 {
@ -189,7 +188,7 @@ input:
if strings.HasSuffix(input, "\\") { if strings.HasSuffix(input, "\\") {
for { for {
input, err = continuePrompt(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
} }
@ -199,7 +198,11 @@ input:
} }
} }
runInput(input, oldInput) // if input has space at the beginning, dont put in history
if !strings.HasPrefix(oldInput, " ") {
handleHistory(input)
}
runInput(input)
termwidth, _, err := term.GetSize(0) termwidth, _, err := term.GetSize(0)
if err != nil { if err != nil {

122
rl.go
View File

@ -1,60 +1,57 @@
//go:build !hilbiline && !goreadline
// +build !hilbiline,!goreadline
package main package main
// Here we define a generic interface for readline and hilbiline,
// making them interchangable during build time
// this is normal readline
import ( import (
"fmt" "os"
"io"
"path/filepath" "path/filepath"
"strings" "strings"
"os"
"github.com/maxlandon/readline" "github.com/Rosettea/readline"
"github.com/yuin/gopher-lua" "github.com/yuin/gopher-lua"
) )
type lineReader struct { type lineReader struct {
rl *readline.Instance Prompt string
} }
// other gophers might hate this naming but this is local, shut up
func newLineReader(prompt string) *lineReader { func newLineReader(prompt string) *lineReader {
rl := readline.NewInstance() readline.Init()
rl.Multiline = true
rl.TabCompleter = func(line []rune, pos int, _ readline.DelayedTabContext) (string, []*readline.CompletionGroup) { readline.Completer = func(query string, ctx string) []string {
ctx := string(line)
var completions []string var completions []string
// trim whitespace from ctx
compGroup := []*readline.CompletionGroup{
&readline.CompletionGroup{
TrimSlash: false,
NoSpace: true,
},
}
ctx = strings.TrimLeft(ctx, " ") ctx = strings.TrimLeft(ctx, " ")
if len(ctx) == 0 { if len(ctx) == 0 {
return "", compGroup return []string{}
} }
fields := strings.Split(ctx, " ") fields := strings.Split(ctx, " ")
if len(fields) == 0 { if len(fields) == 0 {
return "", compGroup return []string{}
} }
query := fields[len(fields) - 1]
ctx = aliases.Resolve(ctx) ctx = aliases.Resolve(ctx)
if len(fields) == 1 { if len(fields) == 1 {
fileCompletions := fileComplete(query, ctx, fields) prefixes := []string{"./", "../", "/", "~/"}
if len(fileCompletions) != 0 { for _, prefix := range prefixes {
if strings.HasPrefix(fields[0], prefix) {
fileCompletions := append(completions, readline.FilenameCompleter(query, ctx)...)
// filter out executables
for _, f := range fileCompletions { for _, f := range fileCompletions {
name := strings.Replace(query + f, "~", curuser.HomeDir, 1) name := strings.Replace(f, "~", curuser.HomeDir, 1)
if info, err := os.Stat(name); err == nil && info.Mode().Perm() & 0100 == 0 { if info, err := os.Stat(name); err == nil && info.Mode().Perm() & 0100 == 0 {
continue continue
} }
completions = append(completions, f) completions = append(completions, f)
} }
compGroup[0].Suggestions = completions return completions
return "", compGroup }
} }
// filter out executables, but in path // filter out executables, but in path
@ -76,16 +73,12 @@ func newLineReader(prompt string) *lineReader {
} }
} }
} }
// add lua registered commands to completions // add lua registered commands to completions
for cmdName := range commands { for cmdName := range commands {
if strings.HasPrefix(cmdName, query) { if strings.HasPrefix(cmdName, query) {
completions = append(completions, cmdName) completions = append(completions, cmdName)
} }
} }
compGroup[0].Suggestions = completions
return query, compGroup
} else { } else {
if completecb, ok := luaCompletions["command." + fields[0]]; ok { if completecb, ok := luaCompletions["command." + fields[0]]; ok {
err := l.CallByParam(lua.P{ err := l.CallByParam(lua.P{
@ -95,7 +88,7 @@ func newLineReader(prompt string) *lineReader {
}) })
if err != nil { if err != nil {
return "", compGroup return []string{}
} }
luacompleteTable := l.Get(-1) luacompleteTable := l.Get(-1)
@ -130,7 +123,7 @@ func newLineReader(prompt string) *lineReader {
val := value.String() val := value.String()
if val == "<file>" { if val == "<file>" {
// complete files // complete files
completions = append(completions, fileComplete(query, ctx, fields)...) completions = append(completions, readline.FilenameCompleter(query, ctx)...)
} else { } else {
if strings.HasPrefix(val, query) { if strings.HasPrefix(val, query) {
completions = append(completions, val) completions = append(completions, val)
@ -178,53 +171,39 @@ func newLineReader(prompt string) *lineReader {
} }
if len(completions) == 0 { if len(completions) == 0 {
completions = fileComplete(query, ctx, fields) completions = readline.FilenameCompleter(query, ctx)
} }
} }
return completions
compGroup[0].Suggestions = completions
return "", compGroup
} }
readline.LoadHistory(defaultHistPath)
return &lineReader{ return &lineReader{
rl, 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)
s, err := lr.rl.Readline() return readline.String(lr.Prompt)
// this is so dumb
if err == readline.EOF {
return "", io.EOF
}
return s, err // might get another error
} }
func (lr *lineReader) SetPrompt(prompt string) { func (lr *lineReader) SetPrompt(prompt string) {
halfPrompt := strings.Split(prompt, "\n") lr.Prompt = prompt
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) { func (lr *lineReader) AddHistory(cmd string) {
return readline.AddHistory(cmd)
readline.SaveHistory(defaultHistPath)
} }
func (lr *lineReader) ClearInput() { func (lr *lineReader) ClearInput() {
return readline.ReplaceLine("", 0)
readline.RefreshLine()
} }
func (lr *lineReader) Resize() { func (lr *lineReader) Resize() {
return readline.Resize()
} }
// lua module // lua module
@ -237,7 +216,7 @@ func (lr *lineReader) Loader(L *lua.LState) *lua.LTable {
"size": lr.luaSize, "size": lr.luaSize,
} }
mod := l.SetFuncs(l.NewTable(), lrLua) mod := L.SetFuncs(L.NewTable(), lrLua)
return mod return mod
} }
@ -250,17 +229,36 @@ func (lr *lineReader) luaAddHistory(l *lua.LState) int {
} }
func (lr *lineReader) luaSize(l *lua.LState) int { func (lr *lineReader) luaSize(l *lua.LState) int {
return 0 l.Push(lua.LNumber(readline.HistorySize()))
return 1
} }
func (lr *lineReader) luaGetHistory(l *lua.LState) int { func (lr *lineReader) luaGetHistory(l *lua.LState) int {
return 0 idx := l.CheckInt(1)
cmd := readline.GetHistory(idx)
l.Push(lua.LString(cmd))
return 1
} }
func (lr *lineReader) luaAllHistory(l *lua.LState) int { func (lr *lineReader) luaAllHistory(l *lua.LState) int {
return 0 tbl := l.NewTable()
size := readline.HistorySize()
for i := 0; i < size; i++ {
cmd := readline.GetHistory(i)
tbl.Append(lua.LString(cmd))
}
l.Push(tbl)
return 1
} }
func (lr *lineReader) luaClearHistory(l *lua.LState) int { func (lr *lineReader) luaClearHistory(l *lua.LState) int {
readline.ClearHistory()
readline.SaveHistory(defaultHistPath)
return 0 return 0
} }

83
rl_hilbiline.go 100644
View File

@ -0,0 +1,83 @@
// +build hilbiline,!goreadline
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 (
"github.com/Rosettea/Hilbiline"
"github.com/yuin/gopher-lua"
)
type lineReader struct {
hl *hilbiline.HilbilineState
}
// other gophers might hate this naming but this is local, shut up
func newLineReader(prompt string) *lineReader {
hl := hilbiline.New(prompt)
return &lineReader{
&hl,
}
}
func (lr *lineReader) Read() (string, error) {
return lr.hl.Read()
}
func (lr *lineReader) SetPrompt(prompt string) {
lr.hl.SetPrompt(prompt)
}
func (lr *lineReader) AddHistory(cmd string) {
return
}
func (lr *lineReader) ClearInput() {
return
}
func (lr *lineReader) Resize() {
return
}
// lua module
func (lr *lineReader) Loader(L *lua.LState) *lua.LTable {
lrLua := map[string]lua.LGFunction{
"add": lr.luaAddHistory,
"all": lr.luaAllHistory,
"clear": lr.luaClearHistory,
"get": lr.luaGetHistory,
"size": lr.luaSize,
}
mod := l.SetFuncs(l.NewTable(), lrLua)
return mod
}
func (lr *lineReader) luaAddHistory(l *lua.LState) int {
cmd := l.CheckString(1)
lr.AddHistory(cmd)
return 0
}
func (lr *lineReader) luaSize(l *lua.LState) int {
return 0
}
func (lr *lineReader) luaGetHistory(l *lua.LState) int {
return 0
}
func (lr *lineReader) luaAllHistory(l *lua.LState) int {
return 0
}
func (lr *lineReader) luaClearHistory(l *lua.LState) int {
return 0
}

103
rl_readline-go.go 100644
View File

@ -0,0 +1,103 @@
// +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"
"github.com/yuin/gopher-lua"
)
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
}
// lua module
func (lr *lineReader) Loader(L *lua.LState) *lua.LTable {
lrLua := map[string]lua.LGFunction{
"add": lr.luaAddHistory,
"all": lr.luaAllHistory,
"clear": lr.luaClearHistory,
"get": lr.luaGetHistory,
"size": lr.luaSize,
}
mod := l.SetFuncs(l.NewTable(), lrLua)
return mod
}
func (lr *lineReader) luaAddHistory(l *lua.LState) int {
cmd := l.CheckString(1)
lr.AddHistory(cmd)
return 0
}
func (lr *lineReader) luaSize(l *lua.LState) int {
return 0
}
func (lr *lineReader) luaGetHistory(l *lua.LState) int {
return 0
}
func (lr *lineReader) luaAllHistory(l *lua.LState) int {
return 0
}
func (lr *lineReader) luaClearHistory(l *lua.LState) int {
return 0
}