]> git.lizzy.rs Git - micro.git/blobdiff - cmd/micro/command.go
Use the new and updated version of tcell
[micro.git] / cmd / micro / command.go
index faed87f432b9b4372138b595055a9550dd48947b..1e41a7b25b636ad857391140800f479ccdb8f838 100644 (file)
@@ -1,27 +1,75 @@
 package main
 
 import (
+       "bytes"
        "os"
        "os/exec"
+       "os/signal"
        "regexp"
        "strings"
 )
 
-func HandleShellCommand(input string, view *View) {
+// RunShellCommand executes a shell command and returns the output/error
+func RunShellCommand(input string) (string, error) {
        inputCmd := strings.Split(input, " ")[0]
        args := strings.Split(input, " ")[1:]
 
-       // Execute Command
-       cmdout := exec.Command(inputCmd, args...)
-       output, err := cmdout.Output()
-       if err != nil {
-               messenger.Error("Error: " + err.Error())
-               return
-       }
+       cmd := exec.Command(inputCmd, args...)
+       outputBytes := &bytes.Buffer{}
+       cmd.Stdout = outputBytes
+       cmd.Stderr = outputBytes
+       cmd.Start()
+       err := cmd.Wait() // wait for command to finish
+       outstring := outputBytes.String()
+       return outstring, err
+}
+
+// HandleShellCommand runs the shell command and outputs to DisplayBlock
+func HandleShellCommand(input string, view *View, openTerm bool) {
+       inputCmd := strings.Split(input, " ")[0]
+       if !openTerm {
+               messenger.Message("Running...")
+               go func() {
+                       output, err := RunShellCommand(input)
+                       totalLines := strings.Split(output, "\n")
+
+                       if len(totalLines) < 3 {
+                               if err == nil {
+                                       messenger.Message(inputCmd, " exited without error")
+                               } else {
+                                       messenger.Message(inputCmd, " exited with error: ", err, ": ", output)
+                               }
+                       } else {
+                               messenger.Message(output)
+                       }
+                       Redraw(view)
+               }()
+       } else {
+               screen.Fini()
+               screen = nil
+
+               args := strings.Split(input, " ")[1:]
+
+               cmd := exec.Command(inputCmd, args...)
+               cmd.Stdin = os.Stdin
+               cmd.Stdout = os.Stdout
+               cmd.Stderr = os.Stderr
+
+               c := make(chan os.Signal, 1)
+               signal.Notify(c, os.Interrupt)
+               go func() {
+                       for range c {
+                               cmd.Process.Kill()
+                       }
+               }()
 
-       // Display last line of output
-       messenger.Message(string(output))
+               cmd.Start()
+               cmd.Wait()
 
+               TermMessage("")
+
+               InitScreen()
+       }
 }
 
 // HandleCommand handles input from the user
@@ -29,7 +77,7 @@ func HandleCommand(input string, view *View) {
        inputCmd := strings.Split(input, " ")[0]
        args := strings.Split(input, " ")[1:]
 
-       commands := []string{"set", "quit", "save", "replace"}
+       commands := []string{"set", "quit", "save", "replace", "run"}
 
        i := 0
        cmd := inputCmd
@@ -47,8 +95,10 @@ func HandleCommand(input string, view *View) {
        switch inputCmd {
        case "set":
                SetOption(view, args)
+       case "run":
+               HandleShellCommand(strings.Join(args, " "), view, false)
        case "quit":
-               if view.CanClose("Quit anyway? ") {
+               if view.CanClose("Quit anyway? (yes, no, save) ") {
                        screen.Fini()
                        os.Exit(0)
                }
@@ -91,20 +141,41 @@ func HandleCommand(input string, view *View) {
 
                found := false
                for {
-                       match := regex.FindStringIndex(view.buf.text)
+                       match := regex.FindStringIndex(view.Buf.String())
                        if match == nil {
                                break
                        }
                        found = true
                        if strings.Contains(flags, "c") {
-                               //      // The 'check' flag was used
-                               //      if messenger.YesNoPrompt("Perform replacement?") {
-                               //              view.eh.Replace(match[0], match[1], replace)
-                               //      } else {
-                               //              continue
-                               //      }
+                               // The 'check' flag was used
+                               Search(search, view, true)
+                               view.Relocate()
+                               Redraw(view)
+                               choice, canceled := messenger.YesNoPrompt("Perform replacement? (y,n)")
+                               if canceled {
+                                       if view.Cursor.HasSelection() {
+                                               view.Cursor.SetLoc(view.Cursor.curSelection[0])
+                                               view.Cursor.ResetSelection()
+                                       }
+                                       messenger.Reset()
+                                       return
+                               }
+                               if choice {
+                                       view.Cursor.DeleteSelection()
+                                       view.eh.Insert(match[0], replace)
+                                       view.Cursor.ResetSelection()
+                                       messenger.Reset()
+                               } else {
+                                       if view.Cursor.HasSelection() {
+                                               searchStart = view.Cursor.curSelection[1]
+                                       } else {
+                                               searchStart = ToCharPos(view.Cursor.x, view.Cursor.y, view.Buf)
+                                       }
+                                       continue
+                               }
+                       } else {
+                               view.eh.Replace(match[0], match[1], replace)
                        }
-                       view.eh.Replace(match[0], match[1], replace)
                }
                if !found {
                        messenger.Message("Nothing matched " + search)