feat: accessible vim input mode (closes #95)

windows-fixes
TorchedSammy 2022-03-01 22:00:46 -04:00
parent 062f40e9e5
commit 065d752b82
Signed by: sammyette
GPG Key ID: 904FC49417B44DCD
4 changed files with 53 additions and 3 deletions

33
api.go
View File

@ -15,6 +15,7 @@ import (
"hilbish/util" "hilbish/util"
"github.com/yuin/gopher-lua" "github.com/yuin/gopher-lua"
"github.com/maxlandon/readline"
"mvdan.cc/sh/v3/interp" "mvdan.cc/sh/v3/interp"
) )
@ -26,6 +27,7 @@ var exports = map[string]lua.LGFunction {
"multiprompt": hlmlprompt, "multiprompt": hlmlprompt,
"prependPath": hlprependPath, "prependPath": hlprependPath,
"prompt": hlprompt, "prompt": hlprompt,
"inputMode": hlinputMode,
"interval": hlinterval, "interval": hlinterval,
"read": hlread, "read": hlread,
"run": hlrun, "run": hlrun,
@ -34,9 +36,11 @@ var exports = map[string]lua.LGFunction {
} }
var greeting string var greeting string
var hshMod *lua.LTable
func hilbishLoader(L *lua.LState) int { func hilbishLoader(L *lua.LState) int {
mod := L.SetFuncs(L.NewTable(), exports) mod := L.SetFuncs(L.NewTable(), exports)
hshMod = mod
host, _ := os.Hostname() host, _ := os.Hostname()
username := curuser.Username username := curuser.Username
@ -57,6 +61,7 @@ The nice lil shell for {blue}Lua{reset} fanatics!
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")
util.SetField(L, mod, "greeting", lua.LString(greeting), "Hilbish's welcome message for interactive shells. It has Lunacolors formatting.") util.SetField(L, mod, "greeting", lua.LString(greeting), "Hilbish's welcome message for interactive shells. It has Lunacolors formatting.")
util.SetField(l, mod, "vimMode", lua.LNil, "Current Vim mode of Hilbish (nil if not in Vim mode)")
util.Document(L, mod, "Hilbish's core API, containing submodules and functions which relate to the shell itself.") util.Document(L, mod, "Hilbish's core API, containing submodules and functions which relate to the shell itself.")
// hilbish.userDir table // hilbish.userDir table
@ -83,6 +88,15 @@ The nice lil shell for {blue}Lua{reset} fanatics!
return 1 return 1
} }
func setVimMode(mode string) {
hooks.Em.Emit("hilbish.vimMode", mode)
util.SetField(l, hshMod, "vimMode", lua.LString(mode), "Current Vim mode of Hilbish (nil if not in Vim mode)")
}
func unsetVimMode() {
util.SetField(l, hshMod, "vimMode", lua.LNil, "Current Vim mode of Hilbish (nil if not in Vim mode)")
}
// run(cmd) // run(cmd)
// Runs `cmd` in Hilbish's sh interpreter. // Runs `cmd` in Hilbish's sh interpreter.
// --- @param cmd string // --- @param cmd string
@ -150,6 +164,9 @@ These will be formatted and replaced with the appropriate values.
*/ */
func hlprompt(L *lua.LState) int { func hlprompt(L *lua.LState) int {
prompt = L.CheckString(1) prompt = L.CheckString(1)
if lr != nil {
lr.SetPrompt(fmtPrompt())
}
return 0 return 0
} }
@ -346,3 +363,19 @@ func hlwhich(L *lua.LState) int {
l.Push(lua.LString(path)) l.Push(lua.LString(path))
return 1 return 1
} }
// inputMode(mode)
// Sets the input mode for Hilbish's line reader. Accepts either emacs for vim
func hlinputMode(L *lua.LState) int {
mode := L.CheckString(1)
switch mode {
case "emacs":
unsetVimMode()
lr.rl.InputMode = readline.Emacs
case "vim":
setVimMode("insert")
lr.rl.InputMode = readline.Vim
default: L.RaiseError("inputMode: expected vim or emacs, received " + mode)
}
return 0
}

2
go.mod
View File

@ -15,6 +15,6 @@ require (
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.20220228022904-61f5e4493011 replace github.com/maxlandon/readline => github.com/Rosettea/readline-1 v0.0.0-20220302012429-9ce5d23760f7
replace layeh.com/gopher-luar => github.com/layeh/gopher-luar v1.0.10 replace layeh.com/gopher-luar => github.com/layeh/gopher-luar v1.0.10

2
go.sum
View File

@ -1,3 +1,5 @@
github.com/Rosettea/readline-1 v0.0.0-20220302012429-9ce5d23760f7 h1:LoY+kBKqMQqBcilRpVvifBTVve84asa3btpx3D/+IvM=
github.com/Rosettea/readline-1 v0.0.0-20220302012429-9ce5d23760f7/go.mod h1:QiUAvbhg8PzCA4hlafCUl0bKD/0VmcocM4AjqtszAJs=
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/readline-1 v0.1.0-beta.0.20220228022904-61f5e4493011 h1:+a61iNamZiO3Xru+l/1qtpKqqltVfWEm2r/rxH9hXxY= github.com/Rosettea/readline-1 v0.1.0-beta.0.20220228022904-61f5e4493011 h1:+a61iNamZiO3Xru+l/1qtpKqqltVfWEm2r/rxH9hXxY=

19
rl.go
View File

@ -18,7 +18,18 @@ type lineReader struct {
// 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 {
rl := readline.NewInstance() rl := readline.NewInstance()
rl.Multiline = true rl.ShowVimMode = false
rl.ViModeCallback = func(mode readline.ViMode) {
modeStr := ""
switch mode {
case readline.VimKeys: modeStr = "normal"
case readline.VimInsert: modeStr = "insert"
case readline.VimDelete: modeStr = "delete"
case readline.VimReplaceOnce:
case readline.VimReplaceMany: modeStr = "replace"
}
setVimMode(modeStr)
}
rl.TabCompleter = func(line []rune, pos int, _ readline.DelayedTabContext) (string, []*readline.CompletionGroup) { rl.TabCompleter = func(line []rune, pos int, _ readline.DelayedTabContext) (string, []*readline.CompletionGroup) {
ctx := string(line) ctx := string(line)
var completions []string var completions []string
@ -196,6 +207,7 @@ func (lr *lineReader) Read() (string, error) {
s, err := lr.rl.Readline() s, err := lr.rl.Readline()
// this is so dumb // this is so dumb
if err == readline.EOF { if err == readline.EOF {
fmt.Println("")
return "", io.EOF return "", io.EOF
} }
@ -209,10 +221,13 @@ func (lr *lineReader) SetPrompt(prompt string) {
lr.rl.MultilinePrompt = halfPrompt[len(halfPrompt) - 1:][0] lr.rl.MultilinePrompt = halfPrompt[len(halfPrompt) - 1:][0]
} else { } else {
// print cursor up ansi code // print cursor up ansi code
fmt.Printf("\033[1A") //fmt.Printf("\033[1A")
lr.rl.SetPrompt("") lr.rl.SetPrompt("")
lr.rl.MultilinePrompt = halfPrompt[len(halfPrompt) - 1:][0] lr.rl.MultilinePrompt = halfPrompt[len(halfPrompt) - 1:][0]
} }
if !running {
lr.rl.RefreshPromptInPlace("")
}
} }
func (lr *lineReader) AddHistory(cmd string) { func (lr *lineReader) AddHistory(cmd string) {