pmacs3/method/buffers.py

212 lines
8.1 KiB
Python
Raw Normal View History

2008-11-08 10:30:04 -05:00
import os, commands, 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, e:
w.buffer.save(force=True)
w.set_error("File had disappeared! Wrote %s" % (w.buffer.path))
except buffer.FileChangedError, 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")
2008-11-29 14:40:00 -05:00
class Pwd(Method):
'''Print the buffer's current working directory'''
def _execute(self, w, **vargs):
2008-11-29 14:52:03 -05:00
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:
u''.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)