From e05e993e25e317c9d4c47ed273ca82e01bfa2ecb Mon Sep 17 00:00:00 2001 From: Zachary Yedidia Date: Sun, 24 Apr 2016 19:52:02 -0400 Subject: [PATCH 01/15] Interface with plugin.lua file --- cmd/micro/bindings.go | 13 +++++++++++-- cmd/micro/micro.go | 16 ++++++++++++++++ cmd/micro/plugin.lua | 8 ++++++++ cmd/micro/view.go | 4 ++-- 4 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 cmd/micro/plugin.lua diff --git a/cmd/micro/bindings.go b/cmd/micro/bindings.go index 437cb618..e97d4ed9 100644 --- a/cmd/micro/bindings.go +++ b/cmd/micro/bindings.go @@ -11,6 +11,7 @@ import ( "time" "github.com/mitchellh/go-homedir" + "github.com/yuin/gopher-lua" "github.com/zyedidia/clipboard" "github.com/zyedidia/tcell" ) @@ -619,6 +620,14 @@ func (v *View) Save() bool { v.GoSave() } } + if err := L.CallByParam(lua.P{ + Fn: L.GetGlobal("onSave"), + NRet: 1, + Protect: true, + }); err != nil { + // The function isn't defined by this plugin + return true + } return true } @@ -633,7 +642,7 @@ func (v *View) GoSave() { } else { messenger.Message("Saved " + v.buf.path) } - v.reOpen() + v.ReOpen() } else if settings["gofmt"] == true { messenger.Message("Running gofmt...") err := gofmt(v.buf.path) @@ -642,7 +651,7 @@ func (v *View) GoSave() { } else { messenger.Message("Saved " + v.buf.path) } - v.reOpen() + v.ReOpen() return } diff --git a/cmd/micro/micro.go b/cmd/micro/micro.go index a05761fb..d9241215 100644 --- a/cmd/micro/micro.go +++ b/cmd/micro/micro.go @@ -7,8 +7,10 @@ import ( "os" "github.com/go-errors/errors" + "github.com/layeh/gopher-luar" "github.com/mattn/go-isatty" "github.com/mitchellh/go-homedir" + "github.com/yuin/gopher-lua" "github.com/zyedidia/tcell" "github.com/zyedidia/tcell/encoding" ) @@ -41,6 +43,9 @@ var ( // Is the help screen open helpOpen = false + + // L is the lua state + L *lua.LState ) // LoadInput loads the file input for the editor @@ -175,6 +180,13 @@ func main() { os.Exit(1) } + L = lua.NewState() + defer L.Close() + + if err := L.DoFile("plugin.lua"); err != nil { + panic(err) + } + encoding.Register() tcell.SetEncodingFallback(tcell.EncodingFallbackASCII) @@ -207,6 +219,10 @@ func main() { messenger = new(Messenger) view := NewView(buf) + L.SetGlobal("view", luar.New(L, view)) + L.SetGlobal("settings", luar.New(L, &settings)) + L.SetGlobal("messenger", luar.New(L, messenger)) + for { // Display everything Redraw(view) diff --git a/cmd/micro/plugin.lua b/cmd/micro/plugin.lua new file mode 100644 index 00000000..c6fab31c --- /dev/null +++ b/cmd/micro/plugin.lua @@ -0,0 +1,8 @@ +function onSave() + local handle = io.popen("goimports -w view.go") + local result = handle:read("*a") + handle:close() + + view:ReOpen() + messenger:Message(result) +end diff --git a/cmd/micro/view.go b/cmd/micro/view.go index 175799f6..5ff868da 100644 --- a/cmd/micro/view.go +++ b/cmd/micro/view.go @@ -172,8 +172,8 @@ func (v *View) OpenBuffer(buf *Buffer) { v.lastClickTime = time.Time{} } -// Close and Re-open the current file. -func (v *View) reOpen() { +// ReOpen reloads the current buffer +func (v *View) ReOpen() { if v.CanClose("Continue? (yes, no, save) ") { file, err := ioutil.ReadFile(v.buf.path) filename := v.buf.name From eba820a9c775de67e85da1da1ba35e58a1928c77 Mon Sep 17 00:00:00 2001 From: Zachary Yedidia Date: Mon, 25 Apr 2016 12:48:43 -0400 Subject: [PATCH 02/15] Rewrite gofmt and goimports as plugins --- cmd/micro/bindings.go | 347 +++++++++++++++++++------------------- cmd/micro/buffer.go | 22 +-- cmd/micro/command.go | 18 +- cmd/micro/cursor.go | 64 +++---- cmd/micro/eventhandler.go | 18 +- cmd/micro/highlighter.go | 34 ++-- cmd/micro/micro.go | 2 +- cmd/micro/plugin.lua | 23 ++- cmd/micro/search.go | 12 +- cmd/micro/settings.go | 2 +- cmd/micro/statusline.go | 10 +- cmd/micro/view.go | 145 ++++++++-------- 12 files changed, 360 insertions(+), 337 deletions(-) diff --git a/cmd/micro/bindings.go b/cmd/micro/bindings.go index e97d4ed9..bacf584e 100644 --- a/cmd/micro/bindings.go +++ b/cmd/micro/bindings.go @@ -297,242 +297,242 @@ func DefaultBindings() map[string]string { // CursorUp moves the cursor up func (v *View) CursorUp() bool { - if v.cursor.HasSelection() { - v.cursor.SetLoc(v.cursor.curSelection[0]) - v.cursor.ResetSelection() + if v.Cursor.HasSelection() { + v.Cursor.SetLoc(v.Cursor.curSelection[0]) + v.Cursor.ResetSelection() } - v.cursor.Up() + v.Cursor.Up() return true } // CursorDown moves the cursor down func (v *View) CursorDown() bool { - if v.cursor.HasSelection() { - v.cursor.SetLoc(v.cursor.curSelection[1]) - v.cursor.ResetSelection() + if v.Cursor.HasSelection() { + v.Cursor.SetLoc(v.Cursor.curSelection[1]) + v.Cursor.ResetSelection() } - v.cursor.Down() + v.Cursor.Down() return true } // CursorLeft moves the cursor left func (v *View) CursorLeft() bool { - if v.cursor.HasSelection() { - v.cursor.SetLoc(v.cursor.curSelection[0]) - v.cursor.ResetSelection() + if v.Cursor.HasSelection() { + v.Cursor.SetLoc(v.Cursor.curSelection[0]) + v.Cursor.ResetSelection() } else { - v.cursor.Left() + v.Cursor.Left() } return true } // CursorRight moves the cursor right func (v *View) CursorRight() bool { - if v.cursor.HasSelection() { - v.cursor.SetLoc(v.cursor.curSelection[1] - 1) - v.cursor.ResetSelection() + if v.Cursor.HasSelection() { + v.Cursor.SetLoc(v.Cursor.curSelection[1] - 1) + v.Cursor.ResetSelection() } else { - v.cursor.Right() + v.Cursor.Right() } return true } // WordRight moves the cursor one word to the right func (v *View) WordRight() bool { - v.cursor.WordRight() + v.Cursor.WordRight() return true } // WordLeft moves the cursor one word to the left func (v *View) WordLeft() bool { - v.cursor.WordLeft() + v.Cursor.WordLeft() return true } // SelectUp selects up one line func (v *View) SelectUp() bool { - loc := v.cursor.Loc() - if !v.cursor.HasSelection() { - v.cursor.origSelection[0] = loc + loc := v.Cursor.Loc() + if !v.Cursor.HasSelection() { + v.Cursor.origSelection[0] = loc } - v.cursor.Up() - v.cursor.SelectTo(v.cursor.Loc()) + v.Cursor.Up() + v.Cursor.SelectTo(v.Cursor.Loc()) return true } // SelectDown selects down one line func (v *View) SelectDown() bool { - loc := v.cursor.Loc() - if !v.cursor.HasSelection() { - v.cursor.origSelection[0] = loc + loc := v.Cursor.Loc() + if !v.Cursor.HasSelection() { + v.Cursor.origSelection[0] = loc } - v.cursor.Down() - v.cursor.SelectTo(v.cursor.Loc()) + v.Cursor.Down() + v.Cursor.SelectTo(v.Cursor.Loc()) return true } // SelectLeft selects the character to the left of the cursor func (v *View) SelectLeft() bool { - loc := v.cursor.Loc() - count := v.buf.Len() - 1 + loc := v.Cursor.Loc() + count := v.Buf.Len() - 1 if loc > count { loc = count } - if !v.cursor.HasSelection() { - v.cursor.origSelection[0] = loc + if !v.Cursor.HasSelection() { + v.Cursor.origSelection[0] = loc } - v.cursor.Left() - v.cursor.SelectTo(v.cursor.Loc()) + v.Cursor.Left() + v.Cursor.SelectTo(v.Cursor.Loc()) return true } // SelectRight selects the character to the right of the cursor func (v *View) SelectRight() bool { - loc := v.cursor.Loc() - count := v.buf.Len() - 1 + loc := v.Cursor.Loc() + count := v.Buf.Len() - 1 if loc > count { loc = count } - if !v.cursor.HasSelection() { - v.cursor.origSelection[0] = loc + if !v.Cursor.HasSelection() { + v.Cursor.origSelection[0] = loc } - v.cursor.Right() - v.cursor.SelectTo(v.cursor.Loc()) + v.Cursor.Right() + v.Cursor.SelectTo(v.Cursor.Loc()) return true } // SelectWordRight selects the word to the right of the cursor func (v *View) SelectWordRight() bool { - loc := v.cursor.Loc() - if !v.cursor.HasSelection() { - v.cursor.origSelection[0] = loc + loc := v.Cursor.Loc() + if !v.Cursor.HasSelection() { + v.Cursor.origSelection[0] = loc } - v.cursor.WordRight() - v.cursor.SelectTo(v.cursor.Loc()) + v.Cursor.WordRight() + v.Cursor.SelectTo(v.Cursor.Loc()) return true } // SelectWordLeft selects the word to the left of the cursor func (v *View) SelectWordLeft() bool { - loc := v.cursor.Loc() - if !v.cursor.HasSelection() { - v.cursor.origSelection[0] = loc + loc := v.Cursor.Loc() + if !v.Cursor.HasSelection() { + v.Cursor.origSelection[0] = loc } - v.cursor.WordLeft() - v.cursor.SelectTo(v.cursor.Loc()) + v.Cursor.WordLeft() + v.Cursor.SelectTo(v.Cursor.Loc()) return true } // StartOfLine moves the cursor to the start of the line func (v *View) StartOfLine() bool { - v.cursor.Start() + v.Cursor.Start() return true } // EndOfLine moves the cursor to the end of the line func (v *View) EndOfLine() bool { - v.cursor.End() + v.Cursor.End() return true } // SelectToStartOfLine selects to the start of the current line func (v *View) SelectToStartOfLine() bool { - loc := v.cursor.Loc() - if !v.cursor.HasSelection() { - v.cursor.origSelection[0] = loc + loc := v.Cursor.Loc() + if !v.Cursor.HasSelection() { + v.Cursor.origSelection[0] = loc } - v.cursor.Start() - v.cursor.SelectTo(v.cursor.Loc()) + v.Cursor.Start() + v.Cursor.SelectTo(v.Cursor.Loc()) return true } // SelectToEndOfLine selects to the end of the current line func (v *View) SelectToEndOfLine() bool { - loc := v.cursor.Loc() - if !v.cursor.HasSelection() { - v.cursor.origSelection[0] = loc + loc := v.Cursor.Loc() + if !v.Cursor.HasSelection() { + v.Cursor.origSelection[0] = loc } - v.cursor.End() - v.cursor.SelectTo(v.cursor.Loc()) + v.Cursor.End() + v.Cursor.SelectTo(v.Cursor.Loc()) return true } // CursorStart moves the cursor to the start of the buffer func (v *View) CursorStart() bool { - v.cursor.x = 0 - v.cursor.y = 0 + v.Cursor.x = 0 + v.Cursor.y = 0 return true } // CursorEnd moves the cursor to the end of the buffer func (v *View) CursorEnd() bool { - v.cursor.SetLoc(v.buf.Len()) + v.Cursor.SetLoc(v.Buf.Len()) return true } // SelectToStart selects the text from the cursor to the start of the buffer func (v *View) SelectToStart() bool { - loc := v.cursor.Loc() - if !v.cursor.HasSelection() { - v.cursor.origSelection[0] = loc + loc := v.Cursor.Loc() + if !v.Cursor.HasSelection() { + v.Cursor.origSelection[0] = loc } v.CursorStart() - v.cursor.SelectTo(0) + v.Cursor.SelectTo(0) return true } // SelectToEnd selects the text from the cursor to the end of the buffer func (v *View) SelectToEnd() bool { - loc := v.cursor.Loc() - if !v.cursor.HasSelection() { - v.cursor.origSelection[0] = loc + loc := v.Cursor.Loc() + if !v.Cursor.HasSelection() { + v.Cursor.origSelection[0] = loc } v.CursorEnd() - v.cursor.SelectTo(v.buf.Len()) + v.Cursor.SelectTo(v.Buf.Len()) return true } // InsertSpace inserts a space func (v *View) InsertSpace() bool { // Insert a space - if v.cursor.HasSelection() { - v.cursor.DeleteSelection() - v.cursor.ResetSelection() + if v.Cursor.HasSelection() { + v.Cursor.DeleteSelection() + v.Cursor.ResetSelection() } - v.eh.Insert(v.cursor.Loc(), " ") - v.cursor.Right() + v.eh.Insert(v.Cursor.Loc(), " ") + v.Cursor.Right() return true } // InsertEnter inserts a newline plus possible some whitespace if autoindent is on func (v *View) InsertEnter() bool { // Insert a newline - if v.cursor.HasSelection() { - v.cursor.DeleteSelection() - v.cursor.ResetSelection() + if v.Cursor.HasSelection() { + v.Cursor.DeleteSelection() + v.Cursor.ResetSelection() } - v.eh.Insert(v.cursor.Loc(), "\n") - ws := GetLeadingWhitespace(v.buf.lines[v.cursor.y]) - v.cursor.Right() + v.eh.Insert(v.Cursor.Loc(), "\n") + ws := GetLeadingWhitespace(v.Buf.Lines[v.Cursor.y]) + v.Cursor.Right() if settings["autoindent"].(bool) { - v.eh.Insert(v.cursor.Loc(), ws) + v.eh.Insert(v.Cursor.Loc(), ws) for i := 0; i < len(ws); i++ { - v.cursor.Right() + v.Cursor.Right() } } - v.cursor.lastVisualX = v.cursor.GetVisualX() + v.Cursor.lastVisualX = v.Cursor.GetVisualX() return true } // Backspace deletes the previous character func (v *View) Backspace() bool { // Delete a character - if v.cursor.HasSelection() { - v.cursor.DeleteSelection() - v.cursor.ResetSelection() - } else if v.cursor.Loc() > 0 { + if v.Cursor.HasSelection() { + v.Cursor.DeleteSelection() + v.Cursor.ResetSelection() + } else if v.Cursor.Loc() > 0 { // We have to do something a bit hacky here because we want to // delete the line by first moving left and then deleting backwards // but the undo redo would place the cursor in the wrong place @@ -542,36 +542,36 @@ func (v *View) Backspace() bool { // If the user is using spaces instead of tabs and they are deleting // whitespace at the start of the line, we should delete as if its a // tab (tabSize number of spaces) - lineStart := v.buf.lines[v.cursor.y][:v.cursor.x] + lineStart := v.Buf.Lines[v.Cursor.y][:v.Cursor.x] tabSize := int(settings["tabsize"].(float64)) if settings["tabsToSpaces"].(bool) && IsSpaces(lineStart) && len(lineStart) != 0 && len(lineStart)%tabSize == 0 { - loc := v.cursor.Loc() - v.cursor.SetLoc(loc - tabSize) - cx, cy := v.cursor.x, v.cursor.y - v.cursor.SetLoc(loc) + loc := v.Cursor.Loc() + v.Cursor.SetLoc(loc - tabSize) + cx, cy := v.Cursor.x, v.Cursor.y + v.Cursor.SetLoc(loc) v.eh.Remove(loc-tabSize, loc) - v.cursor.x, v.cursor.y = cx, cy + v.Cursor.x, v.Cursor.y = cx, cy } else { - v.cursor.Left() - cx, cy := v.cursor.x, v.cursor.y - v.cursor.Right() - loc := v.cursor.Loc() + v.Cursor.Left() + cx, cy := v.Cursor.x, v.Cursor.y + v.Cursor.Right() + loc := v.Cursor.Loc() v.eh.Remove(loc-1, loc) - v.cursor.x, v.cursor.y = cx, cy + v.Cursor.x, v.Cursor.y = cx, cy } } - v.cursor.lastVisualX = v.cursor.GetVisualX() + v.Cursor.lastVisualX = v.Cursor.GetVisualX() return true } // Delete deletes the next character func (v *View) Delete() bool { - if v.cursor.HasSelection() { - v.cursor.DeleteSelection() - v.cursor.ResetSelection() + if v.Cursor.HasSelection() { + v.Cursor.DeleteSelection() + v.Cursor.ResetSelection() } else { - loc := v.cursor.Loc() - if loc < v.buf.Len() { + loc := v.Cursor.Loc() + if loc < v.Buf.Len() { v.eh.Remove(loc, loc+1) } } @@ -581,19 +581,19 @@ func (v *View) Delete() bool { // InsertTab inserts a tab or spaces func (v *View) InsertTab() bool { // Insert a tab - if v.cursor.HasSelection() { - v.cursor.DeleteSelection() - v.cursor.ResetSelection() + if v.Cursor.HasSelection() { + v.Cursor.DeleteSelection() + v.Cursor.ResetSelection() } if settings["tabsToSpaces"].(bool) { tabSize := int(settings["tabsize"].(float64)) - v.eh.Insert(v.cursor.Loc(), Spaces(tabSize)) + v.eh.Insert(v.Cursor.Loc(), Spaces(tabSize)) for i := 0; i < tabSize; i++ { - v.cursor.Right() + v.Cursor.Right() } } else { - v.eh.Insert(v.cursor.Loc(), "\t") - v.cursor.Right() + v.eh.Insert(v.Cursor.Loc(), "\t") + v.Cursor.Right() } return true } @@ -601,31 +601,32 @@ func (v *View) InsertTab() bool { // Save the buffer to disk func (v *View) Save() bool { // If this is an empty buffer, ask for a filename - if v.buf.path == "" { + if v.Buf.Path == "" { filename, canceled := messenger.Prompt("Filename: ") if !canceled { - v.buf.path = filename - v.buf.name = filename + v.Buf.Path = filename + v.Buf.Name = filename } else { return true } } - err := v.buf.Save() + err := v.Buf.Save() if err != nil { messenger.Error(err.Error()) } else { - messenger.Message("Saved " + v.buf.path) - switch v.buf.filetype { + messenger.Message("Saved " + v.Buf.Path) + switch v.Buf.Filetype { case "Go": v.GoSave() } } if err := L.CallByParam(lua.P{ Fn: L.GetGlobal("onSave"), - NRet: 1, + NRet: 0, Protect: true, }); err != nil { // The function isn't defined by this plugin + messenger.Error(err) return true } return true @@ -636,20 +637,20 @@ func (v *View) Save() bool { func (v *View) GoSave() { if settings["goimports"] == true { messenger.Message("Running goimports...") - err := goimports(v.buf.path) + err := goimports(v.Buf.Path) if err != nil { messenger.Error(err) } else { - messenger.Message("Saved " + v.buf.path) + messenger.Message("Saved " + v.Buf.Path) } v.ReOpen() } else if settings["gofmt"] == true { messenger.Message("Running gofmt...") - err := gofmt(v.buf.path) + err := gofmt(v.Buf.Path) if err != nil { messenger.Error(err) } else { - messenger.Message("Saved " + v.buf.path) + messenger.Message("Saved " + v.Buf.Path) } v.ReOpen() return @@ -660,10 +661,10 @@ func (v *View) GoSave() { // Find opens a prompt and searches forward for the input func (v *View) Find() bool { - if v.cursor.HasSelection() { - searchStart = v.cursor.curSelection[1] + if v.Cursor.HasSelection() { + searchStart = v.Cursor.curSelection[1] } else { - searchStart = ToCharPos(v.cursor.x, v.cursor.y, v.buf) + searchStart = ToCharPos(v.Cursor.x, v.Cursor.y, v.Buf) } BeginSearch() return true @@ -671,10 +672,10 @@ func (v *View) Find() bool { // FindNext searches forwards for the last used search term func (v *View) FindNext() bool { - if v.cursor.HasSelection() { - searchStart = v.cursor.curSelection[1] + if v.Cursor.HasSelection() { + searchStart = v.Cursor.curSelection[1] } else { - searchStart = ToCharPos(v.cursor.x, v.cursor.y, v.buf) + searchStart = ToCharPos(v.Cursor.x, v.Cursor.y, v.Buf) } messenger.Message("Find: " + lastSearch) Search(lastSearch, v, true) @@ -683,10 +684,10 @@ func (v *View) FindNext() bool { // FindPrevious searches backwards for the last used search term func (v *View) FindPrevious() bool { - if v.cursor.HasSelection() { - searchStart = v.cursor.curSelection[0] + if v.Cursor.HasSelection() { + searchStart = v.Cursor.curSelection[0] } else { - searchStart = ToCharPos(v.cursor.x, v.cursor.y, v.buf) + searchStart = ToCharPos(v.Cursor.x, v.Cursor.y, v.Buf) } messenger.Message("Find: " + lastSearch) Search(lastSearch, v, false) @@ -707,8 +708,8 @@ func (v *View) Redo() bool { // Copy the selection to the system clipboard func (v *View) Copy() bool { - if v.cursor.HasSelection() { - clipboard.WriteAll(v.cursor.GetSelection()) + if v.Cursor.HasSelection() { + clipboard.WriteAll(v.Cursor.GetSelection()) v.freshClip = true } return true @@ -716,14 +717,14 @@ func (v *View) Copy() bool { // CutLine cuts the current line to the clipboard func (v *View) CutLine() bool { - v.cursor.SelectLine() + v.Cursor.SelectLine() if v.freshClip == true { - if v.cursor.HasSelection() { + if v.Cursor.HasSelection() { if clip, err := clipboard.ReadAll(); err != nil { messenger.Error(err) } else { - clipboard.WriteAll(clip + v.cursor.GetSelection()) + clipboard.WriteAll(clip + v.Cursor.GetSelection()) } } } else if time.Since(v.lastCutTime)/time.Second > 10*time.Second || v.freshClip == false { @@ -731,17 +732,17 @@ func (v *View) CutLine() bool { } v.freshClip = true v.lastCutTime = time.Now() - v.cursor.DeleteSelection() - v.cursor.ResetSelection() + v.Cursor.DeleteSelection() + v.Cursor.ResetSelection() return true } // Cut the selection to the system clipboard func (v *View) Cut() bool { - if v.cursor.HasSelection() { - clipboard.WriteAll(v.cursor.GetSelection()) - v.cursor.DeleteSelection() - v.cursor.ResetSelection() + if v.Cursor.HasSelection() { + clipboard.WriteAll(v.Cursor.GetSelection()) + v.Cursor.DeleteSelection() + v.Cursor.ResetSelection() v.freshClip = true } return true @@ -750,24 +751,24 @@ func (v *View) Cut() bool { // Paste whatever is in the system clipboard into the buffer // Delete and paste if the user has a selection func (v *View) Paste() bool { - if v.cursor.HasSelection() { - v.cursor.DeleteSelection() - v.cursor.ResetSelection() + if v.Cursor.HasSelection() { + v.Cursor.DeleteSelection() + v.Cursor.ResetSelection() } clip, _ := clipboard.ReadAll() - v.eh.Insert(v.cursor.Loc(), clip) - v.cursor.SetLoc(v.cursor.Loc() + Count(clip)) + v.eh.Insert(v.Cursor.Loc(), clip) + v.Cursor.SetLoc(v.Cursor.Loc() + Count(clip)) v.freshClip = false return true } // SelectAll selects the entire buffer func (v *View) SelectAll() bool { - v.cursor.curSelection[1] = 0 - v.cursor.curSelection[0] = v.buf.Len() + v.Cursor.curSelection[1] = 0 + v.Cursor.curSelection[0] = v.Buf.Len() // Put the cursor at the beginning - v.cursor.x = 0 - v.cursor.y = 0 + v.Cursor.x = 0 + v.Cursor.y = 0 return true } @@ -794,57 +795,57 @@ func (v *View) OpenFile() bool { // Start moves the viewport to the start of the buffer func (v *View) Start() bool { - v.topline = 0 + v.Topline = 0 return false } // End moves the viewport to the end of the buffer func (v *View) End() bool { - if v.height > v.buf.numLines { - v.topline = 0 + if v.height > v.Buf.NumLines { + v.Topline = 0 } else { - v.topline = v.buf.numLines - v.height + v.Topline = v.Buf.NumLines - v.height } return false } // PageUp scrolls the view up a page func (v *View) PageUp() bool { - if v.topline > v.height { + if v.Topline > v.height { v.ScrollUp(v.height) } else { - v.topline = 0 + v.Topline = 0 } return false } // PageDown scrolls the view down a page func (v *View) PageDown() bool { - if v.buf.numLines-(v.topline+v.height) > v.height { + if v.Buf.NumLines-(v.Topline+v.height) > v.height { v.ScrollDown(v.height) - } else if v.buf.numLines >= v.height { - v.topline = v.buf.numLines - v.height + } else if v.Buf.NumLines >= v.height { + v.Topline = v.Buf.NumLines - v.height } return false } // HalfPageUp scrolls the view up half a page func (v *View) HalfPageUp() bool { - if v.topline > v.height/2 { + if v.Topline > v.height/2 { v.ScrollUp(v.height / 2) } else { - v.topline = 0 + v.Topline = 0 } return false } // HalfPageDown scrolls the view down half a page func (v *View) HalfPageDown() bool { - if v.buf.numLines-(v.topline+v.height) > v.height/2 { + if v.Buf.NumLines-(v.Topline+v.height) > v.height/2 { v.ScrollDown(v.height / 2) } else { - if v.buf.numLines >= v.height { - v.topline = v.buf.numLines - v.height + if v.Buf.NumLines >= v.height { + v.Topline = v.Buf.NumLines - v.height } } return false @@ -874,12 +875,12 @@ func (v *View) JumpLine() bool { return false } // Move cursor and view if possible. - if lineint < v.buf.numLines { - v.cursor.x = 0 - v.cursor.y = lineint + if lineint < v.Buf.NumLines { + v.Cursor.x = 0 + v.Cursor.y = lineint return true } - messenger.Error("Only ", v.buf.numLines, " lines to jump") + messenger.Error("Only ", v.Buf.NumLines, " lines to jump") return false } diff --git a/cmd/micro/buffer.go b/cmd/micro/buffer.go index 34ef3d1a..0a044341 100644 --- a/cmd/micro/buffer.go +++ b/cmd/micro/buffer.go @@ -15,9 +15,9 @@ type Buffer struct { r *rope.Rope // Path to the file on disk - path string + Path string // Name of the buffer on the status line - name string + Name string // This is the text stored every time the buffer is saved to check if the buffer is modified savedText [16]byte @@ -27,13 +27,13 @@ type Buffer struct { // Provide efficient and easy access to text and lines so the rope String does not // need to be constantly recalculated // These variables are updated in the update() function - lines []string - numLines int + Lines []string + NumLines int // Syntax highlighting rules rules []SyntaxRule // The buffer's filetype - filetype string + Filetype string } // NewBuffer creates a new buffer from `txt` with path and name `path` @@ -44,8 +44,8 @@ func NewBuffer(txt, path string) *Buffer { } else { b.r = rope.New(txt) } - b.path = path - b.name = path + b.Path = path + b.Name = path b.savedText = md5.Sum([]byte(txt)) b.Update() @@ -57,7 +57,7 @@ func NewBuffer(txt, path string) *Buffer { // UpdateRules updates the syntax rules and filetype for this buffer // This is called when the colorscheme changes func (b *Buffer) UpdateRules() { - b.rules, b.filetype = GetRules(b) + b.rules, b.Filetype = GetRules(b) } func (b *Buffer) String() string { @@ -70,13 +70,13 @@ func (b *Buffer) String() string { // Update fetches the string from the rope and updates the `text` and `lines` in the buffer func (b *Buffer) Update() { - b.lines = strings.Split(b.String(), "\n") - b.numLines = len(b.lines) + b.Lines = strings.Split(b.String(), "\n") + b.NumLines = len(b.Lines) } // Save saves the buffer to its default path func (b *Buffer) Save() error { - return b.SaveAs(b.path) + return b.SaveAs(b.Path) } // SaveAs saves the buffer to a specified path (filename), creating the file if it does not exist diff --git a/cmd/micro/command.go b/cmd/micro/command.go index 67fcfeaa..1e41a7b2 100644 --- a/cmd/micro/command.go +++ b/cmd/micro/command.go @@ -141,7 +141,7 @@ func HandleCommand(input string, view *View) { found := false for { - match := regex.FindStringIndex(view.buf.String()) + match := regex.FindStringIndex(view.Buf.String()) if match == nil { break } @@ -153,23 +153,23 @@ func HandleCommand(input string, view *View) { Redraw(view) choice, canceled := messenger.YesNoPrompt("Perform replacement? (y,n)") if canceled { - if view.cursor.HasSelection() { - view.cursor.SetLoc(view.cursor.curSelection[0]) - view.cursor.ResetSelection() + if view.Cursor.HasSelection() { + view.Cursor.SetLoc(view.Cursor.curSelection[0]) + view.Cursor.ResetSelection() } messenger.Reset() return } if choice { - view.cursor.DeleteSelection() + view.Cursor.DeleteSelection() view.eh.Insert(match[0], replace) - view.cursor.ResetSelection() + view.Cursor.ResetSelection() messenger.Reset() } else { - if view.cursor.HasSelection() { - searchStart = view.cursor.curSelection[1] + if view.Cursor.HasSelection() { + searchStart = view.Cursor.curSelection[1] } else { - searchStart = ToCharPos(view.cursor.x, view.cursor.y, view.buf) + searchStart = ToCharPos(view.Cursor.x, view.Cursor.y, view.Buf) } continue } diff --git a/cmd/micro/cursor.go b/cmd/micro/cursor.go index 88287ac4..e48abb7f 100644 --- a/cmd/micro/cursor.go +++ b/cmd/micro/cursor.go @@ -14,11 +14,11 @@ func FromCharPosStart(startLoc, startX, startY, loc int, buf *Buffer) (int, int) charNum := startLoc x, y := startX, startY - lineLen := Count(buf.lines[y]) + 1 + lineLen := Count(buf.Lines[y]) + 1 for charNum+lineLen <= loc { charNum += lineLen y++ - lineLen = Count(buf.lines[y]) + 1 + lineLen = Count(buf.Lines[y]) + 1 } x = loc - charNum @@ -30,7 +30,7 @@ func ToCharPos(x, y int, buf *Buffer) int { loc := 0 for i := 0; i < y; i++ { // + 1 for the newline - loc += Count(buf.lines[i]) + 1 + loc += Count(buf.Lines[i]) + 1 } loc += x return loc @@ -64,7 +64,7 @@ type Cursor struct { // and not x, y location // It's just a simple wrapper of FromCharPos func (c *Cursor) SetLoc(loc int) { - c.x, c.y = FromCharPos(loc, c.v.buf) + c.x, c.y = FromCharPos(loc, c.v.Buf) c.lastVisualX = c.GetVisualX() } @@ -72,7 +72,7 @@ func (c *Cursor) SetLoc(loc int) { // of x, y location // It's just a simple wrapper of ToCharPos func (c *Cursor) Loc() int { - return ToCharPos(c.x, c.y, c.v.buf) + return ToCharPos(c.x, c.y, c.v.Buf) } // ResetSelection resets the user's selection @@ -102,9 +102,9 @@ func (c *Cursor) DeleteSelection() { // GetSelection returns the cursor's selection func (c *Cursor) GetSelection() string { if c.curSelection[0] > c.curSelection[1] { - return c.v.buf.r.Report(c.curSelection[1]+1, c.curSelection[0]-c.curSelection[1]) + return c.v.Buf.r.Report(c.curSelection[1]+1, c.curSelection[0]-c.curSelection[1]) } - return c.v.buf.r.Report(c.curSelection[0]+1, c.curSelection[1]-c.curSelection[0]) + return c.v.Buf.r.Report(c.curSelection[0]+1, c.curSelection[1]-c.curSelection[0]) } // SelectLine selects the current line @@ -112,7 +112,7 @@ func (c *Cursor) SelectLine() { c.Start() c.curSelection[0] = c.Loc() c.End() - if c.v.buf.numLines-1 > c.y { + if c.v.Buf.NumLines-1 > c.y { c.curSelection[1] = c.Loc() + 1 } else { c.curSelection[1] = c.Loc() @@ -143,7 +143,7 @@ func (c *Cursor) AddLineToSelection() { // SelectWord selects the word the cursor is currently on func (c *Cursor) SelectWord() { - if len(c.v.buf.lines[c.y]) == 0 { + if len(c.v.Buf.Lines[c.y]) == 0 { return } @@ -161,14 +161,14 @@ func (c *Cursor) SelectWord() { backward-- } - c.curSelection[0] = ToCharPos(backward, c.y, c.v.buf) + c.curSelection[0] = ToCharPos(backward, c.y, c.v.Buf) c.origSelection[0] = c.curSelection[0] - for forward < Count(c.v.buf.lines[c.y])-1 && IsWordChar(string(c.RuneUnder(forward+1))) { + for forward < Count(c.v.Buf.Lines[c.y])-1 && IsWordChar(string(c.RuneUnder(forward+1))) { forward++ } - c.curSelection[1] = ToCharPos(forward, c.y, c.v.buf) + 1 + c.curSelection[1] = ToCharPos(forward, c.y, c.v.Buf) + 1 c.origSelection[1] = c.curSelection[1] c.SetLoc(c.curSelection[1]) } @@ -189,18 +189,18 @@ func (c *Cursor) AddWordToSelection() { backward-- } - c.curSelection[0] = ToCharPos(backward, c.y, c.v.buf) + c.curSelection[0] = ToCharPos(backward, c.y, c.v.Buf) c.curSelection[1] = c.origSelection[1] } if loc > c.origSelection[1] { forward := c.x - for forward < Count(c.v.buf.lines[c.y])-1 && IsWordChar(string(c.RuneUnder(forward+1))) { + for forward < Count(c.v.Buf.Lines[c.y])-1 && IsWordChar(string(c.RuneUnder(forward+1))) { forward++ } - c.curSelection[1] = ToCharPos(forward, c.y, c.v.buf) + 1 + c.curSelection[1] = ToCharPos(forward, c.y, c.v.Buf) + 1 c.curSelection[0] = c.origSelection[0] } @@ -222,13 +222,13 @@ func (c *Cursor) SelectTo(loc int) { func (c *Cursor) WordRight() { c.Right() for IsWhitespace(c.RuneUnder(c.x)) { - if c.x == Count(c.v.buf.lines[c.y]) { + if c.x == Count(c.v.Buf.Lines[c.y]) { return } c.Right() } for !IsWhitespace(c.RuneUnder(c.x)) { - if c.x == Count(c.v.buf.lines[c.y]) { + if c.x == Count(c.v.Buf.Lines[c.y]) { return } c.Right() @@ -255,7 +255,7 @@ func (c *Cursor) WordLeft() { // RuneUnder returns the rune under the given x position func (c *Cursor) RuneUnder(x int) rune { - line := []rune(c.v.buf.lines[c.y]) + line := []rune(c.v.Buf.Lines[c.y]) if len(line) == 0 { return '\n' } @@ -272,7 +272,7 @@ func (c *Cursor) Up() { if c.y > 0 { c.y-- - runes := []rune(c.v.buf.lines[c.y]) + runes := []rune(c.v.Buf.Lines[c.y]) c.x = c.GetCharPosInLine(c.y, c.lastVisualX) if c.x > len(runes) { c.x = len(runes) @@ -282,10 +282,10 @@ func (c *Cursor) Up() { // Down moves the cursor down one line (if possible) func (c *Cursor) Down() { - if c.y < c.v.buf.numLines-1 { + if c.y < c.v.Buf.NumLines-1 { c.y++ - runes := []rune(c.v.buf.lines[c.y]) + runes := []rune(c.v.Buf.Lines[c.y]) c.x = c.GetCharPosInLine(c.y, c.lastVisualX) if c.x > len(runes) { c.x = len(runes) @@ -309,10 +309,10 @@ func (c *Cursor) Left() { // Right moves the cursor right one cell (if possible) or to the next line if it is at the end func (c *Cursor) Right() { - if c.Loc() == c.v.buf.Len() { + if c.Loc() == c.v.Buf.Len() { return } - if c.x < Count(c.v.buf.lines[c.y]) { + if c.x < Count(c.v.Buf.Lines[c.y]) { c.x++ } else { c.Down() @@ -323,7 +323,7 @@ func (c *Cursor) Right() { // End moves the cursor to the end of the line it is on func (c *Cursor) End() { - c.x = Count(c.v.buf.lines[c.y]) + c.x = Count(c.v.Buf.Lines[c.y]) c.lastVisualX = c.GetVisualX() } @@ -338,7 +338,7 @@ func (c *Cursor) GetCharPosInLine(lineNum, visualPos int) int { // Get the tab size tabSize := int(settings["tabsize"].(float64)) // This is the visual line -- every \t replaced with the correct number of spaces - visualLine := strings.Replace(c.v.buf.lines[lineNum], "\t", "\t"+Spaces(tabSize-1), -1) + visualLine := strings.Replace(c.v.Buf.Lines[lineNum], "\t", "\t"+Spaces(tabSize-1), -1) if visualPos > Count(visualLine) { visualPos = Count(visualLine) } @@ -351,7 +351,7 @@ func (c *Cursor) GetCharPosInLine(lineNum, visualPos int) int { // GetVisualX returns the x value of the cursor in visual spaces func (c *Cursor) GetVisualX() int { - runes := []rune(c.v.buf.lines[c.y]) + runes := []rune(c.v.Buf.Lines[c.y]) tabSize := int(settings["tabsize"].(float64)) return c.x + NumOccurences(string(runes[:c.x]), '\t')*(tabSize-1) } @@ -361,23 +361,23 @@ func (c *Cursor) GetVisualX() int { func (c *Cursor) Relocate() { if c.y < 0 { c.y = 0 - } else if c.y >= c.v.buf.numLines { - c.y = c.v.buf.numLines - 1 + } else if c.y >= c.v.Buf.NumLines { + c.y = c.v.Buf.NumLines - 1 } if c.x < 0 { c.x = 0 - } else if c.x > Count(c.v.buf.lines[c.y]) { - c.x = Count(c.v.buf.lines[c.y]) + } else if c.x > Count(c.v.Buf.Lines[c.y]) { + c.x = Count(c.v.Buf.Lines[c.y]) } } // Display draws the cursor to the screen at the correct position func (c *Cursor) Display() { // Don't draw the cursor if it is out of the viewport or if it has a selection - if (c.y-c.v.topline < 0 || c.y-c.v.topline > c.v.height-1) || c.HasSelection() { + if (c.y-c.v.Topline < 0 || c.y-c.v.Topline > c.v.height-1) || c.HasSelection() { screen.HideCursor() } else { - screen.ShowCursor(c.GetVisualX()+c.v.lineNumOffset-c.v.leftCol, c.y-c.v.topline) + screen.ShowCursor(c.GetVisualX()+c.v.lineNumOffset-c.v.leftCol, c.y-c.v.Topline) } } diff --git a/cmd/micro/eventhandler.go b/cmd/micro/eventhandler.go index a19cf7e7..4904a84e 100644 --- a/cmd/micro/eventhandler.go +++ b/cmd/micro/eventhandler.go @@ -58,7 +58,7 @@ func NewEventHandler(v *View) *EventHandler { // Insert creates an insert text event and executes it func (eh *EventHandler) Insert(start int, text string) { e := &TextEvent{ - c: eh.v.cursor, + c: eh.v.Cursor, eventType: TextEventInsert, text: text, start: start, @@ -71,7 +71,7 @@ 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.v.cursor, + c: eh.v.Cursor, eventType: TextEventRemove, start: start, end: end, @@ -92,7 +92,7 @@ func (eh *EventHandler) Execute(t *TextEvent) { eh.redo = new(Stack) } eh.undo.Push(t) - ExecuteTextEvent(t, eh.v.buf) + ExecuteTextEvent(t, eh.v.Buf) } // Undo the first event in the undo stack @@ -135,12 +135,12 @@ func (eh *EventHandler) UndoOneEvent() { te := t.(*TextEvent) // Undo it // Modifies the text event - UndoTextEvent(te, eh.v.buf) + UndoTextEvent(te, eh.v.Buf) // Set the cursor in the right place teCursor := te.c - te.c = eh.v.cursor - eh.v.cursor = teCursor + te.c = eh.v.Cursor + eh.v.Cursor = teCursor // Push it to the redo stack eh.redo.Push(te) @@ -183,11 +183,11 @@ func (eh *EventHandler) RedoOneEvent() { te := t.(*TextEvent) // Modifies the text event - UndoTextEvent(te, eh.v.buf) + UndoTextEvent(te, eh.v.Buf) teCursor := te.c - te.c = eh.v.cursor - eh.v.cursor = teCursor + te.c = eh.v.Cursor + eh.v.Cursor = teCursor eh.undo.Push(te) } diff --git a/cmd/micro/highlighter.go b/cmd/micro/highlighter.go index bcf0aabd..8ec16de3 100644 --- a/cmd/micro/highlighter.go +++ b/cmd/micro/highlighter.go @@ -363,10 +363,10 @@ func LoadRulesFromFile(text, filename string) []SyntaxRule { // and returns them. It also returns the filetype of the file func GetRules(buf *Buffer) ([]SyntaxRule, string) { for r := range syntaxFiles { - if r[0] != nil && r[0].MatchString(buf.path) { + if r[0] != nil && r[0].MatchString(buf.Path) { // Check if the syntax statement matches the extension return LoadRulesFromFile(syntaxFiles[r].text, syntaxFiles[r].filename), syntaxFiles[r].filetype - } else if r[1] != nil && r[1].MatchString(buf.lines[0]) { + } else if r[1] != nil && r[1].MatchString(buf.Lines[0]) { // Check if the header statement matches the first line return LoadRulesFromFile(syntaxFiles[r].text, syntaxFiles[r].filename), syntaxFiles[r].filetype } @@ -381,16 +381,16 @@ type SyntaxMatches [][]tcell.Style // Match takes a buffer and returns the syntax matches: a 2d array specifying how it should be syntax highlighted // We match the rules from up `synLinesUp` lines and down `synLinesDown` lines func Match(v *View) SyntaxMatches { - buf := v.buf - rules := v.buf.rules + buf := v.Buf + rules := v.Buf.rules - viewStart := v.topline - viewEnd := v.topline + v.height - if viewEnd > buf.numLines { - viewEnd = buf.numLines + viewStart := v.Topline + viewEnd := v.Topline + v.height + if viewEnd > buf.NumLines { + viewEnd = buf.NumLines } - lines := buf.lines[viewStart:viewEnd] + lines := buf.Lines[viewStart:viewEnd] matches := make(SyntaxMatches, len(lines)) for i, line := range lines { @@ -398,19 +398,19 @@ func Match(v *View) SyntaxMatches { } // We don't actually check the entire buffer, just from synLinesUp to synLinesDown - totalStart := v.topline - synLinesUp - totalEnd := v.topline + v.height + synLinesDown + totalStart := v.Topline - synLinesUp + totalEnd := v.Topline + v.height + synLinesDown if totalStart < 0 { totalStart = 0 } - if totalEnd > buf.numLines { - totalEnd = buf.numLines + if totalEnd > buf.NumLines { + totalEnd = buf.NumLines } - str := strings.Join(buf.lines[totalStart:totalEnd], "\n") - startNum := ToCharPos(0, totalStart, v.buf) + str := strings.Join(buf.Lines[totalStart:totalEnd], "\n") + startNum := ToCharPos(0, totalStart, v.Buf) - toplineNum := ToCharPos(0, v.topline, v.buf) + toplineNum := ToCharPos(0, v.Topline, v.Buf) for _, rule := range rules { if rule.startend { @@ -422,7 +422,7 @@ func Match(v *View) SyntaxMatches { if i < toplineNum { continue } - colNum, lineNum := FromCharPosStart(toplineNum, 0, v.topline, i, buf) + colNum, lineNum := FromCharPosStart(toplineNum, 0, v.Topline, i, buf) if lineNum == -1 || colNum == -1 { continue } diff --git a/cmd/micro/micro.go b/cmd/micro/micro.go index d9241215..2a380aa9 100644 --- a/cmd/micro/micro.go +++ b/cmd/micro/micro.go @@ -261,7 +261,7 @@ func main() { case tcell.KeyCtrlG: if !helpOpen { helpBuffer := NewBuffer(helpTxt, "help.md") - helpBuffer.name = "Help" + helpBuffer.Name = "Help" helpOpen = true view.OpenBuffer(helpBuffer) } else { diff --git a/cmd/micro/plugin.lua b/cmd/micro/plugin.lua index c6fab31c..68407502 100644 --- a/cmd/micro/plugin.lua +++ b/cmd/micro/plugin.lua @@ -1,5 +1,26 @@ +go = {} + function onSave() - local handle = io.popen("goimports -w view.go") + if settings.GoImports then + messenger:Message("Running goimports...") + go.goimports() + elseif settings.GoFmt then + messenger:Message("Running gofmt...") + go.gofmt() + end +end + +function go.gofmt() + local handle = io.popen("gofmt -w " .. view.Buf.Path) + local result = handle:read("*a") + handle:close() + + view:ReOpen() + messenger:Message(result) +end + +function go.goimports() + local handle = io.popen("goimports -w " .. view.Buf.Path) local result = handle:read("*a") handle:close() diff --git a/cmd/micro/search.go b/cmd/micro/search.go index d457ba1b..b01f496b 100644 --- a/cmd/micro/search.go +++ b/cmd/micro/search.go @@ -53,7 +53,7 @@ func HandleSearchEvent(event tcell.Event, v *View) { } if messenger.response == "" { - v.cursor.ResetSelection() + v.Cursor.ResetSelection() // We don't end the search though return } @@ -72,7 +72,7 @@ func Search(searchStr string, v *View, down bool) { } var str string var charPos int - text := v.buf.String() + text := v.Buf.String() if down { str = text[searchStart:] charPos = searchStart @@ -90,7 +90,7 @@ func Search(searchStr string, v *View, down bool) { matches = r.FindAllStringIndex(text, -1) charPos = 0 if matches == nil { - v.cursor.ResetSelection() + v.Cursor.ResetSelection() return } @@ -107,9 +107,9 @@ func Search(searchStr string, v *View, down bool) { match = matches[0] } - v.cursor.curSelection[0] = charPos + match[0] - v.cursor.curSelection[1] = charPos + match[1] - v.cursor.x, v.cursor.y = FromCharPos(charPos+match[1]-1, v.buf) + v.Cursor.curSelection[0] = charPos + match[0] + v.Cursor.curSelection[1] = charPos + match[1] + v.Cursor.x, v.Cursor.y = FromCharPos(charPos+match[1]-1, v.Buf) if v.Relocate() { v.matches = Match(v) } diff --git a/cmd/micro/settings.go b/cmd/micro/settings.go index 5eade696..2e409f54 100644 --- a/cmd/micro/settings.go +++ b/cmd/micro/settings.go @@ -102,7 +102,7 @@ func SetOption(view *View, args []string) { if option == "colorscheme" { LoadSyntaxFiles() - view.buf.UpdateRules() + view.Buf.UpdateRules() } err := WriteSettings(filename) diff --git a/cmd/micro/statusline.go b/cmd/micro/statusline.go index 34185ba6..b9cd0af5 100644 --- a/cmd/micro/statusline.go +++ b/cmd/micro/statusline.go @@ -17,14 +17,14 @@ func (sline *Statusline) Display() { // We'll draw the line at the lowest line in the view y := sline.view.height - file := sline.view.buf.name + file := sline.view.Buf.Name // If the name is empty, use 'No name' if file == "" { file = "No name" } // If the buffer is dirty (has been modified) write a little '+' - if sline.view.buf.IsDirty() { + if sline.view.Buf.IsDirty() { file += " +" } @@ -32,13 +32,13 @@ func (sline *Statusline) Display() { // but users will be used to (1,1) (first line,first column) // We use GetVisualX() here because otherwise we get the column number in runes // so a '\t' is only 1, when it should be tabSize - columnNum := strconv.Itoa(sline.view.cursor.GetVisualX() + 1) - lineNum := strconv.Itoa(sline.view.cursor.y + 1) + columnNum := strconv.Itoa(sline.view.Cursor.GetVisualX() + 1) + lineNum := strconv.Itoa(sline.view.Cursor.y + 1) file += " (" + lineNum + "," + columnNum + ")" // Add the filetype - file += " " + sline.view.buf.filetype + file += " " + sline.view.Buf.Filetype rightText := "Ctrl-g for help " if helpOpen { diff --git a/cmd/micro/view.go b/cmd/micro/view.go index 5ff868da..576bf660 100644 --- a/cmd/micro/view.go +++ b/cmd/micro/view.go @@ -13,10 +13,10 @@ import ( // It stores information about the cursor, and the viewport // that the user sees the buffer from. type View struct { - cursor Cursor + Cursor Cursor // The topmost line, used for vertical scrolling - topline int + Topline int // The leftmost column, used for horizontal scrolling leftCol int @@ -34,10 +34,11 @@ type View struct { // The eventhandler for undo/redo eh *EventHandler + // Holds the list of gutter messages messages []GutterMessage // The buffer - buf *Buffer + Buf *Buffer // The statusline sline Statusline @@ -111,20 +112,20 @@ func (v *View) Resize(w, h int) { // ScrollUp scrolls the view up n lines (if possible) func (v *View) ScrollUp(n int) { // Try to scroll by n but if it would overflow, scroll by 1 - if v.topline-n >= 0 { - v.topline -= n - } else if v.topline > 0 { - v.topline-- + if v.Topline-n >= 0 { + v.Topline -= n + } else if v.Topline > 0 { + v.Topline-- } } // ScrollDown scrolls the view down n lines (if possible) func (v *View) ScrollDown(n int) { // Try to scroll by n but if it would overflow, scroll by 1 - if v.topline+n <= v.buf.numLines-v.height { - v.topline += n - } else if v.topline < v.buf.numLines-v.height { - v.topline++ + if v.Topline+n <= v.Buf.NumLines-v.height { + v.Topline += n + } else if v.Topline < v.Buf.NumLines-v.height { + v.Topline++ } } @@ -133,7 +134,7 @@ func (v *View) ScrollDown(n int) { // causing them to lose the unsaved changes // The message is what to print after saying "You have unsaved changes. " func (v *View) CanClose(msg string) bool { - if v.buf.IsDirty() { + if v.Buf.IsDirty() { quit, canceled := messenger.Prompt("You have unsaved changes. " + msg) if !canceled { if strings.ToLower(quit) == "yes" || strings.ToLower(quit) == "y" { @@ -152,16 +153,16 @@ func (v *View) CanClose(msg string) bool { // OpenBuffer opens a new buffer in this view. // This resets the topline, event handler and cursor. func (v *View) OpenBuffer(buf *Buffer) { - v.buf = buf - v.topline = 0 + v.Buf = buf + v.Topline = 0 v.leftCol = 0 // Put the cursor at the first spot - v.cursor = Cursor{ + v.Cursor = Cursor{ x: 0, y: 0, v: v, } - v.cursor.ResetSelection() + v.Cursor.ResetSelection() v.eh = NewEventHandler(v) v.matches = Match(v) @@ -175,17 +176,17 @@ func (v *View) OpenBuffer(buf *Buffer) { // ReOpen reloads the current buffer func (v *View) ReOpen() { if v.CanClose("Continue? (yes, no, save) ") { - file, err := ioutil.ReadFile(v.buf.path) - filename := v.buf.name + file, err := ioutil.ReadFile(v.Buf.Path) + filename := v.Buf.Name if err != nil { messenger.Error(err.Error()) return } buf := NewBuffer(string(file), filename) - v.buf = buf + v.Buf = buf v.matches = Match(v) - v.cursor.Relocate() + v.Cursor.Relocate() v.Relocate() } } @@ -194,17 +195,17 @@ func (v *View) ReOpen() { // This is useful if the user has scrolled far away, and then starts typing func (v *View) Relocate() bool { ret := false - cy := v.cursor.y - if cy < v.topline { - v.topline = cy + cy := v.Cursor.y + if cy < v.Topline { + v.Topline = cy ret = true } - if cy > v.topline+v.height-1 { - v.topline = cy - v.height + 1 + if cy > v.Topline+v.height-1 { + v.Topline = cy - v.height + 1 ret = true } - cx := v.cursor.GetVisualX() + cx := v.Cursor.GetVisualX() if cx < v.leftCol { v.leftCol = cx ret = true @@ -219,12 +220,12 @@ func (v *View) Relocate() bool { // MoveToMouseClick moves the cursor to location x, y assuming x, y were given // by a mouse click func (v *View) MoveToMouseClick(x, y int) { - if y-v.topline > v.height-1 { + if y-v.Topline > v.height-1 { v.ScrollDown(1) - y = v.height + v.topline - 1 + y = v.height + v.Topline - 1 } - if y >= v.buf.numLines { - y = v.buf.numLines - 1 + if y >= v.Buf.NumLines { + y = v.Buf.NumLines - 1 } if y < 0 { y = 0 @@ -233,13 +234,13 @@ func (v *View) MoveToMouseClick(x, y int) { x = 0 } - x = v.cursor.GetCharPosInLine(y, x) - if x > Count(v.buf.lines[y]) { - x = Count(v.buf.lines[y]) + x = v.Cursor.GetCharPosInLine(y, x) + if x > Count(v.Buf.Lines[y]) { + x = Count(v.Buf.Lines[y]) } - v.cursor.x = x - v.cursor.y = y - v.cursor.lastVisualX = v.cursor.GetVisualX() + v.Cursor.x = x + v.Cursor.y = y + v.Cursor.lastVisualX = v.Cursor.GetVisualX() } // HandleEvent handles an event passed by the main loop @@ -255,12 +256,12 @@ func (v *View) HandleEvent(event tcell.Event) { case *tcell.EventKey: if e.Key() == tcell.KeyRune { // Insert a character - if v.cursor.HasSelection() { - v.cursor.DeleteSelection() - v.cursor.ResetSelection() + if v.Cursor.HasSelection() { + v.Cursor.DeleteSelection() + v.Cursor.ResetSelection() } - v.eh.Insert(v.cursor.Loc(), string(e.Rune())) - v.cursor.Right() + v.eh.Insert(v.Cursor.Loc(), string(e.Rune())) + v.Cursor.Right() } else { for key, action := range bindings { if e.Key() == key { @@ -269,18 +270,18 @@ func (v *View) HandleEvent(event tcell.Event) { } } case *tcell.EventPaste: - if v.cursor.HasSelection() { - v.cursor.DeleteSelection() - v.cursor.ResetSelection() + if v.Cursor.HasSelection() { + v.Cursor.DeleteSelection() + v.Cursor.ResetSelection() } clip := e.Text() - v.eh.Insert(v.cursor.Loc(), clip) - v.cursor.SetLoc(v.cursor.Loc() + Count(clip)) + v.eh.Insert(v.Cursor.Loc(), clip) + v.Cursor.SetLoc(v.Cursor.Loc() + Count(clip)) v.freshClip = false case *tcell.EventMouse: x, y := e.Position() x -= v.lineNumOffset - v.leftCol - y += v.topline + y += v.Topline button := e.Buttons() @@ -297,7 +298,7 @@ func (v *View) HandleEvent(event tcell.Event) { v.tripleClick = true v.doubleClick = false - v.cursor.SelectLine() + v.Cursor.SelectLine() } else { // Double click v.lastClickTime = time.Now() @@ -305,27 +306,27 @@ func (v *View) HandleEvent(event tcell.Event) { v.doubleClick = true v.tripleClick = false - v.cursor.SelectWord() + v.Cursor.SelectWord() } } else { v.doubleClick = false v.tripleClick = false v.lastClickTime = time.Now() - loc := v.cursor.Loc() - v.cursor.origSelection[0] = loc - v.cursor.curSelection[0] = loc - v.cursor.curSelection[1] = loc + loc := v.Cursor.Loc() + v.Cursor.origSelection[0] = loc + v.Cursor.curSelection[0] = loc + v.Cursor.curSelection[1] = loc } v.mouseReleased = false } else if !v.mouseReleased { v.MoveToMouseClick(x, y) if v.tripleClick { - v.cursor.AddLineToSelection() + v.Cursor.AddLineToSelection() } else if v.doubleClick { - v.cursor.AddWordToSelection() + v.Cursor.AddWordToSelection() } else { - v.cursor.curSelection[1] = v.cursor.Loc() + v.Cursor.curSelection[1] = v.Cursor.Loc() } } case tcell.ButtonNone: @@ -341,7 +342,7 @@ func (v *View) HandleEvent(event tcell.Event) { if !v.doubleClick && !v.tripleClick { v.MoveToMouseClick(x, y) - v.cursor.curSelection[1] = v.cursor.Loc() + v.Cursor.curSelection[1] = v.Cursor.Loc() } v.mouseReleased = true } @@ -387,11 +388,11 @@ func (v *View) GutterMessage(lineN int, msg string, kind int) { // DisplayView renders the view to the screen func (v *View) DisplayView() { // The character number of the character in the top left of the screen - charNum := ToCharPos(0, v.topline, v.buf) + charNum := ToCharPos(0, v.Topline, v.Buf) // Convert the length of buffer to a string, and get the length of the string // We are going to have to offset by that amount - maxLineLength := len(strconv.Itoa(v.buf.numLines)) + maxLineLength := len(strconv.Itoa(v.Buf.NumLines)) // + 1 for the little space after the line number if settings["ruler"] == true { v.lineNumOffset = maxLineLength + 1 @@ -408,15 +409,15 @@ func (v *View) DisplayView() { var x int // If the buffer is smaller than the view height // and we went too far, break - if lineN+v.topline >= v.buf.numLines { + if lineN+v.Topline >= v.Buf.NumLines { break } - line := v.buf.lines[lineN+v.topline] + line := v.Buf.Lines[lineN+v.Topline] if len(v.messages) > 0 { msgOnLine := false for _, msg := range v.messages { - if msg.lineNum == lineN+v.topline { + if msg.lineNum == lineN+v.Topline { msgOnLine = true gutterStyle := tcell.StyleDefault switch msg.kind { @@ -437,7 +438,7 @@ func (v *View) DisplayView() { x++ screen.SetContent(x, lineN, '>', nil, gutterStyle) x++ - if v.cursor.y == lineN { + if v.Cursor.y == lineN { messenger.Message(msg.msg) messenger.gutterMessage = true } @@ -448,7 +449,7 @@ func (v *View) DisplayView() { x++ screen.SetContent(x, lineN, ' ', nil, tcell.StyleDefault) x++ - if v.cursor.y == lineN && messenger.gutterMessage { + if v.Cursor.y == lineN && messenger.gutterMessage { messenger.Reset() messenger.gutterMessage = false } @@ -463,7 +464,7 @@ func (v *View) DisplayView() { // Write the spaces before the line number if necessary var lineNum string if settings["ruler"] == true { - lineNum = strconv.Itoa(lineN + v.topline + 1) + lineNum = strconv.Itoa(lineN + v.Topline + 1) for i := 0; i < maxLineLength-len(lineNum); i++ { screen.SetContent(x, lineN, ' ', nil, lineNumStyle) x++ @@ -490,9 +491,9 @@ func (v *View) DisplayView() { highlightStyle = v.matches[lineN][colN] } - if v.cursor.HasSelection() && - (charNum >= v.cursor.curSelection[0] && charNum < v.cursor.curSelection[1] || - charNum < v.cursor.curSelection[0] && charNum >= v.cursor.curSelection[1]) { + if v.Cursor.HasSelection() && + (charNum >= v.Cursor.curSelection[0] && charNum < v.Cursor.curSelection[1] || + charNum < v.Cursor.curSelection[0] && charNum >= v.Cursor.curSelection[1]) { lineStyle = tcell.StyleDefault.Reverse(true) @@ -524,9 +525,9 @@ func (v *View) DisplayView() { // The newline may be selected, in which case we should draw the selection style // with a space to represent it - if v.cursor.HasSelection() && - (charNum >= v.cursor.curSelection[0] && charNum < v.cursor.curSelection[1] || - charNum < v.cursor.curSelection[0] && charNum >= v.cursor.curSelection[1]) { + if v.Cursor.HasSelection() && + (charNum >= v.Cursor.curSelection[0] && charNum < v.Cursor.curSelection[1] || + charNum < v.Cursor.curSelection[0] && charNum >= v.Cursor.curSelection[1]) { selectStyle := defStyle.Reverse(true) @@ -543,6 +544,6 @@ func (v *View) DisplayView() { // Display renders the view, the cursor, and statusline func (v *View) Display() { v.DisplayView() - v.cursor.Display() + v.Cursor.Display() v.sline.Display() } From 603cec9d81ddb8d92539aa1ff48e15cd7f66b81e Mon Sep 17 00:00:00 2001 From: Zachary Yedidia Date: Tue, 26 Apr 2016 16:20:26 -0400 Subject: [PATCH 03/15] Load plugins from ~/.config/micro/plugins --- cmd/micro/bindings.go | 17 +++++++++-------- cmd/micro/micro.go | 5 +---- cmd/micro/plugin.go | 26 ++++++++++++++++++++++++++ cmd/micro/plugin.lua | 29 ----------------------------- 4 files changed, 36 insertions(+), 41 deletions(-) create mode 100644 cmd/micro/plugin.go delete mode 100644 cmd/micro/plugin.lua diff --git a/cmd/micro/bindings.go b/cmd/micro/bindings.go index bacf584e..d02aab82 100644 --- a/cmd/micro/bindings.go +++ b/cmd/micro/bindings.go @@ -620,14 +620,15 @@ func (v *View) Save() bool { v.GoSave() } } - if err := L.CallByParam(lua.P{ - Fn: L.GetGlobal("onSave"), - NRet: 0, - Protect: true, - }); err != nil { - // The function isn't defined by this plugin - messenger.Error(err) - return true + for _, pl := range loadedPlugins { + if err := L.CallByParam(lua.P{ + Fn: L.GetGlobal(pl + "_onSave"), + NRet: 0, + Protect: true, + }); err != nil { + // The function isn't defined by this plugin + messenger.Error(err) + } } return true } diff --git a/cmd/micro/micro.go b/cmd/micro/micro.go index 2a380aa9..26ab46ef 100644 --- a/cmd/micro/micro.go +++ b/cmd/micro/micro.go @@ -183,10 +183,6 @@ func main() { L = lua.NewState() defer L.Close() - if err := L.DoFile("plugin.lua"); err != nil { - panic(err) - } - encoding.Register() tcell.SetEncodingFallback(tcell.EncodingFallbackASCII) @@ -199,6 +195,7 @@ func main() { LoadSyntaxFiles() // Load the help files LoadHelp() + LoadPlugins() buf := NewBuffer(string(input), filename) diff --git a/cmd/micro/plugin.go b/cmd/micro/plugin.go new file mode 100644 index 00000000..add2476a --- /dev/null +++ b/cmd/micro/plugin.go @@ -0,0 +1,26 @@ +package main + +import ( + "io/ioutil" +) + +var loadedPlugins []string + +func LoadPlugins() { + files, _ := ioutil.ReadDir(configDir + "/plugins") + for _, plugin := range files { + if plugin.IsDir() { + pluginName := plugin.Name() + files, _ := ioutil.ReadDir(configDir + "/plugins/" + pluginName) + for _, f := range files { + if f.Name() == pluginName+".lua" { + if err := L.DoFile(configDir + "/plugins/" + pluginName + "/" + f.Name()); err != nil { + TermMessage(err) + continue + } + loadedPlugins = append(loadedPlugins, pluginName) + } + } + } + } +} diff --git a/cmd/micro/plugin.lua b/cmd/micro/plugin.lua deleted file mode 100644 index 68407502..00000000 --- a/cmd/micro/plugin.lua +++ /dev/null @@ -1,29 +0,0 @@ -go = {} - -function onSave() - if settings.GoImports then - messenger:Message("Running goimports...") - go.goimports() - elseif settings.GoFmt then - messenger:Message("Running gofmt...") - go.gofmt() - end -end - -function go.gofmt() - local handle = io.popen("gofmt -w " .. view.Buf.Path) - local result = handle:read("*a") - handle:close() - - view:ReOpen() - messenger:Message(result) -end - -function go.goimports() - local handle = io.popen("goimports -w " .. view.Buf.Path) - local result = handle:read("*a") - handle:close() - - view:ReOpen() - messenger:Message(result) -end From a333f0ade2b8127e19a9898fbce90501289101d1 Mon Sep 17 00:00:00 2001 From: Zachary Yedidia Date: Wed, 27 Apr 2016 14:12:32 -0400 Subject: [PATCH 04/15] Add default plugins, and install go plugin by default --- cmd/micro/bindings.go | 55 --------------------------------------- cmd/micro/plugin.go | 19 ++++++++++++++ cmd/micro/view.go | 1 + runtime/plugins/go/go.lua | 49 ++++++++++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 55 deletions(-) create mode 100644 runtime/plugins/go/go.lua diff --git a/cmd/micro/bindings.go b/cmd/micro/bindings.go index d02aab82..dbac7dab 100644 --- a/cmd/micro/bindings.go +++ b/cmd/micro/bindings.go @@ -2,10 +2,8 @@ package main import ( "encoding/json" - "errors" "io/ioutil" "os" - "os/exec" "strconv" "strings" "time" @@ -615,10 +613,6 @@ func (v *View) Save() bool { messenger.Error(err.Error()) } else { messenger.Message("Saved " + v.Buf.Path) - switch v.Buf.Filetype { - case "Go": - v.GoSave() - } } for _, pl := range loadedPlugins { if err := L.CallByParam(lua.P{ @@ -633,33 +627,6 @@ func (v *View) Save() bool { return true } -// GoSave saves the current file (must be a go file) and runs goimports or gofmt -// depending on the user's configuration -func (v *View) GoSave() { - if settings["goimports"] == true { - messenger.Message("Running goimports...") - err := goimports(v.Buf.Path) - if err != nil { - messenger.Error(err) - } else { - messenger.Message("Saved " + v.Buf.Path) - } - v.ReOpen() - } else if settings["gofmt"] == true { - messenger.Message("Running gofmt...") - err := gofmt(v.Buf.Path) - if err != nil { - messenger.Error(err) - } else { - messenger.Message("Saved " + v.Buf.Path) - } - v.ReOpen() - return - } - - return -} - // Find opens a prompt and searches forward for the input func (v *View) Find() bool { if v.Cursor.HasSelection() { @@ -889,25 +856,3 @@ func (v *View) JumpLine() bool { func None() bool { return false } - -// gofmt runs gofmt on a file -func gofmt(file string) error { - cmd := exec.Command("gofmt", "-w", file) - cmd.Start() - err := cmd.Wait() - if err != nil { - return errors.New("Check syntax ") //TODO: highlight or display locations - } - return nil -} - -// goimports runs goimports on a file -func goimports(file string) error { - cmd := exec.Command("goimports", "-w", file) - cmd.Start() - err := cmd.Wait() - if err != nil { - return errors.New("Check syntax ") //TODO: highlight or display locations - } - return nil -} diff --git a/cmd/micro/plugin.go b/cmd/micro/plugin.go index add2476a..667dac2a 100644 --- a/cmd/micro/plugin.go +++ b/cmd/micro/plugin.go @@ -6,6 +6,11 @@ import ( var loadedPlugins []string +var preInstalledPlugins = []string{ + "go", +} + +// LoadPlugins loads the pre-installed plugins and the plugins located in ~/.config/micro/plugins func LoadPlugins() { files, _ := ioutil.ReadDir(configDir + "/plugins") for _, plugin := range files { @@ -23,4 +28,18 @@ func LoadPlugins() { } } } + + for _, pluginName := range preInstalledPlugins { + plugin := "runtime/plugins/" + pluginName + "/" + pluginName + ".lua" + data, err := Asset(plugin) + if err != nil { + TermMessage("Error loading pre-installed plugin: " + pluginName) + continue + } + if err := L.DoString(string(data)); err != nil { + TermMessage(err) + continue + } + loadedPlugins = append(loadedPlugins, pluginName) + } } diff --git a/cmd/micro/view.go b/cmd/micro/view.go index 576bf660..bf1468fd 100644 --- a/cmd/micro/view.go +++ b/cmd/micro/view.go @@ -372,6 +372,7 @@ func (v *View) HandleEvent(event tcell.Event) { // GutterMessage creates a message in this view's gutter func (v *View) GutterMessage(lineN int, msg string, kind int) { + lineN-- gutterMsg := GutterMessage{ lineNum: lineN, msg: msg, diff --git a/runtime/plugins/go/go.lua b/runtime/plugins/go/go.lua new file mode 100644 index 00000000..b08ddac4 --- /dev/null +++ b/runtime/plugins/go/go.lua @@ -0,0 +1,49 @@ +function go_onSave() + if view.Buf.Filetype == "Go" then + if settings.GoImports then + go_goimports() + elseif settings.GoFmt then + go_gofmt() + end + go_golint() + end +end + +function go_gofmt() + local handle = io.popen("gofmt -w " .. view.Buf.Path) + local result = handle:read("*a") + handle:close() + + view:ReOpen() +end + +function go_golint() + local handle = io.popen("golint " .. view.Buf.Path) + local result = go_split(handle:read("*a"), ":") + handle:close() + + local file = result[1] + local line = tonumber(result[2]) + local col = tonumber(result[3]) + local msg = result[4] + + view:ReOpen() + view:GutterMessage(line, msg, 2) +end + +function go_goimports() + local handle = io.popen("goimports -w " .. view.Buf.Path) + local result = go_split(handle:read("*a"), ":") + handle:close() + + view:ReOpen() +end + +function go_split(str, sep) + local result = {} + local regex = ("([^%s]+)"):format(sep) + for each in str:gmatch(regex) do + table.insert(result, each) + end + return result +end From d933efc53d7eede60ea6d0ba04469d910ab09599 Mon Sep 17 00:00:00 2001 From: Zachary Yedidia Date: Wed, 27 Apr 2016 14:37:58 -0400 Subject: [PATCH 05/15] Add hooks for every action that's bindable --- cmd/micro/bindings.go | 11 ----------- cmd/micro/plugin.go | 17 +++++++++++++++++ cmd/micro/view.go | 9 +++++++++ 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/cmd/micro/bindings.go b/cmd/micro/bindings.go index dbac7dab..76214780 100644 --- a/cmd/micro/bindings.go +++ b/cmd/micro/bindings.go @@ -9,7 +9,6 @@ import ( "time" "github.com/mitchellh/go-homedir" - "github.com/yuin/gopher-lua" "github.com/zyedidia/clipboard" "github.com/zyedidia/tcell" ) @@ -614,16 +613,6 @@ func (v *View) Save() bool { } else { messenger.Message("Saved " + v.Buf.Path) } - for _, pl := range loadedPlugins { - if err := L.CallByParam(lua.P{ - Fn: L.GetGlobal(pl + "_onSave"), - NRet: 0, - Protect: true, - }); err != nil { - // The function isn't defined by this plugin - messenger.Error(err) - } - } return true } diff --git a/cmd/micro/plugin.go b/cmd/micro/plugin.go index 667dac2a..242a49f7 100644 --- a/cmd/micro/plugin.go +++ b/cmd/micro/plugin.go @@ -1,6 +1,7 @@ package main import ( + "github.com/yuin/gopher-lua" "io/ioutil" ) @@ -10,6 +11,22 @@ var preInstalledPlugins = []string{ "go", } +// 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 { + luaFunc := L.GetGlobal(function) + if luaFunc.String() == "nil" { + return nil + } + err := L.CallByParam(lua.P{ + Fn: luaFunc, + NRet: 0, + Protect: true, + }) + return err +} + // LoadPlugins loads the pre-installed plugins and the plugins located in ~/.config/micro/plugins func LoadPlugins() { files, _ := ioutil.ReadDir(configDir + "/plugins") diff --git a/cmd/micro/view.go b/cmd/micro/view.go index bf1468fd..489d7bb1 100644 --- a/cmd/micro/view.go +++ b/cmd/micro/view.go @@ -2,6 +2,8 @@ package main import ( "io/ioutil" + "reflect" + "runtime" "strconv" "strings" "time" @@ -266,6 +268,13 @@ func (v *View) HandleEvent(event tcell.Event) { for key, action := range bindings { if e.Key() == key { 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]) + if err != nil { + TermMessage(err) + } + } } } } From 30c7a9c4a54eff578cf5e37f8af43898eb72cd09 Mon Sep 17 00:00:00 2001 From: Zachary Yedidia Date: Thu, 28 Apr 2016 20:43:45 -0400 Subject: [PATCH 06/15] Refine gutter messages and add go build checking to go plugin --- cmd/micro/view.go | 80 ++++++++++++++++++++++++--------------- runtime/plugins/go/go.lua | 49 +++++++++++++++--------- 2 files changed, 81 insertions(+), 48 deletions(-) diff --git a/cmd/micro/view.go b/cmd/micro/view.go index 489d7bb1..031d499f 100644 --- a/cmd/micro/view.go +++ b/cmd/micro/view.go @@ -37,7 +37,7 @@ type View struct { eh *EventHandler // Holds the list of gutter messages - messages []GutterMessage + messages map[string][]GutterMessage // The buffer Buf *Buffer @@ -92,6 +92,8 @@ func NewViewWidthHeight(buf *Buffer, w, h int) *View { v.eh = NewEventHandler(v) + v.messages = make(map[string][]GutterMessage) + v.sline = Statusline{ view: v, } @@ -165,6 +167,7 @@ func (v *View) OpenBuffer(buf *Buffer) { v: v, } v.Cursor.ResetSelection() + v.messages = make(map[string][]GutterMessage) v.eh = NewEventHandler(v) v.matches = Match(v) @@ -380,19 +383,26 @@ func (v *View) HandleEvent(event tcell.Event) { } // GutterMessage creates a message in this view's gutter -func (v *View) GutterMessage(lineN int, msg string, kind int) { +func (v *View) GutterMessage(section string, lineN int, msg string, kind int) { lineN-- gutterMsg := GutterMessage{ lineNum: lineN, msg: msg, kind: kind, } - for _, gmsg := range v.messages { - if gmsg.lineNum == lineN { - return + for _, v := range v.messages { + for _, gmsg := range v { + if gmsg.lineNum == lineN { + return + } } } - v.messages = append(v.messages, gutterMsg) + messages := v.messages[section] + v.messages[section] = append(messages, gutterMsg) +} + +func (v *View) ClearGutterMessages(section string) { + v.messages[section] = []GutterMessage{} } // DisplayView renders the view to the screen @@ -411,7 +421,13 @@ func (v *View) DisplayView() { } var highlightStyle tcell.Style - if len(v.messages) > 0 { + var hasGutterMessages bool + for _, v := range v.messages { + if len(v) > 0 { + hasGutterMessages = true + } + } + if hasGutterMessages { v.lineNumOffset += 2 } @@ -424,33 +440,35 @@ func (v *View) DisplayView() { } line := v.Buf.Lines[lineN+v.Topline] - if len(v.messages) > 0 { + if hasGutterMessages { msgOnLine := false - for _, msg := range v.messages { - if msg.lineNum == lineN+v.Topline { - msgOnLine = true - gutterStyle := tcell.StyleDefault - switch msg.kind { - case GutterInfo: - if style, ok := colorscheme["gutter-info"]; ok { - gutterStyle = style + for k := range v.messages { + for _, msg := range v.messages[k] { + if msg.lineNum == lineN+v.Topline { + msgOnLine = true + gutterStyle := tcell.StyleDefault + switch msg.kind { + case GutterInfo: + if style, ok := colorscheme["gutter-info"]; ok { + gutterStyle = style + } + case GutterWarning: + if style, ok := colorscheme["gutter-warning"]; ok { + gutterStyle = style + } + case GutterError: + if style, ok := colorscheme["gutter-error"]; ok { + gutterStyle = style + } } - case GutterWarning: - if style, ok := colorscheme["gutter-warning"]; ok { - gutterStyle = style + screen.SetContent(x, lineN, '>', nil, gutterStyle) + x++ + screen.SetContent(x, lineN, '>', nil, gutterStyle) + x++ + if v.Cursor.y == lineN { + messenger.Message(msg.msg) + messenger.gutterMessage = true } - case GutterError: - if style, ok := colorscheme["gutter-error"]; ok { - gutterStyle = style - } - } - screen.SetContent(x, lineN, '>', nil, gutterStyle) - x++ - screen.SetContent(x, lineN, '>', nil, gutterStyle) - x++ - if v.Cursor.y == lineN { - messenger.Message(msg.msg) - messenger.gutterMessage = true } } } diff --git a/runtime/plugins/go/go.lua b/runtime/plugins/go/go.lua index b08ddac4..3500e8da 100644 --- a/runtime/plugins/go/go.lua +++ b/runtime/plugins/go/go.lua @@ -5,7 +5,10 @@ function go_onSave() elseif settings.GoFmt then go_gofmt() end + go_build() go_golint() + + view:ReOpen() end end @@ -13,37 +16,49 @@ function go_gofmt() local handle = io.popen("gofmt -w " .. view.Buf.Path) local result = handle:read("*a") handle:close() - - view:ReOpen() end function go_golint() + view:ClearGutterMessages("go-lint") + local handle = io.popen("golint " .. view.Buf.Path) - local result = go_split(handle:read("*a"), ":") + local lines = go_split(handle:read("*a"), "\n") handle:close() - local file = result[1] - local line = tonumber(result[2]) - local col = tonumber(result[3]) - local msg = result[4] + for _,line in ipairs(lines) do + local result = go_split(line, ":") + local line = tonumber(result[2]) + local msg = result[4] - view:ReOpen() - view:GutterMessage(line, msg, 2) + view:GutterMessage("go-lint", line, msg, 2) + end +end + +function go_build() + view:ClearGutterMessages("go-build") + + local handle = io.popen("go build " .. view.Buf.Path .. " 2>&1") + local lines = go_split(handle:read("*a"), "\n") + handle:close() + + messenger:Message(view.Buf.Path) + for _,line in ipairs(lines) do + local line, msg = string.match(line, ".+:(%d+):(.+)") + view:GutterMessage("go-build", tonumber(line), msg, 2) + end end function go_goimports() local handle = io.popen("goimports -w " .. view.Buf.Path) local result = go_split(handle:read("*a"), ":") handle:close() - - view:ReOpen() end function go_split(str, sep) - local result = {} - local regex = ("([^%s]+)"):format(sep) - for each in str:gmatch(regex) do - table.insert(result, each) - end - return result + local result = {} + local regex = ("([^%s]+)"):format(sep) + for each in str:gmatch(regex) do + table.insert(result, each) + end + return result end From a262530217194cc1d50a596155895e9c6ba8e80d Mon Sep 17 00:00:00 2001 From: Zachary Yedidia Date: Sat, 30 Apr 2016 09:37:54 -0400 Subject: [PATCH 07/15] Fix gutter message line counting --- cmd/micro/view.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/micro/view.go b/cmd/micro/view.go index 031d499f..dc912097 100644 --- a/cmd/micro/view.go +++ b/cmd/micro/view.go @@ -465,7 +465,7 @@ func (v *View) DisplayView() { x++ screen.SetContent(x, lineN, '>', nil, gutterStyle) x++ - if v.Cursor.y == lineN { + if v.Cursor.y == lineN+v.Topline { messenger.Message(msg.msg) messenger.gutterMessage = true } @@ -477,7 +477,7 @@ func (v *View) DisplayView() { x++ screen.SetContent(x, lineN, ' ', nil, tcell.StyleDefault) x++ - if v.Cursor.y == lineN && messenger.gutterMessage { + if v.Cursor.y == lineN+v.topline && messenger.gutterMessage { messenger.Reset() messenger.gutterMessage = false } From 05e2886dcaa089e5f143af0d21c46f56359ce6e1 Mon Sep 17 00:00:00 2001 From: Zachary Yedidia Date: Sat, 30 Apr 2016 11:47:21 -0400 Subject: [PATCH 08/15] Fix build error --- cmd/micro/view.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/micro/view.go b/cmd/micro/view.go index dc912097..be7ff115 100644 --- a/cmd/micro/view.go +++ b/cmd/micro/view.go @@ -477,7 +477,7 @@ func (v *View) DisplayView() { x++ screen.SetContent(x, lineN, ' ', nil, tcell.StyleDefault) x++ - if v.Cursor.y == lineN+v.topline && messenger.gutterMessage { + if v.Cursor.y == lineN+v.Topline && messenger.gutterMessage { messenger.Reset() messenger.gutterMessage = false } From 908bcb22ae0c2f77dd591e299a2702364292c84d Mon Sep 17 00:00:00 2001 From: Zachary Yedidia Date: Sat, 30 Apr 2016 12:13:21 -0400 Subject: [PATCH 09/15] Have go plugin create its own options --- cmd/micro/micro.go | 5 ++++- cmd/micro/settings.go | 16 ++++++++++++++-- runtime/help/help.md | 13 ------------- runtime/plugins/go/go.lua | 11 +++++++++-- 4 files changed, 27 insertions(+), 18 deletions(-) diff --git a/cmd/micro/micro.go b/cmd/micro/micro.go index 26ab46ef..caccd976 100644 --- a/cmd/micro/micro.go +++ b/cmd/micro/micro.go @@ -195,7 +195,6 @@ func main() { LoadSyntaxFiles() // Load the help files LoadHelp() - LoadPlugins() buf := NewBuffer(string(input), filename) @@ -219,6 +218,10 @@ func main() { L.SetGlobal("view", luar.New(L, view)) L.SetGlobal("settings", luar.New(L, &settings)) L.SetGlobal("messenger", luar.New(L, messenger)) + L.SetGlobal("GetOption", luar.New(L, GetOption)) + L.SetGlobal("AddOption", luar.New(L, AddOption)) + + LoadPlugins() for { // Display everything diff --git a/cmd/micro/settings.go b/cmd/micro/settings.go index 2e409f54..b0818db8 100644 --- a/cmd/micro/settings.go +++ b/cmd/micro/settings.go @@ -55,6 +55,20 @@ func WriteSettings(filename string) error { return err } +// AddOption creates a new option. This is meant to be called by plugins to add options. +func AddOption(name string, value interface{}) { + settings[name] = value + err := WriteSettings(configDir + "/settings.json") + if err != nil { + TermMessage("Error writing settings.json file: " + err.Error()) + } +} + +// GetOption returns the specified option. This is meant to be called by plugins to add options. +func GetOption(name string) interface{} { + return settings[name] +} + // DefaultSettings returns the default settings for micro func DefaultSettings() map[string]interface{} { return map[string]interface{}{ @@ -64,8 +78,6 @@ func DefaultSettings() map[string]interface{} { "syntax": true, "tabsToSpaces": false, "ruler": true, - "gofmt": false, - "goimports": false, } } diff --git a/runtime/help/help.md b/runtime/help/help.md index 1832c8cc..eb550ae2 100644 --- a/runtime/help/help.md +++ b/runtime/help/help.md @@ -195,20 +195,7 @@ Here are the options that you can set: default value: `on` -* `gofmt`: Run `gofmt` whenever the file is saved (this only applies to `.go` - files) - - default value: `off` - -* `goimports`: run `goimports` whenever the file is saved (this only applies - to `.go` files) - - default value: `off` - Any option you set in the editor will be saved to the file ~/.config/micro/settings.json so, in effect, your configuration file will be created for you. If you'd like to take your configuration with you to another machine, simply copy the settings.json to the other machine. - -In the future, the `gofmt` and `goimports` will be refactored using a plugin -system. However, currently they make it easier to program micro in micro. diff --git a/runtime/plugins/go/go.lua b/runtime/plugins/go/go.lua index 3500e8da..4b2fcd8e 100644 --- a/runtime/plugins/go/go.lua +++ b/runtime/plugins/go/go.lua @@ -1,8 +1,15 @@ +if GetOption("goimports") == nil then + AddOption("goimports", false) +end +if GetOption("gofmt") == nil then + AddOption("gofmt", true) +end + function go_onSave() if view.Buf.Filetype == "Go" then - if settings.GoImports then + if GetOption("goimports") then go_goimports() - elseif settings.GoFmt then + elseif GetOption("gofmt") then go_gofmt() end go_build() From 59e71a4a0c420d9f2a521a5cab8f07829dc00062 Mon Sep 17 00:00:00 2001 From: Zachary Yedidia Date: Sat, 30 Apr 2016 14:30:42 -0400 Subject: [PATCH 10/15] Improved error parsing and use warnings for golint instead of errors --- cmd/micro/view.go | 1 + runtime/plugins/go/go.lua | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/cmd/micro/view.go b/cmd/micro/view.go index be7ff115..1a685407 100644 --- a/cmd/micro/view.go +++ b/cmd/micro/view.go @@ -401,6 +401,7 @@ func (v *View) GutterMessage(section string, lineN int, msg string, kind int) { v.messages[section] = append(messages, gutterMsg) } +// ClearGutterMessages clears all gutter messages from a given section func (v *View) ClearGutterMessages(section string) { v.messages[section] = []GutterMessage{} } diff --git a/runtime/plugins/go/go.lua b/runtime/plugins/go/go.lua index 4b2fcd8e..73608160 100644 --- a/runtime/plugins/go/go.lua +++ b/runtime/plugins/go/go.lua @@ -37,21 +37,23 @@ function go_golint() local line = tonumber(result[2]) local msg = result[4] - view:GutterMessage("go-lint", line, msg, 2) + view:GutterMessage("go-lint", line, msg, 1) end end function go_build() view:ClearGutterMessages("go-build") - local handle = io.popen("go build " .. view.Buf.Path .. " 2>&1") + local handle = io.popen("go build -o /dev/null 2>&1") local lines = go_split(handle:read("*a"), "\n") handle:close() messenger:Message(view.Buf.Path) for _,line in ipairs(lines) do - local line, msg = string.match(line, ".+:(%d+):(.+)") - view:GutterMessage("go-build", tonumber(line), msg, 2) + if string.find(line, ".+:(%d+):(.+)") then + local line, msg = string.match(line, ".+:(%d+):(.+)") + view:GutterMessage("go-build", tonumber(line), msg, 2) + end end end From 1668e9131020fdda0125e14600cd4983c3a381a3 Mon Sep 17 00:00:00 2001 From: Zachary Yedidia Date: Sat, 30 Apr 2016 16:21:08 -0400 Subject: [PATCH 11/15] Add linter plugin to easily make linters --- cmd/micro/plugin.go | 1 + runtime/plugins/go/go.lua | 37 +++---------------------------- runtime/plugins/linter/linter.lua | 32 ++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 34 deletions(-) create mode 100644 runtime/plugins/linter/linter.lua diff --git a/cmd/micro/plugin.go b/cmd/micro/plugin.go index 242a49f7..4138e3a0 100644 --- a/cmd/micro/plugin.go +++ b/cmd/micro/plugin.go @@ -9,6 +9,7 @@ var loadedPlugins []string var preInstalledPlugins = []string{ "go", + "linter", } // Call calls the lua function 'function' diff --git a/runtime/plugins/go/go.lua b/runtime/plugins/go/go.lua index 73608160..f6667304 100644 --- a/runtime/plugins/go/go.lua +++ b/runtime/plugins/go/go.lua @@ -12,8 +12,9 @@ function go_onSave() elseif GetOption("gofmt") then go_gofmt() end - go_build() - go_golint() + + linter_lint("go build", "go build -o /dev/null 2>&1", "%f:%l: %m") + linter_lint("go lint", "golint " .. view.Buf.Path, "%f:%l:%d+: %m") view:ReOpen() end @@ -25,38 +26,6 @@ function go_gofmt() handle:close() end -function go_golint() - view:ClearGutterMessages("go-lint") - - local handle = io.popen("golint " .. view.Buf.Path) - local lines = go_split(handle:read("*a"), "\n") - handle:close() - - for _,line in ipairs(lines) do - local result = go_split(line, ":") - local line = tonumber(result[2]) - local msg = result[4] - - view:GutterMessage("go-lint", line, msg, 1) - end -end - -function go_build() - view:ClearGutterMessages("go-build") - - local handle = io.popen("go build -o /dev/null 2>&1") - local lines = go_split(handle:read("*a"), "\n") - handle:close() - - messenger:Message(view.Buf.Path) - for _,line in ipairs(lines) do - if string.find(line, ".+:(%d+):(.+)") then - local line, msg = string.match(line, ".+:(%d+):(.+)") - view:GutterMessage("go-build", tonumber(line), msg, 2) - end - end -end - function go_goimports() local handle = io.popen("goimports -w " .. view.Buf.Path) local result = go_split(handle:read("*a"), ":") diff --git a/runtime/plugins/linter/linter.lua b/runtime/plugins/linter/linter.lua new file mode 100644 index 00000000..a8e2da85 --- /dev/null +++ b/runtime/plugins/linter/linter.lua @@ -0,0 +1,32 @@ +function linter_lint(linter, cmd, errorformat) + view:ClearGutterMessages(linter) + + local handle = io.popen(cmd) + local lines = linter_split(handle:read("*a"), "\n") + handle:close() + + messenger:Message(view.Buf.Path) + local regex = errorformat:gsub("%%f", "(.+)"):gsub("%%l", "(%d+)"):gsub("%%m", "(.+)") + for _,line in ipairs(lines) do + if string.find(line, regex) then + local file, line, msg = string.match(line, regex) + if linter_basename(view.Buf.Path) == linter_basename(file) then + view:GutterMessage(linter, tonumber(line), msg, 2) + end + end + end +end + +function linter_split(str, sep) + local result = {} + local regex = ("([^%s]+)"):format(sep) + for each in str:gmatch(regex) do + table.insert(result, each) + end + return result +end + +function linter_basename(file) + local name = string.gsub(file, "(.*/)(.*)", "%2") + return name +end From 3cbb23bfbeb6e20e0f70b1057de9e5542af53c75 Mon Sep 17 00:00:00 2001 From: Zachary Yedidia Date: Sat, 30 Apr 2016 18:25:45 -0400 Subject: [PATCH 12/15] Add automatic linting for Go, Python, C, D, Java, Javascript, Lua --- cmd/micro/micro.go | 2 ++ runtime/plugins/linter/linter.lua | 30 ++++++++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/cmd/micro/micro.go b/cmd/micro/micro.go index caccd976..c0e9da5b 100644 --- a/cmd/micro/micro.go +++ b/cmd/micro/micro.go @@ -5,6 +5,7 @@ import ( "fmt" "io/ioutil" "os" + "runtime" "github.com/go-errors/errors" "github.com/layeh/gopher-luar" @@ -215,6 +216,7 @@ func main() { messenger = new(Messenger) view := NewView(buf) + L.SetGlobal("OS", luar.New(L, runtime.GOOS)) L.SetGlobal("view", luar.New(L, view)) L.SetGlobal("settings", luar.New(L, &settings)) L.SetGlobal("messenger", luar.New(L, messenger)) diff --git a/runtime/plugins/linter/linter.lua b/runtime/plugins/linter/linter.lua index a8e2da85..f092603b 100644 --- a/runtime/plugins/linter/linter.lua +++ b/runtime/plugins/linter/linter.lua @@ -1,13 +1,39 @@ +function linter_onSave() + local ft = view.Buf.Filetype + local file = view.Buf.Path + local devnull = "/dev/null" + if OS == "windows" then + devnull = "NUL" + end + if ft == "Go" then + linter_lint("gobuild", "go build -o " .. devnull, "%f:%l: %m") + linter_lint("golint", "golint " .. view.Buf.Path, "%f:%l:%d+: %m") + elseif ft == "Lua" then + linter_lint("luacheck", "luacheck --no-color " .. file, "%f:%l:%d+: %m") + elseif ft == "Python" then + linter_lint("pyflakes", "pyflakes " .. file, "%f:%l: %m") + elseif ft == "C" then + linter_lint("gcc", "gcc -fsyntax-only -Wall -Wextra " .. file, "%f:%l:%d+:.+: %m") + elseif ft == "D" then + linter_lint("dmd", "dmd -color=off -o- -w -wi -c " .. file, "%f%(%l%):.+: %m") + elseif ft == "Java" then + linter_lint("javac", "javac " .. file, "%f:%l: error: %m") + elseif ft == "JavaScript" then + linter_lint("jshint", "jshint " .. file, "%f: line %l,.+, %m") + end +end + function linter_lint(linter, cmd, errorformat) view:ClearGutterMessages(linter) - local handle = io.popen(cmd) + local handle = io.popen("(" .. cmd .. ")" .. " 2>&1") local lines = linter_split(handle:read("*a"), "\n") handle:close() - messenger:Message(view.Buf.Path) local regex = errorformat:gsub("%%f", "(.+)"):gsub("%%l", "(%d+)"):gsub("%%m", "(.+)") for _,line in ipairs(lines) do + -- Trim whitespace + line = line:match("^%s*(.+)%s*$") if string.find(line, regex) then local file, line, msg = string.match(line, regex) if linter_basename(view.Buf.Path) == linter_basename(file) then From 31567c9e1500c2a67a7b83fd709ee80bd763e219 Mon Sep 17 00:00:00 2001 From: Zachary Yedidia Date: Thu, 5 May 2016 11:31:53 -0400 Subject: [PATCH 13/15] Add linter option --- cmd/micro/micro.go | 1 - cmd/micro/runtime.go | 58 +++++++++++++++++++++++++++++-- cmd/micro/view.go | 7 ++++ runtime/plugins/go/go.lua | 3 -- runtime/plugins/linter/linter.lua | 50 +++++++++++++++----------- 5 files changed, 91 insertions(+), 28 deletions(-) diff --git a/cmd/micro/micro.go b/cmd/micro/micro.go index c0e9da5b..718d220d 100644 --- a/cmd/micro/micro.go +++ b/cmd/micro/micro.go @@ -218,7 +218,6 @@ func main() { L.SetGlobal("OS", luar.New(L, runtime.GOOS)) L.SetGlobal("view", luar.New(L, view)) - L.SetGlobal("settings", luar.New(L, &settings)) L.SetGlobal("messenger", luar.New(L, messenger)) L.SetGlobal("GetOption", luar.New(L, GetOption)) L.SetGlobal("AddOption", luar.New(L, AddOption)) diff --git a/cmd/micro/runtime.go b/cmd/micro/runtime.go index bb2cc188..2c2f9a80 100644 --- a/cmd/micro/runtime.go +++ b/cmd/micro/runtime.go @@ -5,6 +5,8 @@ // runtime/colorschemes/solarized-tc.micro // runtime/colorschemes/solarized.micro // runtime/help/help.md +// runtime/plugins/go/go.lua +// runtime/plugins/linter/linter.lua // runtime/syntax/Dockerfile.micro // runtime/syntax/LICENSE // runtime/syntax/README.md @@ -237,7 +239,7 @@ func runtimeColorschemesSolarizedMicro() (*asset, error) { return a, nil } -var _runtimeHelpHelpMd = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x94\x58\x59\x73\xdb\x38\x12\x7e\x0e\x7f\x05\x4a\x99\xaa\x49\x66\x15\xb9\x76\x6b\x9f\xf4\xe6\x71\x9c\xa3\x26\x89\xbd\x8e\xbd\x3b\x99\x97\x10\x22\x41\x09\x63\x92\x60\x00\xd0\xb6\xb2\xc7\x6f\xdf\xaf\x1b\x00\x0f\xc9\xde\xc3\x2f\x16\xbb\x1b\x7d\x5f\xc0\x73\xf1\x51\x17\xd6\x88\x9d\xaa\x3b\xe1\xd5\x83\xcf\xb2\x00\xd0\x4e\x48\x00\x6c\xa3\x5b\x59\xbf\xda\x48\xa7\x4a\xc6\x0b\x55\x6a\x6f\xac\xf0\x3b\xe9\x85\xd4\x8d\x13\xde\x88\x8d\x12\x4a\xba\x3d\xfd\xec\x9d\x12\xb2\x2d\x85\x6e\x7d\xaf\xbd\xbe\x53\x4b\x91\xdd\xef\x74\x0d\x68\xed\x8c\xf0\xf2\x56\xb7\x5b\x21\xcb\x3b\xd9\x7a\xb9\x55\xc2\x54\x60\xa5\x44\xd5\xd7\xb5\x28\x64\x27\x37\xba\xc6\x31\xe5\x08\xd1\x98\x52\xd9\x76\xd0\xc2\xad\xb2\xec\xf9\xf3\xe7\xe2\xc6\xe1\x60\x96\x5d\xb4\x85\x12\x7b\xd3\x8b\x9d\xbc\x53\x62\xd3\xeb\xda\x33\xab\xa0\xe0\x52\x38\xdd\x74\xf5\x5e\x38\x2f\xad\x17\xda\x8b\xcd\x5e\xd8\xbe\x6d\x49\x7c\x96\x37\x6c\x64\x27\xfd\xee\xc4\x9b\x93\x0a\xfa\xad\xfc\x83\xcf\x05\x2c\x8b\xe7\x02\x49\x4e\x36\x99\x4e\xb5\x30\x4a\xa8\xa6\xf3\x7b\x48\xaa\x2a\x65\x57\xc9\x51\x6c\x96\xeb\xbb\xce\x58\xef\x44\x61\x95\xf4\x24\x22\x50\x39\x51\x59\xd3\x40\x87\x52\xb7\xeb\x2c\xcb\xf3\x3c\xfb\x41\xe8\xaa\x30\x6d\xa5\xb7\xe2\x1f\x82\x65\x30\x38\xfb\x02\x4b\x0a\x08\x69\x0c\xac\x21\x3b\x8a\xde\x3a\xa8\x23\xad\xe9\xe1\xcf\x7b\xed\x77\x0c\x96\xd6\x9a\x7b\x71\xab\xf6\x8e\xfd\xdc\x18\x78\x3c\x3a\xe6\x17\xb5\xdf\xe8\x16\xa2\xb6\x2e\xcb\xae\x77\x8a\x42\x61\x03\xb3\x52\x55\xb2\x87\x83\x6e\x47\x92\x25\x54\x37\xd0\x34\x71\xd6\x90\x55\x78\x6d\x5a\xf2\x33\xf1\x7b\x2e\xce\x43\xac\x47\xa6\x3f\x89\x33\x6f\xeb\x57\xdf\xd6\x42\x88\xbf\x20\xbe\x09\xa0\x08\x70\xfe\xa0\x8a\xde\x43\xa6\x28\x4c\xd3\x40\xb9\x84\xdd\x12\xf6\xda\x6c\xb7\xc8\x82\x31\xd1\x22\x72\x43\xc8\xab\x1e\x0e\x16\x0e\xc8\x7a\x38\x1c\x54\xf8\x99\xfd\x78\xac\x82\xa3\x63\x9f\x11\xf9\x04\x30\x04\xb8\xa0\x48\x51\x34\x13\xf4\x3b\x41\x6f\xda\xd2\x24\xc0\x9e\xc5\xa9\x11\x50\x11\xe0\x8d\x1e\xb5\x6d\x13\x40\xb4\x13\x35\xbb\x01\xda\x59\x75\xa7\xe1\xf5\x84\x91\xac\x89\xaa\x55\x81\x82\xa8\xeb\x04\x2e\x08\x7c\x66\xba\x7d\x02\x3c\x30\xa0\x1f\x38\xde\xc6\x6f\x51\xeb\x76\xd0\xf7\x8e\x80\x97\xd2\xf9\x01\xd2\x13\xe4\x9d\xac\x2b\x64\x2b\xea\xa5\xef\x12\xa2\x9c\x23\x4a\x73\xdf\x02\x75\x89\xdf\x37\x5d\xe0\x92\xc8\xe9\xd7\x6b\xa0\xd7\x01\x16\x29\xdf\x99\x86\xc3\x26\xc4\x5b\x13\x8a\x78\xab\x43\x79\xa0\xf4\xa2\x4e\xe7\x6d\x19\x48\x22\x8d\x82\xfd\x23\x96\xd5\xb0\x93\xe0\x12\x5c\xb4\x7d\xb3\x41\xe6\x8f\x19\x4d\x2d\x81\x33\x37\xe4\x9f\x13\x7f\x08\x49\xcc\xad\x83\xd3\xfd\xde\xd8\x92\xea\x93\xfe\xaf\x32\x62\x2b\x6a\x55\x79\x4e\x70\xab\xb7\x3b\x7f\x54\x15\x38\x49\x5f\xa1\xb8\x89\x2c\x6a\x46\x40\xd2\x62\x49\xc0\xac\x20\x4e\x7d\xc7\x04\x64\xf5\x31\x9b\xa7\x78\x0c\x45\x9e\x8c\xd8\x99\xba\x44\x82\x6a\x68\xc5\x05\x83\x48\x47\x5a\x58\x47\x6c\x1b\xd5\xfa\x54\x40\xa4\x9e\x0b\x19\x11\x7a\x1f\x08\xe0\xd8\x15\x57\x65\xe4\x3d\xa4\xb4\x68\xe4\x9e\x3a\xa8\x55\x1b\xae\xf4\xde\x51\x0c\x48\x89\xfc\x5f\x27\xab\xd0\x2a\x4e\xb8\x51\x9c\xa4\x23\xab\xdf\x9d\x69\x73\x91\x71\xdf\x12\xe7\xb2\xd8\x91\x63\xa9\x67\x07\x16\x10\x0f\x95\x83\x32\x10\xfa\x06\x96\xaa\x07\x89\xb6\x06\xbf\x50\xa4\x29\x8d\xf3\x50\x0e\xdc\xe0\x70\xc6\xb0\x07\x02\xf0\x3b\x03\x2d\x8a\x64\xc9\x0d\xb6\x30\x3d\x8c\xef\xfa\xd0\x5f\xb3\xca\xd4\xb5\xb9\x27\x25\x75\x1b\xf4\x3c\xd0\x8b\xd5\xe2\x6e\x47\xdf\xd9\xdf\x33\x4a\xa0\x05\xb1\xfe\xb2\x58\x8b\x05\x95\xe3\x62\x39\x02\x7f\x23\x20\x95\xe4\x22\xfb\x67\xe8\x85\xef\x94\x3d\x6a\x5d\x6e\x3d\xe5\xf8\xec\xd9\xe2\xa6\x5b\xc4\xdc\x8c\x7f\x8b\x33\x0e\x2a\x65\x3a\xd8\x83\x82\x7f\xad\x8f\x29\x70\x92\xf1\x57\x94\x5a\x53\x82\x88\x0f\x70\x26\xf9\x80\x34\x7c\x8c\x05\xc3\x99\xe2\x33\xe5\xc4\x54\x97\x45\xe8\x05\x49\x08\xe3\xa7\x9a\x44\xfc\xa8\x26\x53\x4c\x05\x45\x8a\x03\x19\x53\x6d\x23\xc5\x44\xd1\xd3\xda\xcf\x75\x5d\xfc\x0d\xc5\x34\xb2\x00\x7e\x6e\x2e\xe3\xe7\x0c\xe6\x62\xa2\x8c\x27\xc8\x06\x61\x13\xb2\x51\x1a\x85\x75\xa6\xce\xe2\x33\x55\xd9\x45\xf5\x01\xb5\x39\x92\xcc\x34\x5a\xa0\xd9\x1c\x12\xcc\x44\x45\x49\xd7\xe6\x51\x5e\x33\xe5\x07\xd2\x47\x78\xce\xf2\x26\x86\x93\x39\x8e\x24\xb3\xc4\x89\x24\xe0\x74\x20\x2c\x31\x9a\xeb\x75\x40\x94\x58\x4d\x35\x0a\x24\xe7\x2d\x16\x9b\x59\xf6\xbd\x6f\x9d\xb2\x3e\xc0\x43\xdc\x3b\x59\xa8\x47\x48\x02\x9c\x49\x7e\x96\xc5\xad\x9b\x92\x4d\x20\x73\x82\x3f\xa5\xdc\x39\x20\xb8\x96\x9b\x79\x21\x45\x21\x04\x1f\x6c\xb9\x98\x69\x41\x63\xf6\x0d\x8a\x7c\x62\xeb\x0c\x4f\x73\x79\xc4\xbd\x99\xe1\x68\x86\x8e\xb8\x4f\x47\xb8\x4f\x18\xba\x23\xfe\xf2\x08\x7f\x19\xc7\xef\x48\xf3\xdb\x8c\x26\x76\x97\x88\xfb\x32\xc3\x71\x93\x19\x70\x67\xf3\xd2\xc7\xa8\x1e\x71\xbf\x1e\xb4\x85\x89\x4a\xbf\x1c\xa2\xe6\xe9\xf5\xd7\x19\x9a\x47\xf9\x88\x3c\x9d\xbb\x89\x53\xe2\xb4\xae\x03\x01\x0d\xe4\x79\xaf\x99\x24\x14\xa5\xcd\x3c\x4a\x43\x22\x5d\x6e\x0f\x5a\xe1\x22\x2c\x01\x09\xfb\xba\x3d\xc6\x8e\xdd\x87\x4b\x62\xa6\x16\xed\x14\x53\x0e\x5c\x11\x8f\x52\xcc\xb9\x5c\xcd\x68\xc2\x4a\x70\xd5\xd7\x29\x99\x5f\xc3\x5a\x3f\x35\x30\x41\xd0\xf5\x43\xdb\xe7\x25\xf6\xd2\x38\xa7\x37\x98\x99\x71\x0f\x9c\x2c\x12\x2a\x2d\x98\x6d\xba\x85\x44\x1a\xda\x1d\xb0\x96\x39\x9e\x9c\x61\x86\x29\x8c\x21\x9e\x53\x8a\xb1\x3c\xf3\x03\xf1\x6a\x3e\x5e\xba\x43\x79\xe1\x6a\xb3\x1f\x97\x97\x15\x2d\x9d\xf9\x37\xac\xbb\xf9\x9a\xb7\x5e\x17\xf6\xf6\x15\x81\x1d\x52\x1d\x60\xca\x78\x97\x36\x0b\x4b\xab\xc0\xb0\x41\x80\xc8\xaa\xae\x46\xbd\x89\x85\x53\xd2\x16\xbb\x85\x58\xdc\xc9\xba\x57\x0b\x51\xd5\x72\xeb\x70\xfc\x7a\x87\xd9\x7d\xaf\xb1\x53\x24\xd2\x3c\x90\xe6\x61\xdb\xc8\x99\x3e\x5f\x09\x9a\x9a\xb4\x43\xe4\xe1\x24\x5b\x61\x3a\x9a\xf3\xb2\x5e\x11\xf2\x94\x86\x34\x98\x75\x06\x37\xb0\x25\x69\x04\x0a\x7c\x9b\x16\x77\x1a\x83\xf5\x8c\x0e\xae\x45\x5e\xe4\x4b\xda\x4d\xb0\x39\xa8\x56\xc2\x7c\x07\xd0\x4e\x15\xb7\x39\xdf\xba\x58\x4e\x40\x4b\x77\xeb\x70\x65\x21\x87\xfc\x58\x62\xb7\xba\x55\xb4\x1c\x74\xca\x56\xc6\x36\x6c\x71\x54\x99\x17\x20\x45\xbb\x88\xd7\x0d\xee\x67\xe0\xf0\xc9\x78\x15\xdc\x39\x98\xd3\xf4\xce\xd3\xb6\x23\x05\x4c\xd2\x58\xef\xd4\x56\x3d\xac\x84\x78\x5f\xb1\x76\x71\xfd\x92\x76\xdb\x13\x3f\x47\x5c\x4a\x03\xed\x5a\xe3\xc3\x45\x4f\xb6\xb8\xd3\x51\xf7\x72\xb4\x7e\x68\x1f\x56\x14\xda\xa1\x4c\xa3\xc3\x86\xf2\xad\x87\x5c\x17\x5c\xef\x94\x8f\x0e\x12\xc1\x87\x6b\x6c\x66\x3e\x84\x2a\xc2\x61\x0e\xa3\x56\xe2\xb2\xc6\x35\x16\x1b\xa1\x0a\xa9\x41\xfb\x3f\x3e\x78\x8d\x42\x36\x59\x52\x46\xc2\x05\xb0\x00\x7a\x86\xd3\x6e\xc8\x14\xb0\x8d\xd1\xc6\x65\xc6\xed\x5e\xc5\x7c\x82\x40\x00\x82\xc0\x2d\xee\xc3\xed\xfc\x9a\x93\x76\xa8\x0d\x9a\xf2\x96\xaf\x7a\x2b\x0e\x30\xc9\x8a\x24\x3f\x22\x7a\xbd\xa7\xf5\x8b\x33\x04\xce\x2b\xb5\x83\xcb\xf7\x8a\x4f\x93\xdb\x78\xf1\xbe\xdf\x29\x72\x08\xd6\xaf\x56\x43\x86\x4b\xd7\xdd\x78\x3b\xbc\x08\xfa\xa6\x7b\xab\x43\xfd\x80\x66\xdc\x63\x29\xd5\xa9\xa2\x68\xdf\xec\xad\x64\xa3\xd9\xc3\xee\x00\x58\x6a\x0b\x9f\x18\xbb\x1f\xee\xc0\x38\x19\x0c\xcc\x7f\xf8\xf5\xf5\xdb\xaf\x67\x17\x9f\xde\xbc\x7f\xfb\xf5\xdd\xc5\xc7\xf3\x93\x78\x8b\x96\xb1\x38\x9e\x60\x24\x4e\x1d\xa5\x54\x46\x34\xe0\x80\x00\xab\x62\x49\x59\x77\xc4\x30\xa7\x64\xa6\x64\x80\xbb\x97\x47\x1b\x32\x63\x7b\x7a\xab\x80\xc0\x6c\x94\x38\xd3\x79\x56\xfe\x29\x8a\xb3\xa2\x07\xef\x35\x87\xb2\x30\xb5\xb1\x0e\x85\xd1\x50\xe2\xd4\x46\x96\xc9\x8e\x01\x1e\x1c\xc9\x91\xa0\x98\xfd\xf0\x22\x48\x7c\xad\xed\xcb\x93\x09\x99\x3b\xc9\x83\xa8\x7c\x15\x2e\xfd\xd9\xb3\x74\x27\xe7\xe4\x43\x49\xc6\xef\x3c\x7b\x36\xd6\xcd\xf4\xee\x3e\xe5\x26\x5e\x44\xe8\x52\x38\x53\x4b\xab\xbf\xab\x92\xef\x3c\xe3\xe7\x2b\x5f\xbc\xe4\x25\x9b\x4c\x25\x8f\xd5\xa6\x90\x3e\x68\x3a\xe8\xb8\x44\x3a\x15\x32\xde\xd0\xf6\x4c\xaa\x70\x7d\x2b\x4b\x35\x64\x66\x78\x2a\xc1\x8a\x2f\xed\x9e\xab\x9a\xf3\x73\xea\x01\x72\xd9\x46\xc5\x1b\x0f\x0e\xf2\x9b\x07\x25\x16\xbf\xec\xe8\x3a\x94\xaa\x8f\x59\x2d\x0e\x6f\x35\x33\x2f\x4d\x93\x22\x24\x17\xaa\x00\x0c\xd0\xc3\x93\x1f\xe2\x83\x85\x55\x8a\xd9\x4d\x8f\xaf\x83\x82\x3f\x25\xda\x75\x68\x86\xda\x3d\xe5\xc8\x55\xa4\x1f\xbc\x36\x3f\x31\x80\x67\xf6\xbe\xe0\x0c\x8b\x26\xb9\x02\x8a\xb4\x6e\x67\xfc\xcb\xd0\x9e\xf1\x47\x03\x0b\x10\xba\x35\x71\xcf\x7a\x84\x15\x2e\xed\x18\x7e\x08\x33\xd8\x20\xed\xec\xf0\xca\x95\x1e\xd1\xb4\x3f\xd2\x0d\x11\xfd\x5f\xd4\xab\xe8\x62\x6b\xfb\x18\xa3\xa5\xf8\x9d\x5a\x6e\xd4\xac\x91\xe8\xdf\xae\xb7\xea\x40\xe8\xf0\x80\x35\x1e\x44\x48\xc1\x49\xc5\xfb\xa8\x0e\x57\xe4\x21\x29\x23\xbf\x8f\xef\xcf\xae\x2e\xbe\x5e\x5f\xdd\x9c\x9f\x5d\x7c\xb8\xb8\xc2\x30\xb9\xd3\xd6\xb4\x3c\x0b\xee\xa0\x1b\x8d\x16\xd2\x96\xda\x30\x0c\xfb\x63\x62\xca\x97\x6e\xe2\x1b\x27\x29\x57\x9b\x97\x1b\x07\x6b\xa6\x2d\x1a\x20\x41\x30\x3a\x9c\x0a\xe8\x91\xd2\xf9\x73\x1e\x9a\xfd\xbe\xf5\xf2\x01\xe7\x7d\x6f\x51\xd3\xe1\x13\x0d\x92\x9e\xf5\x4c\x55\x3d\x72\x90\xd9\x45\xd1\x58\xe0\x79\xae\xe0\x3c\x05\x60\x18\x32\xd8\xe0\x64\x78\x18\x00\xd1\x63\x3c\xaa\x2a\x30\x91\xbd\xc7\xd4\x2d\x61\x3b\x58\x70\x37\x1e\x9e\x03\x25\x86\xc9\x7d\x68\xd3\xe9\x39\xc4\xc9\x86\xa2\x4f\xe4\xa1\x1d\xc6\x1e\x49\x9e\x4d\x6f\x4c\xe1\xa5\x85\x7d\xfd\x94\xe6\x96\x36\x2c\xc8\x8b\x33\xe1\xe0\x0d\xe6\x3f\x9d\xdc\x9a\xaa\x21\x4d\xe9\xf1\x2d\x7e\xb0\xd6\xea\x4e\xd9\xa1\x74\x39\x78\xc8\xe1\x52\xbc\xe0\xcc\xe3\x3d\x42\x76\x5d\x4d\x6f\xb4\x14\x94\xd5\x16\x5d\x97\xe4\x70\xa1\xbf\x7c\x42\x64\x72\xd1\xd6\xe8\x86\x13\x2d\x8c\xc5\x29\xe0\xff\x94\x4d\x72\x06\xf9\xff\x5d\xf6\x29\xd6\x86\x38\xef\xa9\xcb\x53\x3e\xc6\x02\x8e\xab\x64\x9a\xad\x41\x60\x7c\x5f\x62\x2d\xb2\xc3\x86\x85\xc3\x7e\x78\xee\x40\x11\x2e\x89\x95\xc2\xba\x57\x84\x6d\xe4\x70\x8a\x32\x97\xc4\x3f\xe3\x9c\xa0\x2e\x09\xa1\x20\x5e\xd1\xea\x33\x5f\xae\x3c\x15\xe9\x23\x7c\xb8\xf1\x91\xf6\xfc\xbe\x63\x68\xb7\xcb\x1a\x2c\x5c\xfc\xde\x15\x9f\xad\x0b\x5c\x63\x42\x7a\xcd\x94\x8c\xf6\xf0\x19\x11\xcf\xa0\xea\xde\xb7\xf1\xf5\x1d\x05\xa3\x96\x61\x84\xc7\x4c\xe0\xe7\xa0\x69\x74\xa2\xfe\x16\xee\x2d\xc2\xc8\x0b\x9d\x41\x8a\xae\xee\xb7\x34\xfe\xdc\x1e\xa5\xd2\xac\xc4\x3b\x6c\xdd\x88\xe3\x32\xed\xc2\xf5\x3e\x4c\x17\x6e\x3e\x9a\x96\x44\xa7\x15\xbf\xe1\x75\xd6\x6c\xad\x6c\xe2\x8c\x01\x8f\xd8\x0e\xfe\x1d\x00\x00\xff\xff\xdd\xaf\xa3\xc8\x97\x18\x00\x00") +var _runtimeHelpHelpMd = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x8c\x58\x4b\x73\xdb\x38\x12\x3e\x87\xbf\x02\xa5\xa4\x6a\x92\x59\x45\xae\xdd\xda\x93\x6e\x1e\xc7\x79\xd4\x24\xb1\xd7\xb1\x77\x27\x73\x09\x21\x12\x94\x30\x26\x09\x06\x00\x6d\x2b\xfb\xf8\xed\xfb\x75\x03\xe0\x43\xb2\xab\xc6\x17\x8b\xdd\x8d\x7e\xa1\x9f\x78\x2e\x3e\xe9\xc2\x1a\xb1\x53\x75\x27\xbc\x7a\xf0\x59\x16\x00\xda\x09\x09\x80\x6d\x74\x2b\xeb\xd7\x1b\xe9\x54\xc9\x78\xa1\x4a\xed\x8d\x15\x7e\x27\xbd\x90\xba\x71\xc2\x1b\xb1\x51\x42\x49\xb7\xa7\x9f\xbd\x53\x42\xb6\xa5\xd0\xad\xef\xb5\xd7\x77\x6a\x29\xb2\xfb\x9d\xae\x01\xad\x9d\x11\x5e\xde\xea\x76\x2b\x64\x79\x27\x5b\x2f\xb7\x4a\x98\x0a\xac\x94\xa8\xfa\xba\x16\x85\xec\xe4\x46\xd7\x38\xa6\x1c\x21\x1a\x53\x2a\xdb\x0e\x5a\xb8\x55\x96\x3d\x7f\xfe\x5c\xdc\x38\x1c\xcc\xb2\x8b\xb6\x50\x62\x6f\x7a\xb1\x93\x77\x4a\x6c\x7a\x5d\x7b\x66\x15\x14\x5c\x0a\xa7\x9b\xae\xde\x0b\xe7\xa5\xf5\x42\x7b\xb1\xd9\x0b\xdb\xb7\x2d\x89\xcf\xf2\x86\x8d\xec\xa4\xdf\x9d\x78\x73\x52\x41\xbf\x95\x7f\xf0\xb9\x80\x65\xf1\x5c\x20\xc9\xc9\x26\xd3\xa9\x16\x46\x09\xd5\x74\x7e\x0f\x49\x55\xa5\xec\x2a\x39\x8a\xcd\x72\x7d\xd7\x19\xeb\x9d\x28\xac\x92\x9e\x44\x04\x2a\x27\x2a\x6b\x1a\xe8\x50\xea\x76\x9d\x65\x79\x9e\x67\x2f\x84\xae\x0a\xd3\x56\x7a\x2b\xfe\x23\x58\x06\x83\xb3\xaf\xb0\xa4\x80\x90\xc6\xc0\x1a\xb2\xa3\xe8\xad\x83\x3a\xd2\x9a\x1e\xfe\xbc\xd7\x7e\xc7\x60\x69\xad\xb9\x17\xb7\x6a\xef\xd8\xcf\x8d\x81\xc7\xa3\x63\x7e\x55\xfb\x8d\x6e\x21\x6a\xeb\xb2\xec\x7a\xa7\xe8\x2a\x6c\x60\x56\xaa\x4a\xf6\x70\xd0\xed\x48\xb2\x84\xea\x06\x9a\x26\xce\x1a\xb2\x0a\xaf\x4d\x4b\x7e\x26\x7e\xcf\xc5\x79\xb8\xeb\x91\xe9\xcf\xe2\xcc\xdb\xfa\xf5\xf7\xb5\x10\xe2\x1f\xb8\xdf\x04\x50\x04\x38\x7f\x50\x45\xef\x21\x53\x14\xa6\x69\xa0\x5c\xc2\x6e\x09\x7b\x6d\xb6\x5b\x44\xc1\x18\x68\x11\xb9\x21\xe4\x55\x0f\x07\x0b\x07\x64\x3d\x1c\x0e\x2a\xfc\xc2\x7e\x3c\x56\xc1\xd1\xb1\x2f\xb8\xf9\x04\x30\x04\xb8\xa0\x9b\xa2\xdb\x4c\xd0\x1f\x04\xbd\x69\x4b\x93\x00\x7b\x16\xa7\x46\x40\x45\x80\xb7\x7a\xd4\xb6\x4d\x00\xd1\x4e\xd4\xec\x06\x68\x67\xd5\x9d\x86\xd7\x13\x46\xb2\x26\xaa\x56\x05\x12\xa2\xae\x13\xb8\x20\xf0\x99\xe9\xf6\x09\xf0\xc0\x80\x7e\xe0\x78\x1b\xbf\x45\xad\xdb\x41\xdf\x3b\x02\x5e\x4a\xe7\x07\x48\x4f\x90\xf7\xb2\xae\x10\xad\xc8\x97\xbe\x4b\x88\x72\x8e\x28\xcd\x7d\x0b\xd4\x25\x7e\xdf\x74\x81\x4b\x22\xa7\x5f\x6f\x80\x5e\x07\x58\xa4\x7c\x6f\x1a\xbe\x36\x21\xde\x99\x90\xc4\x5b\x1d\xd2\x03\xa9\x17\x75\x3a\x6f\xcb\x40\x12\x69\x14\xec\x1f\xb1\xac\x86\x9d\x5c\x2e\xc1\x45\xdb\x37\x1b\x44\xfe\x18\xd1\x54\x12\x38\x72\x43\xfc\x39\xf1\x97\x10\xc4\x5c\x3a\x38\xdc\xef\x8d\x2d\x29\x3f\xe9\xff\x2a\x23\xb6\xa2\x56\x95\xe7\x00\xb7\x7a\xbb\xf3\x47\x59\x81\x93\xf4\x15\x92\x9b\xc8\xa2\x66\x04\x24\x2d\x96\x04\xcc\x0a\xe2\xd4\x77\x4c\x40\x56\x1f\xb3\x79\x8a\xc7\x90\xe4\xc9\x88\x9d\xa9\x4b\x04\xa8\x86\x56\x9c\x30\xb8\xe9\x48\x0b\xeb\x88\x6d\xa3\x5a\x9f\x12\x88\xd4\x73\x21\x22\x42\xed\x03\x01\x1c\xbb\xe2\xac\x8c\xbc\x87\x90\x16\x8d\xdc\x53\x05\xb5\x6a\xc3\x99\xde\x3b\xba\x03\x52\x22\xff\xdf\xc9\x2a\x94\x8a\x13\x2e\x14\x27\xe9\xc8\xea\x0f\x67\xda\x5c\x64\x5c\xb7\xc4\xb9\x2c\x76\xe4\x58\xaa\xd9\x81\x05\xc4\x43\xe5\xa0\x0c\x84\xbe\x85\xa5\xea\x41\xa2\xac\xc1\x2f\x74\xd3\x14\xc6\x79\x48\x07\x2e\x70\x38\x63\xd8\x03\x01\xf8\x83\x81\x16\x49\xb2\xe4\x02\x5b\x98\x1e\xc6\x77\x7d\xa8\xaf\x59\x65\xea\xda\xdc\x93\x92\xba\x0d\x7a\x1e\xe8\xc5\x6a\x71\xb5\xa3\xef\xec\xdf\x19\x05\xd0\x82\x58\x7f\x5d\xac\xc5\x82\xd2\x71\xb1\x1c\x81\xbf\x13\x90\x52\x72\x91\xfd\x37\xd4\xc2\xf7\xca\x1e\x95\x2e\xb7\x9e\x72\x7c\xf6\x6c\x71\xd3\x2d\x62\x6c\xc6\xbf\xc5\x19\x5f\x2a\x45\x3a\xd8\x83\x82\x7f\xad\x8f\x29\x70\x92\xf1\x57\x14\x5a\x53\x82\x88\x0f\x70\x26\xf9\x88\x30\x7c\x8c\x05\xc3\x99\xe2\x0b\xc5\xc4\x54\x97\x45\xa8\x05\x49\x08\xe3\xa7\x9a\x44\xfc\xa8\x26\x53\x4c\x05\x45\x8a\x03\x19\x53\x6d\x23\xc5\x44\xd1\xd3\xda\xcf\x75\x5d\xfc\x0b\xc9\x34\xb2\x00\x7e\x6e\x2e\xe3\xe7\x0c\xe6\x62\xa2\x8c\x27\xc8\x06\x61\x13\xb2\x51\x1a\x5d\xeb\x4c\x9d\xc5\x17\xca\xb2\x8b\xea\x23\x72\x73\x24\x99\x69\xb4\x40\xb1\x39\x24\x98\x89\x8a\x92\xae\xcd\xa3\xbc\x66\xca\x0f\xa4\x8f\xf0\x9c\xc5\x4d\xbc\x4e\xe6\x38\x92\xcc\x02\x27\x92\x80\xd3\x81\xb0\xc4\x68\xae\xd7\x01\x51\x62\x35\xd5\x28\x90\x9c\xb7\x18\x6c\x66\xd1\xf7\xa1\x75\xca\xfa\x00\x0f\xf7\xde\xc9\x42\x3d\x42\x12\xe0\x4c\xf2\x8b\x2c\x6e\xdd\x94\x6c\x02\x99\x13\xfc\x2d\xc5\xce\x01\xc1\xb5\xdc\xcc\x13\x29\x0a\x21\xf8\x60\xcb\xc5\x4c\x0b\x6a\xb3\x6f\x91\xe4\x13\x5b\x67\x78\xea\xcb\x23\xee\xed\x0c\x47\x3d\x74\xc4\x7d\x3e\xc2\x7d\x46\xd3\x1d\xf1\x97\x47\xf8\xcb\xd8\x7e\x47\x9a\xdf\x67\x34\xb1\xba\x44\xdc\xd7\x19\x8e\x8b\xcc\x80\x3b\x9b\xa7\x3e\x5a\xf5\x88\xfb\xed\xa0\x2c\x4c\x54\xfa\xf5\x10\x35\x0f\xaf\x7f\xce\xd0\xdc\xca\x47\xe4\xe9\xdc\x4d\x1c\x12\xa7\x75\x1d\x08\xa8\x21\xcf\x6b\xcd\x24\xa0\x28\x6c\xe6\xb7\x34\x04\xd2\xe5\xf6\xa0\x14\x2e\xc2\x10\x90\xb0\x6f\xda\x63\xec\x58\x7d\x38\x25\x66\x6a\xd1\x4c\x31\xe5\xc0\x19\xf1\x28\xc5\x9c\xcb\xd5\x8c\x26\x8c\x04\x57\x7d\x9d\x82\xf9\x0d\xac\xf5\x53\x03\x13\x04\x55\x3f\x94\x7d\x1e\x62\x2f\x8d\x73\x7a\x83\x9e\x19\xe7\xc0\xc9\x20\xa1\xd2\x80\xd9\xa6\x2d\x24\xd2\xd0\xec\x80\xb1\xcc\x71\xe7\x0c\x3d\x4c\xa1\x0d\x71\x9f\x52\x8c\xe5\x9e\x1f\x88\x57\xf3\xf6\xd2\x1d\xca\x0b\xab\xcd\x7e\x1c\x5e\x56\x34\x74\xe6\xdf\x31\xee\xe6\x6b\x9e\x7a\x5d\x98\xdb\x57\x04\x76\x08\x75\x80\x29\xe2\x5d\x9a\x2c\x2c\x8d\x02\xc3\x04\x01\x22\xab\xba\x1a\xf9\x26\x16\x4e\x49\x5b\xec\x16\x62\x71\x27\xeb\x5e\x2d\x44\x55\xcb\xad\xc3\xf1\xeb\x1d\x7a\xf7\xbd\xc6\x4c\x91\x48\xf3\x40\x9a\x87\x69\x23\x67\xfa\x7c\x25\xa8\x6b\xd2\x0c\x91\x87\x93\x6c\x85\xe9\xa8\xcf\xcb\x7a\x45\xc8\x53\x6a\xd2\x60\xd6\x19\x6c\x60\x4b\xd2\x08\x14\xf8\x36\x2d\x76\x1a\x83\xf1\x8c\x0e\xae\x45\x5e\xe4\x4b\x9a\x4d\x30\x39\xa8\x56\xc2\x7c\x07\xd0\x4e\x15\xb7\x39\x6f\x5d\x2c\x27\xa0\xa5\xbb\x75\x58\x59\xc8\x21\x3f\x95\x98\xad\x6e\x15\x0d\x07\x9d\xb2\x95\xb1\x0d\x5b\x1c\x55\xe6\x01\x48\xd1\x2c\xe2\x75\x83\xfd\x0c\x1c\x3e\x1b\xaf\x82\x3b\x07\x73\x9a\xde\x79\x9a\x76\xa4\x80\x49\x1a\xe3\x9d\xda\xaa\x87\x95\x10\x1f\x2a\xd6\x2e\x8e\x5f\xd2\x6e\x7b\xe2\xe7\x88\x4b\x69\xa0\x5d\x6b\x7c\x58\xf4\x64\x8b\x9d\x8e\xaa\x97\xa3\xf1\x43\xfb\x30\xa2\xd0\x0c\x65\x1a\x1d\x26\x94\xef\x3d\xe4\xba\xe0\x7a\xa7\x7c\x74\x90\x08\x3e\x5c\x63\x32\xf3\xe1\xaa\x22\x1c\xe6\x30\x6a\x25\x2e\x6b\xac\xb1\x98\x08\x55\x08\x0d\x9a\xff\xf1\xc1\x63\x14\xa2\xc9\x92\x32\x12\x2e\x80\x05\xd0\x33\x9c\x76\x43\xa4\x80\x6d\xbc\x6d\x2c\x33\x6e\xf7\x3a\xc6\x13\x04\x02\x10\x04\x6e\xb1\x0f\xb7\xf3\x35\x27\xcd\x50\x1b\x14\xe5\x2d\xaf\x7a\x2b\xbe\x60\x92\x15\x49\x7e\xc2\xed\xf5\x9e\xc6\x2f\x8e\x10\x38\xaf\xd4\x0e\x2e\xdf\x2b\x3e\x4d\x6e\xe3\xc1\xfb\x7e\xa7\xc8\x21\x18\xbf\x5a\x0d\x19\x2e\xad\xbb\x71\x3b\xbc\x08\xfa\xa6\xbd\xd5\x21\x7f\x40\x33\xce\xb1\x14\xea\x94\x51\x34\x6f\xf6\x56\xb2\xd1\xec\x61\x77\x00\x2c\xb5\x85\x4f\x8c\xdd\x0f\x3b\x30\x4e\x06\x03\xf3\x17\xbf\xbd\x79\xf7\xed\xec\xe2\xf3\xdb\x0f\xef\xbe\xbd\xbf\xf8\x74\x7e\x12\xb7\x68\x19\x93\xe3\x09\x46\xe2\xd4\x51\x48\x65\x44\x03\x0e\xb8\x60\x55\x2c\x29\xea\x8e\x18\xe6\x14\xcc\x14\x0c\x70\xf7\xf2\x68\x42\x66\x6c\x4f\x6f\x15\x10\x98\x8d\x12\x67\x3a\xcf\xd2\x3f\xdd\xe2\x2c\xe9\xc1\x7b\xcd\x57\x59\x98\xda\x58\x87\xc4\x68\x28\x70\x6a\x23\xcb\x64\xc7\x00\x0f\x8e\xe4\x9b\xa0\x3b\x7b\xf1\x32\x48\x7c\xa3\xed\xab\x93\x09\x99\x3b\xc9\x83\xa8\x7c\x15\x96\xfe\xec\x59\xda\xc9\x39\xf8\x90\x92\xf1\x3b\xcf\x9e\x8d\x79\x33\xdd\xdd\xa7\xdc\xc4\xcb\x08\x5d\x0a\x67\x6a\x69\xf5\x0f\x55\xf2\xce\x33\x7e\xbe\xf6\xc5\x2b\x1e\xb2\xc9\x54\xf2\x58\x6d\x0a\xe9\x83\xa6\x83\x8e\x4b\x84\x53\x21\xe3\x86\xb6\x67\x52\x85\xf5\xad\x2c\xd5\x10\x99\xe1\xa9\x04\x23\xbe\xb4\x7b\xce\x6a\x8e\xcf\xa9\x07\xc8\x65\x1b\x15\x37\x1e\x1c\xe4\x37\x0f\x0a\x2c\x7e\xd9\xd1\x75\x48\x55\x1f\xa3\x5a\x1c\x6e\x35\x33\x2f\x4d\x83\x22\x04\x17\xb2\x00\x0c\x50\xc3\x93\x1f\xe2\x83\x85\x55\x8a\xd9\x4d\x8f\xaf\x83\x82\x3f\x27\xda\x75\x28\x86\xda\x3d\xe5\xc8\x55\xa4\x1f\xbc\x36\x3f\x31\x80\x67\xf6\xbe\xe4\x08\x8b\x26\xb9\x02\x8a\xb4\x6e\x67\xfc\xab\x50\x9e\xf1\x47\x0d\x0b\x10\xda\x9a\xb8\x66\x3d\xc2\x0a\x4b\x3b\x9a\x1f\xae\x19\x6c\x10\x76\x76\x78\xe5\x4a\x8f\x68\xda\x1f\xe9\x86\x1b\xfd\x33\xea\x55\xb4\xd8\xda\x3e\xde\xd1\x52\xfc\x41\x25\x37\x6a\xd6\x48\xd4\x6f\xd7\x5b\x75\x20\x74\x78\xc0\x1a\x0f\xe2\x4a\xc1\x49\xc5\x7d\x54\x87\x15\x79\x08\xca\xc8\xef\xd3\x87\xb3\xab\x8b\x6f\xd7\x57\x37\xe7\x67\x17\x1f\x2f\xae\xd0\x4c\xee\xb4\x35\x2d\xf7\x82\x3b\xe8\x46\xad\x85\xb4\xa5\x32\x0c\xc3\xfe\x9a\x98\xf2\xd2\x4d\x7c\x63\x27\xe5\x6c\xf3\x72\xe3\x60\xcd\xb4\x44\x03\x24\x08\x46\x87\x53\x02\x3d\x92\x3a\x7f\xcf\x43\xb1\xdf\xb7\x5e\x3e\xe0\xbc\xef\x2d\x72\x3a\x7c\xa2\x40\xd2\xb3\x9e\xa9\xaa\x47\x0e\x32\xbb\x28\x1a\x03\x3c\xf7\x15\x9c\xa7\x0b\x18\x9a\x0c\x26\x38\x19\x1e\x06\x40\xf4\x18\x8f\xaa\x0a\x4c\x64\xef\xd1\x75\x4b\xd8\x0e\x16\x5c\x8d\x87\xe7\x40\x89\x66\x72\x1f\xca\x74\x7a\x0e\x71\xb2\xa1\xdb\x27\xf2\x50\x0e\x63\x8d\x24\xcf\xa6\x37\xa6\xf0\xd2\xc2\xbe\x7e\x4a\x73\x4b\x13\x16\xe4\xc5\x9e\x70\xf0\x06\xf3\xe4\xc9\x53\xb4\xd1\xd8\xff\xa8\xea\xd1\xfd\xc4\x80\x8e\xa3\x55\xea\x35\x34\xe0\x94\xe9\xbd\x85\x92\x59\x64\x87\x09\x8c\xc3\x7e\x58\xff\x11\x94\x4b\x62\xa5\x30\xfe\x14\xa1\x3b\x1f\x76\x15\xe6\x92\xf8\x67\xec\x23\xaa\x1a\x10\x0a\xe2\x15\x8d\x02\xf3\x61\xc3\x53\xd0\x3e\xc2\x87\x0b\x01\x69\xcf\xef\x1d\x86\x66\x9d\xac\xc1\x00\xc2\xef\x3f\xf1\x19\xb7\xc0\x58\x1f\xdc\x3d\x53\x32\xda\xc3\x67\x44\x3c\xb3\xca\xfe\x1f\x00\x00\xff\xff\xbc\x30\x5f\x05\x0e\x17\x00\x00") func runtimeHelpHelpMdBytes() ([]byte, error) { return bindataRead( @@ -252,7 +254,47 @@ func runtimeHelpHelpMd() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "runtime/help/help.md", size: 6295, mode: os.FileMode(420), modTime: time.Unix(1462111989, 0)} + info := bindataFileInfo{name: "runtime/help/help.md", size: 5902, mode: os.FileMode(420), modTime: time.Unix(1462461886, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _runtimePluginsGoGoLua = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x94\x91\x4f\x4f\xec\x20\x14\xc5\xf7\xfd\x14\x37\x24\x2f\xa1\xef\xf5\xf5\x03\x34\x99\x85\x2e\x9c\xe5\x18\x5d\x1a\x35\xd8\xde\xb6\x24\x0c\x10\xb8\x9d\xd1\x18\xbf\xbb\xd0\x32\xff\x9c\xfa\x8f\x4d\x53\xee\x39\x3f\xce\x01\xd9\xc2\x12\x69\x65\x49\x1a\xcd\x59\x67\xe4\xda\x1a\x47\x9e\xe5\xb0\x58\x80\x96\x0a\xa8\x47\x9d\x41\x58\x17\x4d\x73\x2e\x2b\xa0\x15\xca\x63\x9e\xa1\x6e\xb2\x8f\xac\x76\x4d\xdf\x71\xa2\xa4\x00\x72\x43\x42\x64\xed\xa0\xeb\x38\x84\xce\x3c\x1a\x7d\x2b\x36\xc8\xf3\xd1\x16\xe0\x1b\x89\xdb\xf2\x72\x68\xcb\x2b\xa9\x90\x5e\x2c\x46\x36\x5b\x1a\x76\x80\x27\xe5\x27\x95\x4e\x64\x71\x85\x43\xf6\xf3\x74\x4e\x5c\x18\x2a\xcd\x97\x99\x27\x84\xd9\xb1\x3b\xf6\xd8\xfd\xc4\xcc\xd5\x0d\xae\x2c\xea\x24\x89\xe3\xb3\xaa\xc7\x0c\x65\x6a\xa1\xa0\x17\xba\x51\xa1\x21\x48\x53\x5a\x13\xed\x53\x08\xf8\xbf\x05\x06\x65\x79\xb8\x8d\x6b\x41\xfd\xb1\xd3\xa1\x1f\x14\x05\xe7\x84\xa8\x1c\x8a\x86\xb3\xbf\x82\x4d\xa2\xb4\x5b\x2b\xe3\xe3\xdd\xce\x44\x39\xbd\x90\x2f\xe2\x24\xe1\x2f\x22\x05\xbe\xb7\x4a\x12\x3f\xcb\x56\x00\xab\x7e\x98\x70\x22\x78\x72\x05\x78\xb4\xb3\xe7\xbc\xbe\x9d\xec\x76\xf8\x1c\x36\x39\xe3\x77\x0f\x7f\xfc\xfd\xbf\x9c\xe5\x55\x6b\xdc\x5a\x04\xca\x0e\x10\xfe\x01\x45\xdd\x83\xd4\x10\xd0\x55\x17\xa6\x75\xcf\x47\x6f\x0e\x8d\xd9\xbf\x28\x89\x27\x85\xa5\xd4\x1e\x1d\xf1\xe9\xc0\x62\x74\x1e\x9e\x37\x7e\x1d\xd2\xe0\x74\x4a\x34\x76\x78\x0f\x00\x00\xff\xff\xb7\x44\x98\xaf\x6b\x03\x00\x00") + +func runtimePluginsGoGoLuaBytes() ([]byte, error) { + return bindataRead( + _runtimePluginsGoGoLua, + "runtime/plugins/go/go.lua", + ) +} + +func runtimePluginsGoGoLua() (*asset, error) { + bytes, err := runtimePluginsGoGoLuaBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "runtime/plugins/go/go.lua", size: 875, mode: os.FileMode(420), modTime: time.Unix(1462462186, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _runtimePluginsLinterLinterLua = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x8c\x55\x6d\x6b\xe4\x36\x10\xfe\xbe\xbf\x42\x88\xba\x58\x89\xed\xd0\x7c\x5c\x48\xe1\x7a\xa5\x81\x72\xed\x1d\xa4\xe5\x3e\xf4\xe5\xd0\xda\xe3\xb5\x1a\x59\x32\x92\x9c\xcd\x52\xfa\xdf\x3b\x92\x1c\xaf\x6d\x9c\xf8\x96\x10\xcd\xca\x33\xcf\x33\x2f\xcf\x8e\x45\x4d\xee\xc1\x7d\xec\x9c\xd0\x2a\xa5\x52\x28\x07\x86\x32\x72\x77\x47\x94\x90\xc4\x35\xa0\x76\x04\x3f\xef\xaa\x6a\xe1\x93\x11\x67\x7a\x60\x3b\x50\xd5\x6e\x57\xf7\xaa\xf4\x4f\x49\x7c\xf8\x45\xab\x07\xfe\x04\x29\x0b\xb1\xaf\x50\x8c\xd8\xfe\x23\x75\xc9\x25\xa9\x1d\xb9\x23\x4f\x02\x4e\xc5\x0f\x7d\x5d\xfc\x24\x24\xb8\x73\x07\x4b\x27\xbc\x9e\xba\x7d\xe2\xae\x59\xb8\x54\xf0\xa4\x7a\x29\xd1\x8b\xde\xa0\x7d\xe3\xbf\xd0\xd1\x07\xf3\xf9\xf8\xe0\x2b\xa4\x27\xa1\x2a\x7d\xb2\x74\x9e\x8b\xff\x4c\x10\x7e\xfd\xfd\xc3\x25\xd6\x57\x3b\xc1\xf1\x09\xa3\xcb\xbd\x5e\x81\x18\x5a\xe1\x8f\x94\x1e\xf5\xa1\x17\xb2\xc2\xae\xa1\x49\x82\x4d\x72\x4d\x28\x29\x8a\x17\x2e\x7c\x94\xd4\xfb\x44\xee\x49\xd2\x52\xf6\x16\x94\x3f\x23\x92\xb7\x22\xc8\xac\x1d\x23\x54\x52\x5d\x2f\xe0\x40\x5a\xb8\x24\xfe\xa1\xe7\x5b\x99\xcb\x9e\x97\x0d\x94\x8f\x9e\xf0\xc5\x26\x79\xae\x74\x5e\x6a\xa9\x4d\x64\xf7\x33\xf9\x6a\xd2\x4f\x67\xd7\x68\xb5\xc5\xdb\x9d\x6b\xc9\x1f\xc1\x7a\xde\x17\x7b\x85\xec\x2d\xa2\xf7\x9b\x53\x29\xcb\xd0\xc7\xb2\x24\x79\x6d\xcf\xca\xf1\xe7\x5c\x2b\x79\x26\xf9\x67\x8e\xc3\xcf\x3f\xc3\xb3\x33\xfc\x95\x12\x8b\xb7\xab\xfc\x71\x8b\xbc\x6a\x83\x1c\xf0\x20\xb1\x95\x77\xba\xae\x51\x14\x39\xc9\x4f\xf8\x27\xf0\x76\xc1\x9c\xa4\x89\x4c\xd8\x16\xf1\xcf\xfc\x69\x73\xa8\xff\xa0\x4f\x28\x3d\x18\x6b\x6d\x05\x63\xb4\xd9\xe4\x79\x28\x8d\xe8\xdc\x26\x9b\x6d\x06\xc5\x46\x6b\xc9\xe7\xbd\x81\x24\x32\x2b\xae\xb3\x05\xe3\xf0\x73\xf3\xcc\xe3\xa5\x97\xfa\xfe\xbd\x04\x6e\xde\x49\x79\xdf\x3b\x24\xfa\x05\xac\xe5\x47\xb0\xc3\xc6\xf1\x61\xab\x7b\x29\xe4\x13\xed\x8c\x94\x6d\x95\xc5\x3a\x6b\x6d\x5a\xee\x62\xec\x05\x7d\x01\x1d\xc3\xd8\x2e\x78\xc5\x3d\xd3\x70\x55\x85\x65\x24\x74\xd1\xe9\x0e\x70\xbd\xa5\xa1\x36\x84\xf6\x07\x65\xe1\x1b\x25\xb7\xdf\x7f\xfb\xdd\x50\x56\x8c\xf4\x15\x5b\x0c\x1c\xf2\xb2\x9d\x14\x2e\x8d\x70\x7b\x03\xbc\x4a\xe9\x15\xa7\x0c\xdb\xf3\xa7\x1a\xe2\x86\x87\xa5\xd4\xd6\x2f\xd6\x09\x96\x81\x23\x3c\x23\xd6\xa4\x94\xfd\xd1\xf6\x87\x94\x26\x49\xed\xbb\x9e\x16\xd7\x8c\xb2\xf1\x4e\x86\x3b\x94\xf0\xf4\xb2\xbd\x38\x06\x68\xc4\x21\x5f\xb2\x30\x18\xa1\x88\xe8\xb8\x30\xa1\x05\x60\x19\xa9\xf4\x38\x8b\x3c\x27\xbf\x19\xd1\x92\x53\x23\x1c\xd8\x8e\x97\x93\x6d\xed\x63\x43\x85\xb0\xc7\x94\xca\x26\xa5\x7f\x27\xf6\xca\x73\xe0\xf1\xcd\x64\xca\xa8\x29\xeb\x8c\x50\xc7\xa2\xc6\x85\x1c\x58\xb2\x58\x15\x5b\x51\xd6\xf8\x12\xc8\x48\xf4\x6c\xed\x11\x79\x06\x84\xc8\x34\x85\x98\x45\x23\xd5\xd0\xf2\x03\xb7\xa0\x78\x0b\xe9\x6c\x73\x86\x37\xdf\xd2\xc3\x93\xad\x64\x32\xaa\x65\x26\x94\x51\x5e\x4e\xab\xbe\x3d\x80\x09\xc9\xb0\x90\x66\x46\x6e\xe7\xe9\x4c\x5f\x27\xa3\xd6\x5f\x13\x6f\x14\x09\xd6\x99\x11\x0b\x1d\x9b\x29\xc0\xf6\xd2\xbf\x3b\xff\xfd\x6f\x45\x17\x28\xca\x3f\xb0\xf3\x7f\x85\x79\x47\x7d\xa4\x23\x80\x9f\x33\xe0\x56\xf7\x53\x46\xe8\xfd\x31\x36\x70\xe8\xfe\x64\xd2\x8e\x1f\x24\x14\x42\x59\x30\x2e\x8d\x84\x59\x88\xbc\xfc\xe4\xfc\x69\xc0\xf5\x46\x0d\x19\xad\xd7\x31\xef\xeb\x24\x61\x7f\x79\x99\x64\x50\xe6\xb0\x24\xd2\xe2\xea\x86\xe1\x3f\xe6\x55\x9a\xdc\x0e\xda\x19\xb8\x7c\x58\x60\xfa\x3f\x00\x00\xff\xff\xd5\x66\x68\xff\xcc\x08\x00\x00") + +func runtimePluginsLinterLinterLuaBytes() ([]byte, error) { + return bindataRead( + _runtimePluginsLinterLinterLua, + "runtime/plugins/linter/linter.lua", + ) +} + +func runtimePluginsLinterLinterLua() (*asset, error) { + bytes, err := runtimePluginsLinterLinterLuaBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "runtime/plugins/linter/linter.lua", size: 2252, mode: os.FileMode(420), modTime: time.Unix(1462462242, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1552,7 +1594,7 @@ func runtimeSyntaxRMicro() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "runtime/syntax/r.micro", size: 238, mode: os.FileMode(420), modTime: time.Unix(1462215620, 0)} + info := bindataFileInfo{name: "runtime/syntax/r.micro", size: 238, mode: os.FileMode(420), modTime: time.Unix(1462282751, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -2014,6 +2056,8 @@ var _bindata = map[string]func() (*asset, error){ "runtime/colorschemes/solarized-tc.micro": runtimeColorschemesSolarizedTcMicro, "runtime/colorschemes/solarized.micro": runtimeColorschemesSolarizedMicro, "runtime/help/help.md": runtimeHelpHelpMd, + "runtime/plugins/go/go.lua": runtimePluginsGoGoLua, + "runtime/plugins/linter/linter.lua": runtimePluginsLinterLinterLua, "runtime/syntax/Dockerfile.micro": runtimeSyntaxDockerfileMicro, "runtime/syntax/LICENSE": runtimeSyntaxLicense, "runtime/syntax/README.md": runtimeSyntaxReadmeMd, @@ -2151,6 +2195,14 @@ var _bintree = &bintree{nil, map[string]*bintree{ "help": &bintree{nil, map[string]*bintree{ "help.md": &bintree{runtimeHelpHelpMd, map[string]*bintree{}}, }}, + "plugins": &bintree{nil, map[string]*bintree{ + "go": &bintree{nil, map[string]*bintree{ + "go.lua": &bintree{runtimePluginsGoGoLua, map[string]*bintree{}}, + }}, + "linter": &bintree{nil, map[string]*bintree{ + "linter.lua": &bintree{runtimePluginsLinterLinterLua, map[string]*bintree{}}, + }}, + }}, "syntax": &bintree{nil, map[string]*bintree{ "Dockerfile.micro": &bintree{runtimeSyntaxDockerfileMicro, map[string]*bintree{}}, "LICENSE": &bintree{runtimeSyntaxLicense, map[string]*bintree{}}, diff --git a/cmd/micro/view.go b/cmd/micro/view.go index 1a685407..0fd7bd29 100644 --- a/cmd/micro/view.go +++ b/cmd/micro/view.go @@ -406,6 +406,13 @@ func (v *View) ClearGutterMessages(section string) { v.messages[section] = []GutterMessage{} } +// ClearAllGutterMessages clears all the gutter messages +func (v *View) ClearAllGutterMessages() { + for k := range v.messages { + v.messages[k] = []GutterMessage{} + } +} + // DisplayView renders the view to the screen func (v *View) DisplayView() { // The character number of the character in the top left of the screen diff --git a/runtime/plugins/go/go.lua b/runtime/plugins/go/go.lua index f6667304..a1cecddc 100644 --- a/runtime/plugins/go/go.lua +++ b/runtime/plugins/go/go.lua @@ -13,9 +13,6 @@ function go_onSave() go_gofmt() end - linter_lint("go build", "go build -o /dev/null 2>&1", "%f:%l: %m") - linter_lint("go lint", "golint " .. view.Buf.Path, "%f:%l:%d+: %m") - view:ReOpen() end end diff --git a/runtime/plugins/linter/linter.lua b/runtime/plugins/linter/linter.lua index f092603b..f0c3e5f6 100644 --- a/runtime/plugins/linter/linter.lua +++ b/runtime/plugins/linter/linter.lua @@ -1,25 +1,33 @@ +if GetOption("linter") == nil then + AddOption("linter", true) +end + function linter_onSave() - local ft = view.Buf.Filetype - local file = view.Buf.Path - local devnull = "/dev/null" - if OS == "windows" then - devnull = "NUL" - end - if ft == "Go" then - linter_lint("gobuild", "go build -o " .. devnull, "%f:%l: %m") - linter_lint("golint", "golint " .. view.Buf.Path, "%f:%l:%d+: %m") - elseif ft == "Lua" then - linter_lint("luacheck", "luacheck --no-color " .. file, "%f:%l:%d+: %m") - elseif ft == "Python" then - linter_lint("pyflakes", "pyflakes " .. file, "%f:%l: %m") - elseif ft == "C" then - linter_lint("gcc", "gcc -fsyntax-only -Wall -Wextra " .. file, "%f:%l:%d+:.+: %m") - elseif ft == "D" then - linter_lint("dmd", "dmd -color=off -o- -w -wi -c " .. file, "%f%(%l%):.+: %m") - elseif ft == "Java" then - linter_lint("javac", "javac " .. file, "%f:%l: error: %m") - elseif ft == "JavaScript" then - linter_lint("jshint", "jshint " .. file, "%f: line %l,.+, %m") + if GetOption("linter") then + local ft = view.Buf.Filetype + local file = view.Buf.Path + local devnull = "/dev/null" + if OS == "windows" then + devnull = "NUL" + end + if ft == "Go" then + linter_lint("gobuild", "go build -o " .. devnull, "%f:%l: %m") + linter_lint("golint", "golint " .. view.Buf.Path, "%f:%l:%d+: %m") + elseif ft == "Lua" then + linter_lint("luacheck", "luacheck --no-color " .. file, "%f:%l:%d+: %m") + elseif ft == "Python" then + linter_lint("pyflakes", "pyflakes " .. file, "%f:%l: %m") + elseif ft == "C" then + linter_lint("gcc", "gcc -fsyntax-only -Wall -Wextra " .. file, "%f:%l:%d+:.+: %m") + elseif ft == "D" then + linter_lint("dmd", "dmd -color=off -o- -w -wi -c " .. file, "%f%(%l%):.+: %m") + elseif ft == "Java" then + linter_lint("javac", "javac " .. file, "%f:%l: error: %m") + elseif ft == "JavaScript" then + linter_lint("jshint", "jshint " .. file, "%f: line %l,.+, %m") + end + else + view:ClearAllGutterMessages() end end From f80af4670f2c1fd95d4296f8ebf0e55b2b1ae5d9 Mon Sep 17 00:00:00 2001 From: Zachary Yedidia Date: Thu, 5 May 2016 12:56:52 -0400 Subject: [PATCH 14/15] Add options to help text --- runtime/help/help.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/runtime/help/help.md b/runtime/help/help.md index eb550ae2..c89c8e68 100644 --- a/runtime/help/help.md +++ b/runtime/help/help.md @@ -195,6 +195,23 @@ Here are the options that you can set: default value: `on` +--- + +Default plugin options: + +* `linter`: lint languages on save (supported languages are C, D, Go, Java, + Javascript, Lua). Provided by the `linter` plugin. + + default value: `on` + +* `goimports`: Run goimports on save. Provided by the `go` plugin. + + default value: `off` + +* `gofmt`: Run gofmt on save. Provided by the `go` plugin. + + default value: `on` + Any option you set in the editor will be saved to the file ~/.config/micro/settings.json so, in effect, your configuration file will be created for you. If you'd like to take your configuration with you to another From ae946c5f5ea6ce1e97ea7f77ff4bd75391312f21 Mon Sep 17 00:00:00 2001 From: Zachary Yedidia Date: Fri, 6 May 2016 11:55:41 -0400 Subject: [PATCH 15/15] Update runtime --- cmd/micro/runtime.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/micro/runtime.go b/cmd/micro/runtime.go index 2c2f9a80..4fe072ce 100644 --- a/cmd/micro/runtime.go +++ b/cmd/micro/runtime.go @@ -239,7 +239,7 @@ func runtimeColorschemesSolarizedMicro() (*asset, error) { return a, nil } -var _runtimeHelpHelpMd = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x8c\x58\x4b\x73\xdb\x38\x12\x3e\x87\xbf\x02\xa5\xa4\x6a\x92\x59\x45\xae\xdd\xda\x93\x6e\x1e\xc7\x79\xd4\x24\xb1\xd7\xb1\x77\x27\x73\x09\x21\x12\x94\x30\x26\x09\x06\x00\x6d\x2b\xfb\xf8\xed\xfb\x75\x03\xe0\x43\xb2\xab\xc6\x17\x8b\xdd\x8d\x7e\xa1\x9f\x78\x2e\x3e\xe9\xc2\x1a\xb1\x53\x75\x27\xbc\x7a\xf0\x59\x16\x00\xda\x09\x09\x80\x6d\x74\x2b\xeb\xd7\x1b\xe9\x54\xc9\x78\xa1\x4a\xed\x8d\x15\x7e\x27\xbd\x90\xba\x71\xc2\x1b\xb1\x51\x42\x49\xb7\xa7\x9f\xbd\x53\x42\xb6\xa5\xd0\xad\xef\xb5\xd7\x77\x6a\x29\xb2\xfb\x9d\xae\x01\xad\x9d\x11\x5e\xde\xea\x76\x2b\x64\x79\x27\x5b\x2f\xb7\x4a\x98\x0a\xac\x94\xa8\xfa\xba\x16\x85\xec\xe4\x46\xd7\x38\xa6\x1c\x21\x1a\x53\x2a\xdb\x0e\x5a\xb8\x55\x96\x3d\x7f\xfe\x5c\xdc\x38\x1c\xcc\xb2\x8b\xb6\x50\x62\x6f\x7a\xb1\x93\x77\x4a\x6c\x7a\x5d\x7b\x66\x15\x14\x5c\x0a\xa7\x9b\xae\xde\x0b\xe7\xa5\xf5\x42\x7b\xb1\xd9\x0b\xdb\xb7\x2d\x89\xcf\xf2\x86\x8d\xec\xa4\xdf\x9d\x78\x73\x52\x41\xbf\x95\x7f\xf0\xb9\x80\x65\xf1\x5c\x20\xc9\xc9\x26\xd3\xa9\x16\x46\x09\xd5\x74\x7e\x0f\x49\x55\xa5\xec\x2a\x39\x8a\xcd\x72\x7d\xd7\x19\xeb\x9d\x28\xac\x92\x9e\x44\x04\x2a\x27\x2a\x6b\x1a\xe8\x50\xea\x76\x9d\x65\x79\x9e\x67\x2f\x84\xae\x0a\xd3\x56\x7a\x2b\xfe\x23\x58\x06\x83\xb3\xaf\xb0\xa4\x80\x90\xc6\xc0\x1a\xb2\xa3\xe8\xad\x83\x3a\xd2\x9a\x1e\xfe\xbc\xd7\x7e\xc7\x60\x69\xad\xb9\x17\xb7\x6a\xef\xd8\xcf\x8d\x81\xc7\xa3\x63\x7e\x55\xfb\x8d\x6e\x21\x6a\xeb\xb2\xec\x7a\xa7\xe8\x2a\x6c\x60\x56\xaa\x4a\xf6\x70\xd0\xed\x48\xb2\x84\xea\x06\x9a\x26\xce\x1a\xb2\x0a\xaf\x4d\x4b\x7e\x26\x7e\xcf\xc5\x79\xb8\xeb\x91\xe9\xcf\xe2\xcc\xdb\xfa\xf5\xf7\xb5\x10\xe2\x1f\xb8\xdf\x04\x50\x04\x38\x7f\x50\x45\xef\x21\x53\x14\xa6\x69\xa0\x5c\xc2\x6e\x09\x7b\x6d\xb6\x5b\x44\xc1\x18\x68\x11\xb9\x21\xe4\x55\x0f\x07\x0b\x07\x64\x3d\x1c\x0e\x2a\xfc\xc2\x7e\x3c\x56\xc1\xd1\xb1\x2f\xb8\xf9\x04\x30\x04\xb8\xa0\x9b\xa2\xdb\x4c\xd0\x1f\x04\xbd\x69\x4b\x93\x00\x7b\x16\xa7\x46\x40\x45\x80\xb7\x7a\xd4\xb6\x4d\x00\xd1\x4e\xd4\xec\x06\x68\x67\xd5\x9d\x86\xd7\x13\x46\xb2\x26\xaa\x56\x05\x12\xa2\xae\x13\xb8\x20\xf0\x99\xe9\xf6\x09\xf0\xc0\x80\x7e\xe0\x78\x1b\xbf\x45\xad\xdb\x41\xdf\x3b\x02\x5e\x4a\xe7\x07\x48\x4f\x90\xf7\xb2\xae\x10\xad\xc8\x97\xbe\x4b\x88\x72\x8e\x28\xcd\x7d\x0b\xd4\x25\x7e\xdf\x74\x81\x4b\x22\xa7\x5f\x6f\x80\x5e\x07\x58\xa4\x7c\x6f\x1a\xbe\x36\x21\xde\x99\x90\xc4\x5b\x1d\xd2\x03\xa9\x17\x75\x3a\x6f\xcb\x40\x12\x69\x14\xec\x1f\xb1\xac\x86\x9d\x5c\x2e\xc1\x45\xdb\x37\x1b\x44\xfe\x18\xd1\x54\x12\x38\x72\x43\xfc\x39\xf1\x97\x10\xc4\x5c\x3a\x38\xdc\xef\x8d\x2d\x29\x3f\xe9\xff\x2a\x23\xb6\xa2\x56\x95\xe7\x00\xb7\x7a\xbb\xf3\x47\x59\x81\x93\xf4\x15\x92\x9b\xc8\xa2\x66\x04\x24\x2d\x96\x04\xcc\x0a\xe2\xd4\x77\x4c\x40\x56\x1f\xb3\x79\x8a\xc7\x90\xe4\xc9\x88\x9d\xa9\x4b\x04\xa8\x86\x56\x9c\x30\xb8\xe9\x48\x0b\xeb\x88\x6d\xa3\x5a\x9f\x12\x88\xd4\x73\x21\x22\x42\xed\x03\x01\x1c\xbb\xe2\xac\x8c\xbc\x87\x90\x16\x8d\xdc\x53\x05\xb5\x6a\xc3\x99\xde\x3b\xba\x03\x52\x22\xff\xdf\xc9\x2a\x94\x8a\x13\x2e\x14\x27\xe9\xc8\xea\x0f\x67\xda\x5c\x64\x5c\xb7\xc4\xb9\x2c\x76\xe4\x58\xaa\xd9\x81\x05\xc4\x43\xe5\xa0\x0c\x84\xbe\x85\xa5\xea\x41\xa2\xac\xc1\x2f\x74\xd3\x14\xc6\x79\x48\x07\x2e\x70\x38\x63\xd8\x03\x01\xf8\x83\x81\x16\x49\xb2\xe4\x02\x5b\x98\x1e\xc6\x77\x7d\xa8\xaf\x59\x65\xea\xda\xdc\x93\x92\xba\x0d\x7a\x1e\xe8\xc5\x6a\x71\xb5\xa3\xef\xec\xdf\x19\x05\xd0\x82\x58\x7f\x5d\xac\xc5\x82\xd2\x71\xb1\x1c\x81\xbf\x13\x90\x52\x72\x91\xfd\x37\xd4\xc2\xf7\xca\x1e\x95\x2e\xb7\x9e\x72\x7c\xf6\x6c\x71\xd3\x2d\x62\x6c\xc6\xbf\xc5\x19\x5f\x2a\x45\x3a\xd8\x83\x82\x7f\xad\x8f\x29\x70\x92\xf1\x57\x14\x5a\x53\x82\x88\x0f\x70\x26\xf9\x88\x30\x7c\x8c\x05\xc3\x99\xe2\x0b\xc5\xc4\x54\x97\x45\xa8\x05\x49\x08\xe3\xa7\x9a\x44\xfc\xa8\x26\x53\x4c\x05\x45\x8a\x03\x19\x53\x6d\x23\xc5\x44\xd1\xd3\xda\xcf\x75\x5d\xfc\x0b\xc9\x34\xb2\x00\x7e\x6e\x2e\xe3\xe7\x0c\xe6\x62\xa2\x8c\x27\xc8\x06\x61\x13\xb2\x51\x1a\x5d\xeb\x4c\x9d\xc5\x17\xca\xb2\x8b\xea\x23\x72\x73\x24\x99\x69\xb4\x40\xb1\x39\x24\x98\x89\x8a\x92\xae\xcd\xa3\xbc\x66\xca\x0f\xa4\x8f\xf0\x9c\xc5\x4d\xbc\x4e\xe6\x38\x92\xcc\x02\x27\x92\x80\xd3\x81\xb0\xc4\x68\xae\xd7\x01\x51\x62\x35\xd5\x28\x90\x9c\xb7\x18\x6c\x66\xd1\xf7\xa1\x75\xca\xfa\x00\x0f\xf7\xde\xc9\x42\x3d\x42\x12\xe0\x4c\xf2\x8b\x2c\x6e\xdd\x94\x6c\x02\x99\x13\xfc\x2d\xc5\xce\x01\xc1\xb5\xdc\xcc\x13\x29\x0a\x21\xf8\x60\xcb\xc5\x4c\x0b\x6a\xb3\x6f\x91\xe4\x13\x5b\x67\x78\xea\xcb\x23\xee\xed\x0c\x47\x3d\x74\xc4\x7d\x3e\xc2\x7d\x46\xd3\x1d\xf1\x97\x47\xf8\xcb\xd8\x7e\x47\x9a\xdf\x67\x34\xb1\xba\x44\xdc\xd7\x19\x8e\x8b\xcc\x80\x3b\x9b\xa7\x3e\x5a\xf5\x88\xfb\xed\xa0\x2c\x4c\x54\xfa\xf5\x10\x35\x0f\xaf\x7f\xce\xd0\xdc\xca\x47\xe4\xe9\xdc\x4d\x1c\x12\xa7\x75\x1d\x08\xa8\x21\xcf\x6b\xcd\x24\xa0\x28\x6c\xe6\xb7\x34\x04\xd2\xe5\xf6\xa0\x14\x2e\xc2\x10\x90\xb0\x6f\xda\x63\xec\x58\x7d\x38\x25\x66\x6a\xd1\x4c\x31\xe5\xc0\x19\xf1\x28\xc5\x9c\xcb\xd5\x8c\x26\x8c\x04\x57\x7d\x9d\x82\xf9\x0d\xac\xf5\x53\x03\x13\x04\x55\x3f\x94\x7d\x1e\x62\x2f\x8d\x73\x7a\x83\x9e\x19\xe7\xc0\xc9\x20\xa1\xd2\x80\xd9\xa6\x2d\x24\xd2\xd0\xec\x80\xb1\xcc\x71\xe7\x0c\x3d\x4c\xa1\x0d\x71\x9f\x52\x8c\xe5\x9e\x1f\x88\x57\xf3\xf6\xd2\x1d\xca\x0b\xab\xcd\x7e\x1c\x5e\x56\x34\x74\xe6\xdf\x31\xee\xe6\x6b\x9e\x7a\x5d\x98\xdb\x57\x04\x76\x08\x75\x80\x29\xe2\x5d\x9a\x2c\x2c\x8d\x02\xc3\x04\x01\x22\xab\xba\x1a\xf9\x26\x16\x4e\x49\x5b\xec\x16\x62\x71\x27\xeb\x5e\x2d\x44\x55\xcb\xad\xc3\xf1\xeb\x1d\x7a\xf7\xbd\xc6\x4c\x91\x48\xf3\x40\x9a\x87\x69\x23\x67\xfa\x7c\x25\xa8\x6b\xd2\x0c\x91\x87\x93\x6c\x85\xe9\xa8\xcf\xcb\x7a\x45\xc8\x53\x6a\xd2\x60\xd6\x19\x6c\x60\x4b\xd2\x08\x14\xf8\x36\x2d\x76\x1a\x83\xf1\x8c\x0e\xae\x45\x5e\xe4\x4b\x9a\x4d\x30\x39\xa8\x56\xc2\x7c\x07\xd0\x4e\x15\xb7\x39\x6f\x5d\x2c\x27\xa0\xa5\xbb\x75\x58\x59\xc8\x21\x3f\x95\x98\xad\x6e\x15\x0d\x07\x9d\xb2\x95\xb1\x0d\x5b\x1c\x55\xe6\x01\x48\xd1\x2c\xe2\x75\x83\xfd\x0c\x1c\x3e\x1b\xaf\x82\x3b\x07\x73\x9a\xde\x79\x9a\x76\xa4\x80\x49\x1a\xe3\x9d\xda\xaa\x87\x95\x10\x1f\x2a\xd6\x2e\x8e\x5f\xd2\x6e\x7b\xe2\xe7\x88\x4b\x69\xa0\x5d\x6b\x7c\x58\xf4\x64\x8b\x9d\x8e\xaa\x97\xa3\xf1\x43\xfb\x30\xa2\xd0\x0c\x65\x1a\x1d\x26\x94\xef\x3d\xe4\xba\xe0\x7a\xa7\x7c\x74\x90\x08\x3e\x5c\x63\x32\xf3\xe1\xaa\x22\x1c\xe6\x30\x6a\x25\x2e\x6b\xac\xb1\x98\x08\x55\x08\x0d\x9a\xff\xf1\xc1\x63\x14\xa2\xc9\x92\x32\x12\x2e\x80\x05\xd0\x33\x9c\x76\x43\xa4\x80\x6d\xbc\x6d\x2c\x33\x6e\xf7\x3a\xc6\x13\x04\x02\x10\x04\x6e\xb1\x0f\xb7\xf3\x35\x27\xcd\x50\x1b\x14\xe5\x2d\xaf\x7a\x2b\xbe\x60\x92\x15\x49\x7e\xc2\xed\xf5\x9e\xc6\x2f\x8e\x10\x38\xaf\xd4\x0e\x2e\xdf\x2b\x3e\x4d\x6e\xe3\xc1\xfb\x7e\xa7\xc8\x21\x18\xbf\x5a\x0d\x19\x2e\xad\xbb\x71\x3b\xbc\x08\xfa\xa6\xbd\xd5\x21\x7f\x40\x33\xce\xb1\x14\xea\x94\x51\x34\x6f\xf6\x56\xb2\xd1\xec\x61\x77\x00\x2c\xb5\x85\x4f\x8c\xdd\x0f\x3b\x30\x4e\x06\x03\xf3\x17\xbf\xbd\x79\xf7\xed\xec\xe2\xf3\xdb\x0f\xef\xbe\xbd\xbf\xf8\x74\x7e\x12\xb7\x68\x19\x93\xe3\x09\x46\xe2\xd4\x51\x48\x65\x44\x03\x0e\xb8\x60\x55\x2c\x29\xea\x8e\x18\xe6\x14\xcc\x14\x0c\x70\xf7\xf2\x68\x42\x66\x6c\x4f\x6f\x15\x10\x98\x8d\x12\x67\x3a\xcf\xd2\x3f\xdd\xe2\x2c\xe9\xc1\x7b\xcd\x57\x59\x98\xda\x58\x87\xc4\x68\x28\x70\x6a\x23\xcb\x64\xc7\x00\x0f\x8e\xe4\x9b\xa0\x3b\x7b\xf1\x32\x48\x7c\xa3\xed\xab\x93\x09\x99\x3b\xc9\x83\xa8\x7c\x15\x96\xfe\xec\x59\xda\xc9\x39\xf8\x90\x92\xf1\x3b\xcf\x9e\x8d\x79\x33\xdd\xdd\xa7\xdc\xc4\xcb\x08\x5d\x0a\x67\x6a\x69\xf5\x0f\x55\xf2\xce\x33\x7e\xbe\xf6\xc5\x2b\x1e\xb2\xc9\x54\xf2\x58\x6d\x0a\xe9\x83\xa6\x83\x8e\x4b\x84\x53\x21\xe3\x86\xb6\x67\x52\x85\xf5\xad\x2c\xd5\x10\x99\xe1\xa9\x04\x23\xbe\xb4\x7b\xce\x6a\x8e\xcf\xa9\x07\xc8\x65\x1b\x15\x37\x1e\x1c\xe4\x37\x0f\x0a\x2c\x7e\xd9\xd1\x75\x48\x55\x1f\xa3\x5a\x1c\x6e\x35\x33\x2f\x4d\x83\x22\x04\x17\xb2\x00\x0c\x50\xc3\x93\x1f\xe2\x83\x85\x55\x8a\xd9\x4d\x8f\xaf\x83\x82\x3f\x27\xda\x75\x28\x86\xda\x3d\xe5\xc8\x55\xa4\x1f\xbc\x36\x3f\x31\x80\x67\xf6\xbe\xe4\x08\x8b\x26\xb9\x02\x8a\xb4\x6e\x67\xfc\xab\x50\x9e\xf1\x47\x0d\x0b\x10\xda\x9a\xb8\x66\x3d\xc2\x0a\x4b\x3b\x9a\x1f\xae\x19\x6c\x10\x76\x76\x78\xe5\x4a\x8f\x68\xda\x1f\xe9\x86\x1b\xfd\x33\xea\x55\xb4\xd8\xda\x3e\xde\xd1\x52\xfc\x41\x25\x37\x6a\xd6\x48\xd4\x6f\xd7\x5b\x75\x20\x74\x78\xc0\x1a\x0f\xe2\x4a\xc1\x49\xc5\x7d\x54\x87\x15\x79\x08\xca\xc8\xef\xd3\x87\xb3\xab\x8b\x6f\xd7\x57\x37\xe7\x67\x17\x1f\x2f\xae\xd0\x4c\xee\xb4\x35\x2d\xf7\x82\x3b\xe8\x46\xad\x85\xb4\xa5\x32\x0c\xc3\xfe\x9a\x98\xf2\xd2\x4d\x7c\x63\x27\xe5\x6c\xf3\x72\xe3\x60\xcd\xb4\x44\x03\x24\x08\x46\x87\x53\x02\x3d\x92\x3a\x7f\xcf\x43\xb1\xdf\xb7\x5e\x3e\xe0\xbc\xef\x2d\x72\x3a\x7c\xa2\x40\xd2\xb3\x9e\xa9\xaa\x47\x0e\x32\xbb\x28\x1a\x03\x3c\xf7\x15\x9c\xa7\x0b\x18\x9a\x0c\x26\x38\x19\x1e\x06\x40\xf4\x18\x8f\xaa\x0a\x4c\x64\xef\xd1\x75\x4b\xd8\x0e\x16\x5c\x8d\x87\xe7\x40\x89\x66\x72\x1f\xca\x74\x7a\x0e\x71\xb2\xa1\xdb\x27\xf2\x50\x0e\x63\x8d\x24\xcf\xa6\x37\xa6\xf0\xd2\xc2\xbe\x7e\x4a\x73\x4b\x13\x16\xe4\xc5\x9e\x70\xf0\x06\xf3\xe4\xc9\x53\xb4\xd1\xd8\xff\xa8\xea\xd1\xfd\xc4\x80\x8e\xa3\x55\xea\x35\x34\xe0\x94\xe9\xbd\x85\x92\x59\x64\x87\x09\x8c\xc3\x7e\x58\xff\x11\x94\x4b\x62\xa5\x30\xfe\x14\xa1\x3b\x1f\x76\x15\xe6\x92\xf8\x67\xec\x23\xaa\x1a\x10\x0a\xe2\x15\x8d\x02\xf3\x61\xc3\x53\xd0\x3e\xc2\x87\x0b\x01\x69\xcf\xef\x1d\x86\x66\x9d\xac\xc1\x00\xc2\xef\x3f\xf1\x19\xb7\xc0\x58\x1f\xdc\x3d\x53\x32\xda\xc3\x67\x44\x3c\xb3\xca\xfe\x1f\x00\x00\xff\xff\xbc\x30\x5f\x05\x0e\x17\x00\x00") +var _runtimeHelpHelpMd = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xa4\x58\x4b\x73\xdc\xb8\x11\x3e\x9b\xbf\x02\x35\x76\xd5\xda\x9b\xd1\xa8\x92\xca\x69\x6e\x5a\x49\x7e\x64\x6d\x4b\x91\xe5\x64\xbd\x17\x13\x43\x82\x33\x58\x91\x04\x0d\x80\x92\xc6\x79\xfc\xf6\x7c\xdd\x00\xf8\x18\x49\x49\xaa\x56\x17\x0d\xbb\x1b\xfd\x42\x3f\xf1\x5c\x7c\xd0\x85\x35\x62\xa7\xea\x4e\x78\x75\xef\xb3\x2c\x00\xb4\x13\x12\x00\xdb\xe8\x56\xd6\x47\x1b\xe9\x54\xc9\x78\xa1\x4a\xed\x8d\x15\x7e\x27\xbd\x90\xba\x71\xc2\x1b\xb1\x51\x42\x49\xb7\xa7\x9f\xbd\x53\x42\xb6\xa5\xd0\xad\xef\xb5\xd7\xb7\x6a\x29\xb2\xbb\x9d\xae\x01\xad\x9d\x11\x5e\xde\xe8\x76\x2b\x64\x79\x2b\x5b\x2f\xb7\x4a\x98\x0a\xac\x94\xa8\xfa\xba\x16\x85\xec\xe4\x46\xd7\x38\xa6\x1c\x21\x1a\x53\x2a\xdb\x0e\x5a\xb8\x55\x96\x3d\x7f\xfe\x5c\x7c\x76\x38\x98\x65\x17\x6d\xa1\xc4\xde\xf4\x62\x27\x6f\x95\xd8\xf4\xba\xf6\xcc\x2a\x28\xb8\x14\x4e\x37\x5d\xbd\x17\xce\x4b\xeb\x85\xf6\x62\xb3\x17\xb6\x6f\x5b\x12\x9f\xe5\x0d\x1b\xd9\x49\xbf\x3b\xf6\xe6\xb8\x82\x7e\x2b\x7f\xef\x73\x01\xcb\xe2\xb9\x40\x92\x93\x4d\xa6\x53\x2d\x8c\x12\xaa\xe9\xfc\x1e\x92\xaa\x4a\xd9\x55\x72\x14\x9b\xe5\xfa\xae\x33\xd6\x3b\x51\x58\x25\x3d\x89\x08\x54\x4e\x54\xd6\x34\xd0\xa1\xd4\xed\x3a\xcb\xf2\x3c\xcf\x5e\x08\x5d\x15\xa6\xad\xf4\x56\xfc\x53\xb0\x0c\x06\x67\x5f\x60\x49\x01\x21\x8d\x81\x35\x64\x47\xd1\x5b\x07\x75\xa4\x35\x3d\xfc\x79\xa7\xfd\x8e\xc1\xd2\x5a\x73\x27\x6e\xd4\xde\xb1\x9f\x1b\x03\x8f\x47\xc7\xfc\xac\xf6\x1b\xdd\x42\xd4\xd6\x65\xd9\xf5\x4e\xd1\x55\xd8\xc0\xac\x54\x95\xec\xe1\xa0\x9b\x91\x64\x09\xd5\x0d\x34\x4d\x9c\x35\x64\x15\x5e\x9b\x96\xfc\x4c\xfc\x9e\x8b\xf3\x70\xd7\x23\xd3\x1f\xc5\xa9\xb7\xf5\xd1\xb7\xb5\x10\xe2\xaf\xb8\xdf\x04\x50\x04\x38\xbf\x57\x45\xef\x21\x53\x14\xa6\x69\xa0\x5c\xc2\x6e\x09\x7b\x6d\xb6\x5b\x44\xc1\x18\x68\x11\xb9\x21\xe4\x55\x0f\x07\x0b\x07\x64\x3d\x1c\x0e\x2a\xfc\xc4\x7e\x7c\xa8\x82\xa3\x63\x9f\x70\xf3\x09\x60\x08\x70\x41\x37\x45\xb7\x99\xa0\xdf\x09\xfa\xb9\x2d\x4d\x02\xec\x59\x9c\x1a\x01\x15\x01\x5e\xeb\x51\xdb\x36\x01\x44\x3b\x51\xb3\x1b\xa0\x9d\x55\xb7\x1a\x5e\x4f\x18\xc9\x9a\xa8\x5a\x15\x48\x88\xba\x4e\xe0\x82\xc0\xa7\xa6\xdb\x27\xc0\x3d\x03\xfa\x81\xe3\x4d\xfc\x16\xb5\x6e\x07\x7d\x6f\x09\x78\x29\x9d\x1f\x20\x3d\x41\xde\xca\xba\x42\xb4\x22\x5f\xfa\x2e\x21\xca\x39\xa2\x34\x77\x2d\x50\x97\xf8\xfd\xb9\x0b\x5c\x12\x39\xfd\x3a\x03\x7a\x1d\x60\x91\xf2\xad\x69\xf8\xda\x84\x78\x63\x42\x12\x6f\x75\x48\x0f\xa4\x5e\xd4\xe9\xbc\x2d\x03\x49\xa4\x51\xb0\x7f\xc4\xb2\x1a\x76\x72\xb9\x04\x17\x6d\xdf\x6c\x10\xf9\x63\x44\x53\x49\xe0\xc8\x0d\xf1\xe7\xc4\x1f\x42\x10\x73\xe9\xe0\x70\xbf\x33\xb6\xa4\xfc\xa4\xff\xab\x8c\xd8\x8a\x5a\x55\x9e\x03\xdc\xea\xed\xce\x3f\xc8\x0a\x9c\xa4\xaf\x90\xdc\x44\x16\x35\x23\x20\x69\xb1\x24\x60\x56\x10\xa7\xbe\x63\x02\xb2\xfa\x21\x9b\xa7\x78\x0c\x49\x9e\x8c\xd8\x99\xba\x44\x80\x6a\x68\xc5\x09\x83\x9b\x8e\xb4\xb0\x8e\xd8\x36\xaa\xf5\x29\x81\x48\x3d\x17\x22\x22\xd4\x3e\x10\xc0\xb1\x2b\xce\xca\xc8\x7b\x08\x69\xd1\xc8\x3d\x55\x50\xab\x36\x9c\xe9\xbd\xa3\x3b\x20\x25\xf2\x7f\x1f\xaf\x42\xa9\x38\xe6\x42\x71\x9c\x8e\xac\x7e\x73\xa6\xcd\x45\xc6\x75\x4b\x9c\xcb\x62\x47\x8e\xa5\x9a\x1d\x58\x40\x3c\x54\x0e\xca\x40\xe8\x6b\x58\xaa\xee\x25\xca\x1a\xfc\x42\x37\x4d\x61\x9c\x87\x74\xe0\x02\x87\x33\x86\x3d\x10\x80\xdf\x19\x68\x91\x24\x4b\x2e\xb0\x85\xe9\x61\x7c\xd7\x87\xfa\x9a\x55\xa6\xae\xcd\x1d\x29\xa9\xdb\xa0\xe7\x81\x5e\xac\x16\x57\x3b\xfa\xce\xfe\x91\x51\x00\x2d\x88\xf5\x97\xc5\x5a\x2c\x28\x1d\x17\xcb\x11\xf8\x2b\x01\x29\x25\x17\xd9\xbf\x42\x2d\x7c\xab\xec\x83\xd2\xe5\xd6\x53\x8e\xcf\x9e\x2d\x3e\x77\x8b\x18\x9b\xf1\x6f\x71\xca\x97\x4a\x91\x0e\xf6\xa0\xe0\x5f\xeb\x87\x14\x38\xc9\xf8\x2b\x0a\xad\x29\x41\xc4\x07\x38\x93\xbc\x47\x18\x3e\xc6\x82\xe1\x4c\xf1\x89\x62\x62\xaa\xcb\x22\xd4\x82\x24\x84\xf1\x53\x4d\x22\x7e\x54\x93\x29\xa6\x82\x22\xc5\x81\x8c\xa9\xb6\x91\x62\xa2\xe8\x49\xed\xe7\xba\x2e\xfe\x8e\x64\x1a\x59\x00\x3f\x37\x97\xf1\x73\x06\x73\x31\x51\xc6\x13\x64\x83\xb0\x09\xd9\x28\x8d\xae\x75\xa6\xce\xe2\x13\x65\xd9\x45\xf5\x1e\xb9\x39\x92\xcc\x34\x5a\xa0\xd8\x1c\x12\xcc\x44\x45\x49\xd7\xe6\x51\x5e\x33\xe5\x07\xd2\x47\x78\xce\xe2\x26\x5e\x27\x73\x1c\x49\x66\x81\x13\x49\xc0\xe9\x40\x58\x62\x34\xd7\xeb\x80\x28\xb1\x9a\x6a\x14\x48\xce\x5b\x0c\x36\xb3\xe8\x7b\xd7\x3a\x65\x7d\x80\x87\x7b\xef\x64\xa1\x1e\x21\x09\x70\x26\xf9\x49\x16\x37\x6e\x4a\x36\x81\xcc\x09\xfe\x94\x62\xe7\x80\xe0\x5a\x6e\xe6\x89\x14\x85\x10\x7c\xb0\xe5\x62\xa6\x05\xb5\xd9\xd7\x48\xf2\x89\xad\x33\x3c\xf5\xe5\x11\xf7\x7a\x86\xa3\x1e\x3a\xe2\x3e\x3e\xc0\x7d\x44\xd3\x1d\xf1\x97\x0f\xf0\x97\xb1\xfd\x8e\x34\xbf\xce\x68\x62\x75\x89\xb8\x2f\x33\x1c\x17\x99\x01\x77\x3a\x4f\x7d\xb4\xea\x11\xf7\xcb\x41\x59\x98\xa8\xf4\xf3\x21\x6a\x1e\x5e\x7f\x9b\xa1\xb9\x95\x8f\xc8\x93\xb9\x9b\x38\x24\x4e\xea\x3a\x10\x50\x43\x9e\xd7\x9a\x49\x40\x51\xd8\xcc\x6f\x69\x08\xa4\xcb\xed\x41\x29\x5c\x84\x21\x20\x61\xcf\xda\x87\xd8\xb1\xfa\x70\x4a\xcc\xd4\xa2\x99\x62\xca\x81\x33\xe2\x51\x8a\x39\x97\xab\x19\x4d\x18\x09\xae\xfa\x3a\x05\xf3\x19\xac\xf5\x53\x03\x13\x04\x55\x3f\x94\x7d\x1e\x62\x2f\x8d\x73\x7a\x83\x9e\x19\xe7\xc0\xc9\x20\xa1\xd2\x80\xd9\xa6\x2d\x24\xd2\xd0\xec\x80\xb1\xcc\x71\xe7\x0c\x3d\x4c\xa1\x0d\x71\x9f\x52\x8c\xe5\x9e\x1f\x88\x57\xf3\xf6\xd2\x1d\xca\x0b\xab\xcd\x7e\x1c\x5e\x56\x34\x74\xe6\xdf\x30\xee\xe6\x6b\x9e\x7a\x5d\x98\xdb\x57\x04\x76\x08\x75\x80\x29\xe2\x5d\x9a\x2c\x2c\x8d\x02\xc3\x04\x01\x22\xab\xba\x1a\xf9\x26\x16\x4e\x49\x5b\xec\x16\x62\x71\x2b\xeb\x5e\x2d\x44\x55\xcb\xad\xc3\xf1\xeb\x1d\x7a\xf7\x9d\xc6\x4c\x91\x48\xf3\x40\x9a\x87\x69\x23\x67\xfa\x7c\x25\xa8\x6b\xd2\x0c\x91\x87\x93\x6c\x85\xe9\xa8\xcf\xcb\x7a\x45\xc8\x13\x6a\xd2\x60\xd6\x19\x6c\x60\x4b\xd2\x08\x14\xf8\x36\x2d\x76\x1a\x83\xf1\x8c\x0e\xae\x45\x5e\xe4\x4b\x9a\x4d\x30\x39\xa8\x56\xc2\x7c\x07\xd0\x4e\x15\x37\x39\x6f\x5d\x2c\x27\xa0\xa5\xbb\x71\x58\x59\xc8\x21\x3f\x94\x98\xad\x6e\x14\x0d\x07\x9d\xb2\x95\xb1\x0d\x5b\x1c\x55\xe6\x01\x48\xd1\x2c\xe2\x75\x83\xfd\x0c\x1c\x3e\x1a\xaf\x82\x3b\x07\x73\x9a\xde\x79\x9a\x76\xa4\x80\x49\x1a\xe3\x9d\xda\xaa\xfb\x95\x10\xef\x2a\xd6\x2e\x8e\x5f\xd2\x6e\x7b\xe2\xe7\x88\x4b\x69\xa0\x5d\x6b\x7c\x58\xf4\x64\x8b\x9d\x8e\xaa\x97\xa3\xf1\x43\xfb\x30\xa2\xd0\x0c\x65\x1a\x1d\x26\x94\x6f\x3d\xe4\xba\xe0\x7a\xa7\x7c\x74\x90\x08\x3e\x5c\x63\x32\xf3\xe1\xaa\x22\x1c\xe6\x30\x6a\x25\x2e\x6b\xac\xb1\x98\x08\x55\x08\x0d\x9a\xff\xf1\xc1\x63\x14\xa2\xc9\x92\x32\x12\x2e\x80\x05\xd0\x33\x9c\x76\x43\xa4\x80\x6d\xbc\x6d\x2c\x33\x6e\x77\x14\xe3\x09\x02\x01\x08\x02\xb7\xd8\x87\xdb\xf9\x9a\x93\x66\xa8\x0d\x8a\xf2\x96\x57\xbd\x15\x5f\x30\xc9\x8a\x24\x3f\xe0\xf6\x7a\x4f\xe3\x17\x47\x08\x9c\x57\x6a\x07\x97\xef\x15\x9f\x26\xb7\xf1\xe0\x7d\xb7\x53\xe4\x10\x8c\x5f\xad\x86\x0c\x97\xd6\xdd\xb8\x1d\x5e\x04\x7d\xd3\xde\xea\x90\x3f\xa0\x19\xe7\x58\x0a\x75\xca\x28\x9a\x37\x7b\x2b\xd9\x68\xf6\xb0\x3b\x00\x96\xda\xc2\x27\xc6\xee\x87\x1d\x18\x27\x83\x81\xf9\x8b\x5f\xce\xde\x7c\x3d\xbd\xf8\xf8\xfa\xdd\x9b\xaf\x6f\x2f\x3e\x9c\x1f\xc7\x2d\x5a\xc6\xe4\x78\x82\x91\x38\x71\x14\x52\x19\xd1\x80\x03\x2e\x58\x15\x4b\x8a\xba\x07\x0c\x73\x0a\x66\x0a\x06\xb8\x7b\xf9\x60\x42\x66\x6c\x4f\x6f\x15\x10\x98\x8d\x12\x67\x3a\xcf\xd2\x3f\xdd\xe2\x2c\xe9\xc1\x7b\xcd\x57\x59\x98\xda\x58\x87\xc4\x68\x28\x70\x6a\x23\xcb\x64\xc7\x00\x0f\x8e\xe4\x9b\xa0\x3b\x7b\xf1\x32\x48\x3c\xd3\xf6\xd5\xf1\x84\xcc\x1d\xe7\x41\x54\xbe\x0a\x4b\x7f\xf6\x2c\xed\xe4\x1c\x7c\x48\xc9\xf8\x9d\x67\xcf\xc6\xbc\x99\xee\xee\x53\x6e\xe2\x65\x84\x2e\x85\x33\xb5\xb4\xfa\xbb\x2a\x79\xe7\x19\x3f\x8f\x7c\xf1\x8a\x87\x6c\x32\x95\x3c\x56\x9b\x42\xfa\xa0\xe9\xa0\xe3\x12\xe1\x54\xc8\xb8\xa1\xed\x99\x54\x61\x7d\x2b\x4b\x35\x44\x66\x78\x2a\xc1\x88\x2f\xed\x9e\xb3\x9a\xe3\x73\xea\x01\x72\xd9\x46\xc5\x8d\x07\x07\xf9\xcd\x83\x02\x8b\x5f\x76\x74\x1d\x52\xd5\xc7\xa8\x16\x87\x5b\xcd\xcc\x4b\xd3\xa0\x08\xc1\x85\x2c\x00\x03\xd4\xf0\xe4\x87\xf8\x60\x61\x95\x62\x76\xd3\xe3\xeb\xa0\xe0\x8f\x89\x76\x1d\x8a\xa1\x76\x4f\x39\x72\x15\xe9\x07\xaf\xcd\x4f\x0c\xe0\x99\xbd\x2f\x39\xc2\xa2\x49\xae\x80\x22\xad\xdb\x19\xff\x2a\x94\x67\xfc\x51\xc3\x02\x84\xb6\x26\xae\x59\x8f\xb0\xc2\xd2\x8e\xe6\x87\x6b\x06\x1b\x84\x9d\x1d\x5e\xb9\xd2\x23\x9a\xf6\x0f\x74\xc3\x8d\xfe\x3f\xea\x55\xb4\xd8\xda\x3e\xde\xd1\x52\xfc\x46\x25\x37\x6a\xd6\x48\xd4\x6f\xd7\x5b\x75\x20\x74\x78\xc0\x1a\x0f\xe2\x4a\xc1\x49\xc5\x7d\x54\x87\x15\x79\x08\xca\xc8\xef\xc3\xbb\xd3\xab\x8b\xaf\xd7\x57\x9f\xcf\x4f\x2f\xde\x5f\x5c\xa1\x99\xdc\x6a\x6b\x5a\xee\x05\xb7\xd0\x8d\x5a\x0b\x69\x4b\x65\x18\x86\xfd\x31\x31\xe5\xa5\x9b\xf8\xc6\x4e\xca\xd9\xe6\xe5\xc6\xc1\x9a\x69\x89\x06\x48\x10\x8c\x0e\xa7\x04\x7a\x24\x75\xfe\x9c\x87\x62\xbf\x6f\xbd\xbc\xc7\x79\xdf\x5b\xe4\x74\xf8\x44\x81\xa4\x67\x3d\x53\x55\x8f\x1c\x64\x76\x51\x34\x06\x78\xee\x2b\x38\x4f\x17\x30\x34\x19\x4c\x70\x32\x3c\x0c\x80\xe8\x31\x1e\x55\x15\x98\xc8\xde\xa3\xeb\x96\xb0\x1d\x2c\xb8\x1a\x0f\xcf\x81\x12\xcd\xe4\x2e\x94\xe9\xf4\x1c\xe2\x64\x43\xb7\x4f\xe4\xa1\x1c\xc6\x1a\x49\x9e\x4d\x6f\x4c\xe1\xa5\x85\x7d\xfd\x94\xe6\x96\x26\x2c\xc8\x8b\x3d\xe1\xe0\x0d\xe6\xc9\x93\x47\x47\x47\x59\x76\x16\x31\x5d\xdd\x6f\xa9\x93\x84\x5a\x18\x4a\x1f\xf8\x78\x66\x4c\x3f\x44\x2d\xdb\x6d\x8f\x89\x8f\x06\x09\x41\x33\x8f\x78\x19\x43\x06\xc1\x37\x22\xa9\x7e\x9c\x2e\xc5\xd9\x52\xbc\x31\x4b\xf1\x17\x79\x2b\x79\xcf\xa7\x1f\xc8\x13\xdd\xa1\x5c\xbd\xef\x25\x12\xe5\xd2\x9a\x5b\x5d\x8e\xb3\x59\x12\x17\x55\x59\xfd\x77\x9b\xb7\x46\x37\x1c\xae\x50\x8f\x9e\x0e\x87\xef\xa4\xdd\x23\x02\xb6\xe6\x7f\x31\x4f\xd7\xb8\x35\x55\xe3\x07\xce\xf8\xfd\xbb\xb8\x92\xca\x27\x98\x59\xe2\xb0\x41\x2d\x86\x92\x21\x56\x8f\x38\xc7\xa6\xc6\x4e\x52\xca\xf4\xb8\x45\x95\x53\x64\x87\xd5\x12\x87\xfd\xf0\xd6\x82\x0a\xb0\x24\x56\x0a\xb3\x66\x11\x46\xa1\xc3\x16\xce\x5c\x12\xff\x8c\x03\x92\x4a\x34\x84\x82\x78\x45\x73\xd7\x7c\xb2\xf3\x54\x21\x1e\xe1\xc3\x55\x97\xb4\xe7\xc7\x25\x43\x83\x65\xd6\x60\xda\xe3\xc7\xb6\xf8\x66\x5e\x60\x87\x0a\xb1\x3d\x53\x32\xda\xc3\x67\x44\x3c\xb3\xca\xfe\x13\x00\x00\xff\xff\x76\x03\x88\xe2\x7b\x18\x00\x00") func runtimeHelpHelpMdBytes() ([]byte, error) { return bindataRead( @@ -254,7 +254,7 @@ func runtimeHelpHelpMd() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "runtime/help/help.md", size: 5902, mode: os.FileMode(420), modTime: time.Unix(1462461886, 0)} + info := bindataFileInfo{name: "runtime/help/help.md", size: 6267, mode: os.FileMode(420), modTime: time.Unix(1462467388, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -274,7 +274,7 @@ func runtimePluginsGoGoLua() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "runtime/plugins/go/go.lua", size: 875, mode: os.FileMode(420), modTime: time.Unix(1462462186, 0)} + info := bindataFileInfo{name: "runtime/plugins/go/go.lua", size: 875, mode: os.FileMode(420), modTime: time.Unix(1462550078, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -294,7 +294,7 @@ func runtimePluginsLinterLinterLua() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "runtime/plugins/linter/linter.lua", size: 2252, mode: os.FileMode(420), modTime: time.Unix(1462462242, 0)} + info := bindataFileInfo{name: "runtime/plugins/linter/linter.lua", size: 2252, mode: os.FileMode(420), modTime: time.Unix(1462467208, 0)} a := &asset{bytes: bytes, info: info} return a, nil }