elvish/pkg/edit/store_api.go
Qi Xiao 3501b945aa Rewrite pkg/cli/histutil.
- Organize code around two interfaces, Store and Cursor.

- Ensure that a session store is always available, even if the DB is not
  accessible.

This fixes #909.
2020-07-13 23:46:43 +01:00

71 lines
1.7 KiB
Go

package edit
import (
"errors"
"strconv"
"github.com/elves/elvish/pkg/cli"
"github.com/elves/elvish/pkg/cli/histutil"
"github.com/elves/elvish/pkg/eval"
"github.com/elves/elvish/pkg/eval/vals"
"github.com/elves/elvish/pkg/parse/parseutil"
)
var errStoreOffline = errors.New("store offline")
//elvdoc:fn command-history
//
// Outputs the entire command history as a stream of maps. Each map has a `id`
// key that identifies the sequence number of the entry, and a `cmd` key that
// identifies the content.
//
// Use indexing to extract individual entries. For example, to extract the
// content of the last command, do this:
//
// ```elvish
// edit:command-history | put [(all)][-1][cmd]
// ```
func commandHistory(fuser histutil.Store, ch chan<- interface{}) error {
if fuser == nil {
return errStoreOffline
}
cmds, err := fuser.AllCmds()
if err != nil {
return err
}
for _, cmd := range cmds {
ch <- vals.MakeMap("id", strconv.Itoa(cmd.Seq), "cmd", cmd.Text)
}
return nil
}
//elvdoc:fn insert-last-word
//
// Inserts the last word of the last command.
func insertLastWord(app cli.App, histStore histutil.Store) error {
c := histStore.Cursor("")
c.Prev()
cmd, err := c.Get()
if err != nil {
return err
}
words := parseutil.Wordify(cmd.Text)
if len(words) > 0 {
app.CodeArea().MutateState(func(s *cli.CodeAreaState) {
s.Buffer.InsertAtDot(words[len(words)-1])
})
}
return nil
}
func initStoreAPI(app cli.App, ns eval.Ns, fuser histutil.Store) {
ns.AddGoFns("<edit>", map[string]interface{}{
"command-history": func(fm *eval.Frame) error {
return commandHistory(fuser, fm.OutputChan())
},
"insert-last-word": func() { insertLastWord(app, fuser) },
})
}