github.com/elves/elvish@v0.15.0/pkg/cli/histutil/dedup_cursor.go (about) 1 package histutil 2 3 import "github.com/elves/elvish/pkg/store" 4 5 // NewDedupCursor returns a cursor that skips over all duplicate entries. 6 func NewDedupCursor(c Cursor) Cursor { 7 return &dedupCursor{c, 0, nil, make(map[string]bool)} 8 } 9 10 type dedupCursor struct { 11 c Cursor 12 current int 13 stack []store.Cmd 14 occ map[string]bool 15 } 16 17 func (c *dedupCursor) Prev() { 18 if c.current < len(c.stack)-1 { 19 c.current++ 20 return 21 } 22 for { 23 c.c.Prev() 24 cmd, err := c.c.Get() 25 if err != nil { 26 c.current = len(c.stack) 27 break 28 } 29 if !c.occ[cmd.Text] { 30 c.current = len(c.stack) 31 c.stack = append(c.stack, cmd) 32 c.occ[cmd.Text] = true 33 break 34 } 35 } 36 } 37 38 func (c *dedupCursor) Next() { 39 if c.current >= 0 { 40 c.current-- 41 } 42 } 43 44 func (c *dedupCursor) Get() (store.Cmd, error) { 45 switch { 46 case c.current < 0: 47 return store.Cmd{}, ErrEndOfHistory 48 case c.current < len(c.stack): 49 return c.stack[c.current], nil 50 default: 51 return c.c.Get() 52 } 53 }