github.com/hoop33/elvish@v0.0.0-20160801152013-6d25485beab4/edit/history.go (about) 1 package edit 2 3 import "fmt" 4 5 // Command history subsystem. 6 7 // Interface. 8 9 type hist struct { 10 current int 11 prefix string 12 line string 13 } 14 15 func (hist) Mode() ModeType { 16 return modeHistory 17 } 18 19 func (h *hist) ModeLine(width int) *buffer { 20 return makeModeLine(fmt.Sprintf(" HISTORY #%d ", h.current), width) 21 } 22 23 func startHistory(ed *Editor) { 24 ed.hist.prefix = ed.line[:ed.dot] 25 ed.hist.current = -1 26 if ed.prevHistory() { 27 ed.mode = &ed.hist 28 } else { 29 ed.addTip("no matching history item") 30 } 31 } 32 33 func historyUp(ed *Editor) { 34 ed.prevHistory() 35 } 36 37 func historyDown(ed *Editor) { 38 ed.nextHistory() 39 } 40 41 func historyDownOrQuit(ed *Editor) { 42 if !ed.nextHistory() { 43 ed.mode = &ed.insert 44 } 45 } 46 47 func historySwitchToHistlist(ed *Editor) { 48 startHistlist(ed) 49 if ed.mode == ed.histlist { 50 ed.line = "" 51 ed.dot = 0 52 ed.histlist.changeFilter(ed.hist.prefix) 53 } 54 } 55 56 func historyDefault(ed *Editor) { 57 ed.acceptHistory() 58 ed.mode = &ed.insert 59 ed.nextAction = action{typ: reprocessKey} 60 } 61 62 // Implementation. 63 64 func (h *hist) jump(i int, line string) { 65 h.current = i 66 h.line = line 67 } 68 69 func (ed *Editor) appendHistory(line string) { 70 if ed.store != nil { 71 go func() { 72 ed.store.Waits.Add(1) 73 // TODO(xiaq): Report possible error 74 ed.store.AddCmd(line) 75 ed.store.Waits.Done() 76 Logger.Println("added cmd to store:", line) 77 }() 78 } 79 } 80 81 func (ed *Editor) prevHistory() bool { 82 if ed.store != nil { 83 i, line, err := ed.store.LastCmd(ed.hist.current, ed.hist.prefix, true) 84 if err == nil { 85 ed.hist.jump(i, line) 86 return true 87 } 88 // TODO(xiaq): Errors other than ErrNoMatchingCmd should be reported 89 } 90 return false 91 } 92 93 func (ed *Editor) nextHistory() bool { 94 if ed.store != nil { 95 // Persistent history 96 i, line, err := ed.store.FirstCmd(ed.hist.current+1, ed.hist.prefix, true) 97 if err == nil { 98 ed.hist.jump(i, line) 99 return true 100 } 101 // TODO(xiaq): Errors other than ErrNoMatchingCmd should be reported 102 } 103 104 return false 105 } 106 107 // acceptHistory accepts the currently selected history. 108 func (ed *Editor) acceptHistory() { 109 ed.line = ed.hist.line 110 ed.dot = len(ed.line) 111 }