@@ -337,6 +337,27 @@ func (b *Buffer) saveToFile(filename string, withSudo bool, autoSave bool) error
337337 return err
338338}
339339
340+ func (b * Buffer ) backupFile (path string ) (string , error ) {
341+ backupDir := b .backupDir ()
342+ if _ , err := os .Stat (backupDir ); err != nil {
343+ if ! errors .Is (err , fs .ErrNotExist ) {
344+ return "" , err
345+ }
346+ if err = os .Mkdir (backupDir , os .ModePerm ); err != nil {
347+ return "" , err
348+ }
349+ }
350+
351+ backupName := util .DetermineEscapePath (backupDir , path )
352+ _ , err := b .overwriteFile (backupName )
353+ if err != nil {
354+ os .Remove (backupName )
355+ return "" , err
356+ }
357+
358+ return backupName , nil
359+ }
360+
340361// safeWrite writes the buffer to a file in a "safe" way, preventing loss of the
341362// contents of the file if it fails to write the new contents.
342363// This means that the file is not overwritten directly but by writing to the
@@ -353,39 +374,36 @@ func (b *Buffer) safeWrite(path string, withSudo bool, newFile bool) (int, error
353374 }
354375 }()
355376
356- backupDir := b .backupDir ()
357- if _ , err := os .Stat (backupDir ); err != nil {
358- if ! errors .Is (err , fs .ErrNotExist ) {
359- return 0 , err
360- }
361- if err = os .Mkdir (backupDir , os .ModePerm ); err != nil {
362- return 0 , err
363- }
364- }
377+ b .forceKeepBackup = true
378+ size := 0
365379
366- backupName := util . DetermineEscapePath ( backupDir , path )
367- _ , err = b .overwriteFile ( backupName )
380+ // Try to backup first before writing
381+ backupName , err : = b .backupFile ( path )
368382 if err != nil {
369- os . Remove ( backupName )
383+ file . Close ( )
370384 return 0 , err
371385 }
372386
373- b .forceKeepBackup = true
374- size , err := file .Write (b )
375- if err != nil {
376- err = util.OverwriteError {err , backupName }
377- return size , err
387+ {
388+ // If we failed to write or close, keep the backup we made
389+ size , err = file .Write (b )
390+ if err != nil {
391+ file .Close ()
392+ err = util.OverwriteError {err , backupName }
393+ return 0 , err
394+ }
395+
396+ err := file .Close ()
397+ if err != nil {
398+ err = util.OverwriteError {err , backupName }
399+ return 0 , err
400+ }
378401 }
379402 b .forceKeepBackup = false
380403
381404 if ! b .keepBackup () {
382405 os .Remove (backupName )
383406 }
384407
385- err2 := file .Close ()
386- if err2 != nil && err == nil {
387- err = err2
388- }
389-
390408 return size , err
391409}
0 commit comments