X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=cmd%2Fmicro%2Faction%2Fcommand.go;h=ef4762df95b4d9be9d2d01d90db27c40f3493d28;hb=538f0117bcc1014b08b48eebcd8b7878c9421cb4;hp=e4525ab01decad0e6bc54fe865c1a45130ee8ed1;hpb=a5e7122b306bd8c71a9ede13dd35e329507564d5;p=micro.git diff --git a/cmd/micro/action/command.go b/cmd/micro/action/command.go index e4525ab0..ef4762df 100644 --- a/cmd/micro/action/command.go +++ b/cmd/micro/action/command.go @@ -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) } } }