PK R4=M
backups.py#
# backups.py
# (c) Steve Cooper 2008
#
# Utilities for manipulating a backup store
import sublime, sublimeplugin, os, _winreg, re, datetime
def base_dir(view):
options = view.options()
backupDir = sublime.options().getString("backupDir")
if (backupDir is None):
#log("no backup dir specified")
# change this if you want backups to go somewhere else
return os.path.join(get_shell_folder("Personal"), "Sublime Text Backups")
else:
return backupDir
def log(message):
print "Automatic backup: " + message
def timestampFile(file_name):
"""Puts a datestamp in file_name, just before the extension."""
now = datetime.datetime.today()
filepart, extensionpart = os.path.splitext(file_name)
return "%s-%04d-%02d-%02d-%02d-%02d-%02d%s" % \
(filepart, now.year, now.month, now.day, now.hour, now.minute, now.second, extensionpart)
def backupFilePath(view, just_dir=False):
"""Creates a new name for the file to back up,
in the base directory, with a timestamp.
Eg, turns c:\\myfile.txt into d:\\backups\\c-drive\\myfile-2008-03-20-12-44-03.txt
"""
buffer_file_name = view.fileName()
backup_base = base_dir(view)
unc_rx = re.compile('^\\\\\\\\') # unc format, eg \\svr\share
drive_rx = re.compile('^[A-Za-z]\:\\\\') # drive-colon, eg c:\foo
drive_match = drive_rx.match(buffer_file_name)
unc_match = unc_rx.match(buffer_file_name)
rewritten_path = None
if just_dir: buffer_file_name = os.path.split(buffer_file_name)[0]
if (drive_match):
# rewrite C:\foo\baras d:\backups\c-drive\foo\bar
rewritten_path = os.path.join(backup_base, buffer_file_name[0] + "-drive", buffer_file_name[3:])
elif (unc_match):
# rewrite \\unc\share as d:\backups\network\unc\share
rewritten_path = os.path.join(backup_base, "network", buffer_file_name[2:])
if rewritten_path:
return timestampFile(rewritten_path) if not just_dir else rewritten_path
else:
return None # we can't save this kind of file -- what the hell is it?
#
# FUNCTIONS FOR ACCESSING WINDOWS REGISTRY FOR USER'S SHELL FOLDERS
#
def _substenv(m):
return os.environ.get(m.group(1), m.group(0))
def get_shell_folder(name):
"""Returns the shell folder with the given name, eg "AppData", "Personal",
"Programs". Environment variables in values of type REG_EXPAND_SZ are expanded
if possible."""
HKCU = _winreg.HKEY_CURRENT_USER
USER_SHELL_FOLDERS = \
r'Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders'
key = _winreg.OpenKey(HKCU, USER_SHELL_FOLDERS)
ret = _winreg.QueryValueEx(key, name)
key.Close()
if ret[1] == _winreg.REG_EXPAND_SZ and '%' in ret[0]:
return re.compile(r'%([^|<>=^%]+)%').sub(_substenv, ret[0])
else:
return ret[0]
PK R4= main.sublime-distroPK R4=? automaticBackups.py#
# AutomaticBackupsPlugin.py
# (c) Steve Cooper, 2008
# This software comes with NO WARRANTIES.
#
from __future__ import with_statement
import sublime, sublimeplugin, os, shutil, sys, re
from functools import partial
from subprocess import Popen
import backups
WINMERGE = '"C:\Program Files\WinMerge\WinMergeU.exe"'
class NavigateBackupsCommand(sublimeplugin.TextCommand):
def __init__(self):
self.reInit()
def reInit(self):
self.index = None
self.justReverted = False
self.foundBackupFiles = None
self.currentFile = None
def run(self, view, args):
if self.index is None: self.findBackups(view)
cmd = args[0]
if cmd == 'forward': self.navForwards()
elif cmd == 'backward': self.navBackwards()
if self.foundBackupFiles:
if self.navigatedToEndOfBackups():
if cmd != 'merge' and not self.justReverted:
self.revert(view)
else:
self.backup = self.foundBackupFiles[self.index]
self.backupFullPath = os.path.join(self.backupPath, self.backup)
if cmd == 'merge': self.merge()
else: self.buffer(view)
def navForwards(self):
self.index +=1
self.index = min(len(self.foundBackupFiles)-1, self.index)
def navBackwards(self):
self.index -=1
self.index = max(0, self.index)
self.justReverted = False
def findBackups(self, view):
fn = view.fileName()
self.currentFile = fn
f, ext = os.path.splitext(os.path.split(fn)[1])
self.backupPath = backups.backupFilePath(view, just_dir=True)
dirListing = os.listdir(self.backupPath)
date = "-[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{2}-[0-9]{2}-[0-9]{2}"
pattern = "%s%s%s" % (f, date, ext)
matcher = re.compile(pattern)
self.foundBackupFiles = \
filter(lambda x: matcher.match(x), dirListing)
self.index = len(self.foundBackupFiles)-1
def merge(self):
CMD = '%s /e /wr /s /x /ul /ur /dr "AUTOMATIC BACKUP: %s" "%s" "%s"' %\
(WINMERGE, self.backup, self.currentFile, self.backupFullPath)
Popen(CMD)
def buffer(self, view):
with file(self.backupFullPath) as old_file:
view.erase(sublime.Region(0, view.size()))
view.insert(0, unicode(old_file.read(), 'utf8'))
sublime.statusMessage("%s [%s of %s]" %\
(self.backup, self.index+1, len(self.foundBackupFiles)-1))
def navigatedToEndOfBackups(self):
return self.index == len(self.foundBackupFiles)-1
def revert(self, view):
sublime.setTimeout(partial(view.runCommand, 'revert'), 50)
self.justReverted = True
def onActivated(self, view):
if view.fileName() != self.currentFile:
self.reInit()
def onLoad(self, view):
self.reInit()
def onPostSave(self, view):
self.reInit()
def isEnabled(self, view, args):
return view.fileName()
class AutomaticBackupsPlugin(sublimeplugin.Plugin):
"""Creates an automatic backup of every file you save. This
gives you a rudimentary mechanism for making sure you don't lose
information while working."""
def onPostSave(self, view):
"""When a file is saved, put a copy of the file into the
backup directory"""
buffer_file_name = view.fileName()
# if buffer_file_name.endswith('.lnk'): return
newname = backups.backupFilePath(view)
if newname == None:
return
backup_dir, file_to_write = os.path.split(newname)
# make sure that we have a directory to write into
if (os.access(backup_dir, os.F_OK) == False):
os.makedirs(backup_dir)
backups.log("backing up to " + newname)
shutil.copy(buffer_file_name, newname)PK R4=s3 Default.sublime-keymap
PK R4=}
README.txt"Automatic Backups" is a plugin by SteveCooper.
When you edit text files (scripts, prose, whatever) you often find yourself wishing for an older version. Ever accidentally deleted a chunk from an important configuration file, or wished you could roll back a document a few hours? This plugin takes a copy of every file you save and copies it into a backup directory structure, ensuring that you never lose an old version of the file.
Once installed, any file you save will be copied into your documents folder, eg `\Sublime Text Backups`. For example, if you change `c:\autoexec.bat`, you'll get a backup saved to:
c:\Documents and Settings\yourUserName\Sublime Text Backups\c-drive\autoexec-2008-03-22-22-22-46.bat
That end bit is the timestamp, so you can see when the file was edited.
If you want to back up your files somewhere other than your documents folder, you can add an option. To change where all backups are made, open the `Preferences` menu and choose `Preferences`. Then double-click `Application`, and add a line like this to the end of the file;
backupDir c:\my files\archive\
To see if it's working, open the console with the `View` | `Console` menu item. When you save a file, you should see a line like this, indicating that the file has been backed up;
Automatic backup: backing up to d:\backups\C-drive\Documents and Settings\steve\Application Data\Sublime Text\Packages\User\AutomaticBackupsPlugin-2008-03-22-22-22-46.py
PK R4=M
backups.pyPK R4= F main.sublime-distroPK R4=? w automaticBackups.pyPK R4=s3 | Default.sublime-keymapPK R4=}
README.txtPK 6 !