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  }