From ee9f2a3d9ce5dcda316dbcf2f77cfe346a5c1d86 Mon Sep 17 00:00:00 2001 From: Zachary Yedidia Date: Sun, 29 May 2016 11:02:56 -0400 Subject: [PATCH] Add persistent undo as the option --- cmd/micro/buffer.go | 56 +++++++++++-------- cmd/micro/cursor.go | 5 ++ cmd/micro/eventhandler.go | 111 ++++++++++++++++++-------------------- cmd/micro/runtime.go | 4 +- cmd/micro/settings.go | 1 + cmd/micro/stack.go | 32 +++++------ cmd/micro/stack_test.go | 39 -------------- runtime/help/help.md | 5 ++ todolist.md | 4 +- 9 files changed, 116 insertions(+), 141 deletions(-) delete mode 100644 cmd/micro/stack_test.go diff --git a/cmd/micro/buffer.go b/cmd/micro/buffer.go index 8bb2cafa..6a0aaec6 100644 --- a/cmd/micro/buffer.go +++ b/cmd/micro/buffer.go @@ -41,6 +41,12 @@ type Buffer struct { FileType string } +// The SerializedBuffer holds the types that get serialized when a buffer is saved +type SerializedBuffer struct { + EventHandler *EventHandler + Cursor Cursor +} + // NewBuffer creates a new buffer from `txt` with path and name `path` func NewBuffer(txt, path string) *Buffer { b := new(Buffer) @@ -61,35 +67,36 @@ func NewBuffer(txt, path string) *Buffer { os.Mkdir(configDir+"/buffers/", os.ModePerm) } - if settings["savecursor"].(bool) { + // Put the cursor at the first spot + b.Cursor = Cursor{ + X: 0, + Y: 0, + buf: b, + } + + if settings["savecursor"].(bool) || settings["saveundo"].(bool) { absPath, _ := filepath.Abs(b.Path) file, err := os.Open(configDir + "/buffers/" + EscapePath(absPath)) if err == nil { - var cursor Cursor + var buffer SerializedBuffer decoder := gob.NewDecoder(file) - err = decoder.Decode(&cursor) + gob.Register(TextEvent{}) + err = decoder.Decode(&buffer) if err != nil { TermMessage(err.Error()) } - b.Cursor = cursor - b.Cursor.buf = b - b.Cursor.Clamp() - } else { - // Put the cursor at the first spot - b.Cursor = Cursor{ - X: 0, - Y: 0, - buf: b, + if settings["savecursor"].(bool) { + b.Cursor = buffer.Cursor + b.Cursor.buf = b + b.Cursor.Clamp() + } + + if settings["saveundo"].(bool) { + b.EventHandler = buffer.EventHandler + b.EventHandler.buf = b } } file.Close() - } else { - // Put the cursor at the first spot - b.Cursor = Cursor{ - X: 0, - Y: 0, - buf: b, - } } return b @@ -121,12 +128,17 @@ func (b *Buffer) Save() error { // Serialize serializes the buffer to configDir/buffers func (b *Buffer) Serialize() error { - if settings["savecursor"].(bool) { + if settings["savecursor"].(bool) || settings["saveundo"].(bool) { absPath, _ := filepath.Abs(b.Path) file, err := os.Create(configDir + "/buffers/" + EscapePath(absPath)) if err == nil { enc := gob.NewEncoder(file) - err = enc.Encode(b.Cursor) + gob.Register(TextEvent{}) + err = enc.Encode(SerializedBuffer{ + b.EventHandler, + b.Cursor, + }) + // err = enc.Encode(b.Cursor) } file.Close() return err @@ -141,7 +153,7 @@ func (b *Buffer) SaveAs(filename string) error { err := ioutil.WriteFile(filename, data, 0644) if err == nil { b.IsModified = false - err = b.Serialize() + return b.Serialize() } return err } diff --git a/cmd/micro/cursor.go b/cmd/micro/cursor.go index ec5acbcc..d83598b3 100644 --- a/cmd/micro/cursor.go +++ b/cmd/micro/cursor.go @@ -74,6 +74,11 @@ func (c *Cursor) Clamp() { } } +func (c *Cursor) Goto(b Cursor) { + c.X, c.Y, c.LastVisualX = b.X, b.Y, b.LastVisualX + c.OrigSelection, c.CurSelection = b.OrigSelection, b.CurSelection +} + // SetLoc sets the location of the cursor in terms of character number // and not x, y location // It's just a simple wrapper of FromCharPos diff --git a/cmd/micro/eventhandler.go b/cmd/micro/eventhandler.go index 2e182c4c..2c0e6482 100644 --- a/cmd/micro/eventhandler.go +++ b/cmd/micro/eventhandler.go @@ -15,42 +15,42 @@ const ( // TextEvent holds data for a manipulation on some text that can be undone type TextEvent struct { - c Cursor + C Cursor - eventType int - text string - start int - end int - time time.Time + EventType int + Text string + Start int + End int + Time time.Time } // ExecuteTextEvent runs a text event func ExecuteTextEvent(t *TextEvent, buf *Buffer) { - if t.eventType == TextEventInsert { - buf.insert(t.start, t.text) - } else if t.eventType == TextEventRemove { - t.text = buf.remove(t.start, t.end) + if t.EventType == TextEventInsert { + buf.insert(t.Start, t.Text) + } else if t.EventType == TextEventRemove { + t.Text = buf.remove(t.Start, t.End) } } // UndoTextEvent undoes a text event func UndoTextEvent(t *TextEvent, buf *Buffer) { - t.eventType = -t.eventType + t.EventType = -t.EventType ExecuteTextEvent(t, buf) } // EventHandler executes text manipulations and allows undoing and redoing type EventHandler struct { - buf *Buffer - undo *Stack - redo *Stack + buf *Buffer + UndoStack *Stack + RedoStack *Stack } // NewEventHandler returns a new EventHandler func NewEventHandler(buf *Buffer) *EventHandler { eh := new(EventHandler) - eh.undo = new(Stack) - eh.redo = new(Stack) + eh.UndoStack = new(Stack) + eh.RedoStack = new(Stack) eh.buf = buf return eh } @@ -58,12 +58,12 @@ func NewEventHandler(buf *Buffer) *EventHandler { // Insert creates an insert text event and executes it func (eh *EventHandler) Insert(start int, text string) { e := &TextEvent{ - c: eh.buf.Cursor, - eventType: TextEventInsert, - text: text, - start: start, - end: start + Count(text), - time: time.Now(), + C: eh.buf.Cursor, + EventType: TextEventInsert, + Text: text, + Start: start, + End: start + Count(text), + Time: time.Now(), } eh.Execute(e) } @@ -71,11 +71,11 @@ func (eh *EventHandler) Insert(start int, text string) { // Remove creates a remove text event and executes it func (eh *EventHandler) Remove(start, end int) { e := &TextEvent{ - c: eh.buf.Cursor, - eventType: TextEventRemove, - start: start, - end: end, - time: time.Now(), + C: eh.buf.Cursor, + EventType: TextEventRemove, + Start: start, + End: end, + Time: time.Now(), } eh.Execute(e) } @@ -88,38 +88,34 @@ func (eh *EventHandler) Replace(start, end int, replace string) { // Execute a textevent and add it to the undo stack func (eh *EventHandler) Execute(t *TextEvent) { - if eh.redo.Len() > 0 { - eh.redo = new(Stack) + if eh.RedoStack.Len() > 0 { + eh.RedoStack = new(Stack) } - eh.undo.Push(t) + eh.UndoStack.Push(t) ExecuteTextEvent(t, eh.buf) } // Undo the first event in the undo stack func (eh *EventHandler) Undo() { - t := eh.undo.Peek() + t := eh.UndoStack.Peek() if t == nil { return } - te := t.(*TextEvent) - startTime := t.(*TextEvent).time.UnixNano() / int64(time.Millisecond) + startTime := t.Time.UnixNano() / int64(time.Millisecond) eh.UndoOneEvent() for { - t = eh.undo.Peek() + t = eh.UndoStack.Peek() if t == nil { return } - te = t.(*TextEvent) - - if startTime-(te.time.UnixNano()/int64(time.Millisecond)) > undoThreshold { + if startTime-(t.Time.UnixNano()/int64(time.Millisecond)) > undoThreshold { return - } else { - startTime = t.(*TextEvent).time.UnixNano() / int64(time.Millisecond) } + startTime = t.Time.UnixNano() / int64(time.Millisecond) eh.UndoOneEvent() } @@ -129,46 +125,42 @@ func (eh *EventHandler) Undo() { func (eh *EventHandler) UndoOneEvent() { // This event should be undone // Pop it off the stack - t := eh.undo.Pop() + t := eh.UndoStack.Pop() if t == nil { return } - te := t.(*TextEvent) // Undo it // Modifies the text event - UndoTextEvent(te, eh.buf) + UndoTextEvent(t, eh.buf) // Set the cursor in the right place - teCursor := te.c - te.c = eh.buf.Cursor - eh.buf.Cursor = teCursor + teCursor := t.C + t.C = eh.buf.Cursor + eh.buf.Cursor.Goto(teCursor) // Push it to the redo stack - eh.redo.Push(te) + eh.RedoStack.Push(t) } // Redo the first event in the redo stack func (eh *EventHandler) Redo() { - t := eh.redo.Peek() + t := eh.RedoStack.Peek() if t == nil { return } - te := t.(*TextEvent) - startTime := t.(*TextEvent).time.UnixNano() / int64(time.Millisecond) + startTime := t.Time.UnixNano() / int64(time.Millisecond) eh.RedoOneEvent() for { - t = eh.redo.Peek() + t = eh.RedoStack.Peek() if t == nil { return } - te = t.(*TextEvent) - - if (te.time.UnixNano()/int64(time.Millisecond))-startTime > undoThreshold { + if (t.Time.UnixNano()/int64(time.Millisecond))-startTime > undoThreshold { return } @@ -178,18 +170,17 @@ func (eh *EventHandler) Redo() { // RedoOneEvent redoes one event func (eh *EventHandler) RedoOneEvent() { - t := eh.redo.Pop() + t := eh.RedoStack.Pop() if t == nil { return } - te := t.(*TextEvent) // Modifies the text event - UndoTextEvent(te, eh.buf) + UndoTextEvent(t, eh.buf) - teCursor := te.c - te.c = eh.buf.Cursor - eh.buf.Cursor = teCursor + teCursor := t.C + t.C = eh.buf.Cursor + eh.buf.Cursor.Goto(teCursor) - eh.undo.Push(te) + eh.UndoStack.Push(t) } diff --git a/cmd/micro/runtime.go b/cmd/micro/runtime.go index 508de871..36178329 100644 --- a/cmd/micro/runtime.go +++ b/cmd/micro/runtime.go @@ -240,7 +240,7 @@ func runtimeColorschemesSolarizedMicro() (*asset, error) { return a, nil } -var _runtimeHelpHelpMd = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x9c\x59\xdd\x73\xdb\xb8\x11\x7f\x36\xff\x0a\x8c\x72\x33\x97\x5c\x25\x79\x7a\xed\x93\xdf\x7c\xb6\xf3\x71\x97\xc4\x3e\xc7\x69\x2f\xf7\x12\x42\x24\x24\xe1\x4c\x12\x0c\x00\xca\x56\xda\xeb\xdf\xde\xdf\x2e\x00\x8a\x94\xe4\x4c\xa7\x79\x89\xb8\xbb\xd8\x2f\xec\x17\xd6\xcf\xc4\x3b\x5d\x58\x23\xd6\xaa\x6a\x85\x57\x8f\x3e\xcb\x02\x40\x3b\x21\x01\xb0\xb5\x6e\x64\x35\x5b\x48\xa7\x4a\xc6\x0b\x55\x6a\x6f\xac\xf0\x6b\xe9\x85\xd4\xb5\x13\xde\x88\x85\x12\x4a\xba\x2d\xfd\xec\x9c\x12\xb2\x29\x85\x6e\x7c\xa7\xbd\xde\xa8\xa9\xc8\x1e\xd6\xba\x02\xb4\x72\x46\x78\x79\xaf\x9b\x95\x90\xe5\x46\x36\x5e\xae\x94\x30\x4b\xb0\x52\x62\xd9\x55\x95\x28\x64\x2b\x17\xba\xc2\x31\xe5\x08\x51\x9b\x52\xd9\xa6\xd7\xc2\xcd\xb3\xec\xd9\xb3\x67\xe2\xa3\xc3\xc1\x2c\xbb\x6e\x0a\x25\xb6\xa6\x13\x6b\xb9\x51\x62\xd1\xe9\xca\x33\xab\xa0\xe0\x54\x38\x5d\xb7\xd5\x56\x38\x2f\xad\x17\xda\x8b\xc5\x56\xd8\xae\x69\x48\x7c\x96\xd7\x6c\x64\x2b\xfd\xfa\xd4\x9b\xd3\x25\xf4\x9b\xfb\x47\x9f\x0b\x58\x16\xcf\x05\x92\x9c\x6c\x32\xad\x6a\x60\x94\x50\x75\xeb\xb7\x90\xb4\x5c\x2a\x3b\x4f\x8e\x62\xb3\x5c\xd7\xb6\xc6\x7a\x27\x0a\xab\xa4\x27\x11\x81\xca\x89\xa5\x35\x35\x74\x28\x75\x73\x96\x65\x79\x9e\x67\xdf\x09\xbd\x2c\x4c\xb3\xd4\x2b\xf1\x6f\xc1\x32\x18\x9c\x7d\x82\x25\x05\x84\xd4\x06\xd6\x90\x1d\x45\x67\x1d\xd4\x91\xd6\x74\xf0\xe7\x83\xf6\x6b\x06\x4b\x6b\xcd\x83\xb8\x57\x5b\xc7\x7e\xae\x0d\x3c\x1e\x1d\xf3\x8b\xda\x2e\x74\x03\x51\x2b\x97\x65\x77\x6b\x45\x57\x61\x03\xb3\x52\x2d\x65\x07\x07\xdd\xef\x48\xa6\x50\xdd\x40\xd3\xc4\x59\x43\x56\xe1\xb5\x69\xc8\xcf\xd9\x0f\xe2\xc2\xdb\x6a\xf6\xe5\x4c\x08\xf1\x2b\x6e\x32\x01\x14\x01\xae\x1e\x55\xd1\x79\x70\x17\x85\xa9\x6b\xa8\x91\xb0\x2b\xc2\xde\x99\xd5\x0a\xf7\xbd\x0b\xa9\x88\x5c\x10\xf2\xb6\x83\x2b\x85\x03\xb2\xda\x3f\xec\x08\xff\x01\x97\x99\x00\x86\x00\xd7\xe4\x7c\xba\xa0\x04\xfd\x4a\xd0\x8f\x4d\x69\x12\x60\xcb\x7c\xd5\x0e\xb0\x24\xc0\x4b\xbd\xe3\xdc\x24\x80\x68\x06\xfa\xb4\x3d\xb4\xb5\x6a\xa3\xe1\xc8\x84\x91\xac\x89\xaa\x54\x81\x18\xaf\xaa\x04\x2e\x08\x7c\x61\xda\x6d\x02\x3c\x32\xa0\xeb\x39\xde\xc7\x6f\x51\xe9\xa6\xd7\xb7\x24\xe0\x65\xd7\x56\xba\x90\xf0\xd9\x10\xb5\x21\xd4\x8d\x74\x9e\x20\x37\x88\xea\x8f\x6d\x80\x20\x31\xba\x36\xc2\x2e\xcd\x03\xf4\x67\x58\x89\x9f\x80\xbe\x36\x35\x5f\x83\x10\xaf\x4c\x48\xbf\x95\x0e\x81\x8d\xa4\x89\xfc\xaf\x9a\x32\x90\x44\x1a\x05\x33\x77\x58\x96\x6e\x07\x97\x45\x70\xd1\x74\xf5\x02\x31\xbb\x8b\x45\x4a\x66\x8e\xb9\x10\x39\x4e\xfc\x25\x84\x1f\x27\x3d\x07\xea\x83\xb1\x25\x65\x16\xfd\x3f\xcf\x88\xad\xa8\xd4\xd2\x73\x68\x5a\xbd\x5a\xfb\x83\x78\xc6\x49\xfa\x0a\x69\x49\x64\x51\x33\x02\x92\x16\x53\x02\x66\x05\x71\xea\x5a\x26\x20\xab\x0f\xd9\x3c\xc5\xa3\x4f\xcf\x64\xc4\xda\x54\x25\x02\x4e\x43\x2b\x0e\x75\x5c\x68\xa4\x85\x75\xc4\xb6\x56\x8d\x4f\xa1\x4f\xea\xb9\x70\xf1\xa1\x6a\x81\x00\x8e\x9d\x73\x3e\x89\x94\x3a\xa2\x96\x5b\x2a\x7a\x56\x2d\x38\x39\x3b\x47\xce\x27\xe9\xf9\x7f\x4e\xe7\x21\xbb\x4f\x39\xb7\x4f\xd3\x91\xf9\x1f\xce\x34\xb9\xc8\xb8\xd4\x88\x2b\x59\xac\xc9\xa3\x54\x66\x03\x0b\xc8\x85\xae\x41\x0b\x48\x7b\x09\x13\xd5\xa3\x44\x25\x82\x43\xe8\x8a\x29\x4c\xf3\x10\xee\x5c\x93\x70\xc6\xb0\xe9\x01\xf8\x95\x81\x16\x49\x30\xe5\x9a\x58\x98\x0e\x56\xb7\x5d\x28\x89\xd9\xd2\x54\x95\x79\x20\x25\x75\x13\xf4\xdc\xd3\x8b\xd5\xe2\x02\x45\xdf\xd9\xbf\xb2\x93\x09\xf1\xfd\x34\x39\x13\x13\xca\xb5\xc9\x34\x42\x7e\x27\x08\x25\xdb\x24\xfb\x33\x14\xae\xd7\xca\x1e\xd4\x19\x77\x36\xe4\x45\x51\x38\xf9\xd8\x4e\x62\x40\xc6\x7f\x93\x0b\xbe\x49\xc0\xa7\x81\x82\x02\x7d\x44\x13\x29\x18\x1e\x69\x6e\x29\xa6\x86\x44\x91\x26\xc0\x23\xd1\x5b\x44\xe0\x31\x46\x0c\x8f\x34\x1f\x28\x20\x86\x3a\x4d\x42\xbe\xef\xd4\x61\x8a\xa1\x4e\x91\x62\xa8\x0e\xd3\x0c\xc5\x45\x9a\x03\x49\x43\xbd\x23\xcd\x48\xe5\xf3\xca\x8f\xb5\x9e\xfc\x13\x19\x35\x64\x03\x8a\xb1\xf1\x4c\xb1\xcf\x64\x2c\x2c\x4a\x7a\x92\xb0\x17\x39\x20\x1c\xca\xa4\x0b\x1f\xa9\x35\xf9\x40\x29\x77\xbd\x7c\x8b\x44\x1d\x12\x8d\x34\x9b\xa0\xf6\x1c\x92\x8c\x04\x46\x79\x77\xe6\x09\x7e\x23\x33\x7a\xe2\xa3\x7c\x47\x71\x15\x2f\x9a\xb9\x0e\x89\x46\xa1\x15\x89\xc0\xed\x40\x64\x62\x36\xd6\xef\x80\x2c\xb1\x1b\x6a\x96\x88\xae\x1a\xcc\x2b\xa3\x08\x7d\xd3\x38\x65\x7d\x80\xa7\x98\x68\x65\xa1\x8e\x10\x05\x78\x24\xfa\x49\x16\xf7\x6e\x48\x38\x80\xec\x93\xfc\x98\x62\xeb\x80\xe4\x4e\x2e\xc6\x89\x17\x45\x11\x7c\x60\xd7\xf5\x48\x1b\x6a\xba\x2f\x51\x12\x46\x96\x8f\x28\xa8\x4f\x0f\xb1\x2f\x47\x58\xea\xaa\x43\xec\xfb\x03\xec\x7b\x34\xe2\x21\xc5\xcd\x01\xc5\x4d\x6c\xca\x43\xaa\xdf\x47\x54\xb1\x30\xf5\xd8\x4f\x23\x2c\x17\xa9\x01\xf6\x62\x5c\x36\xd0\xc6\x87\xd8\xdf\xf6\x8a\xca\x48\xb9\x5f\xf6\x91\xfb\x41\x78\x39\x22\xe8\x9b\xfd\x3e\xd9\x3f\x46\x64\xdc\xf8\x87\xe8\xf3\xb1\x87\x39\xb6\xce\xab\x2a\x91\x50\xdb\x1f\x97\xb5\x51\x74\x52\x0c\x8e\x2f\x7a\x10\x95\x37\xab\xbd\xfa\x3b\x09\xe3\xc6\x0e\x7f\xd9\x1c\xe2\x87\xa5\x8e\x14\x7c\x35\x52\x30\x8c\x0e\xaf\x31\xe6\x8d\x4a\xc1\x11\x9a\xdb\xae\xda\xc5\x3e\x17\x95\x11\xd1\xcf\x5d\xdd\x0e\x5d\x75\x09\xcb\xfd\xd0\xd4\x04\x49\x96\xba\x62\xcf\xd2\x8b\x4a\x49\xca\x7a\x3f\x0e\x97\x9f\xc6\x0e\xa5\xa1\xf3\x1d\xde\x14\x43\x92\x5f\x47\x24\x34\xe9\x0e\xb1\x57\x7b\x31\xc3\xf3\x6a\x64\xc1\x54\xa7\xa7\xe2\xaa\x96\x85\x9b\x39\xbf\xc5\xb4\x30\x18\xaf\xfb\x4a\x3b\x5b\x52\x0d\x3b\x56\x83\x67\x8b\x84\xd9\x2b\xf4\x33\xc9\x65\xef\xb0\x36\x12\x8e\x1c\x73\x58\x62\x09\x43\x37\x7c\xd0\x55\x09\xd1\xec\x10\xf1\x4a\xff\x0c\x8f\x91\xf0\x6e\xb8\x31\xce\xe9\x05\xd4\x8f\x03\xf9\x60\x02\x54\x69\xd2\x6f\xd2\xc3\x2f\xd2\xd0\xd0\x87\xb1\xd9\xf1\xe4\x13\x66\x10\x85\x31\x82\xe7\x0c\xc5\x58\x1e\xd6\x02\xf1\x7c\x3c\x24\xb4\xfb\xf2\xc2\x6b\x72\xbb\x9b\x3a\xe7\xf4\x00\xc9\xbf\xe0\x36\xf2\x33\x7e\x7e\xb8\xf0\x54\x9a\x13\xd8\xa1\xf4\x00\x4c\x15\xc8\xa5\x91\xd0\xd2\x0c\xd7\x8f\x7e\x20\xb2\xaa\xad\x50\x05\xc5\xc4\x21\x32\x8a\xf5\x44\x4c\x36\xb2\xea\xd4\x44\x2c\x2b\xb9\x72\x38\x7e\xb7\xc6\xec\xf5\xa0\x31\x0c\x26\xd2\x3c\x90\xe6\x61\x4c\xcc\x99\x3e\x9f\x0b\x72\x23\x0d\x7f\x79\x38\xc9\x56\x98\x96\xe6\x34\x59\xcd\x09\x79\x4e\x43\x16\x98\xb5\x06\x8f\xde\x29\x69\x04\x0a\x7c\x9b\x06\xcf\x48\x83\xb9\x9a\x0e\x9e\x89\xbc\xc8\xa7\x34\x54\x62\xf2\x53\x8d\x84\xf9\x0e\xa0\xb5\x2a\xee\x73\x7e\xe8\xb2\x9c\x80\x96\xee\xde\xe1\x95\x48\x0e\xf9\xbe\xc4\x50\x7c\xaf\x68\xb8\x6b\x95\x5d\x1a\x5b\xb3\xc5\x51\x65\x9e\x5c\x15\xcd\x92\x5e\xd7\x8a\x23\xf2\xbd\xf1\x2a\xb8\xb3\x37\xa7\xee\x9c\xa7\x69\x55\x0a\x98\xa4\x31\x97\xab\x95\x7a\x9c\x0b\xf1\x66\xc9\xda\xc5\xb9\x59\xda\x55\x47\xfc\x38\x70\x4b\x03\xed\x1a\xe3\xc3\xdb\x5a\x36\x78\x46\x53\x4f\x71\x34\x3e\x6a\x1f\x46\x4c\x9a\x81\x4d\xad\xc3\x84\xf9\xa5\x83\x5c\x17\x5c\xef\x94\x8f\x0e\x12\xc1\x87\x67\x18\xa9\x7d\xb8\xaa\x08\x87\x39\x8c\x9a\x8b\x1b\x64\x2e\xe6\x70\xa7\x42\x68\xd0\xfb\x0c\x1f\x3c\x06\x23\x9a\x2c\x29\x23\xe1\x02\x58\x00\x3d\xc3\x69\xd7\x47\x0a\xd8\xc6\xdb\xc6\xab\xd2\xad\x67\x31\x9e\x20\x10\x80\x20\x70\xa5\x37\xaa\x19\xbf\x37\xd3\x0c\xbc\x40\xab\x5c\xf1\xeb\x7a\xce\x17\x4c\xb2\x22\xc9\xf7\xb8\xbd\xce\xd3\xf8\xcc\x11\x02\xe7\x95\xda\xc1\xe5\x5b\xc5\xa7\xc9\x6d\xfc\x62\x7a\x58\x2b\x72\x08\xc6\xe7\x46\x43\x86\x4b\x1b\x86\xf8\x20\xbf\x0e\xfa\xa6\x55\x81\x43\xfe\x80\x66\xf7\x00\xa1\x50\xa7\x8c\xa2\xf7\x42\x67\x25\x1b\xcd\x1e\x76\x7b\xc0\x52\x5b\xf8\xc4\xd8\x6d\xbf\x76\xc0\xc9\x60\x60\xfe\xdd\x6f\x97\xaf\x3e\x5f\x5c\xbf\x7f\xf9\xe6\xd5\xe7\xd7\xd7\xef\xae\x4e\xe3\xe2\x42\xc6\xe4\x78\x82\x91\x38\x77\x14\x52\x19\xd1\x80\x03\x2e\x58\x15\x53\x8a\xba\x03\x86\x39\x05\x33\x05\x03\xdc\x3d\x3d\x78\xe1\x30\xb6\xa3\xf5\x10\x04\x66\x3b\x89\x23\x9d\x47\xe9\x9f\x6e\x71\x94\xf4\xe0\x7d\xc6\x57\x59\x98\xca\x58\x87\xc4\xa8\x29\x70\x2a\x23\xcb\x64\x47\x0f\x0f\x8e\xe4\x9b\xa0\x3b\xfb\xee\x79\x90\x78\xa9\xed\x8b\xd3\x01\x99\x3b\xcd\x83\xa8\x7c\x1e\xf6\x2c\xd9\x49\x5a\x83\x70\xf0\x21\x25\xe3\x77\x9e\x9d\xec\xf2\x66\xb8\x2e\x19\x72\x13\xcf\x23\x74\x2a\x9c\xa9\xa4\xd5\x5f\x55\xc9\x8f\xd5\xdd\xe7\xcc\x17\x2f\xb2\x13\xb2\x93\xdc\x55\x19\x9a\x01\x58\xcd\x5e\xc1\x29\x62\xa9\x90\xf1\x5d\xbd\x65\x97\x28\x3c\xba\xcb\x52\xf5\x61\x19\x56\x53\x68\x23\xd2\x6e\xa1\xf2\xdd\x9e\xed\xe4\xac\x85\x8a\x8f\x54\x9c\xe2\x05\x13\x85\x14\xaf\xd1\x74\x15\x92\x94\x5f\x7d\x27\xfb\x8f\xd1\x91\x73\x86\xb1\x10\x62\x0a\xc1\x8f\xd3\x28\xdd\xc9\xfc\xb8\x1a\xb2\x4a\x65\x27\xc3\xb3\xb8\xa9\x93\x1f\x12\xd5\x59\xa8\x7e\xda\x3d\xe5\xb9\x39\x11\xf7\x3e\x1a\x93\xf7\xe0\x91\x8d\xcf\x39\x9e\xa2\x19\xae\x80\xfc\xc6\xad\x8d\x7f\x81\x62\x7c\x22\x04\xf5\x26\x7c\xd2\x03\x97\xcb\xd3\x11\x3e\xa2\x95\x18\x18\x70\xa3\xe0\x81\x08\xb3\xfd\x0e\x31\xad\x28\xb5\x1f\x6b\x85\x9b\xfb\x5f\x14\x5b\xd2\xe6\xc1\x76\xf1\x46\xa6\xe2\x0f\x2a\xad\xa4\x53\x2d\x51\xa4\x5d\x67\xd5\x9e\xb8\x7e\x31\xb8\x3b\x85\xdb\x03\x1b\x15\x97\x06\x3a\x2c\x30\xfa\xc8\x23\x66\xef\xde\x5c\xdc\x5e\x7f\xbe\xbb\xfd\x78\x75\x71\xfd\xf6\xfa\x16\xed\x62\xa3\xad\x69\xb8\xda\x6f\xa0\x15\x35\x0f\xd2\x93\x0a\x2d\xec\xf9\x6b\xe2\xc8\xfb\x10\x62\x1a\x7b\x25\xe7\x93\x97\x0b\x07\x3b\x86\x45\x18\x20\x41\x30\x3a\x9c\x52\xe4\x48\x72\xfc\x3d\x67\x06\x98\x67\x20\xb8\x58\x4b\x3b\xe4\x11\xa0\xa1\xa8\x10\x4e\x22\x18\xed\x11\x26\x22\x32\x59\x35\xd0\xb0\x40\xa9\x07\x93\xd4\xc9\xe8\x73\xa6\xf1\x1a\x69\x1c\xaf\x8a\x45\xe8\x58\xca\x1d\xe1\x63\x96\xcb\xc0\xc9\x6d\x21\xf6\x11\x5c\x7c\x67\x51\x44\xc2\x27\x2a\x32\xad\x6e\x41\x74\xec\x68\x93\xf7\x9e\xf0\x26\x34\x32\x9c\xa7\x30\xe8\xbb\x1a\x26\x71\x19\x56\x48\x20\xfa\x96\x78\xd9\x79\x13\x6c\x07\x0b\x2e\xff\xfd\xca\x57\xa2\x7b\x3d\x84\xbe\x90\x16\x67\x4e\xd6\x63\x57\xc5\xa2\x4c\x65\x2b\x2d\x1d\xc3\x4e\xee\x69\xb5\x2d\x0d\xcf\x10\x16\x3b\xd0\xde\xaa\xee\xc9\x63\x8e\xa7\x61\x22\x1e\x9c\x8d\x5b\x33\x1f\xa5\x8a\x18\x74\x0b\xe3\x3d\xaa\x48\x6c\x4a\x21\xe1\xbe\xc5\x1a\x59\x17\xd6\x70\xd4\x69\x91\x17\xa4\x0b\x39\xc3\x8e\x56\x74\x0f\x30\xb6\xc2\x1b\x87\x87\x93\xbe\x3c\x31\x98\x36\xea\xd4\x31\x9a\x92\x3d\xd1\xf1\x82\x3e\x0c\x4e\xec\x53\xea\x0a\xbc\x75\xef\x4f\xc9\x95\xd4\x4d\x98\xb9\x9f\x0e\x0d\x44\x7d\x55\xd5\x98\x64\x74\x03\xcd\x64\x8d\xde\xee\xd3\xd6\x33\x4c\x0d\x0f\x5c\x36\xd2\x48\x45\x53\x87\x5c\x98\x4d\xf8\x93\xc5\x42\x61\x76\x1d\x18\x70\xc4\x03\x7f\x1b\x0a\x42\xc7\x54\xe5\x11\x39\xc4\x98\x09\xb8\x5c\xd0\xac\x10\x3f\x15\x46\x11\x7f\x84\xeb\x8f\xe0\x3a\x9b\xcd\xb2\xec\x32\x22\xda\xaa\x5b\xd1\x98\x11\x1a\x65\xe8\x8b\xe0\xed\x39\x0e\xe8\x07\xfc\xda\xac\x3a\xbc\xd0\x68\xca\x14\x74\x1f\xe2\x79\x2c\x35\x70\xeb\x0e\x49\xfd\xe5\x62\x2a\x2e\xa7\xe2\x95\x99\x8a\x9f\xe5\x46\xf2\xab\x80\x7e\x40\x27\xdd\xa2\x97\xbd\xed\x24\xea\xea\x8d\x35\x1b\x5d\xee\x06\xf7\x24\x2e\xaa\x32\xff\x46\x34\xac\x8c\xae\xb9\xc6\x41\x37\xda\xee\xf7\xdf\x49\xb5\x23\xdc\x57\xe6\x9b\x9c\xd3\x85\xae\xcc\xb2\xf6\x3d\x5b\xfc\xfe\xff\x59\x92\xb2\xe7\x98\x63\xe3\x00\x4a\xb1\x40\xe5\x33\xf6\x98\xf8\xb6\x49\xc3\x1e\x89\x28\xd3\xa6\x9a\xc3\x2f\xdb\x6f\xa5\x38\xec\xfb\xfd\x29\xba\xc5\x94\x58\x29\xbc\x3f\x8a\x30\x1e\xef\x8f\x75\x21\xf4\x23\xff\x8c\x6b\x06\x35\x6f\x08\x05\xf1\x9c\x66\xf1\xf1\xb4\xef\xa9\xa1\x1c\xe1\xc3\x2d\x99\xb4\xe7\x85\xb1\xa1\x9c\xc9\xf0\x00\x5d\xf3\xe6\x3c\xfe\xe9\xaa\x30\x6d\x4c\xf5\x91\x92\xd1\x1e\x3e\x23\xe2\x99\x79\xf6\xdf\x00\x00\x00\xff\xff\x01\x6e\xc3\xcf\x02\x1c\x00\x00") +var _runtimeHelpHelpMd = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x9c\x59\x5d\x77\xdb\x36\xd2\xbe\x36\x7f\x05\x8e\xd2\x73\x9a\xf4\x95\xe4\xf3\x76\xf7\xca\x77\xae\xed\x7c\xb4\x49\xec\x3a\xce\x6e\xd3\x9b\x10\x22\x21\x09\x35\x49\x30\x00\x28\x5b\xd9\xed\xfe\xf6\x7d\x66\x00\x50\xa4\x24\x67\xf7\x6c\x6e\x22\xce\x0c\xe6\x0b\x33\x83\x99\xf1\x33\xf1\x4e\x17\xd6\x88\xb5\xaa\x5a\xe1\xd5\xa3\xcf\xb2\x00\xd0\x4e\x48\x00\x6c\xad\x1b\x59\xcd\x16\xd2\xa9\x92\xf1\x42\x95\xda\x1b\x2b\xfc\x5a\x7a\x21\x75\xed\x84\x37\x62\xa1\x84\x92\x6e\x4b\x3f\x3b\xa7\x84\x6c\x4a\xa1\x1b\xdf\x69\xaf\x37\x6a\x2a\xb2\x87\xb5\xae\x00\xad\x9c\x11\x5e\xde\xeb\x66\x25\x64\xb9\x91\x8d\x97\x2b\x25\xcc\x12\xac\x94\x58\x76\x55\x25\x0a\xd9\xca\x85\xae\x70\x4c\x39\x42\xd4\xa6\x54\xb6\xe9\xb5\x70\xf3\x2c\x7b\xf6\xec\x99\xf8\xe8\x70\x30\xcb\xae\x9b\x42\x89\xad\xe9\xc4\x5a\x6e\x94\x58\x74\xba\xf2\xcc\x2a\x28\x38\x15\x4e\xd7\x6d\xb5\x15\xce\x4b\xeb\x85\xf6\x62\xb1\x15\xb6\x6b\x1a\x12\x9f\xe5\x35\x1b\xd9\x4a\xbf\x3e\xf5\xe6\x74\x09\xfd\xe6\xfe\xd1\xe7\x02\x96\xc5\x73\x81\x24\x27\x9b\x4c\xab\x1a\x18\x25\x54\xdd\xfa\x2d\x24\x2d\x97\xca\xce\x93\xa3\xd8\x2c\xd7\xb5\xad\xb1\xde\x89\xc2\x2a\xe9\x49\x44\xa0\x72\x62\x69\x4d\x0d\x1d\x4a\xdd\x9c\x65\x59\x9e\xe7\xd9\x77\x42\x2f\x0b\xd3\x2c\xf5\x4a\xfc\x53\xb0\x0c\x06\x67\x9f\x60\x49\x01\x21\xb5\x81\x35\x64\x47\xd1\x59\x07\x75\xa4\x35\x1d\xfc\xf9\xa0\xfd\x9a\xc1\xd2\x5a\xf3\x20\xee\xd5\xd6\xb1\x9f\x6b\x03\x8f\x47\xc7\xfc\xa2\xb6\x0b\xdd\x40\xd4\xca\x65\xd9\xdd\x5a\xd1\x55\xd8\xc0\xac\x54\x4b\xd9\xc1\x41\xf7\x3b\x92\x29\x54\x37\xd0\x34\x71\xd6\x90\x55\x78\x6d\x1a\xf2\x73\xf6\x83\xb8\xf0\xb6\x9a\x7d\x39\x13\x42\xfc\x8a\x9b\x4c\x00\x45\x80\xab\x47\x55\x74\x1e\xdc\x45\x61\xea\x1a\x6a\x24\xec\x8a\xb0\x77\x66\xb5\xc2\x7d\xef\x42\x2a\x22\x17\x84\xbc\xed\xe0\x4a\xe1\x80\xac\xf6\x0f\x3b\xc2\x7f\xc0\x65\x26\x80\x21\xc0\x35\x39\x9f\x2e\x28\x41\xbf\x12\xf4\x63\x53\x9a\x04\xd8\x32\x5f\xb5\x03\x2c\x09\xf0\x52\xef\x38\x37\x09\x20\x9a\x81\x3e\x6d\x0f\x6d\xad\xda\x68\x38\x32\x61\x24\x6b\xa2\x2a\x55\x20\xc6\xab\x2a\x81\x0b\x02\x5f\x98\x76\x9b\x00\x8f\x0c\xe8\x7a\x8e\xf7\xf1\x5b\x54\xba\xe9\xf5\x2d\x09\x78\xd9\xb5\x95\x2e\x24\x7c\x36\x44\x6d\x08\x75\x23\x9d\x27\xc8\x0d\xa2\xfa\x63\x1b\x20\x48\x8c\xae\x8d\xb0\x4b\xf3\x00\xfd\x19\x56\xe2\x27\xa0\xaf\x4d\xcd\xd7\x20\xc4\x2b\x13\xd2\x6f\xa5\x43\x60\x23\x69\x22\xff\xab\xa6\x0c\x24\x91\x46\xc1\xcc\x1d\x96\xa5\xdb\xc1\x65\x11\x5c\x34\x5d\xbd\x40\xcc\xee\x62\x91\x92\x99\x63\x2e\x44\x8e\x13\xff\x17\xc2\x8f\x93\x9e\x03\xf5\xc1\xd8\x92\x32\x8b\xfe\x9f\x67\xc4\x56\x54\x6a\xe9\x39\x34\xad\x5e\xad\xfd\x41\x3c\xe3\x24\x7d\x85\xb4\x24\xb2\xa8\x19\x01\x49\x8b\x29\x01\xb3\x82\x38\x75\x2d\x13\x90\xd5\x87\x6c\x9e\xe2\xd1\xa7\x67\x32\x62\x6d\xaa\x12\x01\xa7\xa1\x15\x87\x3a\x2e\x34\xd2\xc2\x3a\x62\x5b\xab\xc6\xa7\xd0\x27\xf5\x5c\xb8\xf8\x50\xb5\x40\x00\xc7\xce\x39\x9f\x44\x4a\x1d\x51\xcb\x2d\x15\x3d\xab\x16\x9c\x9c\x9d\x23\xe7\x93\xf4\xfc\x5f\xa7\xf3\x90\xdd\xa7\x9c\xdb\xa7\xe9\xc8\xfc\x0f\x67\x9a\x5c\x64\x5c\x6a\xc4\x95\x2c\xd6\xe4\x51\x2a\xb3\x81\x05\xe4\x42\xd7\xa0\x05\xa4\xbd\x84\x89\xea\x51\xa2\x12\xc1\x21\x74\xc5\x14\xa6\x79\x08\x77\xae\x49\x38\x63\xd8\xf4\x00\xfc\xca\x40\x8b\x24\x98\x72\x4d\x2c\x4c\x07\xab\xdb\x2e\x94\xc4\x6c\x69\xaa\xca\x3c\x90\x92\xba\x09\x7a\xee\xe9\xc5\x6a\x71\x81\xa2\xef\xec\x1f\xd9\xc9\x84\xf8\x7e\x9a\x9c\x89\x09\xe5\xda\x64\x1a\x21\xbf\x13\x84\x92\x6d\x92\xfd\x19\x0a\xd7\x6b\x65\x0f\xea\x8c\x3b\x1b\xf2\xa2\x28\x9c\x7c\x6c\x27\x31\x20\xe3\xbf\xc9\x05\xdf\x24\xe0\xd3\x40\x41\x81\x3e\xa2\x89\x14\x0c\x8f\x34\xb7\x14\x53\x43\xa2\x48\x13\xe0\x91\xe8\x2d\x22\xf0\x18\x23\x86\x47\x9a\x0f\x14\x10\x43\x9d\x26\x21\xdf\x77\xea\x30\xc5\x50\xa7\x48\x31\x54\x87\x69\x86\xe2\x22\xcd\x81\xa4\xa1\xde\x91\x66\xa4\xf2\x79\xe5\xc7\x5a\x4f\xfe\x8e\x8c\x1a\xb2\x01\xc5\xd8\x78\xa6\xd8\x67\x32\x16\x16\x25\x3d\x49\xd8\x8b\x1c\x10\x0e\x65\xd2\x85\x8f\xd4\x9a\x7c\xa0\x94\xbb\x5e\xbe\x45\xa2\x0e\x89\x46\x9a\x4d\x50\x7b\x0e\x49\x46\x02\xa3\xbc\x3b\xf3\x04\xbf\x91\x19\x3d\xf1\x51\xbe\xa3\xb8\x8a\x17\xcd\x5c\x87\x44\xa3\xd0\x8a\x44\xe0\x76\x20\x32\x31\x1b\xeb\x77\x40\x96\xd8\x0d\x35\x4b\x44\x57\x0d\xfa\x95\x51\x84\xbe\x69\x9c\xb2\x3e\xc0\x53\x4c\xb4\xb2\x50\x47\x88\x02\x3c\x12\xfd\x24\x8b\x7b\x37\x24\x1c\x40\xf6\x49\x7e\x4c\xb1\x75\x40\x72\x27\x17\xe3\xc4\x8b\xa2\x08\x3e\xb0\xeb\x7a\xa4\x0d\x3d\xba\x2f\x51\x12\x46\x96\x8f\x28\xe8\x9d\x1e\x62\x5f\x8e\xb0\xf4\xaa\x0e\xb1\xef\x0f\xb0\xef\xf1\x10\x0f\x29\x6e\x0e\x28\x6e\xe2\xa3\x3c\xa4\xfa\x7d\x44\x15\x0b\x53\x8f\xfd\x34\xc2\x72\x91\x1a\x60\x2f\xc6\x65\x03\xcf\xf8\x10\xfb\xdb\x5e\x51\x19\x29\xf7\xcb\x3e\x72\x3f\x08\x2f\x47\x04\xfd\x63\xbf\x4f\xf6\xb7\x11\x19\x3f\xfc\x43\xf4\xf9\xd8\xc3\x1c\x5b\xe7\x55\x95\x48\xe8\xd9\x1f\x97\xb5\x51\x74\x52\x0c\x8e\x2f\x7a\x10\x95\x37\xab\xbd\xfa\x3b\x09\xed\xc6\x0e\x7f\xd9\x1c\xe2\x87\xa5\x8e\x14\x7c\x35\x52\x30\xb4\x0e\xaf\xd1\xe6\x8d\x4a\xc1\x11\x9a\xdb\xae\xda\xc5\x3e\x17\x95\x11\xd1\xcf\x5d\xdd\x0e\x5d\x75\x09\xcb\xfd\xd0\xd4\x04\x49\x96\xba\x62\xcf\xd2\x8b\x4a\x49\xca\x7a\x3f\x0e\x97\x9f\xc6\x0e\xa5\xa6\xf3\x1d\x66\x8a\x21\xc9\xaf\x23\x12\xea\x74\x87\xd8\xab\xbd\x98\xe1\x7e\x35\xb2\x60\xaa\xd3\x53\x71\x55\xcb\xc2\xcd\x9c\xdf\xa2\x5b\x18\xb4\xd7\x7d\xa5\x9d\x2d\xa9\x86\x1d\xab\xc1\xb3\x45\xc2\xec\x15\xfa\x99\xe4\xb2\x77\x58\x1b\x09\x47\x8e\x39\x2c\xb1\x84\xa1\x1b\x3e\x78\x55\x09\xd1\xec\x10\xf1\x4a\xff\x0c\xc3\x48\x98\x1b\x6e\x8c\x73\x7a\x01\xf5\x63\x43\x3e\xe8\x00\x55\xea\xf4\x9b\x34\xf8\x45\x1a\x6a\xfa\xd0\x36\x3b\xee\x7c\x42\x0f\xa2\xd0\x46\x70\x9f\xa1\x18\xcb\xcd\x5a\x20\x9e\x8f\x9b\x84\x76\x5f\x5e\x98\x26\xb7\xbb\xae\x73\x4e\x03\x48\xfe\x05\xb7\x91\x9f\xf1\xf8\xe1\xc2\xa8\x34\x27\xb0\x43\xe9\x01\x98\x2a\x90\x4b\x2d\xa1\xa5\x1e\xae\x6f\xfd\x40\x64\x55\x5b\xa1\x0a\x8a\x89\x43\x64\x14\xeb\x89\x98\x6c\x64\xd5\xa9\x89\x58\x56\x72\xe5\x70\xfc\x6e\x8d\xde\xeb\x41\xa3\x19\x4c\xa4\x79\x20\xcd\x43\x9b\x98\x33\x7d\x3e\x17\xe4\x46\x6a\xfe\xf2\x70\x92\xad\x30\x2d\xf5\x69\xb2\x9a\x13\xf2\x9c\x9a\x2c\x30\x6b\x0d\x86\xde\x29\x69\x04\x0a\x7c\x9b\x06\x63\xa4\x41\x5f\x4d\x07\xcf\x44\x5e\xe4\x53\x6a\x2a\xd1\xf9\xa9\x46\xc2\x7c\x07\xd0\x5a\x15\xf7\x39\x0f\xba\x2c\x27\xa0\xa5\xbb\x77\x98\x12\xc9\x21\xdf\x97\x68\x8a\xef\x15\x35\x77\xad\xb2\x4b\x63\x6b\xb6\x38\xaa\xcc\x9d\xab\xa2\x5e\xd2\xeb\x5a\x71\x44\xbe\x37\x5e\x05\x77\xf6\xe6\xd4\x9d\xf3\xd4\xad\x4a\x01\x93\x34\xfa\x72\xb5\x52\x8f\x73\x21\xde\x2c\x59\xbb\xd8\x37\x4b\xbb\xea\x88\x1f\x07\x6e\x69\xa0\x5d\x63\x7c\x98\xad\x65\x83\x31\x9a\xde\x14\x47\xed\xa3\xf6\xa1\xc5\xa4\x1e\xd8\xd4\x3a\x74\x98\x5f\x3a\xc8\x75\xc1\xf5\x4e\xf9\xe8\x20\x11\x7c\x78\x86\x96\xda\x87\xab\x8a\x70\x98\xc3\xa8\xb9\xb8\x41\xe6\xa2\x0f\x77\x2a\x84\x06\xcd\x67\xf8\xe0\x36\x18\xd1\x64\x49\x19\x09\x17\xc0\x02\xe8\x19\x4e\xbb\x3e\x52\xc0\x36\xde\x36\xa6\x4a\xb7\x9e\xc5\x78\x82\x40\x00\x82\xc0\x95\xde\xa8\x66\x3c\x6f\xa6\x1e\x78\x81\xa7\x72\xc5\xd3\xf5\x9c\x2f\x98\x64\x45\x92\xef\x71\x7b\x9d\xa7\xf6\x99\x23\x04\xce\x2b\xb5\x83\xcb\xb7\x8a\x4f\x93\xdb\x78\x62\x7a\x58\x2b\x72\x08\xda\xe7\x46\x43\x86\x4b\x1b\x86\x38\x90\x5f\x07\x7d\xd3\xaa\xc0\x21\x7f\x40\xb3\x1b\x40\x28\xd4\x29\xa3\x68\x5e\xe8\xac\x64\xa3\xd9\xc3\x6e\x0f\x58\x6a\x0b\x9f\x18\xbb\xed\xd7\x0e\x38\x19\x0c\xcc\xbf\xfb\xed\xf2\xd5\xe7\x8b\xeb\xf7\x2f\xdf\xbc\xfa\xfc\xfa\xfa\xdd\xd5\x69\x5c\x5c\xc8\x98\x1c\x4f\x30\x12\xe7\x8e\x42\x2a\x23\x1a\x70\xc0\x05\xab\x62\x4a\x51\x77\xc0\x30\xa7\x60\xa6\x60\x80\xbb\xa7\x07\x13\x0e\x63\x3b\x5a\x0f\x41\x60\xb6\x93\x38\xd2\x79\x94\xfe\xe9\x16\x47\x49\x0f\xde\x67\x7c\x95\x85\xa9\x8c\x75\x48\x8c\x9a\x02\xa7\x32\xb2\x4c\x76\xf4\xf0\xe0\x48\xbe\x09\xba\xb3\xef\x9e\x07\x89\x97\xda\xbe\x38\x1d\x90\xb9\xd3\x3c\x88\xca\xe7\x61\xcf\x92\x9d\xa4\x35\x08\x07\x1f\x52\x32\x7e\xe7\xd9\xc9\x2e\x6f\x86\xeb\x92\x21\x37\xf1\x3c\x42\xa7\xc2\x99\x4a\x5a\xfd\x55\x95\x3c\xac\xee\x3e\x67\xbe\x78\x91\x9d\x90\x9d\xe4\xae\xca\x50\x0f\xc0\x6a\xf6\x0a\x4e\x11\x4b\x85\x8c\x73\xf5\x96\x5d\xa2\x30\x74\x97\xa5\xea\xc3\x32\xac\xa6\xf0\x8c\x48\xbb\x85\xca\x77\x7b\xb6\x93\xb3\x16\x2a\x0e\xa9\x38\xc5\x0b\x26\x0a\x29\x5e\xa3\xe9\x2a\x24\x29\x4f\x7d\x27\xfb\xc3\xe8\xc8\x39\xc3\x58\x08\x31\x85\xe0\xc7\x69\x94\xee\x64\x7e\x5c\x0d\x59\xa5\xb2\x93\xe1\x59\xdc\xd4\xc9\x0f\x89\xea\x2c\x54\x3f\xed\x9e\xf2\xdc\x9c\x88\x7b\x1f\x8d\xc9\x7b\xf0\xc8\xc6\xe7\x1c\x4f\xd1\x0c\x57\x40\x7e\xe3\xd6\xc6\xbf\x40\x31\x3e\x11\x82\xde\x26\x7c\xd2\x80\xcb\xe5\xe9\x08\x1f\xd1\x4a\x34\x0c\xb8\x51\xf0\x40\x84\xd9\x7e\x87\x98\x56\x94\xda\x8f\xb5\xc2\xcd\xfd\x37\x8a\x2d\x69\xf3\x60\xbb\x78\x23\x53\xf1\x07\x95\x56\xd2\xa9\x96\x28\xd2\xae\xb3\x6a\x4f\x5c\xbf\x18\xdc\x9d\xc2\xed\x81\x8d\x8a\x4b\x03\x1d\x16\x18\x7d\xe4\x11\xb3\x77\x6f\x2e\x6e\xaf\x3f\xdf\xdd\x7e\xbc\xba\xb8\x7e\x7b\x7d\x8b\xe7\x62\xa3\xad\x69\xb8\xda\x6f\xa0\x15\x3d\x1e\xa4\x27\x15\x5a\xd8\xf3\xff\x89\x23\xef\x43\x88\x69\x7c\x2b\x39\x9f\xbc\x5c\x38\xd8\x31\x2c\xc2\x00\x09\x82\xd1\xe1\x94\x22\x47\x92\xe3\xaf\x39\x33\x40\x3f\x03\xc1\xc5\x5a\xda\x21\x8f\x00\x0d\x45\x85\x70\x12\xc1\x68\x8f\x30\x11\x91\xc9\xaa\x81\x86\x05\x4a\x3d\x98\xa4\x97\x8c\x3e\x67\x1a\xd3\x48\xe3\x78\x55\x2c\xc2\x8b\xa5\xdc\x11\x3e\x66\xb9\x0c\x9c\xdc\x16\x62\x1f\xc1\xc5\x77\x16\x45\x24\x7c\xa2\x22\xd3\xea\x16\x44\xc7\x8e\x36\x79\xef\x09\x6f\xc2\x43\x86\xf3\x14\x06\xfd\xab\x86\x4e\x5c\x86\x15\x12\x88\xbe\x25\x5e\x76\xde\x04\xdb\xc1\x82\xcb\x7f\xbf\xf2\x95\x78\xbd\x1e\xc2\xbb\x90\x16\x67\x4e\xd6\x63\x57\xc5\xa2\x4c\x65\x2b\x2d\x1d\xc3\x4e\xee\x69\xb5\x2d\x35\xcf\x10\x16\x5f\xa0\xbd\x55\xdd\x93\xc7\x1c\x77\xc3\x44\x3c\x38\x1b\xb7\x66\x3e\x4a\x15\x31\xe8\x16\xc6\x7b\x54\x91\xf8\x28\x85\x84\xfb\x16\x6b\x64\x5d\x58\xc3\xd1\x4b\x8b\xbc\x20\x5d\xc8\x19\x76\xb4\xa2\x7b\x80\xb1\x15\x66\x1c\x6e\x4e\xfa\xf2\xc4\x60\xda\xa8\xd3\x8b\xd1\x94\xec\x89\x8e\x17\xf4\xa1\x71\x62\x9f\xd2\xab\xc0\x5b\xf7\xfe\x94\x5c\x49\xdd\x84\x9e\xfb\xe9\xd0\x80\x5e\xb4\x17\x4b\x37\xc3\xf9\x1c\x3b\x0e\xee\xc7\xa6\x61\x6d\x46\xa9\x03\xd2\x52\x28\xea\x0d\xe4\x12\x91\x1b\xde\xa1\xca\xd0\xca\x3c\x6c\x9b\x21\xc8\x99\xd8\x85\x25\x0c\x2d\x35\x55\xf8\x6b\x00\x13\x4d\xfb\xe7\xeb\x5e\xa9\x96\x99\x23\x10\xfe\x93\x96\xc8\xcd\xaa\xaa\xd1\x6f\xe9\x06\x9a\xca\x1a\x1d\x88\x4f\xbb\xd9\xd0\xdb\x3c\x70\x71\x4b\x8d\x1f\xf5\x46\x72\x61\x36\x41\x81\x85\x42\x87\x3d\x70\xf3\x91\x7b\xfa\xcb\x50\x10\xde\x75\x55\x1e\x91\x43\x8c\x99\x80\x8b\x1a\x75\x34\xf1\x93\x9c\xe2\x8f\x70\xfd\x11\x5c\x67\xb3\x59\x96\x5d\x46\x44\x5b\x75\x2b\x6a\x86\xc2\x73\x1e\x5e\x6f\xf0\xf6\x1c\xad\xf4\x03\xb7\xdf\xac\x3a\xcc\x91\xe4\x7b\x76\xb9\x78\x1e\x0b\x22\x9c\xbf\x43\xd2\x2b\x78\x31\x15\x97\x53\xf1\xca\x4c\xc5\xcf\x72\x23\x79\x76\xa1\x1f\xd0\x49\xb7\x78\x71\xdf\x76\x12\xd5\xff\xc6\x9a\x8d\x2e\x77\xe3\x45\x12\x17\x55\x99\x7f\x23\x66\x57\x46\xd7\x5c\x89\xa1\x1b\xfd\x0d\xa2\xff\x4e\xaa\x1d\xe1\xbe\x32\xdf\xe4\x9c\x2e\x74\x65\x96\xb5\xef\xd9\xe2\xf7\xff\xce\x92\x94\x3d\x47\xb7\x1d\x83\x96\x62\x81\x8a\x7c\x7c\x09\xe3\x04\x96\x5a\xd2\x10\xc3\x71\x9f\xce\x49\x92\xed\x3f\xf8\x38\xec\xfb\x2d\x2f\xe2\x79\x4a\xac\x14\xa6\xa4\x22\x34\xf1\xfb\xcd\x67\x48\xd0\xc8\x3f\xe3\xca\x46\x2d\x86\xe1\xfc\x98\xd3\xc4\x30\x9e\x49\x3c\x3d\x7b\x47\xf8\x70\xe3\x40\xda\xf3\x5a\xdb\x50\x66\x67\x18\x93\xd7\xbc\xdf\x8f\x7f\x60\x2b\x4c\x1b\x0b\xd2\x48\xc9\x68\x0f\x9f\x11\xf1\xcc\x3c\xfb\x77\x00\x00\x00\xff\xff\xdd\x03\x83\x1f\xa8\x1c\x00\x00") func runtimeHelpHelpMdBytes() ([]byte, error) { return bindataRead( @@ -255,7 +255,7 @@ func runtimeHelpHelpMd() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "runtime/help/help.md", size: 7170, mode: os.FileMode(420), modTime: time.Unix(1464470931, 0)} + info := bindataFileInfo{name: "runtime/help/help.md", size: 7336, mode: os.FileMode(420), modTime: time.Unix(1464534110, 0)} a := &asset{bytes: bytes, info: info} return a, nil } diff --git a/cmd/micro/settings.go b/cmd/micro/settings.go index cb961661..ade6f276 100644 --- a/cmd/micro/settings.go +++ b/cmd/micro/settings.go @@ -78,6 +78,7 @@ func DefaultSettings() map[string]interface{} { "indentchar": " ", "ruler": true, "savecursor": false, + "saveundo": false, "scrollspeed": float64(2), "scrollmargin": float64(3), "statusline": true, diff --git a/cmd/micro/stack.go b/cmd/micro/stack.go index c7c8fd78..070bd769 100644 --- a/cmd/micro/stack.go +++ b/cmd/micro/stack.go @@ -1,43 +1,43 @@ package main -// Stack is a simple implementation of a LIFO stack +// Stack is a simple implementation of a LIFO stack for text events type Stack struct { - top *Element - size int + Top *Element + Size int } // An Element which is stored in the Stack type Element struct { - value interface{} // All types satisfy the empty interface, so we can store anything here. - next *Element + Value *TextEvent + Next *Element } // Len returns the stack's length func (s *Stack) Len() int { - return s.size + return s.Size } // Push a new element onto the stack -func (s *Stack) Push(value interface{}) { - s.top = &Element{value, s.top} - s.size++ +func (s *Stack) Push(value *TextEvent) { + s.Top = &Element{value, s.Top} + s.Size++ } // Pop removes the top element from the stack and returns its value // If the stack is empty, return nil -func (s *Stack) Pop() (value interface{}) { - if s.size > 0 { - value, s.top = s.top.value, s.top.next - s.size-- +func (s *Stack) Pop() (value *TextEvent) { + if s.Size > 0 { + value, s.Top = s.Top.Value, s.Top.Next + s.Size-- return } return nil } // Peek returns the top element of the stack without removing it -func (s *Stack) Peek() interface{} { - if s.size > 0 { - return s.top.value +func (s *Stack) Peek() *TextEvent { + if s.Size > 0 { + return s.Top.Value } return nil } diff --git a/cmd/micro/stack_test.go b/cmd/micro/stack_test.go deleted file mode 100644 index a3526946..00000000 --- a/cmd/micro/stack_test.go +++ /dev/null @@ -1,39 +0,0 @@ -package main - -import "testing" - -func TestStack(t *testing.T) { - stack := new(Stack) - - if stack.Len() != 0 { - t.Errorf("Len failed") - } - stack.Push(5) - stack.Push("test") - stack.Push(10) - if stack.Len() != 3 { - t.Errorf("Len failed") - } - - var popped interface{} - popped = stack.Pop() - if popped != 10 { - t.Errorf("Pop failed") - } - - popped = stack.Pop() - if popped != "test" { - t.Errorf("Pop failed") - } - - stack.Push("test") - popped = stack.Pop() - if popped != "test" { - t.Errorf("Pop failed") - } - stack.Pop() - popped = stack.Pop() - if popped != nil { - t.Errorf("Pop failed") - } -} diff --git a/runtime/help/help.md b/runtime/help/help.md index f8fa1104..69431260 100644 --- a/runtime/help/help.md +++ b/runtime/help/help.md @@ -219,6 +219,11 @@ Here are the options that you can set: default value: `off` +* `saveundo`: when this option is on, undo is saved even after you close a file + so if you close and reopen a file, you can keep undoing + + default value: `off` + * `scrollmargin`: amount of lines you would like to see above and below the cursor default value: `3` diff --git a/todolist.md b/todolist.md index 888ea70a..98973f15 100644 --- a/todolist.md +++ b/todolist.md @@ -10,12 +10,12 @@ - [ ] Horizontal splits - [ ] Vertical splits -- [ ] Persistent undo/redo (saved between open and closing micro) - - [ ] Wrap lines ### Done +- [x] Persistent undo/redo (saved between open and closing micro) + - [x] Auto indent - [x] Custom bindings