Module: VER::Methods::Save

Included in:
VER::Methods, Shortcuts
Defined in:
lib/ver/methods/save.rb

Instance Method Summary collapse

Instance Method Details

#file_save(filename = self.filename) ⇒ Object



37
38
39
# File 'lib/ver/methods/save.rb', line 37

def file_save(filename = self.filename)
  save_to(filename)
end

#file_save_popup(options = {}) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/ver/methods/save.rb', line 41

def file_save_popup(options = {})
  options = options.dup
  options[:filetypes] ||= [
    ['ALL Files',  '*'    ],
    ['Text Files', '*.txt'],
  ]

  options[:filename]  ||= ::File.basename(@filename)
  options[:extension] ||= ::File.extname(@filename)
  options[:directory] ||= ::File.dirname(@filename)

  fpath = Tk.get_save_file(options)

  return unless fpath

  save_to(fpath)
end

#may_closeObject



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/ver/methods/save.rb', line 4

def may_close
  return yield unless edit_modified?
  return yield if persisted?

  question = 'Save this buffer before closing? [y]es [n]o [c]ancel: '

  status_ask question, take: 1 do |answer|
    case answer[0]
    when 'Y', 'y'
      yield if file_save
      :saved
    when 'N', 'n'
      yield
      :close_without_saving
    else
      "Cancel closing"
    end
  end
end

#persisted?Boolean

Returns:

  • (Boolean)


24
25
26
27
28
29
30
31
# File 'lib/ver/methods/save.rb', line 24

def persisted?
  return false unless filename && filename.file?
  require 'digest/md5'

  on_disk = Digest::MD5.hexdigest(filename.read)
  in_memory = Digest::MD5.hexdigest(value)
  on_disk == in_memory
end

#quitObject



33
34
35
# File 'lib/ver/methods/save.rb', line 33

def quit
  VER.exit
end

#save_atomic(from, to) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/ver/methods/save.rb', line 79

def save_atomic(from, to)
  require 'tmpdir'
  sha1 = Digest::SHA1.hexdigest([from, to].join)
  temp_path = File.join(Dir.tmpdir, 'ver', sha1)
  temp_dir = File.dirname(temp_path)

  FileUtils.mkdir_p(temp_dir)
  FileUtils.copy_file(from, temp_path, preserve = true)
  File.open(temp_path, 'w+') do |io|
    io.write(self.value)
  end
  FileUtils.mv(temp_path, to)

  status.message "Saved to #{to}"
  return true
rescue Errno::ENOENT
  save_dumb(to)
end

#save_dumb(to) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
# File 'lib/ver/methods/save.rb', line 98

def save_dumb(to)
  File.open(to, 'w+') do |io|
    io.write(self.value)
  end

  status.message "Saved to #{to}"
  return true
rescue Exception => ex
  VER.error(ex)
  return false
end

#save_to(to) ⇒ Object

Some strategies are discussed at:

bitworking.org/news/390/text-editor-saving-routines

I try another, “wasteful” approach, copying the original file to a temporary location, overwriting the contents in the copy, then moving the file to the location of the original file.

This way all permissions should be kept identical without any effort, but it will take up additional disk space.

If there is some failure during the normal saving procedure, we will simply overwrite the original file in place, make sure you have good insurance ;)



72
73
74
75
76
77
# File 'lib/ver/methods/save.rb', line 72

def save_to(to)
  save_atomic(filename, to)
rescue => exception
  VER.error(exception)
  save_dumb(to)
end