mirror of
https://github.com/go-sylixos/elvish.git
synced 2024-12-04 02:37:50 +08:00
Prompt can now be customized by modifying le:{,r}prompt.
This fixes #103.
This commit is contained in:
parent
9d7e5de667
commit
67e4b5df11
|
@ -29,6 +29,8 @@ type Editor struct {
|
|||
store *store.Store
|
||||
evaler *eval.Evaler
|
||||
cmdSeq int
|
||||
ps1 Prompt
|
||||
rps1 Prompt
|
||||
editorState
|
||||
}
|
||||
|
||||
|
@ -93,6 +95,8 @@ func NewEditor(file *os.File, sigs chan os.Signal, ev *eval.Evaler, st *store.St
|
|||
}
|
||||
}
|
||||
|
||||
prompt, rprompt := defaultPrompts()
|
||||
|
||||
ed := &Editor{
|
||||
file: file,
|
||||
writer: newWriter(file),
|
||||
|
@ -101,6 +105,8 @@ func NewEditor(file *os.File, sigs chan os.Signal, ev *eval.Evaler, st *store.St
|
|||
store: st,
|
||||
evaler: ev,
|
||||
cmdSeq: seq,
|
||||
ps1: prompt,
|
||||
rps1: rprompt,
|
||||
}
|
||||
ev.AddModule("le", makeModule(ed))
|
||||
return ed
|
||||
|
@ -282,7 +288,7 @@ func (ed *Editor) finishReadLine(addError func(error)) {
|
|||
}
|
||||
|
||||
// ReadLine reads a line interactively.
|
||||
func (ed *Editor) ReadLine(prompt, rprompt func() string) (lr LineRead) {
|
||||
func (ed *Editor) ReadLine() (lr LineRead) {
|
||||
ed.editorState = editorState{active: true}
|
||||
isExternalCh := make(chan map[string]bool, 1)
|
||||
go getIsExternal(ed.evaler, isExternalCh)
|
||||
|
@ -302,8 +308,8 @@ func (ed *Editor) ReadLine(prompt, rprompt func() string) (lr LineRead) {
|
|||
|
||||
MainLoop:
|
||||
for {
|
||||
ed.prompt = prompt()
|
||||
ed.rprompt = rprompt()
|
||||
ed.prompt = ed.ps1.Call(ed)
|
||||
ed.rprompt = ed.rps1.Call(ed)
|
||||
|
||||
err := ed.refresh(false, true)
|
||||
if err != nil {
|
||||
|
|
|
@ -39,6 +39,9 @@ func makeModule(ed *Editor) eval.Namespace {
|
|||
|
||||
ns["binding"] = eval.NewRoVariable(binding)
|
||||
|
||||
ns["prompt"] = PromptVariable{&ed.ps1}
|
||||
ns["rprompt"] = PromptVariable{&ed.rps1}
|
||||
|
||||
return ns
|
||||
}
|
||||
|
||||
|
|
|
@ -2,11 +2,36 @@ package edit
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"os"
|
||||
"os/user"
|
||||
|
||||
"github.com/elves/elvish/eval"
|
||||
"github.com/elves/elvish/util"
|
||||
)
|
||||
|
||||
var ErrPromptMustBeStringOrFunc = errors.New("prompt must be string or function")
|
||||
|
||||
// PromptVariable implements $le:prompt and $le:rprompt.
|
||||
type PromptVariable struct {
|
||||
Prompt *Prompt
|
||||
}
|
||||
|
||||
func (pv PromptVariable) Get() eval.Value {
|
||||
// XXX Should return a proper eval.Caller
|
||||
return eval.String("<prompt>")
|
||||
}
|
||||
|
||||
func (pv PromptVariable) Set(v eval.Value) {
|
||||
if s, ok := v.(eval.String); ok {
|
||||
*pv.Prompt = BuiltinPrompt(func(*Editor) string { return string(s) })
|
||||
} else if c, ok := v.(eval.Caller); ok {
|
||||
*pv.Prompt = CallerPrompt{c}
|
||||
} else {
|
||||
throw(ErrPromptMustBeStringOrFunc)
|
||||
}
|
||||
}
|
||||
|
||||
// Prompt is the interface of prompt functions.
|
||||
type Prompt interface {
|
||||
Call(*Editor) string
|
||||
|
@ -29,7 +54,7 @@ func (c CallerPrompt) Call(ed *Editor) string {
|
|||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
ports := []*eval.Port{in, nil, &eval.Port{File: os.Stderr}}
|
||||
ports := []*eval.Port{in, &eval.Port{File: os.Stdout}, &eval.Port{File: os.Stderr}}
|
||||
|
||||
// XXX There is no source to pass to NewTopEvalCtx.
|
||||
ec := eval.NewTopEvalCtx(ed.evaler, "[editor prompt]", "", ports)
|
||||
|
@ -44,3 +69,24 @@ func (c CallerPrompt) Call(ed *Editor) string {
|
|||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func defaultPrompts() (Prompt, Prompt) {
|
||||
// Make default prompts.
|
||||
username := "???"
|
||||
user, err := user.Current()
|
||||
if err == nil {
|
||||
username = user.Username
|
||||
}
|
||||
hostname, err := os.Hostname()
|
||||
if err != nil {
|
||||
hostname = "???"
|
||||
}
|
||||
rpromptStr := username + "@" + hostname
|
||||
prompt := func(*Editor) string {
|
||||
return util.Getwd() + "> "
|
||||
}
|
||||
rprompt := func(*Editor) string {
|
||||
return rpromptStr
|
||||
}
|
||||
return BuiltinPrompt(prompt), BuiltinPrompt(rprompt)
|
||||
}
|
||||
|
|
21
run/run.go
21
run/run.go
|
@ -8,7 +8,6 @@ import (
|
|||
"io"
|
||||
"os"
|
||||
"os/signal"
|
||||
"os/user"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
|
@ -127,27 +126,9 @@ func interact(ev *eval.Evaler, st *store.Store) {
|
|||
}
|
||||
}
|
||||
|
||||
// Build prompt and rprompt.
|
||||
username := "???"
|
||||
user, err := user.Current()
|
||||
if err == nil {
|
||||
username = user.Username
|
||||
}
|
||||
hostname, err := os.Hostname()
|
||||
if err != nil {
|
||||
hostname = "???"
|
||||
}
|
||||
rpromptStr := username + "@" + hostname
|
||||
prompt := func() string {
|
||||
return util.Getwd() + "> "
|
||||
}
|
||||
rprompt := func() string {
|
||||
return rpromptStr
|
||||
}
|
||||
|
||||
// Build readLine function.
|
||||
readLine := func() edit.LineRead {
|
||||
return ed.ReadLine(prompt, rprompt)
|
||||
return ed.ReadLine()
|
||||
}
|
||||
|
||||
cooldown := time.Second
|
||||
|
|
Loading…
Reference in New Issue
Block a user