11 . "github.com/zyedidia/micro/cmd/micro/util"
13 "github.com/zyedidia/micro/cmd/micro/config"
16 // Save saves the buffer to its default path
17 func (b *Buffer) Save() error {
18 return b.SaveAs(b.Path)
21 // SaveAs saves the buffer to a specified path (filename), creating the file if it does not exist
22 func (b *Buffer) SaveAs(filename string) error {
23 // TODO: rmtrailingws and updaterules
25 // if b.Settings["rmtrailingws"].(bool) {
26 // for i, l := range b.lines {
27 // pos := len(bytes.TrimRightFunc(l.data, unicode.IsSpace))
29 // if pos < len(l.data) {
30 // b.deleteToEnd(Loc{pos, i})
34 // b.Cursor.Relocate()
37 if b.Settings["eofnewline"].(bool) {
39 if b.RuneAt(Loc{end.X - 1, end.Y}) != '\n' {
44 // Update the last time this file was updated after saving
46 b.ModTime, _ = GetModTime(filename)
49 // Removes any tilde and replaces with the absolute path to home
50 absFilename, _ := ReplaceHome(filename)
52 // TODO: save creates parent dirs
53 // // Get the leading path to the file | "." is returned if there's no leading path provided
54 // if dirname := filepath.Dir(absFilename); dirname != "." {
55 // // Check if the parent dirs don't exist
56 // if _, statErr := os.Stat(dirname); os.IsNotExist(statErr) {
57 // // Prompt to make sure they want to create the dirs that are missing
58 // if yes, canceled := messenger.YesNoPrompt("Parent folders \"" + dirname + "\" do not exist. Create them? (y,n)"); yes && !canceled {
59 // // Create all leading dir(s) since they don't exist
60 // if mkdirallErr := os.MkdirAll(dirname, os.ModePerm); mkdirallErr != nil {
61 // // If there was an error creating the dirs
65 // // If they canceled the creation of leading dirs
66 // return errors.New("Save aborted")
73 err := overwriteFile(absFilename, func(file io.Writer) (e error) {
74 if len(b.lines) == 0 {
80 if b.Settings["fileformat"] == "dos" {
81 eol = []byte{'\r', '\n'}
87 if fileSize, e = file.Write(b.lines[0].data); e != nil {
91 for _, l := range b.lines[1:] {
92 if _, e = file.Write(eol); e != nil {
95 if _, e = file.Write(l.data); e != nil {
98 fileSize += len(eol) + len(l.data)
107 if !b.Settings["fastdirty"].(bool) {
108 if fileSize > LargeFileThreshold {
109 // For large files 'fastdirty' needs to be on
110 b.Settings["fastdirty"] = true
112 calcHash(b, &b.origHash)
117 absPath, _ := filepath.Abs(filename)
123 // SaveWithSudo saves the buffer to the default path with sudo
124 func (b *Buffer) SaveWithSudo() error {
125 return b.SaveAsWithSudo(b.Path)
128 // SaveAsWithSudo is the same as SaveAs except it uses a neat trick
129 // with tee to use sudo so the user doesn't have to reopen micro with sudo
130 func (b *Buffer) SaveAsWithSudo(filename string) error {
133 absPath, _ := filepath.Abs(filename)
136 // Set up everything for the command
137 cmd := exec.Command(config.GlobalSettings["sucmd"].(string), "tee", filename)
138 cmd.Stdin = bytes.NewBuffer(b.Bytes())
140 // This is a trap for Ctrl-C so that it doesn't kill micro
141 // Instead we trap Ctrl-C to kill the program we're running
142 c := make(chan os.Signal, 1)
143 signal.Notify(c, os.Interrupt)
156 b.ModTime, _ = GetModTime(filename)