feat: add right prompt (closes #111)

right-prompt
TorchedSammy 2022-04-13 08:57:35 -04:00
parent ce625aca0c
commit a2a2d5e5e7
Signed by: sammyette
GPG Key ID: 904FC49417B44DCD
6 changed files with 54 additions and 11 deletions

28
api.go
View File

@ -35,7 +35,7 @@ var exports = map[string]util.LuaExport{
"hinter": {hlhinter, 1, false},
"multiprompt": {hlmultiprompt, 1, false},
"prependPath": {hlprependPath, 1, false},
"prompt": {hlprompt, 1, false},
"prompt": {hlprompt, 1, true},
"inputMode": {hlinputMode, 1, false},
"interval": {hlinterval, 2, false},
"read": {hlread, 1, false},
@ -315,15 +315,31 @@ These will be formatted and replaced with the appropriate values.
--- @param str string
*/
func hlprompt(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
var prompt string
err := c.Check1Arg()
if err == nil {
prompt, err = c.StringArg(0)
}
if err != nil {
return nil, err
}
lr.SetPrompt(fmtPrompt(prompt))
p, err := c.StringArg(0)
if err != nil {
return nil, err
}
typ := "left"
if len(c.Etc()) != 0 {
ltyp := c.Etc()[0]
var ok bool
typ, ok = ltyp.TryString()
if !ok {
return nil, errors.New("bad argument to run (expected string, got " + ltyp.TypeName() + ")")
}
}
switch typ {
case "left":
prompt = p
lr.SetPrompt(fmtPrompt(prompt))
case "right":
lr.SetRightPrompt(fmtPrompt(p))
}
return c.Next(), nil
}

View File

@ -30,11 +30,13 @@ type Instance struct {
Multiline bool // If set to true, the shell will have a two-line prompt.
MultilinePrompt string // If multiline is true, this is the content of the 2nd line.
mainPrompt string // If multiline true, the full prompt string / If false, the 1st line of the prompt
realPrompt []rune // The prompt that is actually on the same line as the beginning of the input line.
defaultPrompt []rune
promptLen int
stillOnRefresh bool // True if some logs have printed asynchronously since last loop. Check refresh prompt funcs
mainPrompt string // If multiline true, the full prompt string / If false, the 1st line of the prompt
rightPrompt string
rightPromptLen int
realPrompt []rune // The prompt that is actually on the same line as the beginning of the input line.
defaultPrompt []rune
promptLen int
stillOnRefresh bool // True if some logs have printed asynchronously since last loop. Check refresh prompt funcs
//
// Input Line ---------------------------------------------------------------------------------

View File

@ -14,6 +14,11 @@ func (rl *Instance) SetPrompt(s string) {
rl.computePrompt()
}
func (rl *Instance) SetRightPrompt(s string) {
rl.rightPrompt = s
rl.computePrompt()
}
// RefreshPromptLog - A simple function to print a string message (a log, or more broadly,
// an asynchronous event) without bothering the user, and by "pushing" the prompt below the message.
func (rl *Instance) RefreshPromptLog(log string) (err error) {
@ -185,6 +190,7 @@ func (rl *Instance) computePrompt() (prompt []rune) {
// Strip color escapes
rl.promptLen = getRealLength(string(rl.realPrompt))
rl.rightPromptLen = getRealLength(string(rl.rightPrompt))
return
}
@ -205,3 +211,11 @@ func getRealLength(s string) (l int) {
stripped := ansi.Strip(s)
return uniseg.GraphemeClusterCount(stripped)
}
func (rl *Instance) echoRightPrompt() {
if rl.fullX < GetTermWidth() - rl.rightPromptLen - 1 {
moveCursorForwards(GetTermWidth())
moveCursorBackwards(rl.rightPromptLen)
print(rl.rightPrompt)
}
}

View File

@ -564,6 +564,8 @@ func (rl *Instance) editorInput(r []rune) {
rl.writeHintText()
}
rl.echoRightPrompt()
if len(rl.multisplit) == 0 {
rl.syntaxCompletion()
}

View File

@ -121,6 +121,8 @@ func (rl *Instance) renderHelpers() {
rl.writeHintText()
}
rl.echoRightPrompt()
// Go at beginning of first line after input remainder
moveCursorDown(rl.fullY - rl.posY)
moveCursorBackwards(GetTermWidth())

7
rl.go
View File

@ -281,6 +281,13 @@ func (lr *lineReader) SetPrompt(p string) {
}
}
func (lr *lineReader) SetRightPrompt(p string) {
lr.rl.SetRightPrompt(p)
if initialized && !running {
lr.rl.RefreshPromptInPlace("")
}
}
func (lr *lineReader) AddHistory(cmd string) {
fileHist.Write(cmd)
}