]> git.lizzy.rs Git - micro.git/blobdiff - cmd/micro/action/command.go
Fix yn callback bug
[micro.git] / cmd / micro / action / command.go
index e4525ab01decad0e6bc54fe865c1a45130ee8ed1..ef4762df95b4d9be9d2d01d90db27c40f3493d28 100644 (file)
@@ -1,7 +1,12 @@
 package action
 
 import (
+       "errors"
+       "fmt"
        "os"
+       "path/filepath"
+       "strconv"
+       "strings"
 
        "github.com/zyedidia/micro/cmd/micro/buffer"
        "github.com/zyedidia/micro/cmd/micro/config"
@@ -32,6 +37,7 @@ var commandActions = map[string]func(*BufHandler, []string){
        "ShowKey":    (*BufHandler).ShowKeyCmd,
        "Run":        (*BufHandler).RunCmd,
        "Bind":       (*BufHandler).BindCmd,
+       "Unbind":     (*BufHandler).UnbindCmd,
        "Quit":       (*BufHandler).QuitCmd,
        "Save":       (*BufHandler).SaveCmd,
        "Replace":    (*BufHandler).ReplaceCmd,
@@ -89,6 +95,7 @@ func DefaultCommands() map[string]StrCommand {
                "show":       {"Show", []Completion{OptionCompletion, NoCompletion}},
                "showkey":    {"ShowKey", []Completion{NoCompletion}},
                "bind":       {"Bind", []Completion{NoCompletion}},
+               "unbind":     {"Unbind", []Completion{NoCompletion}},
                "run":        {"Run", []Completion{NoCompletion}},
                "quit":       {"Quit", []Completion{NoCompletion}},
                "save":       {"Save", []Completion{NoCompletion}},
@@ -143,6 +150,7 @@ func (h *BufHandler) PluginCmd(args []string) {
 // RetabCmd changes all spaces to tabs or all tabs to spaces
 // depending on the user's settings
 func (h *BufHandler) RetabCmd(args []string) {
+       h.Buf.Retab()
 }
 
 // RawCmd opens a new raw view which displays the escape sequences micro
@@ -152,10 +160,55 @@ func (h *BufHandler) RawCmd(args []string) {
 
 // TabSwitchCmd switches to a given tab either by name or by number
 func (h *BufHandler) TabSwitchCmd(args []string) {
+       if len(args) > 0 {
+               num, err := strconv.Atoi(args[0])
+               if err != nil {
+                       // Check for tab with this name
+
+                       found := false
+                       for i, t := range Tabs.List {
+                               if t.Panes[t.active].Name() == args[0] {
+                                       Tabs.SetActive(i)
+                                       found = true
+                               }
+                       }
+                       if !found {
+                               InfoBar.Error("Could not find tab: ", err)
+                       }
+               } else {
+                       num--
+                       if num >= 0 && num < len(Tabs.List) {
+                               Tabs.SetActive(num)
+                       } else {
+                               InfoBar.Error("Invalid tab index")
+                       }
+               }
+       }
 }
 
 // CdCmd changes the current working directory
 func (h *BufHandler) CdCmd(args []string) {
+       if len(args) > 0 {
+               path, err := util.ReplaceHome(args[0])
+               if err != nil {
+                       InfoBar.Error(err)
+                       return
+               }
+               err = os.Chdir(path)
+               if err != nil {
+                       InfoBar.Error(err)
+                       return
+               }
+               wd, _ := os.Getwd()
+               for _, b := range buffer.OpenBuffers {
+                       if len(b.Path) > 0 {
+                               b.Path, _ = util.MakeRelative(b.AbsPath, wd)
+                               if p, _ := filepath.Abs(b.Path); !strings.Contains(p, wd) {
+                                       b.Path = b.AbsPath
+                               }
+                       }
+               }
+       }
 }
 
 // MemUsageCmd prints micro's memory usage
@@ -181,6 +234,39 @@ func (h *BufHandler) PwdCmd(args []string) {
 
 // OpenCmd opens a new buffer with a given filename
 func (h *BufHandler) OpenCmd(args []string) {
+       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)
+               if err != nil {
+                       InfoBar.Error("Error parsing args ", err)
+                       return
+               }
+               filename = strings.Join(args, " ")
+
+               open := func() {
+                       b, err := buffer.NewBufferFromFile(filename, buffer.BTDefault)
+                       if err != nil {
+                               InfoBar.Error(err)
+                               return
+                       }
+                       h.OpenBuffer(b)
+               }
+               if h.Buf.Modified() {
+                       InfoBar.YNPrompt("Save changes to "+h.Buf.GetName()+" before closing? (y,n,esc)", func(yes, canceled bool) {
+                               if !canceled && !yes {
+                                       open()
+                               } else if !canceled && yes {
+                                       h.Save()
+                                       open()
+                               }
+                       })
+               } else {
+                       open()
+               }
+       } else {
+               InfoBar.Error("No filename")
+       }
 }
 
 // ToggleLogCmd toggles the log view
@@ -191,8 +277,37 @@ func (h *BufHandler) ToggleLogCmd(args []string) {
 func (h *BufHandler) ReloadCmd(args []string) {
 }
 
+func (h *BufHandler) openHelp(page string) error {
+       if data, err := config.FindRuntimeFile(config.RTHelp, page).Data(); err != nil {
+               return errors.New(fmt.Sprint("Unable to load help text", page, "\n", err))
+       } else {
+               helpBuffer := buffer.NewBufferFromString(string(data), page+".md", buffer.BTHelp)
+               helpBuffer.SetName("Help " + page)
+
+               if h.Buf.Type == buffer.BTHelp {
+                       h.OpenBuffer(helpBuffer)
+               } else {
+                       h.HSplitBuf(helpBuffer)
+               }
+       }
+       return nil
+}
+
 // HelpCmd tries to open the given help page in a horizontal split
 func (h *BufHandler) HelpCmd(args []string) {
+       if len(args) < 1 {
+               // Open the default help if the user just typed "> help"
+               h.openHelp("help")
+       } else {
+               if config.FindRuntimeFile(config.RTHelp, args[0]) != nil {
+                       err := h.openHelp(args[0])
+                       if err != nil {
+                               InfoBar.Error(err)
+                       }
+               } else {
+                       InfoBar.Error("Sorry, no help for ", args[0])
+               }
+       }
 }
 
 // VSplitCmd opens a vertical split with file given in the first argument
@@ -238,6 +353,7 @@ func (h *BufHandler) EvalCmd(args []string) {
 // NewTabCmd opens the given file in a new tab
 func (h *BufHandler) NewTabCmd(args []string) {
        width, height := screen.Screen.Size()
+       iOffset := config.GetInfoBarOffset()
        if len(args) > 0 {
                for _, a := range args {
                        b, err := buffer.NewBufferFromFile(a, buffer.BTDefault)
@@ -245,13 +361,13 @@ func (h *BufHandler) NewTabCmd(args []string) {
                                InfoBar.Error(err)
                                return
                        }
-                       tp := NewTabFromBuffer(0, 0, width, height-1, b)
+                       tp := NewTabFromBuffer(0, 0, width, height-1-iOffset, b)
                        Tabs.AddTab(tp)
                        Tabs.SetActive(len(Tabs.List) - 1)
                }
        } else {
                b := buffer.NewBufferFromString("", "", buffer.BTDefault)
-               tp := NewTabFromBuffer(0, 0, width, height-1, b)
+               tp := NewTabFromBuffer(0, 0, width, height-iOffset, b)
                Tabs.AddTab(tp)
                Tabs.SetActive(len(Tabs.List) - 1)
        }
@@ -278,11 +394,9 @@ func SetGlobalOption(option, value string) error {
        }
 
        // TODO: info and keymenu option change
-       // if option == "infobar" || option == "keymenu" {
-       //      for _, tab := range tabs {
-       //              tab.Resize()
-       //      }
-       // }
+       if option == "infobar" || option == "keymenu" {
+               Tabs.Resize()
+       }
 
        if option == "mouse" {
                if !nativeValue.(bool) {
@@ -341,6 +455,24 @@ func (h *BufHandler) SetLocalCmd(args []string) {
 
 // ShowCmd shows the value of the given option
 func (h *BufHandler) ShowCmd(args []string) {
+       if len(args) < 1 {
+               InfoBar.Error("Please provide an option to show")
+               return
+       }
+
+       var option interface{}
+       if opt, ok := h.Buf.Settings[args[0]]; ok {
+               option = opt
+       } else if opt, ok := config.GlobalSettings[args[0]]; ok {
+               option = opt
+       }
+
+       if option == nil {
+               InfoBar.Error(args[0], " is not a valid option")
+               return
+       }
+
+       InfoBar.Message(option)
 }
 
 // ShowKeyCmd displays the action that a key is bound to
@@ -359,6 +491,28 @@ func (h *BufHandler) ShowKeyCmd(args []string) {
 
 // BindCmd creates a new keybinding
 func (h *BufHandler) BindCmd(args []string) {
+       if len(args) < 2 {
+               InfoBar.Error("Not enough arguments")
+               return
+       }
+
+       _, err := TryBindKey(args[0], args[1], true)
+       if err != nil {
+               InfoBar.Error(err)
+       }
+}
+
+// UnbindCmd binds a key to its default action
+func (h *BufHandler) UnbindCmd(args []string) {
+       if len(args) < 1 {
+               InfoBar.Error("Not enough arguements")
+               return
+       }
+
+       err := UnbindKey(args[0])
+       if err != nil {
+               InfoBar.Error(err)
+       }
 }
 
 // RunCmd runs a shell command in the background
@@ -376,10 +530,12 @@ func (h *BufHandler) RunCmd(args []string) {
 
 // QuitCmd closes the main view
 func (h *BufHandler) QuitCmd(args []string) {
+       h.Quit()
 }
 
 // SaveCmd saves the buffer in the main view
 func (h *BufHandler) SaveCmd(args []string) {
+       h.Save()
 }
 
 // ReplaceCmd runs search and replace
@@ -403,9 +559,7 @@ func (h *BufHandler) TermCmd(args []string) {
                args = []string{sh}
        }
 
-       term := func(i int) {
-               // If there is only one open file we make a new tab instead of overwriting it
-               newtab := len(MainTab().Panes) == 1 && len(Tabs.List) == 1
+       term := func(i int, newtab bool) {
 
                t := new(shell.Terminal)
                t.Start(args, false, true)
@@ -424,19 +578,27 @@ func (h *BufHandler) TermCmd(args []string) {
                MainTab().SetActive(i)
        }
 
+       // If there is only one open file we make a new tab instead of overwriting it
+       newtab := len(MainTab().Panes) == 1 && len(Tabs.List) == 1
+
+       if newtab {
+               term(0, true)
+               return
+       }
+
        for i, p := range ps {
                if p.ID() == h.ID() {
                        if h.Buf.Modified() {
                                InfoBar.YNPrompt("Save changes to "+h.Buf.GetName()+" before closing? (y,n,esc)", func(yes, canceled bool) {
                                        if !canceled && !yes {
-                                               term(i)
+                                               term(i, false)
                                        } else if !canceled && yes {
                                                h.Save()
-                                               term(i)
+                                               term(i, false)
                                        }
                                })
                        } else {
-                               term(i)
+                               term(i, false)
                        }
                }
        }