X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=cmd%2Fmicro%2Fmicro.go;h=066e3200d98ae2c4f7519e6e0ac2d7a6a6309dff;hb=7adcb13c084842822b2991a4d1ee3881535ceb1e;hp=cef6c976f84711490fe5a271a2fac9189b35ef44;hpb=2adaf68bd438ffe648bf17bb5d912d2e628250a3;p=micro.git diff --git a/cmd/micro/micro.go b/cmd/micro/micro.go index cef6c976..066e3200 100644 --- a/cmd/micro/micro.go +++ b/cmd/micro/micro.go @@ -5,12 +5,15 @@ import ( "fmt" "io/ioutil" "os" + "runtime" - "github.com/gdamore/tcell" - "github.com/gdamore/tcell/encoding" "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" ) const ( @@ -27,7 +30,8 @@ var ( // Object to send messages and prompts to the user messenger *Messenger - // The default style + // The default highlighting style + // This simply defines the default foreground and background colors defStyle tcell.Style // Where the user's configuration is @@ -35,17 +39,25 @@ var ( // If $XDG_CONFIG_HOME is not set, it is ~/.config/micro configDir string - // Version is the version number. + // Version is the version number or commit hash // This should be set by the linker Version = "Unknown" - // Is the help screen open - helpOpen = false + // L is the lua state + // This is the VM that runs the plugins + L *lua.LState + + // The list of views + views []*View + // This is the currently open view + // It's just an index to the view in the views array + mainView int ) // LoadInput loads the file input for the editor func LoadInput() (string, []byte, error) { // There are a number of ways micro should start given its input + // 1. If it is given a file in os.Args, it should open that // 2. If there is no input file and the input is not a terminal, that means @@ -79,15 +91,15 @@ func LoadInput() (string, []byte, error) { return filename, input, err } -// InitConfigDir finds the configuration directory for micro according to the -// XDG spec. +// InitConfigDir finds the configuration directory for micro according to the XDG spec. // If no directory is found, it creates one. func InitConfigDir() { xdgHome := os.Getenv("XDG_CONFIG_HOME") if xdgHome == "" { + // The user has not set $XDG_CONFIG_HOME so we should act like it was set to ~/.config home, err := homedir.Dir() if err != nil { - TermMessage("Error finding your home directory\nCan't load syntax files") + TermMessage("Error finding your home directory\nCan't load config files") return } xdgHome = home + "/.config" @@ -95,6 +107,7 @@ func InitConfigDir() { configDir = xdgHome + "/micro" if _, err := os.Stat(xdgHome); os.IsNotExist(err) { + // If the xdgHome doesn't exist we should create it err = os.Mkdir(xdgHome, os.ModePerm) if err != nil { TermMessage("Error creating XDG_CONFIG_HOME directory: " + err.Error()) @@ -102,6 +115,7 @@ func InitConfigDir() { } if _, err := os.Stat(configDir); os.IsNotExist(err) { + // If the micro specific config directory doesn't exist we should create that too err = os.Mkdir(configDir, os.ModePerm) if err != nil { TermMessage("Error creating configuration directory: " + err.Error()) @@ -144,6 +158,7 @@ func InitScreen() { Background(tcell.ColorDefault) // There may be another default style defined in the colorscheme + // In that case we should use that one if style, ok := colorscheme["default"]; ok { defStyle = style } @@ -152,10 +167,12 @@ func InitScreen() { screen.EnableMouse() } -// Redraw redraws the screen and the given view -func Redraw(view *View) { +// RedrawAll redraws everything -- all the views and the messenger +func RedrawAll() { screen.Clear() - view.Display() + for _, v := range views { + v.Display() + } messenger.Display() screen.Show() } @@ -175,6 +192,10 @@ func main() { os.Exit(1) } + L = lua.NewState() + defer L.Close() + + // Some encoding stuff in case the user isn't using UTF-8 encoding.Register() tcell.SetEncodingFallback(tcell.EncodingFallbackASCII) @@ -182,9 +203,12 @@ func main() { InitConfigDir() // Load the user's settings InitSettings() + InitCommands() InitBindings() // Load the syntax files, including the colorscheme LoadSyntaxFiles() + // Load the help files + LoadHelp() buf := NewBuffer(string(input), filename) @@ -192,6 +216,7 @@ func main() { // This is just so if we have an error, we can exit cleanly and not completely // mess up the terminal being worked in + // In other words we need to shut down tcell before the program crashes defer func() { if err := recover(); err != nil { screen.Fini() @@ -203,58 +228,35 @@ func main() { }() messenger = new(Messenger) - view := NewView(buf) + messenger.history = make(map[string][]string) + views = make([]*View, 1) + views[0] = NewView(buf) + + L.SetGlobal("OS", luar.New(L, runtime.GOOS)) + L.SetGlobal("views", luar.New(L, views)) + L.SetGlobal("mainView", luar.New(L, mainView)) + L.SetGlobal("messenger", luar.New(L, messenger)) + L.SetGlobal("GetOption", luar.New(L, GetOption)) + L.SetGlobal("AddOption", luar.New(L, AddOption)) + L.SetGlobal("BindKey", luar.New(L, BindKey)) + L.SetGlobal("MakeCommand", luar.New(L, MakeCommand)) + + LoadPlugins() for { // Display everything - Redraw(view) + RedrawAll() // Wait for the user's action event := screen.PollEvent() if searching { - HandleSearchEvent(event, view) + // Since searching is done in real time, we need to redraw every time + // there is a new event in the search bar + HandleSearchEvent(event, views[mainView]) } else { - // Check if we should quit - switch e := event.(type) { - case *tcell.EventKey: - switch e.Key() { - case tcell.KeyCtrlQ: - // Make sure not to quit if there are unsaved changes - if helpOpen { - view.OpenBuffer(buf) - helpOpen = false - } else { - if view.CanClose("Quit anyway? (yes, no, save) ") { - screen.Fini() - os.Exit(0) - } - } - case tcell.KeyCtrlE: - input, canceled := messenger.Prompt("> ") - if !canceled { - HandleCommand(input, view) - } - case tcell.KeyCtrlB: - input, canceled := messenger.Prompt("$ ") - if !canceled { - HandleShellCommand(input, view, true) - } - case tcell.KeyCtrlG: - if !helpOpen { - helpBuffer := NewBuffer(helpTxt, "") - helpBuffer.name = "Help" - helpOpen = true - view.OpenBuffer(helpBuffer) - } else { - view.OpenBuffer(buf) - helpOpen = false - } - } - } - // Send it to the view - view.HandleEvent(event) + views[mainView].HandleEvent(event) } } }