Module: VER::Methods::Save
- Defined in:
- lib/ver/methods/save.rb
Overview
TODO: we must write backup files, VER can corrupt files on a system
crash for some reason.
Class Method Summary collapse
- .file_save(text, filename = text.filename) ⇒ Object
- .file_save_popup(text, options = {}) ⇒ Object
- .may_close(text) ⇒ Object
- .may_save(text, as = nil) ⇒ Object
- .quit(text = nil) ⇒ Object
- .save(text) ⇒ Object
- .save_all(text) ⇒ Object
- .save_as(text) ⇒ Object
- .save_atomic(text, from, to) ⇒ Object
- .save_dumb(text, to) ⇒ Object
-
.save_to(text, to) ⇒ Object
Some strategies are discussed at:.
- .success(text, message) ⇒ Object
Class Method Details
.file_save(text, filename = text.filename) ⇒ Object
109 110 111 |
# File 'lib/ver/methods/save.rb', line 109 def file_save(text, filename = text.filename) save_to(text, filename) end |
.file_save_popup(text, options = {}) ⇒ Object
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/ver/methods/save.rb', line 113 def file_save_popup(text, = {}) = .dup [:filetypes] ||= [ ['ALL Files', '*' ], ['Text Files', '*.txt'], ] filename = text.filename [:initialfile] ||= ::File.basename(filename) [:defaultextension] ||= ::File.extname(filename) [:initialdir] ||= ::File.dirname(filename) fpath = Tk.get_save_file() return unless fpath save_to(text, fpath) end |
.may_close(text) ⇒ Object
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/ver/methods/save.rb', line 8 def may_close(text) return yield if text.pristine? return yield if text.persisted? question = "Save buffer #{text.buffer.name} " \ "before closing? [y]es [n]o [c]ancel: " text.ask question, value: 'y' do |answer, action| case action when :attempt case answer[0] when /y/i yield if save(text) VER. 'Saved' :abort when /n/i yield VER. 'Closing without saving' :abort else VER.warn "Cancel closing" :abort end end end end |
.may_save(text, as = nil) ⇒ Object
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/ver/methods/save.rb', line 35 def may_save(text, as = nil) last = text.store(:stat, :mtime) current = text.filename.mtime rescue nil if last && current if last == current yield else question = "The buffer #{text.buffer.name} " \ "has changed since last save, overwrite? [y]es [n]o: " text.ask question, value: 'n' do |answer, action| case action when :attempt case answer[0] when /y/i yield :abort else VER.warn "Save aborted" :abort end end end end else yield end end |
.quit(text = nil) ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/ver/methods/save.rb', line 64 def quit(text = nil) buffers = VER.buffers.values pending = Array.new(buffers.size) buffers.each_with_index do |buffer, index| VER.defer do may_close(buffer.text) do pending[index] = true # p pending VER.exit if pending.all? end end end end |
.save(text) ⇒ Object
85 86 87 |
# File 'lib/ver/methods/save.rb', line 85 def save(text) save_to(text, text.filename) end |
.save_all(text) ⇒ Object
79 80 81 82 83 |
# File 'lib/ver/methods/save.rb', line 79 def save_all(text) VER.buffers.each do |name, buffer| save(buffer.text) end end |
.save_as(text) ⇒ Object
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/ver/methods/save.rb', line 89 def save_as(text) dir = text.filename.dirname.to_s + '/' text.ask 'Filename: ', value: dir do |answer, action| case action when :complete Pathname(answer + '*')..glob.map{|f| File.directory?(f) ? "#{f}/" : f } when :attempt begin save_to(text, Pathname(answer).) :abort rescue => exception VER.warn exception end end end end |
.save_atomic(text, from, to) ⇒ Object
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/ver/methods/save.rb', line 152 def save_atomic(text, 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) save_dumb(text, temp_path) && FileUtils.mv(temp_path, to) success(text, "Saved to #{to}") rescue Errno::EACCES => ex # sshfs-mounts raise error but save correctly. if ex.backtrace[0].match(/chown\'$/) success(text, "Saved to #{to} (chown issue)") else VER.warn ex false end rescue Errno::ENOENT save_dumb(text, to) end |
.save_dumb(text, to) ⇒ Object
175 176 177 178 179 180 181 182 183 184 |
# File 'lib/ver/methods/save.rb', line 175 def save_dumb(text, to) File.open(to, 'w+') do |io| io.write(text.value) end success(text, "Saved to #{to}") rescue Exception => ex VER.error(ex) return false end |
.save_to(text, 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 ;)
145 146 147 148 149 150 |
# File 'lib/ver/methods/save.rb', line 145 def save_to(text, to) may_save(text){ save_atomic(text, text.filename, to) } rescue => exception VER.error(exception) may_save(text){ save_dumb(text, to) } end |
.success(text, message) ⇒ Object
186 187 188 189 190 191 |
# File 'lib/ver/methods/save.rb', line 186 def success(text, ) VER. text.pristine = true Open.update_mtime(text) true end |