mirror of
https://github.com/go-sylixos/elvish.git
synced 2024-12-13 18:07:51 +08:00
edit: color and complete external command names
This commit is contained in:
parent
673c2438d2
commit
30f07d9e7f
|
@ -43,6 +43,7 @@ var styleForSep = map[byte]string{
|
|||
|
||||
// Styles for semantic coloring.
|
||||
var (
|
||||
styleForBadCommand = ";31;3"
|
||||
styleForGoodCommand = ";32"
|
||||
styleForBadCommand = ";31"
|
||||
styleForBadVariable = ";31;3"
|
||||
)
|
||||
|
|
|
@ -5,19 +5,34 @@ import (
|
|||
"github.com/elves/elvish/parse"
|
||||
)
|
||||
|
||||
type colorist func(parse.Node, *eval.Evaler) string
|
||||
type colorist func(parse.Node, *Editor) string
|
||||
|
||||
var colorists = []colorist{
|
||||
colorFormHead,
|
||||
colorVariable,
|
||||
}
|
||||
|
||||
func colorFormHead(n parse.Node, ev *eval.Evaler) string {
|
||||
func colorFormHead(n parse.Node, ed *Editor) string {
|
||||
// BUG doesn't work when the form head is compound
|
||||
n, head := formHead(n)
|
||||
if n == nil {
|
||||
return ""
|
||||
}
|
||||
if goodFormHead(head, ed) {
|
||||
return styleForGoodCommand
|
||||
}
|
||||
return styleForBadCommand
|
||||
}
|
||||
|
||||
func colorVariable(n parse.Node, ev *eval.Evaler) string {
|
||||
func goodFormHead(head string, ed *Editor) bool {
|
||||
if eval.DontSearch(head) {
|
||||
return eval.IsExecutable(head)
|
||||
} else {
|
||||
return ed.evaler.HasVariable("fn-"+head) || ed.isExternal[head]
|
||||
}
|
||||
}
|
||||
|
||||
func colorVariable(n parse.Node, ed *Editor) string {
|
||||
pn, ok := n.(*parse.Primary)
|
||||
if !ok {
|
||||
return ""
|
||||
|
@ -25,7 +40,7 @@ func colorVariable(n parse.Node, ev *eval.Evaler) string {
|
|||
if pn.Type != parse.Variable || len(pn.Value) == 0 {
|
||||
return ""
|
||||
}
|
||||
has := ev.HasVariable(pn.Value[1:])
|
||||
has := ed.evaler.HasVariable(pn.Value[1:])
|
||||
if has {
|
||||
return ""
|
||||
}
|
||||
|
|
|
@ -33,6 +33,13 @@ func complFormHead(n parse.Node, ed *Editor) ([]*candidate, int) {
|
|||
tokenPart{head, false}, tokenPart{s[len(head):], true}))
|
||||
}
|
||||
}
|
||||
// XXX reduplication
|
||||
for s := range ed.isExternal {
|
||||
if strings.HasPrefix(s, head) {
|
||||
cands = append(cands, newCandidate(
|
||||
tokenPart{head, false}, tokenPart{s[len(head):], true}))
|
||||
}
|
||||
}
|
||||
return cands, n.Begin()
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ type editorState struct {
|
|||
completionLines int
|
||||
navigation *navigation
|
||||
history history
|
||||
isExternal map[string]bool
|
||||
}
|
||||
|
||||
type history struct {
|
||||
|
@ -180,7 +181,7 @@ func (ed *Editor) refresh() error {
|
|||
ed.tokens, _ = tokenize(ed.line)
|
||||
for i, t := range ed.tokens {
|
||||
for _, colorist := range colorists {
|
||||
ed.tokens[i].MoreStyle += colorist(t.Node, ed.evaler)
|
||||
ed.tokens[i].MoreStyle += colorist(t.Node, ed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -380,6 +381,8 @@ func (ed *Editor) finishReadLine(lr *LineRead) {
|
|||
// other signals.
|
||||
func (ed *Editor) ReadLine(prompt, rprompt func() string) (lr LineRead) {
|
||||
ed.editorState = editorState{}
|
||||
go ed.updateIsExternal()
|
||||
|
||||
ed.writer.oldBuf.cells = nil
|
||||
ones := ed.reader.Chan()
|
||||
|
||||
|
|
14
edit/isexternal.go
Normal file
14
edit/isexternal.go
Normal file
|
@ -0,0 +1,14 @@
|
|||
package edit
|
||||
|
||||
func (ed *Editor) updateIsExternal() {
|
||||
names := make(chan string, 32)
|
||||
go func() {
|
||||
ed.evaler.AllExecutables(names)
|
||||
close(names)
|
||||
}()
|
||||
isExternal := make(map[string]bool)
|
||||
for name := range names {
|
||||
isExternal[name] = true
|
||||
}
|
||||
ed.isExternal = isExternal
|
||||
}
|
Loading…
Reference in New Issue
Block a user