"strings"
"unicode/utf8"
- luar "layeh.com/gopher-luar"
-
- lua "github.com/yuin/gopher-lua"
+ shellquote "github.com/kballard/go-shellquote"
"github.com/zyedidia/micro/internal/buffer"
"github.com/zyedidia/micro/internal/config"
- ulua "github.com/zyedidia/micro/internal/lua"
"github.com/zyedidia/micro/internal/screen"
"github.com/zyedidia/micro/internal/shell"
"github.com/zyedidia/micro/internal/util"
- "github.com/zyedidia/micro/pkg/shellwords"
)
// A Command contains information about how to execute a command
// MakeCommand is a function to easily create new commands
// This can be called by plugins in Lua so that plugins can define their own commands
-func LuaMakeCommand(name, function string, completer buffer.Completer) {
- action := LuaFunctionCommand(function)
- commands[name] = Command{action, completer}
-}
-
-// LuaFunctionCommand returns a normal function
-// so that a command can be bound to a lua function
-func LuaFunctionCommand(fn string) func(*BufPane, []string) {
- luaFn := strings.Split(fn, ".")
- if len(luaFn) <= 1 {
- return nil
- }
- plName, plFn := luaFn[0], luaFn[1]
- pl := config.FindPlugin(plName)
- if pl == nil {
- return nil
- }
- return func(bp *BufPane, args []string) {
- luaArgs := []lua.LValue{luar.New(ulua.L, bp), luar.New(ulua.L, args)}
- _, err := pl.Call(plFn, luaArgs...)
- if err != nil {
- screen.TermMessage(err)
- }
+func MakeCommand(name string, action func(bp *BufPane, args []string), completer buffer.Completer) {
+ if action != nil {
+ commands[name] = Command{action, completer}
}
}
}
}
-var PluginCmds = []string{"list", "info", "version"}
+var PluginCmds = []string{"install", "remove", "update", "available", "list", "search"}
// PluginCmd installs, removes, updates, lists, or searches for given plugins
func (h *BufPane) PluginCmd(args []string) {
- if len(args) <= 0 {
- InfoBar.Error("Not enough arguments, see 'help commands'")
- return
- }
-
- valid := true
- switch args[0] {
- case "list":
- for _, pl := range config.Plugins {
- var en string
- if pl.IsEnabled() {
- en = "enabled"
- } else {
- en = "disabled"
- }
- WriteLog(fmt.Sprintf("%s: %s", pl.Name, en))
- if pl.Default {
- WriteLog(" (default)\n")
- } else {
- WriteLog("\n")
- }
- }
- WriteLog("Default plugins come pre-installed with micro.")
- case "version":
- if len(args) <= 1 {
- InfoBar.Error("No plugin provided to give info for")
- return
- }
- found := false
- for _, pl := range config.Plugins {
- if pl.Name == args[1] {
- found = true
- if pl.Info == nil {
- InfoBar.Message("Sorry no version for", pl.Name)
- return
- }
-
- WriteLog("Version: " + pl.Info.Vstr + "\n")
- }
- }
- if !found {
- InfoBar.Message(args[1], "is not installed")
- }
- case "info":
- if len(args) <= 1 {
- InfoBar.Error("No plugin provided to give info for")
- return
- }
- found := false
- for _, pl := range config.Plugins {
- if pl.Name == args[1] {
- found = true
- if pl.Info == nil {
- InfoBar.Message("Sorry no info for ", pl.Name)
- return
- }
-
- var buffer bytes.Buffer
- buffer.WriteString("Name: ")
- buffer.WriteString(pl.Info.Name)
- buffer.WriteString("\n")
- buffer.WriteString("Description: ")
- buffer.WriteString(pl.Info.Desc)
- buffer.WriteString("\n")
- buffer.WriteString("Website: ")
- buffer.WriteString(pl.Info.Site)
- buffer.WriteString("\n")
- buffer.WriteString("Installation link: ")
- buffer.WriteString(pl.Info.Install)
- buffer.WriteString("\n")
- buffer.WriteString("Version: ")
- buffer.WriteString(pl.Info.Vstr)
- buffer.WriteString("\n")
- buffer.WriteString("Requirements:")
- buffer.WriteString("\n")
- for _, r := range pl.Info.Require {
- buffer.WriteString(" - ")
- buffer.WriteString(r)
- buffer.WriteString("\n")
- }
-
- WriteLog(buffer.String())
- }
- }
- if !found {
- InfoBar.Message(args[1], "is not installed")
- return
- }
- default:
- InfoBar.Error("Not a valid plugin command")
+ if len(args) < 1 {
+ InfoBar.Error("Not enough arguments")
return
}
- if valid && h.Buf.Type != buffer.BTLog {
+ if h.Buf.Type != buffer.BTLog {
OpenLogBuf(h)
}
+
+ config.PluginCommand(buffer.LogBuf, args[0], args[1:])
}
// RetabCmd changes all spaces to tabs or all tabs to spaces
func (h *BufPane) RawCmd(args []string) {
width, height := screen.Screen.Size()
iOffset := config.GetInfoBarOffset()
- tp := NewTabFromPane(0, 0, width, height-iOffset, NewRawPane())
+ tp := NewTabFromPane(0, 0, width, height-iOffset, NewRawPane(nil))
Tabs.AddTab(tp)
Tabs.SetActive(len(Tabs.List) - 1)
}
if len(args) > 0 {
filename := args[0]
// the filename might or might not be quoted, so unquote first then join the strings.
- args, err := shellwords.Split(filename)
+ args, err := shellquote.Split(filename)
if err != nil {
InfoBar.Error("Error parsing args ", err)
return
}
+ if len(args) == 0 {
+ return
+ }
filename = strings.Join(args, " ")
open := func() {
}
func SetGlobalOptionNative(option string, nativeValue interface{}) error {
- config.GlobalSettings[option] = nativeValue
-
- if option == "colorscheme" {
- // LoadSyntaxFiles()
- config.InitColorscheme()
- for _, b := range buffer.OpenBuffers {
- b.UpdateRules()
+ local := false
+ for _, s := range config.LocalSettings {
+ if s == option {
+ local = true
+ break
}
- } else if option == "infobar" || option == "keymenu" {
- Tabs.Resize()
- } else if option == "mouse" {
- if !nativeValue.(bool) {
- screen.Screen.DisableMouse()
+ }
+
+ if !local {
+ config.GlobalSettings[option] = nativeValue
+
+ if option == "colorscheme" {
+ // LoadSyntaxFiles()
+ config.InitColorscheme()
+ for _, b := range buffer.OpenBuffers {
+ b.UpdateRules()
+ }
+ } else if option == "infobar" || option == "keymenu" {
+ Tabs.Resize()
+ } else if option == "mouse" {
+ if !nativeValue.(bool) {
+ screen.Screen.DisableMouse()
+ } else {
+ screen.Screen.EnableMouse()
+ }
+ } else if option == "autosave" {
+ if nativeValue.(float64) > 0 {
+ config.SetAutoTime(int(nativeValue.(float64)))
+ config.StartAutoSave()
+ } else {
+ config.SetAutoTime(0)
+ }
+ } else if option == "paste" {
+ screen.Screen.SetPaste(nativeValue.(bool))
} else {
- screen.Screen.EnableMouse()
- }
- // } else if option == "autosave" {
- // if nativeValue.(float64) > 0 {
- // config.SetAutoTime(int(nativeValue.(float64)))
- // config.StartAutoSave()
- // } else {
- // config.SetAutoTime(0)
- // }
- } else if option == "paste" {
- screen.Screen.SetPaste(nativeValue.(bool))
- } else {
- for _, pl := range config.Plugins {
- if option == pl.Name {
- if nativeValue.(bool) && !pl.Loaded {
- pl.Load()
- pl.Call("init")
- } else if !nativeValue.(bool) && pl.Loaded {
- pl.Call("deinit")
+ for _, pl := range config.Plugins {
+ if option == pl.Name {
+ if nativeValue.(bool) && !pl.Loaded {
+ pl.Load()
+ _, err := pl.Call("init")
+ if err != nil && err != config.ErrNoSuchFunction {
+ screen.TermMessage(err)
+ }
+ } else if !nativeValue.(bool) && pl.Loaded {
+ _, err := pl.Call("deinit")
+ if err != nil && err != config.ErrNoSuchFunction {
+ screen.TermMessage(err)
+ }
+ }
}
}
}
// RunCmd runs a shell command in the background
func (h *BufPane) RunCmd(args []string) {
- runf, err := shell.RunBackgroundShell(shellwords.Join(args...))
+ runf, err := shell.RunBackgroundShell(shellquote.Join(args...))
if err != nil {
InfoBar.Error(err)
} else {
// TermCmd opens a terminal in the current view
func (h *BufPane) TermCmd(args []string) {
- ps := MainTab().Panes
+ ps := h.tab.Panes
if len(args) == 0 {
sh := os.Getenv("SHELL")
term := func(i int, newtab bool) {
t := new(shell.Terminal)
- t.Start(args, false, true, "", nil)
+ t.Start(args, false, true, nil, nil)
id := h.ID()
if newtab {
}
v := h.GetView()
- MainTab().Panes[i] = NewTermPane(v.X, v.Y, v.Width, v.Height, t, id)
+ MainTab().Panes[i] = NewTermPane(v.X, v.Y, v.Width, v.Height, t, id, MainTab())
MainTab().SetActive(i)
}
// HandleCommand handles input from the user
func (h *BufPane) HandleCommand(input string) {
- args, err := shellwords.Split(input)
+ args, err := shellquote.Split(input)
if err != nil {
InfoBar.Error("Error parsing args ", err)
return
}
+ if len(args) == 0 {
+ return
+ }
+
inputCmd := args[0]
if _, ok := commands[inputCmd]; !ok {