package action
import (
+ "errors"
+ "fmt"
"os"
+ "path/filepath"
+ "strconv"
+ "strings"
"github.com/zyedidia/micro/cmd/micro/buffer"
"github.com/zyedidia/micro/cmd/micro/config"
"ShowKey": (*BufHandler).ShowKeyCmd,
"Run": (*BufHandler).RunCmd,
"Bind": (*BufHandler).BindCmd,
+ "Unbind": (*BufHandler).UnbindCmd,
"Quit": (*BufHandler).QuitCmd,
"Save": (*BufHandler).SaveCmd,
"Replace": (*BufHandler).ReplaceCmd,
"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}},
// 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
// 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
// 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
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
// 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)
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)
}
}
// 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) {
// 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
// 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
// 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
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)
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)
}
}
}