edit: color and complete external command names

This commit is contained in:
Qi Xiao 2016-01-26 00:31:45 +01:00
parent 673c2438d2
commit 30f07d9e7f
5 changed files with 47 additions and 7 deletions

View File

@ -43,6 +43,7 @@ var styleForSep = map[byte]string{
// Styles for semantic coloring.
var (
styleForBadCommand = ";31;3"
styleForGoodCommand = ";32"
styleForBadCommand = ";31"
styleForBadVariable = ";31;3"
)

View File

@ -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
return ""
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 ""
}

View File

@ -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()
}

View File

@ -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
View 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
}