]> git.lizzy.rs Git - micro.git/commitdiff
Add support for user-created commands
authorZachary Yedidia <zyedidia@gmail.com>
Mon, 30 May 2016 17:38:50 +0000 (13:38 -0400)
committerZachary Yedidia <zyedidia@gmail.com>
Mon, 30 May 2016 17:38:50 +0000 (13:38 -0400)
Plugins can now create their own commands using the `MakeCommand`
function. Plugins can also now create their own keybindings with the
`BindKey` function. See the go plugin for an example of `MakeCommand`.

cmd/micro/bindings.go
cmd/micro/command.go
cmd/micro/micro.go
cmd/micro/plugin.go
cmd/micro/runtime.go
cmd/micro/view.go
runtime/help/help.md
runtime/plugins/go/go.lua

index cfb8390fb1a54d252fae6ab1a3e7f62dee5afc58..c450ce196aef88fed248b84b3c629e5f77f629a8 100644 (file)
@@ -16,6 +16,209 @@ import (
 var bindings map[Key]func(*View) bool
 var helpBinding string
 
+var bindingActions = map[string]func(*View) bool{
+       "CursorUp":            (*View).CursorUp,
+       "CursorDown":          (*View).CursorDown,
+       "CursorLeft":          (*View).CursorLeft,
+       "CursorRight":         (*View).CursorRight,
+       "CursorStart":         (*View).CursorStart,
+       "CursorEnd":           (*View).CursorEnd,
+       "SelectToStart":       (*View).SelectToStart,
+       "SelectToEnd":         (*View).SelectToEnd,
+       "SelectUp":            (*View).SelectUp,
+       "SelectDown":          (*View).SelectDown,
+       "SelectLeft":          (*View).SelectLeft,
+       "SelectRight":         (*View).SelectRight,
+       "WordRight":           (*View).WordRight,
+       "WordLeft":            (*View).WordLeft,
+       "SelectWordRight":     (*View).SelectWordRight,
+       "SelectWordLeft":      (*View).SelectWordLeft,
+       "DeleteWordRight":     (*View).DeleteWordRight,
+       "DeleteWordLeft":      (*View).DeleteWordLeft,
+       "SelectToStartOfLine": (*View).SelectToStartOfLine,
+       "SelectToEndOfLine":   (*View).SelectToEndOfLine,
+       "InsertEnter":         (*View).InsertEnter,
+       "InsertSpace":         (*View).InsertSpace,
+       "Backspace":           (*View).Backspace,
+       "Delete":              (*View).Delete,
+       "InsertTab":           (*View).InsertTab,
+       "Save":                (*View).Save,
+       "Find":                (*View).Find,
+       "FindNext":            (*View).FindNext,
+       "FindPrevious":        (*View).FindPrevious,
+       "Undo":                (*View).Undo,
+       "Redo":                (*View).Redo,
+       "Copy":                (*View).Copy,
+       "Cut":                 (*View).Cut,
+       "CutLine":             (*View).CutLine,
+       "DuplicateLine":       (*View).DuplicateLine,
+       "Paste":               (*View).Paste,
+       "SelectAll":           (*View).SelectAll,
+       "OpenFile":            (*View).OpenFile,
+       "Start":               (*View).Start,
+       "End":                 (*View).End,
+       "PageUp":              (*View).PageUp,
+       "PageDown":            (*View).PageDown,
+       "HalfPageUp":          (*View).HalfPageUp,
+       "HalfPageDown":        (*View).HalfPageDown,
+       "StartOfLine":         (*View).StartOfLine,
+       "EndOfLine":           (*View).EndOfLine,
+       "ToggleHelp":          (*View).ToggleHelp,
+       "ToggleRuler":         (*View).ToggleRuler,
+       "JumpLine":            (*View).JumpLine,
+       "ClearStatus":         (*View).ClearStatus,
+       "ShellMode":           (*View).ShellMode,
+       "CommandMode":         (*View).CommandMode,
+       "Quit":                (*View).Quit,
+}
+
+var bindingKeys = map[string]Key{
+       "Up":             Key{tcell.KeyUp, tcell.ModNone, 0},
+       "Down":           Key{tcell.KeyDown, tcell.ModNone, 0},
+       "Right":          Key{tcell.KeyRight, tcell.ModNone, 0},
+       "Left":           Key{tcell.KeyLeft, tcell.ModNone, 0},
+       "AltUp":          Key{tcell.KeyUp, tcell.ModAlt, 0},
+       "AltDown":        Key{tcell.KeyDown, tcell.ModAlt, 0},
+       "AltLeft":        Key{tcell.KeyLeft, tcell.ModAlt, 0},
+       "AltRight":       Key{tcell.KeyRight, tcell.ModAlt, 0},
+       "CtrlUp":         Key{tcell.KeyUp, tcell.ModCtrl, 0},
+       "CtrlDown":       Key{tcell.KeyDown, tcell.ModCtrl, 0},
+       "CtrlLeft":       Key{tcell.KeyLeft, tcell.ModCtrl, 0},
+       "CtrlRight":      Key{tcell.KeyRight, tcell.ModCtrl, 0},
+       "ShiftUp":        Key{tcell.KeyUp, tcell.ModShift, 0},
+       "ShiftDown":      Key{tcell.KeyDown, tcell.ModShift, 0},
+       "ShiftLeft":      Key{tcell.KeyLeft, tcell.ModShift, 0},
+       "ShiftRight":     Key{tcell.KeyRight, tcell.ModShift, 0},
+       "AltShiftUp":     Key{tcell.KeyUp, tcell.ModShift | tcell.ModAlt, 0},
+       "AltShiftDown":   Key{tcell.KeyDown, tcell.ModShift | tcell.ModAlt, 0},
+       "AltShiftLeft":   Key{tcell.KeyLeft, tcell.ModShift | tcell.ModAlt, 0},
+       "AltShiftRight":  Key{tcell.KeyRight, tcell.ModShift | tcell.ModAlt, 0},
+       "CtrlShiftUp":    Key{tcell.KeyUp, tcell.ModShift | tcell.ModCtrl, 0},
+       "CtrlShiftDown":  Key{tcell.KeyDown, tcell.ModShift | tcell.ModCtrl, 0},
+       "CtrlShiftLeft":  Key{tcell.KeyLeft, tcell.ModShift | tcell.ModCtrl, 0},
+       "CtrlShiftRight": Key{tcell.KeyRight, tcell.ModShift | tcell.ModCtrl, 0},
+       "UpLeft":         Key{tcell.KeyUpLeft, tcell.ModNone, 0},
+       "UpRight":        Key{tcell.KeyUpRight, tcell.ModNone, 0},
+       "DownLeft":       Key{tcell.KeyDownLeft, tcell.ModNone, 0},
+       "DownRight":      Key{tcell.KeyDownRight, tcell.ModNone, 0},
+       "Center":         Key{tcell.KeyCenter, tcell.ModNone, 0},
+       "PgUp":           Key{tcell.KeyPgUp, tcell.ModNone, 0},
+       "PgDn":           Key{tcell.KeyPgDn, tcell.ModNone, 0},
+       "Home":           Key{tcell.KeyHome, tcell.ModNone, 0},
+       "End":            Key{tcell.KeyEnd, tcell.ModNone, 0},
+       "Insert":         Key{tcell.KeyInsert, tcell.ModNone, 0},
+       "Delete":         Key{tcell.KeyDelete, tcell.ModNone, 0},
+       "Help":           Key{tcell.KeyHelp, tcell.ModNone, 0},
+       "Exit":           Key{tcell.KeyExit, tcell.ModNone, 0},
+       "Clear":          Key{tcell.KeyClear, tcell.ModNone, 0},
+       "Cancel":         Key{tcell.KeyCancel, tcell.ModNone, 0},
+       "Print":          Key{tcell.KeyPrint, tcell.ModNone, 0},
+       "Pause":          Key{tcell.KeyPause, tcell.ModNone, 0},
+       "Backtab":        Key{tcell.KeyBacktab, tcell.ModNone, 0},
+       "F1":             Key{tcell.KeyF1, tcell.ModNone, 0},
+       "F2":             Key{tcell.KeyF2, tcell.ModNone, 0},
+       "F3":             Key{tcell.KeyF3, tcell.ModNone, 0},
+       "F4":             Key{tcell.KeyF4, tcell.ModNone, 0},
+       "F5":             Key{tcell.KeyF5, tcell.ModNone, 0},
+       "F6":             Key{tcell.KeyF6, tcell.ModNone, 0},
+       "F7":             Key{tcell.KeyF7, tcell.ModNone, 0},
+       "F8":             Key{tcell.KeyF8, tcell.ModNone, 0},
+       "F9":             Key{tcell.KeyF9, tcell.ModNone, 0},
+       "F10":            Key{tcell.KeyF10, tcell.ModNone, 0},
+       "F11":            Key{tcell.KeyF11, tcell.ModNone, 0},
+       "F12":            Key{tcell.KeyF12, tcell.ModNone, 0},
+       "F13":            Key{tcell.KeyF13, tcell.ModNone, 0},
+       "F14":            Key{tcell.KeyF14, tcell.ModNone, 0},
+       "F15":            Key{tcell.KeyF15, tcell.ModNone, 0},
+       "F16":            Key{tcell.KeyF16, tcell.ModNone, 0},
+       "F17":            Key{tcell.KeyF17, tcell.ModNone, 0},
+       "F18":            Key{tcell.KeyF18, tcell.ModNone, 0},
+       "F19":            Key{tcell.KeyF19, tcell.ModNone, 0},
+       "F20":            Key{tcell.KeyF20, tcell.ModNone, 0},
+       "F21":            Key{tcell.KeyF21, tcell.ModNone, 0},
+       "F22":            Key{tcell.KeyF22, tcell.ModNone, 0},
+       "F23":            Key{tcell.KeyF23, tcell.ModNone, 0},
+       "F24":            Key{tcell.KeyF24, tcell.ModNone, 0},
+       "F25":            Key{tcell.KeyF25, tcell.ModNone, 0},
+       "F26":            Key{tcell.KeyF26, tcell.ModNone, 0},
+       "F27":            Key{tcell.KeyF27, tcell.ModNone, 0},
+       "F28":            Key{tcell.KeyF28, tcell.ModNone, 0},
+       "F29":            Key{tcell.KeyF29, tcell.ModNone, 0},
+       "F30":            Key{tcell.KeyF30, tcell.ModNone, 0},
+       "F31":            Key{tcell.KeyF31, tcell.ModNone, 0},
+       "F32":            Key{tcell.KeyF32, tcell.ModNone, 0},
+       "F33":            Key{tcell.KeyF33, tcell.ModNone, 0},
+       "F34":            Key{tcell.KeyF34, tcell.ModNone, 0},
+       "F35":            Key{tcell.KeyF35, tcell.ModNone, 0},
+       "F36":            Key{tcell.KeyF36, tcell.ModNone, 0},
+       "F37":            Key{tcell.KeyF37, tcell.ModNone, 0},
+       "F38":            Key{tcell.KeyF38, tcell.ModNone, 0},
+       "F39":            Key{tcell.KeyF39, tcell.ModNone, 0},
+       "F40":            Key{tcell.KeyF40, tcell.ModNone, 0},
+       "F41":            Key{tcell.KeyF41, tcell.ModNone, 0},
+       "F42":            Key{tcell.KeyF42, tcell.ModNone, 0},
+       "F43":            Key{tcell.KeyF43, tcell.ModNone, 0},
+       "F44":            Key{tcell.KeyF44, tcell.ModNone, 0},
+       "F45":            Key{tcell.KeyF45, tcell.ModNone, 0},
+       "F46":            Key{tcell.KeyF46, tcell.ModNone, 0},
+       "F47":            Key{tcell.KeyF47, tcell.ModNone, 0},
+       "F48":            Key{tcell.KeyF48, tcell.ModNone, 0},
+       "F49":            Key{tcell.KeyF49, tcell.ModNone, 0},
+       "F50":            Key{tcell.KeyF50, tcell.ModNone, 0},
+       "F51":            Key{tcell.KeyF51, tcell.ModNone, 0},
+       "F52":            Key{tcell.KeyF52, tcell.ModNone, 0},
+       "F53":            Key{tcell.KeyF53, tcell.ModNone, 0},
+       "F54":            Key{tcell.KeyF54, tcell.ModNone, 0},
+       "F55":            Key{tcell.KeyF55, tcell.ModNone, 0},
+       "F56":            Key{tcell.KeyF56, tcell.ModNone, 0},
+       "F57":            Key{tcell.KeyF57, tcell.ModNone, 0},
+       "F58":            Key{tcell.KeyF58, tcell.ModNone, 0},
+       "F59":            Key{tcell.KeyF59, tcell.ModNone, 0},
+       "F60":            Key{tcell.KeyF60, tcell.ModNone, 0},
+       "F61":            Key{tcell.KeyF61, tcell.ModNone, 0},
+       "F62":            Key{tcell.KeyF62, tcell.ModNone, 0},
+       "F63":            Key{tcell.KeyF63, tcell.ModNone, 0},
+       "F64":            Key{tcell.KeyF64, tcell.ModNone, 0},
+       "CtrlSpace":      Key{tcell.KeyCtrlSpace, tcell.ModCtrl, 0},
+       "CtrlA":          Key{tcell.KeyCtrlA, tcell.ModCtrl, 0},
+       "CtrlB":          Key{tcell.KeyCtrlB, tcell.ModCtrl, 0},
+       "CtrlC":          Key{tcell.KeyCtrlC, tcell.ModCtrl, 0},
+       "CtrlD":          Key{tcell.KeyCtrlD, tcell.ModCtrl, 0},
+       "CtrlE":          Key{tcell.KeyCtrlE, tcell.ModCtrl, 0},
+       "CtrlF":          Key{tcell.KeyCtrlF, tcell.ModCtrl, 0},
+       "CtrlG":          Key{tcell.KeyCtrlG, tcell.ModCtrl, 0},
+       "CtrlH":          Key{tcell.KeyCtrlH, tcell.ModCtrl, 0},
+       "CtrlI":          Key{tcell.KeyCtrlI, tcell.ModCtrl, 0},
+       "CtrlJ":          Key{tcell.KeyCtrlJ, tcell.ModCtrl, 0},
+       "CtrlK":          Key{tcell.KeyCtrlK, tcell.ModCtrl, 0},
+       "CtrlL":          Key{tcell.KeyCtrlL, tcell.ModCtrl, 0},
+       "CtrlM":          Key{tcell.KeyCtrlM, tcell.ModCtrl, 0},
+       "CtrlN":          Key{tcell.KeyCtrlN, tcell.ModCtrl, 0},
+       "CtrlO":          Key{tcell.KeyCtrlO, tcell.ModCtrl, 0},
+       "CtrlP":          Key{tcell.KeyCtrlP, tcell.ModCtrl, 0},
+       "CtrlQ":          Key{tcell.KeyCtrlQ, tcell.ModCtrl, 0},
+       "CtrlR":          Key{tcell.KeyCtrlR, tcell.ModCtrl, 0},
+       "CtrlS":          Key{tcell.KeyCtrlS, tcell.ModCtrl, 0},
+       "CtrlT":          Key{tcell.KeyCtrlT, tcell.ModCtrl, 0},
+       "CtrlU":          Key{tcell.KeyCtrlU, tcell.ModCtrl, 0},
+       "CtrlV":          Key{tcell.KeyCtrlV, tcell.ModCtrl, 0},
+       "CtrlW":          Key{tcell.KeyCtrlW, tcell.ModCtrl, 0},
+       "CtrlX":          Key{tcell.KeyCtrlX, tcell.ModCtrl, 0},
+       "CtrlY":          Key{tcell.KeyCtrlY, tcell.ModCtrl, 0},
+       "CtrlZ":          Key{tcell.KeyCtrlZ, tcell.ModCtrl, 0},
+       "CtrlLeftSq":     Key{tcell.KeyCtrlLeftSq, tcell.ModCtrl, 0},
+       "CtrlBackslash":  Key{tcell.KeyCtrlBackslash, tcell.ModCtrl, 0},
+       "CtrlRightSq":    Key{tcell.KeyCtrlRightSq, tcell.ModCtrl, 0},
+       "CtrlCarat":      Key{tcell.KeyCtrlCarat, tcell.ModCtrl, 0},
+       "CtrlUnderscore": Key{tcell.KeyCtrlUnderscore, tcell.ModCtrl, 0},
+       "Backspace":      Key{tcell.KeyBackspace, tcell.ModNone, 0},
+       "Tab":            Key{tcell.KeyTab, tcell.ModNone, 0},
+       "Esc":            Key{tcell.KeyEsc, tcell.ModNone, 0},
+       "Escape":         Key{tcell.KeyEscape, tcell.ModNone, 0},
+       "Enter":          Key{tcell.KeyEnter, tcell.ModNone, 0},
+       "Backspace2":     Key{tcell.KeyBackspace2, tcell.ModNone, 0},
+}
+
 // The Key struct holds the data for a keypress (keycode + modifiers)
 type Key struct {
        keyCode   tcell.Key
@@ -27,209 +230,6 @@ type Key struct {
 func InitBindings() {
        bindings = make(map[Key]func(*View) bool)
 
-       actions := map[string]func(*View) bool{
-               "CursorUp":            (*View).CursorUp,
-               "CursorDown":          (*View).CursorDown,
-               "CursorLeft":          (*View).CursorLeft,
-               "CursorRight":         (*View).CursorRight,
-               "CursorStart":         (*View).CursorStart,
-               "CursorEnd":           (*View).CursorEnd,
-               "SelectToStart":       (*View).SelectToStart,
-               "SelectToEnd":         (*View).SelectToEnd,
-               "SelectUp":            (*View).SelectUp,
-               "SelectDown":          (*View).SelectDown,
-               "SelectLeft":          (*View).SelectLeft,
-               "SelectRight":         (*View).SelectRight,
-               "WordRight":           (*View).WordRight,
-               "WordLeft":            (*View).WordLeft,
-               "SelectWordRight":     (*View).SelectWordRight,
-               "SelectWordLeft":      (*View).SelectWordLeft,
-               "DeleteWordRight":     (*View).DeleteWordRight,
-               "DeleteWordLeft":      (*View).DeleteWordLeft,
-               "SelectToStartOfLine": (*View).SelectToStartOfLine,
-               "SelectToEndOfLine":   (*View).SelectToEndOfLine,
-               "InsertEnter":         (*View).InsertEnter,
-               "InsertSpace":         (*View).InsertSpace,
-               "Backspace":           (*View).Backspace,
-               "Delete":              (*View).Delete,
-               "InsertTab":           (*View).InsertTab,
-               "Save":                (*View).Save,
-               "Find":                (*View).Find,
-               "FindNext":            (*View).FindNext,
-               "FindPrevious":        (*View).FindPrevious,
-               "Undo":                (*View).Undo,
-               "Redo":                (*View).Redo,
-               "Copy":                (*View).Copy,
-               "Cut":                 (*View).Cut,
-               "CutLine":             (*View).CutLine,
-               "DuplicateLine":       (*View).DuplicateLine,
-               "Paste":               (*View).Paste,
-               "SelectAll":           (*View).SelectAll,
-               "OpenFile":            (*View).OpenFile,
-               "Start":               (*View).Start,
-               "End":                 (*View).End,
-               "PageUp":              (*View).PageUp,
-               "PageDown":            (*View).PageDown,
-               "HalfPageUp":          (*View).HalfPageUp,
-               "HalfPageDown":        (*View).HalfPageDown,
-               "StartOfLine":         (*View).StartOfLine,
-               "EndOfLine":           (*View).EndOfLine,
-               "ToggleHelp":          (*View).ToggleHelp,
-               "ToggleRuler":         (*View).ToggleRuler,
-               "JumpLine":            (*View).JumpLine,
-               "ClearStatus":         (*View).ClearStatus,
-               "ShellMode":           (*View).ShellMode,
-               "CommandMode":         (*View).CommandMode,
-               "Quit":                (*View).Quit,
-       }
-
-       keys := map[string]Key{
-               "Up":             Key{tcell.KeyUp, tcell.ModNone, 0},
-               "Down":           Key{tcell.KeyDown, tcell.ModNone, 0},
-               "Right":          Key{tcell.KeyRight, tcell.ModNone, 0},
-               "Left":           Key{tcell.KeyLeft, tcell.ModNone, 0},
-               "AltUp":          Key{tcell.KeyUp, tcell.ModAlt, 0},
-               "AltDown":        Key{tcell.KeyDown, tcell.ModAlt, 0},
-               "AltLeft":        Key{tcell.KeyLeft, tcell.ModAlt, 0},
-               "AltRight":       Key{tcell.KeyRight, tcell.ModAlt, 0},
-               "CtrlUp":         Key{tcell.KeyUp, tcell.ModCtrl, 0},
-               "CtrlDown":       Key{tcell.KeyDown, tcell.ModCtrl, 0},
-               "CtrlLeft":       Key{tcell.KeyLeft, tcell.ModCtrl, 0},
-               "CtrlRight":      Key{tcell.KeyRight, tcell.ModCtrl, 0},
-               "ShiftUp":        Key{tcell.KeyUp, tcell.ModShift, 0},
-               "ShiftDown":      Key{tcell.KeyDown, tcell.ModShift, 0},
-               "ShiftLeft":      Key{tcell.KeyLeft, tcell.ModShift, 0},
-               "ShiftRight":     Key{tcell.KeyRight, tcell.ModShift, 0},
-               "AltShiftUp":     Key{tcell.KeyUp, tcell.ModShift | tcell.ModAlt, 0},
-               "AltShiftDown":   Key{tcell.KeyDown, tcell.ModShift | tcell.ModAlt, 0},
-               "AltShiftLeft":   Key{tcell.KeyLeft, tcell.ModShift | tcell.ModAlt, 0},
-               "AltShiftRight":  Key{tcell.KeyRight, tcell.ModShift | tcell.ModAlt, 0},
-               "CtrlShiftUp":    Key{tcell.KeyUp, tcell.ModShift | tcell.ModCtrl, 0},
-               "CtrlShiftDown":  Key{tcell.KeyDown, tcell.ModShift | tcell.ModCtrl, 0},
-               "CtrlShiftLeft":  Key{tcell.KeyLeft, tcell.ModShift | tcell.ModCtrl, 0},
-               "CtrlShiftRight": Key{tcell.KeyRight, tcell.ModShift | tcell.ModCtrl, 0},
-               "UpLeft":         Key{tcell.KeyUpLeft, tcell.ModNone, 0},
-               "UpRight":        Key{tcell.KeyUpRight, tcell.ModNone, 0},
-               "DownLeft":       Key{tcell.KeyDownLeft, tcell.ModNone, 0},
-               "DownRight":      Key{tcell.KeyDownRight, tcell.ModNone, 0},
-               "Center":         Key{tcell.KeyCenter, tcell.ModNone, 0},
-               "PgUp":           Key{tcell.KeyPgUp, tcell.ModNone, 0},
-               "PgDn":           Key{tcell.KeyPgDn, tcell.ModNone, 0},
-               "Home":           Key{tcell.KeyHome, tcell.ModNone, 0},
-               "End":            Key{tcell.KeyEnd, tcell.ModNone, 0},
-               "Insert":         Key{tcell.KeyInsert, tcell.ModNone, 0},
-               "Delete":         Key{tcell.KeyDelete, tcell.ModNone, 0},
-               "Help":           Key{tcell.KeyHelp, tcell.ModNone, 0},
-               "Exit":           Key{tcell.KeyExit, tcell.ModNone, 0},
-               "Clear":          Key{tcell.KeyClear, tcell.ModNone, 0},
-               "Cancel":         Key{tcell.KeyCancel, tcell.ModNone, 0},
-               "Print":          Key{tcell.KeyPrint, tcell.ModNone, 0},
-               "Pause":          Key{tcell.KeyPause, tcell.ModNone, 0},
-               "Backtab":        Key{tcell.KeyBacktab, tcell.ModNone, 0},
-               "F1":             Key{tcell.KeyF1, tcell.ModNone, 0},
-               "F2":             Key{tcell.KeyF2, tcell.ModNone, 0},
-               "F3":             Key{tcell.KeyF3, tcell.ModNone, 0},
-               "F4":             Key{tcell.KeyF4, tcell.ModNone, 0},
-               "F5":             Key{tcell.KeyF5, tcell.ModNone, 0},
-               "F6":             Key{tcell.KeyF6, tcell.ModNone, 0},
-               "F7":             Key{tcell.KeyF7, tcell.ModNone, 0},
-               "F8":             Key{tcell.KeyF8, tcell.ModNone, 0},
-               "F9":             Key{tcell.KeyF9, tcell.ModNone, 0},
-               "F10":            Key{tcell.KeyF10, tcell.ModNone, 0},
-               "F11":            Key{tcell.KeyF11, tcell.ModNone, 0},
-               "F12":            Key{tcell.KeyF12, tcell.ModNone, 0},
-               "F13":            Key{tcell.KeyF13, tcell.ModNone, 0},
-               "F14":            Key{tcell.KeyF14, tcell.ModNone, 0},
-               "F15":            Key{tcell.KeyF15, tcell.ModNone, 0},
-               "F16":            Key{tcell.KeyF16, tcell.ModNone, 0},
-               "F17":            Key{tcell.KeyF17, tcell.ModNone, 0},
-               "F18":            Key{tcell.KeyF18, tcell.ModNone, 0},
-               "F19":            Key{tcell.KeyF19, tcell.ModNone, 0},
-               "F20":            Key{tcell.KeyF20, tcell.ModNone, 0},
-               "F21":            Key{tcell.KeyF21, tcell.ModNone, 0},
-               "F22":            Key{tcell.KeyF22, tcell.ModNone, 0},
-               "F23":            Key{tcell.KeyF23, tcell.ModNone, 0},
-               "F24":            Key{tcell.KeyF24, tcell.ModNone, 0},
-               "F25":            Key{tcell.KeyF25, tcell.ModNone, 0},
-               "F26":            Key{tcell.KeyF26, tcell.ModNone, 0},
-               "F27":            Key{tcell.KeyF27, tcell.ModNone, 0},
-               "F28":            Key{tcell.KeyF28, tcell.ModNone, 0},
-               "F29":            Key{tcell.KeyF29, tcell.ModNone, 0},
-               "F30":            Key{tcell.KeyF30, tcell.ModNone, 0},
-               "F31":            Key{tcell.KeyF31, tcell.ModNone, 0},
-               "F32":            Key{tcell.KeyF32, tcell.ModNone, 0},
-               "F33":            Key{tcell.KeyF33, tcell.ModNone, 0},
-               "F34":            Key{tcell.KeyF34, tcell.ModNone, 0},
-               "F35":            Key{tcell.KeyF35, tcell.ModNone, 0},
-               "F36":            Key{tcell.KeyF36, tcell.ModNone, 0},
-               "F37":            Key{tcell.KeyF37, tcell.ModNone, 0},
-               "F38":            Key{tcell.KeyF38, tcell.ModNone, 0},
-               "F39":            Key{tcell.KeyF39, tcell.ModNone, 0},
-               "F40":            Key{tcell.KeyF40, tcell.ModNone, 0},
-               "F41":            Key{tcell.KeyF41, tcell.ModNone, 0},
-               "F42":            Key{tcell.KeyF42, tcell.ModNone, 0},
-               "F43":            Key{tcell.KeyF43, tcell.ModNone, 0},
-               "F44":            Key{tcell.KeyF44, tcell.ModNone, 0},
-               "F45":            Key{tcell.KeyF45, tcell.ModNone, 0},
-               "F46":            Key{tcell.KeyF46, tcell.ModNone, 0},
-               "F47":            Key{tcell.KeyF47, tcell.ModNone, 0},
-               "F48":            Key{tcell.KeyF48, tcell.ModNone, 0},
-               "F49":            Key{tcell.KeyF49, tcell.ModNone, 0},
-               "F50":            Key{tcell.KeyF50, tcell.ModNone, 0},
-               "F51":            Key{tcell.KeyF51, tcell.ModNone, 0},
-               "F52":            Key{tcell.KeyF52, tcell.ModNone, 0},
-               "F53":            Key{tcell.KeyF53, tcell.ModNone, 0},
-               "F54":            Key{tcell.KeyF54, tcell.ModNone, 0},
-               "F55":            Key{tcell.KeyF55, tcell.ModNone, 0},
-               "F56":            Key{tcell.KeyF56, tcell.ModNone, 0},
-               "F57":            Key{tcell.KeyF57, tcell.ModNone, 0},
-               "F58":            Key{tcell.KeyF58, tcell.ModNone, 0},
-               "F59":            Key{tcell.KeyF59, tcell.ModNone, 0},
-               "F60":            Key{tcell.KeyF60, tcell.ModNone, 0},
-               "F61":            Key{tcell.KeyF61, tcell.ModNone, 0},
-               "F62":            Key{tcell.KeyF62, tcell.ModNone, 0},
-               "F63":            Key{tcell.KeyF63, tcell.ModNone, 0},
-               "F64":            Key{tcell.KeyF64, tcell.ModNone, 0},
-               "CtrlSpace":      Key{tcell.KeyCtrlSpace, tcell.ModCtrl, 0},
-               "CtrlA":          Key{tcell.KeyCtrlA, tcell.ModCtrl, 0},
-               "CtrlB":          Key{tcell.KeyCtrlB, tcell.ModCtrl, 0},
-               "CtrlC":          Key{tcell.KeyCtrlC, tcell.ModCtrl, 0},
-               "CtrlD":          Key{tcell.KeyCtrlD, tcell.ModCtrl, 0},
-               "CtrlE":          Key{tcell.KeyCtrlE, tcell.ModCtrl, 0},
-               "CtrlF":          Key{tcell.KeyCtrlF, tcell.ModCtrl, 0},
-               "CtrlG":          Key{tcell.KeyCtrlG, tcell.ModCtrl, 0},
-               "CtrlH":          Key{tcell.KeyCtrlH, tcell.ModCtrl, 0},
-               "CtrlI":          Key{tcell.KeyCtrlI, tcell.ModCtrl, 0},
-               "CtrlJ":          Key{tcell.KeyCtrlJ, tcell.ModCtrl, 0},
-               "CtrlK":          Key{tcell.KeyCtrlK, tcell.ModCtrl, 0},
-               "CtrlL":          Key{tcell.KeyCtrlL, tcell.ModCtrl, 0},
-               "CtrlM":          Key{tcell.KeyCtrlM, tcell.ModCtrl, 0},
-               "CtrlN":          Key{tcell.KeyCtrlN, tcell.ModCtrl, 0},
-               "CtrlO":          Key{tcell.KeyCtrlO, tcell.ModCtrl, 0},
-               "CtrlP":          Key{tcell.KeyCtrlP, tcell.ModCtrl, 0},
-               "CtrlQ":          Key{tcell.KeyCtrlQ, tcell.ModCtrl, 0},
-               "CtrlR":          Key{tcell.KeyCtrlR, tcell.ModCtrl, 0},
-               "CtrlS":          Key{tcell.KeyCtrlS, tcell.ModCtrl, 0},
-               "CtrlT":          Key{tcell.KeyCtrlT, tcell.ModCtrl, 0},
-               "CtrlU":          Key{tcell.KeyCtrlU, tcell.ModCtrl, 0},
-               "CtrlV":          Key{tcell.KeyCtrlV, tcell.ModCtrl, 0},
-               "CtrlW":          Key{tcell.KeyCtrlW, tcell.ModCtrl, 0},
-               "CtrlX":          Key{tcell.KeyCtrlX, tcell.ModCtrl, 0},
-               "CtrlY":          Key{tcell.KeyCtrlY, tcell.ModCtrl, 0},
-               "CtrlZ":          Key{tcell.KeyCtrlZ, tcell.ModCtrl, 0},
-               "CtrlLeftSq":     Key{tcell.KeyCtrlLeftSq, tcell.ModCtrl, 0},
-               "CtrlBackslash":  Key{tcell.KeyCtrlBackslash, tcell.ModCtrl, 0},
-               "CtrlRightSq":    Key{tcell.KeyCtrlRightSq, tcell.ModCtrl, 0},
-               "CtrlCarat":      Key{tcell.KeyCtrlCarat, tcell.ModCtrl, 0},
-               "CtrlUnderscore": Key{tcell.KeyCtrlUnderscore, tcell.ModCtrl, 0},
-               "Backspace":      Key{tcell.KeyBackspace, tcell.ModNone, 0},
-               "Tab":            Key{tcell.KeyTab, tcell.ModNone, 0},
-               "Esc":            Key{tcell.KeyEsc, tcell.ModNone, 0},
-               "Escape":         Key{tcell.KeyEscape, tcell.ModNone, 0},
-               "Enter":          Key{tcell.KeyEnter, tcell.ModNone, 0},
-               "Backspace2":     Key{tcell.KeyBackspace2, tcell.ModNone, 0},
-       }
-
        var parsed map[string]string
        defaults := DefaultBindings()
 
@@ -247,35 +247,40 @@ func InitBindings() {
                }
        }
 
-       parse(defaults, actions, keys)
-       parse(parsed, actions, keys)
+       parseBindings(defaults)
+       parseBindings(parsed)
 }
 
-func parse(userBindings map[string]string, actions map[string]func(*View) bool, keys map[string]Key) {
+func parseBindings(userBindings map[string]string) {
        for k, v := range userBindings {
-               var key Key
-               if strings.Contains(k, "Alt-") {
-                       split := strings.Split(k, "-")
-                       if len(split[1]) > 1 {
-                               key = Key{keys[split[1]].keyCode, keys[k].modifiers | tcell.ModAlt, 0}
-                       } else {
-                               key = Key{tcell.KeyRune, tcell.ModAlt, rune(k[len(k)-1])}
-                       }
+               BindKey(k, v)
+       }
+}
+
+// BindKey takes a key and an action and binds the two together
+func BindKey(k, v string) {
+       var key Key
+       if strings.Contains(k, "Alt-") {
+               split := strings.Split(k, "-")
+               if len(split[1]) > 1 {
+                       key = Key{bindingKeys[split[1]].keyCode, bindingKeys[k].modifiers | tcell.ModAlt, 0}
                } else {
-                       key = keys[k]
+                       key = Key{tcell.KeyRune, tcell.ModAlt, rune(k[len(k)-1])}
                }
+       } else {
+               key = bindingKeys[k]
+       }
 
-               action := actions[v]
-               if _, ok := actions[v]; !ok {
-                       // If the user seems to be binding a function that doesn't exist
-                       // We hope that it's a lua function that exists and bind it to that
-                       action = LuaFunctionBinding(v)
-               }
+       action := bindingActions[v]
+       if _, ok := bindingActions[v]; !ok {
+               // If the user seems to be binding a function that doesn't exist
+               // We hope that it's a lua function that exists and bind it to that
+               action = LuaFunctionBinding(v)
+       }
 
-               bindings[key] = action
-               if v == "ToggleHelp" {
-                       helpBinding = k
-               }
+       bindings[key] = action
+       if v == "ToggleHelp" {
+               helpBinding = k
        }
 }
 
index a6d5cc5e3fedafc6528fc9850bfc1b76b65e17f8..04a9ad79c54f6b3c43cebbcfacf868f8f5e5906f 100644 (file)
@@ -9,6 +9,183 @@ import (
        "strings"
 )
 
+var commands map[string]func([]string)
+
+var commandActions = map[string]func([]string){
+       "Set":     Set,
+       "Run":     Run,
+       "Bind":    Bind,
+       "Quit":    Quit,
+       "Save":    Save,
+       "Replace": Replace,
+}
+
+// InitCommands initializes the default commands
+func InitCommands() {
+       commands = make(map[string]func([]string))
+
+       defaults := DefaultCommands()
+       parseCommands(defaults)
+}
+
+func parseCommands(userCommands map[string]string) {
+       for k, v := range userCommands {
+               MakeCommand(k, v)
+       }
+}
+
+// MakeCommand is a function to easily create new commands
+// This can be called by plugins in Lua so that plugins can define their own commands
+func MakeCommand(name, function string) {
+       action := commandActions[function]
+       if _, ok := commandActions[function]; !ok {
+               // If the user seems to be binding a function that doesn't exist
+               // We hope that it's a lua function that exists and bind it to that
+               action = LuaFunctionCommand(function)
+       }
+
+       commands[name] = action
+}
+
+// DefaultCommands returns a map containing micro's default commands
+func DefaultCommands() map[string]string {
+       return map[string]string{
+               "set":     "Set",
+               "bind":    "Bind",
+               "run":     "Run",
+               "quit":    "Quit",
+               "save":    "Save",
+               "replace": "Replace",
+       }
+}
+
+// Set sets an option
+func Set(args []string) {
+       // Set an option and we have to set it for every view
+       for _, view := range views {
+               SetOption(view, args)
+       }
+}
+
+// Bind creates a new keybinding
+func Bind(args []string) {
+       if len(args) != 2 {
+               messenger.Error("Incorrect number of arguments")
+               return
+       }
+       BindKey(args[0], args[1])
+}
+
+// Run runs a shell command in the background
+func Run(args []string) {
+       // Run a shell command in the background (openTerm is false)
+       HandleShellCommand(strings.Join(args, " "), false)
+}
+
+// Quit closes the main view
+func Quit(args []string) {
+       // Close the main view
+       views[mainView].Quit()
+}
+
+// Save saves the buffer in the main view
+func Save(args []string) {
+       // Save the main view
+       views[mainView].Save()
+}
+
+// Replace runs search and replace
+func Replace(args []string) {
+       // This is a regex to parse the replace expression
+       // We allow no quotes if there are no spaces, but if you want to search
+       // for or replace an expression with spaces, you can add double quotes
+       r := regexp.MustCompile(`"[^"\\]*(?:\\.[^"\\]*)*"|[^\s]*`)
+       replaceCmd := r.FindAllString(strings.Join(args, " "), -1)
+       if len(replaceCmd) < 2 {
+               // We need to find both a search and replace expression
+               messenger.Error("Invalid replace statement: " + strings.Join(args, " "))
+               return
+       }
+
+       var flags string
+       if len(replaceCmd) == 3 {
+               // The user included some flags
+               flags = replaceCmd[2]
+       }
+
+       search := string(replaceCmd[0])
+       replace := string(replaceCmd[1])
+
+       // If the search and replace expressions have quotes, we need to remove those
+       if strings.HasPrefix(search, `"`) && strings.HasSuffix(search, `"`) {
+               search = search[1 : len(search)-1]
+       }
+       if strings.HasPrefix(replace, `"`) && strings.HasSuffix(replace, `"`) {
+               replace = replace[1 : len(replace)-1]
+       }
+
+       // We replace all escaped double quotes to real double quotes
+       search = strings.Replace(search, `\"`, `"`, -1)
+       replace = strings.Replace(replace, `\"`, `"`, -1)
+       // Replace some things so users can actually insert newlines and tabs in replacements
+       replace = strings.Replace(replace, "\\n", "\n", -1)
+       replace = strings.Replace(replace, "\\t", "\t", -1)
+
+       regex, err := regexp.Compile(search)
+       if err != nil {
+               // There was an error with the user's regex
+               messenger.Error(err.Error())
+               return
+       }
+
+       view := views[mainView]
+
+       found := false
+       for {
+               match := regex.FindStringIndex(view.Buf.String())
+               if match == nil {
+                       break
+               }
+               found = true
+               if strings.Contains(flags, "c") {
+                       // The 'check' flag was used
+                       Search(search, view, true)
+                       view.Relocate()
+                       if settings["syntax"].(bool) {
+                               view.matches = Match(view)
+                       }
+                       RedrawAll()
+                       choice, canceled := messenger.YesNoPrompt("Perform replacement? (y,n)")
+                       if canceled {
+                               if view.Cursor.HasSelection() {
+                                       view.Cursor.SetLoc(view.Cursor.CurSelection[0])
+                                       view.Cursor.ResetSelection()
+                               }
+                               messenger.Reset()
+                               return
+                       }
+                       if choice {
+                               view.Cursor.DeleteSelection()
+                               view.Buf.Insert(match[0], replace)
+                               view.Cursor.ResetSelection()
+                               messenger.Reset()
+                       } else {
+                               if view.Cursor.HasSelection() {
+                                       searchStart = view.Cursor.CurSelection[1]
+                               } else {
+                                       searchStart = ToCharPos(view.Cursor.X, view.Cursor.Y, view.Buf)
+                               }
+                               continue
+                       }
+               } else {
+                       view.Buf.Replace(match[0], match[1], replace)
+               }
+       }
+       if !found {
+               messenger.Message("Nothing matched " + search)
+       }
+}
+
 // RunShellCommand executes a shell command and returns the output/error
 func RunShellCommand(input string) (string, error) {
        inputCmd := strings.Split(input, " ")[0]
@@ -88,117 +265,9 @@ func HandleCommand(input string) {
        inputCmd := strings.Split(input, " ")[0]
        args := strings.Split(input, " ")[1:]
 
-       switch inputCmd {
-       case "set":
-               // Set an option and we have to set it for every view
-               for _, view := range views {
-                       SetOption(view, args)
-               }
-       case "run":
-               // Run a shell command in the background (openTerm is false)
-               HandleShellCommand(strings.Join(args, " "), false)
-       case "quit":
-               // This is a bit weird because micro only has one view for now so there is no way to close
-               // a single view
-               // Currently if multiple views were open, it would close all of them, and not check the non-mainviews
-               // for unsaved changes. This, and the behavior of Ctrl-Q need to be changed when splits are implemented
-               if views[mainView].CanClose("Quit anyway? (yes, no, save) ") {
-                       screen.Fini()
-                       os.Exit(0)
-               }
-       case "save":
-               // Save the main view
-               views[mainView].Save()
-       case "replace":
-               // This is a regex to parse the replace expression
-               // We allow no quotes if there are no spaces, but if you want to search
-               // for or replace an expression with spaces, you can add double quotes
-               r := regexp.MustCompile(`"[^"\\]*(?:\\.[^"\\]*)*"|[^\s]*`)
-               replaceCmd := r.FindAllString(strings.Join(args, " "), -1)
-               if len(replaceCmd) < 2 {
-                       // We need to find both a search and replace expression
-                       messenger.Error("Invalid replace statement: " + strings.Join(args, " "))
-                       return
-               }
-
-               var flags string
-               if len(replaceCmd) == 3 {
-                       // The user included some flags
-                       flags = replaceCmd[2]
-               }
-
-               search := string(replaceCmd[0])
-               replace := string(replaceCmd[1])
-
-               // If the search and replace expressions have quotes, we need to remove those
-               if strings.HasPrefix(search, `"`) && strings.HasSuffix(search, `"`) {
-                       search = search[1 : len(search)-1]
-               }
-               if strings.HasPrefix(replace, `"`) && strings.HasSuffix(replace, `"`) {
-                       replace = replace[1 : len(replace)-1]
-               }
-
-               // We replace all escaped double quotes to real double quotes
-               search = strings.Replace(search, `\"`, `"`, -1)
-               replace = strings.Replace(replace, `\"`, `"`, -1)
-               // Replace some things so users can actually insert newlines and tabs in replacements
-               replace = strings.Replace(replace, "\\n", "\n", -1)
-               replace = strings.Replace(replace, "\\t", "\t", -1)
-
-               regex, err := regexp.Compile(search)
-               if err != nil {
-                       // There was an error with the user's regex
-                       messenger.Error(err.Error())
-                       return
-               }
-
-               view := views[mainView]
-
-               found := false
-               for {
-                       match := regex.FindStringIndex(view.Buf.String())
-                       if match == nil {
-                               break
-                       }
-                       found = true
-                       if strings.Contains(flags, "c") {
-                               // The 'check' flag was used
-                               Search(search, view, true)
-                               view.Relocate()
-                               if settings["syntax"].(bool) {
-                                       view.matches = Match(view)
-                               }
-                               RedrawAll()
-                               choice, canceled := messenger.YesNoPrompt("Perform replacement? (y,n)")
-                               if canceled {
-                                       if view.Cursor.HasSelection() {
-                                               view.Cursor.SetLoc(view.Cursor.CurSelection[0])
-                                               view.Cursor.ResetSelection()
-                                       }
-                                       messenger.Reset()
-                                       return
-                               }
-                               if choice {
-                                       view.Cursor.DeleteSelection()
-                                       view.Buf.Insert(match[0], replace)
-                                       view.Cursor.ResetSelection()
-                                       messenger.Reset()
-                               } else {
-                                       if view.Cursor.HasSelection() {
-                                               searchStart = view.Cursor.CurSelection[1]
-                                       } else {
-                                               searchStart = ToCharPos(view.Cursor.X, view.Cursor.Y, view.Buf)
-                                       }
-                                       continue
-                               }
-                       } else {
-                               view.Buf.Replace(match[0], match[1], replace)
-                       }
-               }
-               if !found {
-                       messenger.Message("Nothing matched " + search)
-               }
-       default:
-               messenger.Error("Unknown command: " + inputCmd)
+       if _, ok := commands[inputCmd]; !ok {
+               messenger.Error("Unkown command ", inputCmd)
+       } else {
+               commands[inputCmd](args)
        }
 }
index bfeae5a5f12be0a15e671ae3260890a701d101e4..066e3200d98ae2c4f7519e6e0ac2d7a6a6309dff 100644 (file)
@@ -203,6 +203,7 @@ func main() {
        InitConfigDir()
        // Load the user's settings
        InitSettings()
+       InitCommands()
        InitBindings()
        // Load the syntax files, including the colorscheme
        LoadSyntaxFiles()
@@ -237,6 +238,8 @@ func main() {
        L.SetGlobal("messenger", luar.New(L, messenger))
        L.SetGlobal("GetOption", luar.New(L, GetOption))
        L.SetGlobal("AddOption", luar.New(L, AddOption))
+       L.SetGlobal("BindKey", luar.New(L, BindKey))
+       L.SetGlobal("MakeCommand", luar.New(L, MakeCommand))
 
        LoadPlugins()
 
index 6401970b20ab6193012ebe7036e190e2ffdf1d36..3ac7ebae7c3c876c12ae01845d06af1b0db8a0d4 100644 (file)
@@ -4,6 +4,7 @@ import (
        "errors"
        "io/ioutil"
 
+       "github.com/layeh/gopher-luar"
        "github.com/yuin/gopher-lua"
 )
 
@@ -17,16 +18,17 @@ var preInstalledPlugins = []string{
 // Call calls the lua function 'function'
 // If it does not exist nothing happens, if there is an error,
 // the error is returned
-func Call(function string) error {
+func Call(function string, args []string) error {
        luaFunc := L.GetGlobal(function)
        if luaFunc.String() == "nil" {
                return errors.New("function does not exist: " + function)
        }
+       luaArgs := luar.New(L, args)
        err := L.CallByParam(lua.P{
                Fn:      luaFunc,
                NRet:    0,
                Protect: true,
-       })
+       }, luaArgs)
        return err
 }
 
@@ -36,7 +38,7 @@ func Call(function string) error {
 // to bind keys to lua functions
 func LuaFunctionBinding(function string) func(*View) bool {
        return func(v *View) bool {
-               err := Call(function)
+               err := Call(function, nil)
                if err != nil {
                        TermMessage(err)
                }
@@ -46,9 +48,9 @@ func LuaFunctionBinding(function string) func(*View) bool {
 
 // LuaFunctionCommand is the same as LuaFunctionBinding except it returns a normal function
 // so that a command can be bound to a lua function
-func LuaFunctionCommand(function string) func() {
-       return func() {
-               err := Call(function)
+func LuaFunctionCommand(function string) func([]string) {
+       return func(args []string) {
+               err := Call(function, args)
                if err != nil {
                        TermMessage(err)
                }
index 3e1a494a2b619a1539fdc423623d75a92e05ec4d..4331cf97a1b6ad6cd8cfe6d0080daa144c12749b 100644 (file)
@@ -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\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")
+var _runtimeHelpHelpMd = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x9c\x59\x5b\x77\xe3\xb6\xf1\x7f\x36\x3f\x05\x8e\x36\xe7\x64\x93\xbf\x2c\x9f\x7f\xda\x27\xbf\x6d\x6c\xef\x25\xd9\x5d\x3b\x8e\xb7\x4d\xf2\x12\x42\x24\x24\x21\x26\x09\x06\x00\x6d\x2b\x6d\xfa\xd9\xfb\x9b\x01\x40\x11\x92\xbc\xed\xe9\xbe\xac\x39\x18\xcc\x0d\x73\xd7\x0b\xf1\x41\x57\xd6\x88\x8d\x6a\x7a\xe1\xd5\x93\x2f\x8a\x00\xd0\x4e\x48\x00\x6c\xab\x3b\xd9\x9c\x2e\xa5\x53\x35\x9f\x0b\x55\x6b\x6f\xac\xf0\x1b\xe9\x85\xd4\xad\x13\xde\x88\xa5\x12\x4a\xba\x2d\xfd\x39\x38\x25\x64\x57\x0b\xdd\xf9\x41\x7b\xfd\xa0\xe6\xa2\x78\xdc\xe8\x06\xd0\xc6\x19\xe1\xe5\xbd\xee\xd6\x42\xd6\x0f\xb2\xf3\x72\xad\x84\x59\x81\x94\x12\xab\xa1\x69\x44\x25\x7b\xb9\xd4\x0d\xae\x29\x47\x07\xad\xa9\x95\xed\x46\x29\xdc\xa2\x28\x5e\xbc\x78\x21\x3e\x39\x5c\x2c\x8a\xeb\xae\x52\x62\x6b\x06\xb1\x91\x0f\x4a\x2c\x07\xdd\x78\x26\x15\x04\x9c\x0b\xa7\xdb\xbe\xd9\x0a\xe7\xa5\xf5\x42\x7b\xb1\xdc\x0a\x3b\x74\x1d\xb1\x2f\xca\x96\x95\xec\xa5\xdf\x9c\x79\x73\xb6\x82\x7c\x0b\xff\xe4\x4b\x01\xcd\xe2\xbd\x80\x52\x92\x4e\xa6\x57\x1d\x94\x12\xaa\xed\xfd\x16\x9c\x56\x2b\x65\x17\xc9\x50\xac\x96\x1b\xfa\xde\x58\xef\x44\x65\x95\xf4\xc4\x22\x60\x39\xb1\xb2\xa6\x85\x0c\xb5\xee\xce\x8b\xa2\x2c\xcb\xe2\x0b\xa1\x57\x95\xe9\x56\x7a\x2d\xfe\x29\x98\x07\x83\x8b\x9f\xa1\x49\x05\x26\xad\x81\x36\xa4\x47\x35\x58\x07\x71\xa4\x35\x03\xec\xf9\xa8\xfd\x86\xc1\xd2\x5a\xf3\x28\xee\xd5\xd6\xb1\x9d\x5b\x03\x8b\x47\xc3\x7c\xaf\xb6\x4b\xdd\x81\xd5\xda\x15\xc5\xdd\x46\xd1\x53\xd8\x40\xac\x56\x2b\x39\xc0\x40\xf7\x3b\x94\x39\x44\x37\x90\x34\x51\xd6\xe0\x55\x79\x6d\x3a\xb2\x73\xf1\xb5\xb8\xf0\xb6\x39\xfd\xfd\x5c\x08\xf1\x03\x5e\x32\x01\x14\x01\xae\x9e\x54\x35\x78\x50\x17\x95\x69\x5b\x88\x91\x4e\xd7\x74\x7a\x67\xd6\x6b\xbc\xf7\xce\xa5\xe2\xe1\x92\x0e\x6f\x07\x98\x52\x38\x1c\x36\xfb\x97\x1d\x9d\xff\x88\xc7\x4c\x00\x43\x80\x6b\x32\x3e\x3d\x50\x82\xfe\x41\xd0\x4f\x5d\x6d\x12\x60\xcb\x74\xd5\x0e\xb0\x22\xc0\x6b\xbd\xa3\xdc\x25\x80\xe8\x26\xf2\xf4\x23\xb4\xb7\xea\x41\xc3\x90\xe9\x44\xb2\x24\xaa\x51\x15\x7c\xbc\x69\x12\xb8\x22\xf0\x85\xe9\xb7\x09\xf0\xc4\x80\x61\xa4\x78\x1f\xbf\x45\xa3\xbb\x51\xde\x9a\x80\x97\x43\xdf\xe8\x4a\xc2\x66\xd3\xa3\x07\x3a\xba\x91\xce\x13\xe4\x06\x5e\xfd\xa9\x0f\x10\x04\xc6\xd0\x47\xd8\xa5\x79\x84\xfc\x0c\xab\xf1\x27\xa0\x6f\x4d\xcb\xcf\x20\xc4\x1b\x13\xc2\x6f\xad\x83\x63\x23\x68\x22\xfd\xab\xae\x0e\x28\x11\x47\x41\xcd\xdd\x29\x73\xb7\x93\xc7\x22\xb8\xe8\x86\x76\x09\x9f\xdd\xf9\x22\x05\x33\xfb\x5c\xf0\x1c\x27\xfe\x2f\xb8\x1f\x07\x3d\x3b\xea\xa3\xb1\x35\x45\x16\xfd\xbf\x28\x88\xac\x68\xd4\xca\xb3\x6b\x5a\xbd\xde\xf8\x03\x7f\xc6\x4d\xfa\x0a\x61\x49\x68\x51\x32\x02\x92\x14\x73\x02\x16\x15\x51\x1a\x7a\x46\x20\xad\x0f\xc9\x3c\x47\x63\x0c\xcf\xa4\xc4\xc6\x34\x35\x1c\x4e\x43\x2a\x76\x75\x3c\x68\xc4\x85\x76\x44\xb6\x55\x9d\x4f\xae\x4f\xe2\xb9\xf0\xf0\x21\x6b\x01\x01\x86\x5d\x70\x3c\x89\x14\x3a\xa2\x95\x5b\x4a\x7a\x56\x2d\x39\x38\x07\x47\xc6\x27\xee\xe5\xbf\xce\x16\x21\xba\xcf\x38\xb6\xcf\xd2\x95\xc5\x6f\xce\x74\xa5\x28\x38\xd5\x88\x2b\x59\x6d\xc8\xa2\x94\x66\x03\x09\xf0\x85\xac\x41\x0a\x70\x7b\x0d\x15\xd5\x93\x44\x26\x82\x41\xe8\x89\xc9\x4d\xcb\xe0\xee\x9c\x93\x70\xc7\xb0\xea\x01\xf8\x07\x03\x2d\x82\x60\xce\x39\xb1\x32\x03\xb4\xee\x87\x90\x12\x8b\x95\x69\x1a\xf3\x48\x42\xea\x2e\xc8\xb9\x27\x17\x8b\xc5\x09\x8a\xbe\x8b\x7f\x14\x27\x33\xa2\xfb\xf3\xec\x5c\xcc\x28\xd6\x66\xf3\x08\xf9\x85\x20\x14\x6c\xb3\xe2\xcf\x90\xb8\xde\x2a\x7b\x90\x67\xdc\xf9\x94\x16\x79\xe1\xec\x53\x3f\x8b\x0e\x19\xff\xcd\x2e\xf8\x25\x01\x9f\x07\x0c\x72\xf4\x0c\x27\x62\x30\x3c\xe2\xdc\x92\x4f\x4d\x91\x22\x4e\x80\x47\xa4\xf7\xf0\xc0\x63\x84\x18\x1e\x71\x7e\x24\x87\x98\xca\x34\x0b\xf1\xbe\x13\x87\x31\xa6\x32\x45\x8c\xa9\x38\x8c\x33\x65\x17\x71\x0e\x38\x4d\xe5\x8e\x38\x99\xc8\xaf\x1a\x9f\x4b\x3d\xfb\x3b\x22\x6a\x4a\x06\x18\xb9\xf2\x8c\xb1\x4f\x24\x67\x16\x39\x3d\x8b\x38\xb2\x9c\x20\x4e\x79\xd2\x83\x67\x62\xcd\x7e\xa4\x90\xbb\x5e\xbd\x47\xa0\x4e\x91\x32\xc9\x66\xc8\x3d\x87\x28\x19\xc3\xc8\xef\xce\x3c\x43\x2f\x53\x63\x44\x3e\x4a\x37\xf3\xab\xf8\xd0\x4c\x75\x8a\x94\xb9\x56\x44\x02\xb5\x03\x96\x89\x58\x2e\xdf\x01\x5a\x22\x37\x95\x2c\x21\x5d\x75\xe8\x57\x32\x0f\x7d\xd7\x39\x65\x7d\x80\x27\x9f\xe8\x65\xa5\x8e\x20\x05\x78\x44\xfa\x56\x56\xf7\x6e\x8a\x38\x81\xec\xa3\x7c\x93\x7c\xeb\x00\xe5\x4e\x2e\xf3\xc0\x8b\xac\x08\x3e\xd1\xeb\x3a\x93\x86\x8a\xee\x6b\xa4\x84\x4c\xf3\x0c\x83\xea\xf4\xf4\xf4\x75\x76\x4a\x55\x75\x7a\xfa\xf1\xe0\xf4\x23\x0a\xf1\x14\xe3\xe6\x00\xe3\x26\x16\xe5\x29\xd6\x2f\x19\x56\x4c\x4c\xe3\xe9\xcf\xd9\x29\x27\xa9\xc9\xe9\x45\x9e\x36\x50\xc6\xa7\xa7\x3f\xed\x25\x95\x4c\xb8\xef\xf7\x0f\xf7\x9d\xf0\x32\x43\x18\x8b\xfd\x3e\xda\xdf\x32\x34\x2e\xfc\xd3\xe3\x57\xb9\x85\xd9\xb7\x5e\x35\x4d\x42\xa1\xb2\x9f\xa7\xb5\xcc\x3b\xc9\x07\xf3\x87\x9e\x78\xe5\xcd\x7a\x2f\xff\xce\x42\xbb\xb1\x3b\xbf\xec\x0e\xcf\xa7\xa9\x8e\x04\x7c\x93\x09\x18\x5a\x87\xb7\x68\xf3\xb2\x54\x70\x04\xe7\x76\x68\x76\xbe\xcf\x49\x25\x43\xfa\x6e\x68\xfb\xa9\xa9\x2e\xa1\xb9\x9f\xaa\x9a\x20\x49\x53\x57\xed\x69\x7a\xd1\x28\x49\x51\xef\x73\x77\xf9\x36\x37\x28\x35\x9d\x1f\x30\x53\x4c\x51\x7e\xc8\x50\xa8\xd3\x9d\x9e\x5e\xed\xf9\x0c\xf7\xab\x91\x04\x63\x9d\x9d\x89\xab\x56\x56\xee\xd4\xf9\x2d\xba\x85\x49\x7b\x3d\x66\xda\xd3\x15\xe5\xb0\x63\x39\xf8\x74\x99\x4e\xf6\x12\xfd\xa9\xe4\xb4\x77\x98\x1b\xe9\x8c\x0c\x73\x98\x62\xe9\x84\x5e\xf8\xa0\xaa\xd2\x41\xb7\x3b\x88\x4f\xfa\x67\x18\x46\xc2\xdc\x70\x63\x9c\xd3\x4b\x88\x1f\x1b\xf2\x49\x07\xa8\x52\xa7\xdf\xa5\xc1\x2f\xe2\x50\xd3\x87\xb6\xd9\x71\xe7\x13\x7a\x10\x85\x36\x82\xfb\x0c\xc5\xa7\xdc\xac\x05\xe4\x45\xde\x24\xf4\xfb\xfc\xc2\x34\xb9\xdd\x75\x9d\x0b\x1a\x40\xca\xdf\xf1\x1a\xe5\x39\x8f\x1f\x2e\x8c\x4a\x0b\x02\x3b\xa4\x1e\x80\x29\x03\xb9\xd4\x12\x5a\xea\xe1\xc6\xd6\x0f\x48\x56\xf5\x0d\xb2\xa0\x98\x39\x78\x46\xb5\x99\x89\xd9\x83\x6c\x06\x35\x13\xab\x46\xae\x1d\xae\xdf\x6d\xd0\x7b\x3d\x6a\x34\x83\x09\xb5\x0c\xa8\x65\x68\x13\x4b\xc6\x2f\x17\x82\xcc\x48\xcd\x5f\x19\x6e\xb2\x16\xa6\xa7\x3e\x4d\x36\x0b\x3a\x7c\x45\x4d\x16\x88\xf5\x06\x43\xef\x9c\x24\x02\x06\xbe\x4d\x87\x31\xd2\xa0\xaf\xa6\x8b\xe7\xa2\xac\xca\x39\x35\x95\xe8\xfc\x54\x27\xa1\xbe\x03\x68\xa3\xaa\xfb\x92\x07\x5d\xe6\x13\x8e\xa5\xbb\x77\x98\x12\xc9\x20\x5f\xd6\x68\x8a\xef\x15\x35\x77\xbd\xb2\x2b\x63\x5b\xd6\x38\x8a\xcc\x9d\xab\xa2\x5e\xd2\xeb\x56\xb1\x47\x7e\x34\x5e\x05\x73\x8e\xea\xb4\x83\xf3\xd4\xad\x4a\x01\x95\x34\xfa\x72\xb5\x56\x4f\x0b\x21\xde\xad\x58\xba\xd8\x37\x4b\xbb\x1e\x88\x1e\x3b\x6e\x6d\x20\x5d\x67\x7c\x98\xad\x65\x87\x31\x9a\x6a\x8a\xa3\xf6\x51\xfb\xd0\x62\x52\x0f\x6c\x5a\x1d\x3a\xcc\xdf\x07\xf0\x75\xc1\xf4\x4e\xf9\x68\x20\x11\x6c\x78\x8e\x96\xda\x87\xa7\x8a\x70\xa8\xc3\x47\x0b\x71\x83\xc8\x45\x1f\xee\x54\x70\x0d\x9a\xcf\xf0\xc1\x6d\x30\xbc\xc9\x92\x30\x12\x26\x80\x06\x90\x33\xdc\x76\xa3\xa7\x80\x6c\x7c\x6d\x4c\x95\x6e\x73\x1a\xfd\x09\x0c\x01\x08\x0c\xd7\xfa\x41\x75\xf9\xbc\x99\x7a\xe0\x25\x4a\xe5\x9a\xa7\xeb\x05\x3f\x30\xf1\x8a\x28\x5f\xe2\xf5\x06\x4f\xed\x33\x7b\x08\x8c\x57\x6b\x07\x93\x6f\x15\xdf\x26\xb3\xf1\xc4\xf4\xb8\x51\x64\x10\xb4\xcf\x9d\x06\x0f\x97\x36\x0c\x41\x2a\x6e\xda\xa9\xcb\x0f\x6d\x3d\xc4\xe2\xf5\x80\xa2\xd5\xca\x2e\x53\x84\x15\x01\xa1\xd1\x0c\x10\x06\x00\x0c\x9f\xc1\x1e\xd1\x14\xe4\x4c\x24\xde\x24\xbf\x08\xb9\xa4\x91\x08\x36\x82\xfb\x90\xc3\x75\x2b\x43\x30\x92\x99\x9e\x7f\xdc\x10\xa4\xc9\x86\xfc\x56\x3e\x48\xdd\x90\xef\xc5\x8d\xc1\x75\x30\x68\xda\x65\x38\x04\x38\x49\x37\x4e\x48\x14\x8b\x14\xf2\x34\xd0\x0c\x56\xf2\xab\xb0\x0b\xb8\x3d\x60\xad\x2d\x24\x35\x76\x3b\xee\x45\x70\x33\xbc\x40\xf9\xc5\x4f\x97\x6f\x7e\xbd\xb8\xfe\xf8\xfa\xdd\x9b\x5f\xdf\x5e\x7f\xb8\x3a\x8b\x9b\x15\x19\xa3\xf7\x19\x42\xe2\x95\x23\x9f\x2f\x08\x07\x14\xe0\x81\xaa\x9a\x53\x58\x1c\x10\x2c\x29\xda\xc8\x5b\xe1\x0f\xf3\x83\x11\x8c\x4f\x07\xda\x5f\x81\x61\xb1\xe3\x98\xc9\x9c\xe5\xa7\xe4\x66\x59\x56\x02\xed\x73\x7e\xd5\xca\x34\xc6\x3a\x44\x6e\x4b\x9e\xdd\x18\x59\x27\x3d\x46\x78\x30\x24\xbb\x0a\xbd\xda\x17\x2f\x03\xc7\x4b\x6d\xbf\x3a\x9b\xa0\xb9\xb3\x32\xb0\x2a\x17\x61\x11\x54\x9c\xa4\x3d\x0d\x47\x07\x72\x46\xfc\x2e\x8b\x93\x5d\x60\x4f\xf7\x39\x53\x6a\xe2\x65\x84\xce\x85\x33\x8d\xb4\xfa\x0f\x55\xf3\x34\xbd\xfb\x3c\xf5\xd5\x57\xc5\x09\xe9\x49\xe6\x6a\x0c\x35\x29\x2c\xe6\x28\xe0\x1c\xce\x5e\xc9\x38\xf8\x6f\xd9\x24\xaa\x5d\xaa\xba\x56\x63\xdc\x84\xdd\x19\xfc\x50\xda\x2d\x44\xbe\xdb\xd3\x9d\x8c\xb5\x54\x71\x8a\xc6\x2d\x76\x6f\x72\x29\xde\xf3\xe9\x26\x64\x11\x1e\x4b\x4f\xf6\xa7\xe5\xcc\x38\x53\x5f\x08\x3e\x85\xe8\xc4\x6d\xd4\x96\xa4\x7e\xdc\x5d\x59\xa5\x8a\x93\xe9\x5d\xbc\xd4\xc9\xd7\x09\xeb\x3c\xa4\x67\xed\x9e\xb3\xdc\x82\x90\x47\x1b\xe5\xe8\x23\x38\xd3\xf1\x25\xfb\x53\x54\xc3\x21\xaa\x55\xe7\x36\xc6\x7f\x85\x6a\x71\x22\x04\x15\x4f\x7c\xd2\x04\xce\xf9\xf3\x08\x1d\xd1\x4b\x74\x34\x9e\xc2\x96\x3c\xcc\x8e\x4b\xce\xb4\x43\xd5\x3e\x97\x0a\x2f\xf7\xdf\x08\x46\xe9\xc0\xdb\x21\xbe\xc8\x5c\xfc\x46\xb9\x9f\x64\x6a\x25\xaa\x88\x1b\xac\xda\x63\x37\x6e\x2e\x77\xb7\xf0\x7a\x2b\xca\x28\x61\xab\xa1\xc3\x86\x65\xf4\x3c\x22\xf6\xe1\xdd\xc5\xed\xf5\xaf\x77\xb7\x9f\xae\x2e\xae\xdf\x5f\xdf\xa2\x9e\x3d\x68\x6b\x3a\x2e\x47\x0f\x90\x8a\x32\x0c\xc9\x49\x95\x00\xfa\xfc\x7f\xa2\xc8\x0b\x1b\x22\x1a\x8b\x39\xc7\x93\x97\x4b\x07\x3d\xa6\x55\x02\x20\x41\x30\xba\x9c\x42\xe4\x48\x70\xfc\xb5\x64\x02\x48\x88\x60\x5c\x6d\xa4\x9d\xd2\x08\xd0\x90\x54\xe8\x0c\x69\x10\xc9\xe4\x90\x88\x88\x44\xd6\x1d\x24\xac\x50\x8b\x40\x24\x95\x5a\xfa\x3c\xd5\x18\x97\x3a\xc7\xbb\x6c\x11\x4a\xaa\x72\x47\xe8\x98\xd5\x2a\x50\x72\x5b\xb0\x7d\x02\x15\x3f\x58\x24\x91\xf0\x89\xfc\x4d\xbb\x65\x20\x1d\xbb\xda\x95\xa3\x25\xbc\x09\x95\x16\xf7\xc9\x0d\xc6\xb2\x8b\x51\x41\x86\x1d\x17\x90\x3e\xc7\x5e\x0e\xde\x04\xdd\x41\x82\xeb\xd3\xb8\x93\x96\x28\xaf\x8f\xa1\x70\xa5\xcd\x9e\x93\x6d\x6e\xaa\x98\x94\x29\x6d\xa5\xad\x68\x58\x1a\x3e\x2f\xb6\xa5\xee\x1e\xcc\x62\x89\xdc\xdb\x25\x3e\x7b\xcd\x71\xbb\x4e\xc8\x93\xbb\x71\xad\xe7\x23\x57\x11\x9d\x6e\x69\xbc\x47\x16\x89\x45\x29\x04\xdc\xe7\x48\x23\xea\xc2\x9e\x90\x5a\x01\xc4\x05\xc9\x42\xc6\xb0\xd9\x0e\xf1\x11\xca\x36\x18\xc2\xb8\x7b\x1a\xd3\x13\x83\x69\xe5\x4f\x15\xa3\xab\xd9\x12\x03\xff\x82\x10\x3a\x3b\xb6\x29\x55\x05\xfe\x59\x60\xbc\x25\xd7\x52\x77\x61\x28\x78\xde\x35\x20\x17\x2d\xee\xd2\xcb\x70\x3c\xc7\x96\x88\x1b\xc6\x79\xd8\xeb\x51\xe8\x00\xb5\x16\x8a\x9a\x17\xb9\x82\xe7\x86\x3a\xd4\x18\xda\xe9\x87\x75\x38\x18\x39\x13\xdb\xc4\x74\x42\x5b\x57\x15\x7e\xae\x60\xa4\xf9\x58\xbe\xee\x95\xea\x99\x38\x1c\xe1\x3f\x49\x89\xd8\x6c\x9a\x16\x0d\xa1\xa6\x9e\x45\xb6\x68\x91\x7c\x5a\x1e\x87\xe6\xeb\x91\x93\x5b\xea\x4c\xa9\x79\x0b\xdd\x08\x0f\x06\x0a\x23\xc0\xc4\xcc\x47\xde\xe9\x2f\x53\x46\xa8\xeb\xaa\x3e\xc2\x87\x08\x33\x02\x27\x35\x6a\xb9\xe2\x27\x19\xc5\x1f\xa1\xfa\x0d\xa8\x9e\x9e\x9e\x16\xc5\x65\x3c\xe8\x9b\x61\x4d\xdd\x5a\x28\xe7\xa1\x7a\x83\xb6\x67\x6f\xa5\x3f\xf0\xfa\xdd\x7a\xc0\xa0\x4b\xb6\x67\x93\x8b\x97\x31\x21\xc2\xf8\xbb\x43\xaa\x82\x17\x73\x71\x39\x17\x6f\xcc\x5c\x7c\x87\x2e\x8a\x87\x2b\xfa\x03\x32\xe9\x1e\x15\xf7\xfd\x20\x91\xfd\x6f\xac\x79\xd0\xf5\x6e\xfe\x49\xec\xa2\x28\x8b\xcf\xf8\xec\xda\xe8\x96\x33\x31\x64\xa3\x1f\x49\xc6\xef\x24\xda\x11\xea\x6b\xf3\x59\xca\xe9\x41\xd7\x66\xd5\xfa\x91\x2c\xfe\xfe\xdf\x49\x92\xb0\xaf\x30\x0e\x44\xa7\x25\x5f\xa0\x24\x1f\x2b\x61\x1c\x11\x53\xcf\x1c\x7c\x38\x2e\xfc\x39\x48\x8a\xfd\x82\x8f\xcb\x7e\x5c\x43\xc3\x9f\xe7\x44\x4a\x61\x8c\xab\xc2\x94\xb1\xdf\x7c\x86\x00\x8d\xf4\x8b\xd0\x4e\xd7\xec\x20\x40\x5e\xd0\x48\x93\x0f\x4d\x9e\xca\xde\x11\x3a\xdc\x38\x90\xf4\xbc\x77\x37\x14\xd9\x05\xe6\xf8\x0d\xff\x00\x11\x7f\x01\xac\x4c\x1f\x13\x52\x26\x64\xd4\x87\xef\x88\x78\x67\x51\xfc\x3b\x00\x00\xff\xff\x97\x66\xc9\x68\x49\x1d\x00\x00")
 
 func runtimeHelpHelpMdBytes() ([]byte, error) {
        return bindataRead(
@@ -255,12 +255,12 @@ func runtimeHelpHelpMd() (*asset, error) {
                return nil, err
        }
 
-       info := bindataFileInfo{name: "runtime/help/help.md", size: 7336, mode: os.FileMode(420), modTime: time.Unix(1464534110, 0)}
+       info := bindataFileInfo{name: "runtime/help/help.md", size: 7497, mode: os.FileMode(420), modTime: time.Unix(1464629921, 0)}
        a := &asset{bytes: bytes, info: info}
        return a, nil
 }
 
-var _runtimePluginsGoGoLua = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x9c\x91\x4f\x4f\xb4\x30\x10\xc6\xef\x7c\x8a\x49\x93\x37\x29\xef\x22\x89\x57\x92\x3d\xe8\xc1\x3d\xae\x51\xe3\x65\xb3\x9a\x0a\x03\x34\x29\x2d\x69\xcb\xae\xc6\xf8\xdd\x6d\xa1\xfb\x4f\x58\x35\xf6\x02\xed\xcc\xfc\x9e\xe7\x69\x79\x09\x0b\xb4\xcb\xd6\x72\x25\x29\xa9\x14\x6f\x5a\xa5\xad\x21\x31\xcc\xe7\x20\xb9\x00\x5b\xa3\x8c\xc0\xad\xab\xa2\x18\xb7\x25\x50\x32\x61\x30\x8e\x50\x16\xd1\x57\x56\xd9\xd8\x9f\x38\xbe\x25\x01\xab\xbb\x80\x88\xca\x4e\xe6\xbe\x08\x95\x7a\x56\xf2\x9e\x6d\x90\xc6\xfd\x98\x83\x6f\x38\x6e\xcd\xaa\x61\x5c\x3e\xba\xbf\xd9\xe5\x3a\xbd\xee\xca\xf4\x86\x0b\x7c\x78\x6b\xd1\x0b\x91\x85\x22\x07\xa5\x30\x76\x26\xdf\x49\x9b\x5f\x4e\x71\x5f\x0f\xa2\x7e\xa1\xcb\x37\x9d\x6c\x9a\xe0\x6a\xc7\xd3\x3e\xd4\x6e\x33\x0a\x90\xdd\xe1\xb2\x45\x19\xfa\x7d\xef\xe8\x12\x8e\x81\x42\xe5\x4c\x40\xcd\x64\x21\x5c\x5c\xe0\x2a\x6d\x95\x1f\x1f\x1c\xc1\xc5\x16\x08\xa4\xe9\x99\x7b\xba\x65\xb6\x3e\xc6\x68\x34\x9d\xb0\x0e\x33\xf0\x32\x8d\xac\xa0\xe4\x3f\x23\x43\x53\x38\xcd\x85\x32\xfe\x09\x26\x7c\x9d\x5e\xd5\x37\xde\x42\xe3\x5f\xfd\x39\x31\xd3\x0a\x6e\xe9\xc8\x68\x02\x24\xfb\xa5\xdd\x81\x60\xac\x4e\xc0\x60\x3b\xa9\xf3\xfe\x71\x72\x5a\xe1\xab\x3b\xa4\x84\xae\x9e\xfe\x99\xf5\x2c\x26\x71\x56\x2a\xdd\x30\x47\xd9\x01\xdc\x1e\x90\xe5\x35\x70\x09\x0e\x9d\x55\xae\x9a\xd7\xb4\x9f\x8d\xa1\x50\xfb\x87\xb7\xec\x45\x60\xca\xa5\x41\x6d\xe9\x20\x98\xf4\x93\x87\x87\xf7\x5f\x8d\xb6\xd3\x32\x38\xea\x33\x7c\x06\x00\x00\xff\xff\xff\xc6\x74\xc8\x9f\x03\x00\x00")
+var _runtimePluginsGoGoLua = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xac\x52\x4f\x6b\xdb\x30\x14\xbf\xfb\x53\x3c\x04\x03\x6b\xf1\x0c\xbb\x1a\x72\xd8\x06\xcb\x69\x64\x6c\x63\x97\x90\x16\xd5\x7e\x8e\x45\x65\xc9\x48\x72\xd2\x52\xfa\xdd\xfb\xfc\x27\xad\x9c\x38\x14\x42\x75\x49\xfc\xfc\x7b\xbf\x7f\x96\x2c\x61\x85\x7e\xdd\x78\x69\x74\xcc\x76\x46\xd6\x8d\xb1\xde\x31\x0e\xcb\x25\x68\xa9\xc0\x57\xa8\x23\xa0\xf3\xad\x28\xce\x61\x09\x94\x42\x39\xe4\x11\xea\x22\x3a\xe5\x2a\x6b\xff\x1e\x4f\x07\x49\xc0\xdb\x76\xa4\x88\x7e\x89\x7b\xfc\x61\xea\x5a\xe8\x62\xaa\x43\x0f\xb7\x81\xbd\x53\xe0\x40\x34\x80\x7a\xdd\x28\x2a\x5b\x9d\x77\x3a\x40\x43\xa3\xff\x8a\x3d\xc6\xbc\x77\x40\x3e\xf7\x12\x0f\x6e\x53\x0b\xa9\xff\xd3\xbf\xc5\xd7\x6d\xfa\xbd\x2d\xd3\x9f\x52\xe1\xbf\xc7\x06\x3b\xcf\x6c\x65\xd8\x9b\xe9\x71\xed\x42\x55\x13\x58\x77\x42\xaf\xa3\x68\x77\x90\xaa\x9a\x2f\x69\x9e\x81\xde\x85\xdb\xd4\xcf\xf1\xb7\xef\x2a\x0c\x18\x82\xcf\xc2\x65\x41\x78\x65\x72\xa1\xa0\xa2\xda\x14\xe5\x04\x69\xd2\xc6\x34\x78\xb4\x02\x5f\x0e\xc0\x20\x4d\x2f\x14\xf4\x5b\xf8\x2a\xa4\xb1\xe8\x5a\xe5\x89\x66\xe0\xcb\x2c\x0a\xfa\x1a\x9f\x05\x1b\x40\xe3\x34\x57\xc6\x75\xf2\x17\xcc\xfd\xc1\x75\x67\x80\xcf\x85\x9a\x76\x78\x6d\xb0\x91\xe5\xda\x70\xe4\xc4\x35\x4a\xfa\xf8\x2c\x25\xdd\xb8\xec\x83\xb2\x0e\x0a\xce\xdb\x04\x1c\x36\xb3\x3e\x9e\x9e\x27\xd3\x1d\x3e\xd0\x30\x66\xf1\xe6\xe6\x93\xdb\x2e\x38\xe3\x59\x69\x6c\x2d\x88\xe5\x48\x40\xcf\x80\x22\xaf\x40\x6a\x20\xea\x6c\x47\x6f\xf3\x2a\xee\x77\x39\x14\xe6\xf5\x6e\x79\x71\xa7\x30\x95\xda\xa1\xf5\xf1\x20\x98\xf4\x9b\x3c\x0a\xaf\x9e\x45\xdf\x5a\x3d\x3a\xea\x33\xbc\x04\x00\x00\xff\xff\x96\x4d\x4a\x5a\x40\x04\x00\x00")
 
 func runtimePluginsGoGoLuaBytes() ([]byte, error) {
        return bindataRead(
@@ -275,7 +275,7 @@ func runtimePluginsGoGoLua() (*asset, error) {
                return nil, err
        }
 
-       info := bindataFileInfo{name: "runtime/plugins/go/go.lua", size: 927, mode: os.FileMode(420), modTime: time.Unix(1464613212, 0)}
+       info := bindataFileInfo{name: "runtime/plugins/go/go.lua", size: 1088, mode: os.FileMode(420), modTime: time.Unix(1464629526, 0)}
        a := &asset{bytes: bytes, info: info}
        return a, nil
 }
index eb9ea80731970b6e58a9d683ce49f735056d22fa..a2c7713f0fea29adb3c9751e3166c8a6270727ff 100644 (file)
@@ -301,7 +301,7 @@ func (v *View) HandleEvent(event tcell.Event) {
                                                relocate = action(v)
                                                for _, pl := range loadedPlugins {
                                                        funcName := strings.Split(runtime.FuncForPC(reflect.ValueOf(action).Pointer()).Name(), ".")
-                                                       err := Call(pl + "_on" + funcName[len(funcName)-1])
+                                                       err := Call(pl+"_on"+funcName[len(funcName)-1], nil)
                                                        if err != nil && !strings.HasPrefix(err.Error(), "function does not exist") {
                                                                TermMessage(err)
                                                        }
index 694312606c2c82a9177afe2672f19c2966aba022..4af7bee0239cc1c32e404f01d103c616c557deb2 100644 (file)
@@ -152,6 +152,9 @@ Here are the possible commands that you can use.
 * `run sh-command`: runs the given shell command in the background. The 
    command's output will be displayed in one line when it finishes running.
 
+* `bind key action`: creates a keybinding from key to action. See the sections on
+   keybindings above for more info about what keys and actions are available.
+
 ### Options
 
 Micro stores all of the user configuration in its configuration directory.
index 6c545f5109e8a6939374e1d9f5ec4341f0d45018..6ea14cd07165af6f0d9d4d0a3ec446083812d57a 100644 (file)
@@ -5,6 +5,9 @@ if GetOption("gofmt") == nil then
     AddOption("gofmt", true)
 end
 
+MakeCommand("goimports", "go_goimports")
+MakeCommand("gofmt", "go_gofmt")
+
 function go_onSave()
     if views[mainView+1].Buf.FileType == "Go" then
         if GetOption("goimports") then
@@ -12,21 +15,25 @@ function go_onSave()
         elseif GetOption("gofmt") then
             go_gofmt()
         end
-
-        views[mainView+1]:ReOpen()
     end
 end
 
 function go_gofmt()
+    views[mainView+1]:Save()
     local handle = io.popen("gofmt -w " .. views[mainView+1].Buf.Path)
     local result = handle:read("*a")
     handle:close()
+
+    views[mainView+1]:ReOpen()
 end
 
 function go_goimports()
+    views[mainView+1]:Save()
     local handle = io.popen("goimports -w " .. views[mainView+1].Buf.Path)
     local result = go_split(handle:read("*a"), ":")
     handle:close()
+
+    views[mainView+1]:ReOpen()
 end
 
 function go_split(str, sep)