Synchronize access to command history from editor.

This commit is contained in:
Qi Xiao 2016-09-08 18:15:09 +02:00
parent 3057420fca
commit 8f404e0a46
4 changed files with 19 additions and 2 deletions

View File

@ -5,6 +5,7 @@ import (
"bytes"
"fmt"
"os"
"sync"
"syscall"
"time"
@ -40,6 +41,8 @@ type Editor struct {
rpromptPersistent bool
beforeReadLine eval.Variable
historyMutex sync.RWMutex
editorState
}

View File

@ -1,12 +1,15 @@
package edit
import (
"sync"
"github.com/elves/elvish/eval"
"github.com/elves/elvish/store"
)
type History struct {
st *store.Store
mutex *sync.RWMutex
st *store.Store
}
var _ eval.ListLike = History{}
@ -20,12 +23,18 @@ func (hv History) Repr(int) string {
}
func (hv History) Len() int {
hv.mutex.RLock()
defer hv.mutex.RUnlock()
nextseq, err := hv.st.NextCmdSeq()
maybeThrow(err)
return nextseq - 1
}
func (hv History) Iterate(f func(eval.Value) bool) {
hv.mutex.RLock()
defer hv.mutex.RUnlock()
n := hv.Len()
for i := 1; i <= n; i++ {
s, err := hv.st.Cmd(i)
@ -37,6 +46,9 @@ func (hv History) Iterate(f func(eval.Value) bool) {
}
func (hv History) IndexOne(idx eval.Value) eval.Value {
hv.mutex.RLock()
defer hv.mutex.RUnlock()
slice, i, j := eval.ParseAndFixListIndex(eval.ToString(idx), hv.Len())
if slice {
ss := make([]eval.Value, j-i)

View File

@ -68,11 +68,13 @@ func (h *hist) jump(i int, line string) {
func (ed *Editor) appendHistory(line string) {
if ed.store != nil {
ed.historyMutex.Lock()
go func() {
ed.store.Waits.Add(1)
// TODO(xiaq): Report possible error
ed.store.AddCmd(line)
ed.store.Waits.Done()
ed.historyMutex.Unlock()
Logger.Println("added cmd to store:", line)
}()
}

View File

@ -40,7 +40,7 @@ func makeModule(ed *Editor) eval.Namespace {
ns["rprompt"] = ed.rps1
ns["rprompt-persistent"] = BoolExposer{&ed.rpromptPersistent}
ns["current-command"] = StringExposer{&ed.line}
ns["history"] = eval.NewRoVariable(History{ed.store})
ns["history"] = eval.NewRoVariable(History{&ed.historyMutex, ed.store})
ns["abbr"] = eval.NewRoVariable(eval.MapStringString(ed.abbreviations))