mirror of
https://github.com/go-sylixos/elvish.git
synced 2024-12-15 11:57:55 +08:00
parent
d2c58c34cf
commit
1097ad5891
|
@ -35,14 +35,17 @@ type Editor struct {
|
||||||
evaler *eval.Evaler
|
evaler *eval.Evaler
|
||||||
cmdSeq int
|
cmdSeq int
|
||||||
|
|
||||||
prompt eval.Variable
|
prompt eval.Variable
|
||||||
rprompt eval.Variable
|
rprompt eval.Variable
|
||||||
|
rpromptPersistent eval.Variable
|
||||||
|
|
||||||
abbreviations map[string]string
|
abbreviations map[string]string
|
||||||
|
|
||||||
locationHidden eval.Variable
|
locationHidden eval.Variable
|
||||||
rpromptPersistent eval.Variable
|
locationPinned eval.Variable
|
||||||
beforeReadLine eval.Variable
|
|
||||||
afterReadLine eval.Variable
|
beforeReadLine eval.Variable
|
||||||
|
afterReadLine eval.Variable
|
||||||
|
|
||||||
historyMutex sync.RWMutex
|
historyMutex sync.RWMutex
|
||||||
|
|
||||||
|
@ -104,20 +107,22 @@ func NewEditor(file *os.File, sigs chan os.Signal, ev *eval.Evaler, st *store.St
|
||||||
prompt, rprompt := defaultPrompts()
|
prompt, rprompt := defaultPrompts()
|
||||||
|
|
||||||
ed := &Editor{
|
ed := &Editor{
|
||||||
file: file,
|
file: file,
|
||||||
writer: newWriter(file),
|
writer: newWriter(file),
|
||||||
reader: tty.NewReader(file),
|
reader: tty.NewReader(file),
|
||||||
sigs: sigs,
|
sigs: sigs,
|
||||||
store: st,
|
store: st,
|
||||||
evaler: ev,
|
evaler: ev,
|
||||||
cmdSeq: seq,
|
cmdSeq: seq,
|
||||||
prompt: eval.NewPtrVariableWithValidator(prompt, eval.ShouldBeFn),
|
|
||||||
rprompt: eval.NewPtrVariableWithValidator(rprompt, eval.ShouldBeFn),
|
prompt: eval.NewPtrVariableWithValidator(prompt, eval.ShouldBeFn),
|
||||||
|
rprompt: eval.NewPtrVariableWithValidator(rprompt, eval.ShouldBeFn),
|
||||||
|
rpromptPersistent: eval.NewPtrVariableWithValidator(eval.Bool(false), eval.ShouldBeBool),
|
||||||
|
|
||||||
abbreviations: make(map[string]string),
|
abbreviations: make(map[string]string),
|
||||||
|
|
||||||
locationHidden: eval.NewPtrVariableWithValidator(eval.NewList(), eval.ShouldBeList),
|
locationHidden: eval.NewPtrVariableWithValidator(eval.NewList(), eval.ShouldBeList),
|
||||||
rpromptPersistent: eval.NewPtrVariableWithValidator(eval.Bool(false), eval.ShouldBeBool),
|
locationPinned: eval.NewPtrVariableWithValidator(eval.NewList(), eval.ShouldBeList),
|
||||||
|
|
||||||
beforeReadLine: eval.NewPtrVariableWithValidator(eval.NewList(), eval.ShouldBeList),
|
beforeReadLine: eval.NewPtrVariableWithValidator(eval.NewList(), eval.ShouldBeList),
|
||||||
afterReadLine: eval.NewPtrVariableWithValidator(eval.NewList(), eval.ShouldBeList),
|
afterReadLine: eval.NewPtrVariableWithValidator(eval.NewList(), eval.ShouldBeList),
|
||||||
|
|
|
@ -3,6 +3,7 @@ package edit
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
@ -16,6 +17,10 @@ import (
|
||||||
|
|
||||||
// Location mode.
|
// Location mode.
|
||||||
|
|
||||||
|
// PinnedScore is a special value of Score in store.Dir to represent that the
|
||||||
|
// directory is pinned.
|
||||||
|
var PinnedScore = math.Inf(1)
|
||||||
|
|
||||||
type location struct {
|
type location struct {
|
||||||
listing
|
listing
|
||||||
home string // The home directory; leave empty if unknown.
|
home string // The home directory; leave empty if unknown.
|
||||||
|
@ -42,7 +47,13 @@ func (loc *location) Len() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (loc *location) Show(i int) (string, styled) {
|
func (loc *location) Show(i int) (string, styled) {
|
||||||
header := fmt.Sprintf("%.0f", loc.filtered[i].Score)
|
var header string
|
||||||
|
score := loc.filtered[i].Score
|
||||||
|
if score == PinnedScore {
|
||||||
|
header = "*"
|
||||||
|
} else {
|
||||||
|
header = fmt.Sprintf("%.0f", score)
|
||||||
|
}
|
||||||
return header, unstyled(showPath(loc.filtered[i].Path, loc.home))
|
return header, unstyled(showPath(loc.filtered[i].Path, loc.home))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,13 +137,28 @@ func startLocation(ed *Editor) {
|
||||||
ed.Notify("%v", ErrStoreOffline)
|
ed.Notify("%v", ErrStoreOffline)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
black := convertBlacklist(ed.locationHidden.Get().(eval.List))
|
black := convertListToSet(ed.locationHidden.Get().(eval.List))
|
||||||
dirs, err := ed.store.GetDirs(black)
|
dirs, err := ed.store.GetDirs(black)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ed.Notify("store error: %v", err)
|
ed.Notify("store error: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pinnedValue := ed.locationPinned.Get().(eval.List)
|
||||||
|
pinned := convertListToDirs(pinnedValue)
|
||||||
|
pinnedSet := convertListToSet(pinnedValue)
|
||||||
|
|
||||||
|
// TODO(xiaq): Optimize this by changing GetDirs to a callback API, and
|
||||||
|
// build dirs by first putting pinned directories and then appending those
|
||||||
|
// from store.
|
||||||
|
for _, d := range dirs {
|
||||||
|
_, inPinned := pinnedSet[d.Path]
|
||||||
|
if !inPinned {
|
||||||
|
pinned = append(pinned, d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dirs = pinned
|
||||||
|
|
||||||
// Drop the error. When there is an error, home is "", which is used to
|
// Drop the error. When there is an error, home is "", which is used to
|
||||||
// signify "no home known" in location.
|
// signify "no home known" in location.
|
||||||
home, _ := util.GetHome("")
|
home, _ := util.GetHome("")
|
||||||
|
@ -140,14 +166,28 @@ func startLocation(ed *Editor) {
|
||||||
ed.mode = ed.location
|
ed.mode = ed.location
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertBlacklist(li eval.List) map[string]struct{} {
|
// convertListToDirs converts a list of strings to []store.Dir. It uses the
|
||||||
black := make(map[string]struct{})
|
// special score of PinnedScore to signify that the directory is pinned.
|
||||||
|
func convertListToDirs(li eval.List) []store.Dir {
|
||||||
|
pinned := make([]store.Dir, 0, li.Len())
|
||||||
// XXX(xiaq): silently drops non-string items.
|
// XXX(xiaq): silently drops non-string items.
|
||||||
li.Iterate(func(v eval.Value) bool {
|
li.Iterate(func(v eval.Value) bool {
|
||||||
if s, ok := v.(eval.String); ok {
|
if s, ok := v.(eval.String); ok {
|
||||||
black[string(s)] = struct{}{}
|
pinned = append(pinned, store.Dir{string(s), PinnedScore})
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
return black
|
return pinned
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertListToSet(li eval.List) map[string]struct{} {
|
||||||
|
set := make(map[string]struct{})
|
||||||
|
// XXX(xiaq): silently drops non-string items.
|
||||||
|
li.Iterate(func(v eval.Value) bool {
|
||||||
|
if s, ok := v.(eval.String); ok {
|
||||||
|
set[string(s)] = struct{}{}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
return set
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
theLocation = newLocation([]store.Dir{
|
theLocation = newLocation([]store.Dir{
|
||||||
|
{"/pinned", PinnedScore},
|
||||||
{"/src/github.com/elves/elvish", 300},
|
{"/src/github.com/elves/elvish", 300},
|
||||||
{"/src/home/xyz", 233},
|
{"/src/home/xyz", 233},
|
||||||
{"/home/dir", 100},
|
{"/home/dir", 100},
|
||||||
|
@ -17,6 +18,7 @@ var (
|
||||||
|
|
||||||
locationFilterTests = []listingFilterTestCases{
|
locationFilterTests = []listingFilterTestCases{
|
||||||
{"", []shown{
|
{"", []shown{
|
||||||
|
{"*", unstyled("/pinned")},
|
||||||
{"300", unstyled("/src/github.com/elves/elvish")},
|
{"300", unstyled("/src/github.com/elves/elvish")},
|
||||||
{"233", unstyled("/src/home/xyz")},
|
{"233", unstyled("/src/home/xyz")},
|
||||||
{"100", unstyled("~/dir")}, // home is abbreviated
|
{"100", unstyled("~/dir")}, // home is abbreviated
|
||||||
|
|
|
@ -78,6 +78,7 @@ func makeModule(ed *Editor) eval.Namespace {
|
||||||
|
|
||||||
ns["abbr"] = eval.NewRoVariable(eval.MapStringString(ed.abbreviations))
|
ns["abbr"] = eval.NewRoVariable(eval.MapStringString(ed.abbreviations))
|
||||||
|
|
||||||
|
ns["loc-pinned"] = ed.locationPinned
|
||||||
ns["loc-hidden"] = ed.locationHidden
|
ns["loc-hidden"] = ed.locationHidden
|
||||||
|
|
||||||
ns["before-readline"] = ed.beforeReadLine
|
ns["before-readline"] = ed.beforeReadLine
|
||||||
|
|
Loading…
Reference in New Issue
Block a user