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
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
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)
}
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)