import os, subprocess, re, tempfile from subprocess import Popen, PIPE, STDOUT import buffer, default, dirutil, regex, util, window from point import Point from method import Method, Argument, arg class OpenFile(Method): '''Open file in a new buffer, or go to file's open buffer''' args = [arg('filename', dt="path", p="Open File: ", dv=default.path_dirname, ld=True, h="file to open")] def _execute(self, w, **vargs): b = w.application.open_path(vargs['filename']) SwitchBuffer().execute(w, buffername=b.name()) class OpenAesFile(Method): '''Open AES encrypted file in a new buffer, or go to file's open buffer''' args = [arg('filename', dt="path", p="Open AES File: ", dv=default.path_dirname, h="file to open"), arg('password', p="Use AES Password: ", h="the AES password the file was encrypted with")] def _execute(self, w, **vargs): b = w.application.open_path(vargs['filename'], 'aes', vargs['password']) SwitchBuffer().execute(w, buffername=b.name()) return class ViewBufferParent(Method): def _execute(self, w, **vargs): b = w.buffer if not hasattr(b, 'path'): w.set_error('Buffer has no path') elif b.path == '/': w.set_error("Root directory has no parent") else: path = os.path.dirname(b.path) w.application.methods['open-file'].execute(w, filename=path) class SwitchBuffer(Method): '''Switch to a different''' args = [arg('buffername', dt="buffer", p="Switch To Buffer: ", dv=default.last_buffer, h="name of the buffer to switch to")] def _pre_execute(self, w, **vargs): a = w.application if len(a.bufferlist.buffers) < 1: raise Exception("No other buffers") def _execute(self, w, **vargs): name = vargs['buffername'] buf = None if w.application.has_buffer_name(name): b = w.application.bufferlist.get_buffer_by_name(name) w.application.switch_buffer(b) else: w.set_error("buffer %r was not found" % name) class KillBuffer(Method): '''Close the current buffer''' force = False args = [arg('buffername', dt="buffer", p="Kill Buffer: ", dv=default.current_buffer, h="name of the buffer to kill")] def _execute(self, w, **vargs): name = vargs['buffername'] a = w.application if name not in a.bufferlist.buffer_names: raise Exception("Buffer %r does not exist" % name) elif len(a.bufferlist.buffers) == 1: raise Exception("Can't close only open buffer") self._to_kill = a.bufferlist.buffer_names[name] self._old_window = w if self.force or not self._to_kill.changed(): self._doit() else: self._prompt = "Buffer has unsaved changes; kill anyway? " a.open_mini_buffer(self._prompt, self._callback) def _doit(self): a = self._old_window.application b = self._to_kill a.close_buffer(b) def _callback(self, v): a = self._old_window.application if v == 'yes': self._doit() a.close_mini_buffer() elif v == 'no': a.close_mini_buffer() else: a.close_mini_buffer() a.set_error('Please type "yes" or "no"') class ForceKillBuffer(KillBuffer): '''Close the current buffer, automatically discarding any changes''' force=True class ListBuffers(Method): '''List all open buffers in a new buffer''' def _execute(self, w, **vargs): bl = w.application.bufferlist bnames = [b.name() for b in bl.buffers] bnames.sort() data = '\n'.join(bnames) w.application.data_buffer("*Buffers*", data, switch_to=True) class SaveBufferAs(Method): '''Save the contents of a buffer to the specified path''' args = [arg('path', dt="path", p="Write file: ", ld=True, dv=default.current_working_dir, h="new path to use")] def _execute(self, w, **vargs): a = w.application curr_buffer = w.buffer curr_buffer_name = curr_buffer.name() data = curr_buffer.make_string() path = os.path.realpath(os.path.expanduser(vargs['path'])) w.set_error("got %r (%d)" % (path, len(data))) if a.has_buffer_name(path): w.set_error("buffer for %r is already open" % path) return a.new_file_buffer(path, data, switch_to=True) a.methods['kill-buffer'].execute(w, buffername=curr_buffer_name) w.set_error('Wrote %r' % path) class SaveBuffer(Method): '''Save the contents of a buffer''' def _execute(self, w, **vargs): a = w.application if not w.buffer.changed(): w.set_error("(No changes need to be saved)") return try: w.buffer.save() w.set_error("Wrote %s" % (w.buffer.path)) except buffer.FileGoneError as e: w.buffer.save(force=True) w.set_error("File had disappeared! Wrote %s" % (w.buffer.path)) except buffer.FileChangedError as e: self._old_window = w self._prompt = "File changed on-disk; reload(r), overwrite(o) or diff(d)? " a.open_mini_buffer(self._prompt, self._callback) def _callback(self, v): w = self._old_window a = w.application a.close_mini_buffer() if v in ('reload', 'r'): a.methods['reload-buffer'].execute(w) elif v in ('overwrite', 'o'): a.methods['overwrite-buffer'].execute(w) elif v in ('diff', 'd'): path1 = w.buffer.path tf = tempfile.NamedTemporaryFile(delete=False) tf.write(w.buffer.make_string()) tf.close() path2 = tf.name a.methods['diff'].execute(w, path1=path1, path2=path2) os.unlink(path2) w.set_error("File changed on disk; showing differences") else: a.open_mini_buffer(self._prompt, self._callback) a.set_error('Please type reload(r), overwrite(o) or diff(d)') class ReloadBuffer(Method): '''Reload the contents of a buffer from the filesystem''' def _execute(self, w, **vargs): w.buffer.reload() w.set_error("Buffer contents reloaded from %r" % w.buffer.path) class OverwriteBuffer(Method): '''Unconditionally overwrite path with the contents of the buffer''' def _execute(self, w, **vargs): w.buffer.save(force=True) w.set_error("Wrote %s" % (w.buffer.path)) class ToggleTabs(Method): '''Toggle whether to write tabs out or not (defaults to false)''' def _execute(self, w, **vargs): b = w.buffer b.writetabs = not b.writetabs if b.writetabs: b.usetabs = True w.set_error("Buffer will save tabs") else: b.usetabs = False w.set_error("Buffer will not save tabs") class Pwd(Method): '''Print the buffer's current working directory''' def _execute(self, w, **vargs): home = os.getenv('HOME') if hasattr(w.buffer, 'path'): cwd = os.path.dirname(w.buffer.path) + '/' if cwd.startswith(home): cwd = cwd.replace(home, '~') w.set_error("Directory %s" % cwd) else: w.set_error("Directory %s/" % os.getcwd()) class GetBufferCodec(Method): '''Print the buffer's current codec''' def _execute(self, w, **vargs): w.set_error('Codec is %r' % w.buffer.codec) class SetBufferCodec(Method): '''Print the buffer's current codec''' args = [arg('codec', p="Codec Name: ", dv=lambda w: w.buffer.codec, h="name of the codec to use")] def _execute(self, w, **vargs): codec = vargs['codec'] try: ''.encode(codec) except: w.set_error('%r is not a valid codec' % codec) return w.set_error('Reassigning codec to %r' % codec) u = w.buffer.make_string() s = u.encode(w.buffer.codec) w.buffer.codec = codec u = s.decode(codec) w.buffer.set_data(u, force=True)