]> git.lizzy.rs Git - micro.git/blobdiff - internal/buffer/save.go
Support csharp-script syntax. (#1425)
[micro.git] / internal / buffer / save.go
index 5b23cb3bb934dff33633174a224f04c9284ced4f..6f07ea6c8b6b923a6558986b73872ee7bfc765b7 100644 (file)
@@ -1,6 +1,7 @@
 package buffer
 
 import (
+       "bufio"
        "bytes"
        "errors"
        "io"
@@ -8,6 +9,7 @@ import (
        "os/exec"
        "os/signal"
        "path/filepath"
+       "runtime"
        "unicode"
        "unicode/utf8"
 
@@ -26,70 +28,43 @@ const LargeFileThreshold = 50000
 // overwriteFile opens the given file for writing, truncating if one exists, and then calls
 // the supplied function with the file as io.Writer object, also making sure the file is
 // closed afterwards.
-func overwriteFile(name string, enc encoding.Encoding, fn func(io.Writer) error) (err error) {
-       var file *os.File
+func overwriteFile(name string, enc encoding.Encoding, fn func(io.Writer) error, withSudo bool) (err error) {
+       var writeCloser io.WriteCloser
 
-       if file, err = os.OpenFile(name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644); err != nil {
-               return
-       }
+       if withSudo {
+               cmd := exec.Command(config.GlobalSettings["sucmd"].(string), "dd", "bs=4k", "of="+name)
 
-       defer func() {
-               if e := file.Close(); e != nil && err == nil {
-                       err = e
+               if writeCloser, err = cmd.StdinPipe(); err != nil {
+                       return
                }
-       }()
 
-       w := transform.NewWriter(file, enc.NewEncoder())
-       // w := bufio.NewWriter(file)
-
-       if err = fn(w); err != nil {
-               return
-       }
-
-       // err = w.Flush()
-       return
-}
-
-// overwriteFileAsRoot executes dd as root and then calls the supplied function
-// with dd's standard input as an io.Writer object. Dd opens the given file for writing,
-// truncating it if it exists, and writes what it receives on its standard input to the file.
-func overwriteFileAsRoot(name string, enc encoding.Encoding, fn func(io.Writer) error) (err error) {
-       cmd := exec.Command(config.GlobalSettings["sucmd"].(string), "dd", "status=none", "bs=4K", "of="+name)
-       var stdin io.WriteCloser
-
-       screenb := screen.TempFini()
-
-       // This is a trap for Ctrl-C so that it doesn't kill micro
-       // Instead we trap Ctrl-C to kill the program we're running
-       c := make(chan os.Signal, 1)
-       signal.Notify(c, os.Interrupt)
-       go func() {
-               for range c {
+               c := make(chan os.Signal, 1)
+               signal.Notify(c, os.Interrupt)
+               go func() {
+                       <-c
                        cmd.Process.Kill()
-               }
-       }()
+               }()
 
-       if stdin, err = cmd.StdinPipe(); err != nil {
-               return
-       }
-
-       if err = cmd.Start(); err != nil {
+               defer func() {
+                       screenb := screen.TempFini()
+                       if e := cmd.Run(); e != nil && err == nil {
+                               err = e
+                       }
+                       screen.TempStart(screenb)
+               }()
+       } else if writeCloser, err = os.OpenFile(name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644); err != nil {
                return
        }
 
-       e := fn(stdin)
+       w := bufio.NewWriter(transform.NewWriter(writeCloser, enc.NewEncoder()))
+       err = fn(w)
+       w.Flush()
 
-       if err = stdin.Close(); err != nil {
-               return
-       }
-
-       if err = cmd.Wait(); err != nil {
-               return
+       if e := writeCloser.Close(); e != nil && err == nil {
+               err = e
        }
 
-       screen.TempStart(screenb)
-
-       return e
+       return
 }
 
 // Save saves the buffer to its default path
@@ -118,6 +93,9 @@ func (b *Buffer) saveToFile(filename string, withSudo bool) error {
        if b.Type.Scratch {
                return errors.New("Cannot save scratch buffer")
        }
+       if withSudo && runtime.GOOS == "windows" {
+               return errors.New("Save with sudo not supported on Windows")
+       }
 
        b.UpdateRules()
        if b.Settings["rmtrailingws"].(bool) {
@@ -133,8 +111,8 @@ func (b *Buffer) saveToFile(filename string, withSudo bool) error {
 
        if b.Settings["eofnewline"].(bool) {
                end := b.End()
-               if b.RuneAt(Loc{end.X - 1, end.Y}) != '\n' {
-                       b.Insert(end, "\n")
+               if b.RuneAt(Loc{end.X, end.Y}) != '\n' {
+                       b.insert(end, []byte{'\n'})
                }
        }
 
@@ -201,13 +179,7 @@ func (b *Buffer) saveToFile(filename string, withSudo bool) error {
                return
        }
 
-       if withSudo {
-               err = overwriteFileAsRoot(absFilename, enc, fwriter)
-       } else {
-               err = overwriteFile(absFilename, enc, fwriter)
-       }
-
-       if err != nil {
+       if err = overwriteFile(absFilename, enc, fwriter, withSudo); err != nil {
                return err
        }