480 lines
13 KiB
Python
480 lines
13 KiB
Python
# coding=utf8
|
|
import sublime
|
|
import os
|
|
import re
|
|
import shutil
|
|
|
|
from SideBarProject import SideBarProject
|
|
|
|
try:
|
|
import desktop
|
|
except:
|
|
pass
|
|
|
|
class Object():
|
|
pass
|
|
|
|
def expand_vars(path):
|
|
for k, v in os.environ.iteritems():
|
|
try:
|
|
# dirty hack, this should be autofixed in python3
|
|
k = unicode(k.encode('utf8'))
|
|
v = unicode(v.encode('utf8'))
|
|
path = path.replace(u'%'+k+'%', v).replace(u'%'+k.lower()+'%', v)
|
|
except:
|
|
pass
|
|
return path
|
|
|
|
class SideBarItem:
|
|
|
|
def __init__(self, path, is_directory):
|
|
self._path = path
|
|
self._is_directory = is_directory
|
|
|
|
def path(self, path = ''):
|
|
if path == '':
|
|
return self._path
|
|
else:
|
|
self._path = path
|
|
self._is_directory = os.path.isdir(path)
|
|
return path
|
|
|
|
def pathSystem(self):
|
|
import sys
|
|
return self.path().encode(sys.getfilesystemencoding())
|
|
|
|
def pathWithoutProject(self):
|
|
path = self.path()
|
|
for directory in SideBarProject().getDirectories():
|
|
path = path.replace(directory, '', 1)
|
|
return path.replace('\\', '/')
|
|
|
|
def pathProject(self):
|
|
path = self.path()
|
|
for directory in SideBarProject().getDirectories():
|
|
path2 = path.replace(directory, '', 1)
|
|
if path2 != path:
|
|
return directory
|
|
return False
|
|
|
|
def projectURL(self, type):
|
|
filename = os.path.normpath(os.path.join(sublime.packages_path(), '..', 'Settings', 'SideBarEnhancements.json'))
|
|
if os.path.lexists(filename):
|
|
#try:
|
|
import json
|
|
data = file(filename, 'r').read()
|
|
data = data.replace('\t', ' ').replace('\\', '/').replace('\\', '/').replace('//', '/').replace('//', '/').replace('http:/', 'http://').replace('https:/', 'https://')
|
|
data = json.loads(data, strict=False)
|
|
|
|
for path in data.keys():
|
|
path2 = expand_vars(path)
|
|
print '-------------------------------------------------------'
|
|
print 'searching:'
|
|
path2 = path2.replace('\\', '/').replace('\\', '/').replace('//', '/').replace('//', '/')
|
|
print path2
|
|
print 'in:'
|
|
path3 = self.path().replace('\\', '/').replace('\\', '/').replace('//', '/').replace('//', '/')
|
|
print path3
|
|
print '-------------------------------------------------------'
|
|
path4 = re.sub(re.compile("^"+re.escape(path2), re.IGNORECASE), '', path3);
|
|
print path4
|
|
if path4 != path3:
|
|
url = data[path][type]
|
|
if url:
|
|
if url[-1:] != '/':
|
|
url = url+'/'
|
|
import urllib
|
|
return url+(re.sub("^/", '', urllib.quote(path4.encode('utf-8'))));
|
|
|
|
#except:
|
|
# return False
|
|
else:
|
|
return False
|
|
|
|
def isUnderCurrentProject(self):
|
|
path = self.path()
|
|
path2 = self.path()
|
|
for directory in SideBarProject().getDirectories():
|
|
path2 = path2.replace(directory, '', 1)
|
|
return path != path2
|
|
|
|
def pathRelativeFromProject(self):
|
|
return re.sub('^/+', '', self.pathWithoutProject())
|
|
|
|
def pathRelativeFromProjectEncoded(self):
|
|
import urllib
|
|
return urllib.quote(self.pathRelativeFromProject().encode('utf-8'))
|
|
|
|
def pathRelativeFromView(self):
|
|
return os.path.relpath(self.path(), os.path.dirname(sublime.active_window().active_view().file_name())).replace('\\', '/')
|
|
|
|
def pathRelativeFromViewEncoded(self):
|
|
import urllib
|
|
return urllib.quote(os.path.relpath(self.path(), os.path.dirname(sublime.active_window().active_view().file_name())).replace('\\', '/').encode('utf-8'))
|
|
|
|
def pathAbsoluteFromProject(self):
|
|
return self.pathWithoutProject()
|
|
|
|
def pathAbsoluteFromProjectEncoded(self):
|
|
import urllib
|
|
return urllib.quote(self.pathAbsoluteFromProject().encode('utf-8'))
|
|
|
|
def uri(self):
|
|
import urllib
|
|
return 'file:'+urllib.pathname2url(self.path().encode('utf-8'));
|
|
|
|
def join(self, name):
|
|
return os.path.join(self.path(), name)
|
|
|
|
def dirname(self):
|
|
branch, leaf = os.path.split(self.path())
|
|
return branch;
|
|
|
|
def forCwdSystemPath(self):
|
|
if self.isDirectory():
|
|
return self.pathSystem()
|
|
else:
|
|
return self.dirnameSystem()
|
|
|
|
def forCwdSystemName(self):
|
|
if self.isDirectory():
|
|
return '.'
|
|
else:
|
|
path = self.pathSystem()
|
|
branch = self.dirnameSystem()
|
|
leaf = path.replace(branch, '', 1).replace('\\', '').replace('/', '')
|
|
return leaf
|
|
|
|
def forCwdSystemPathRelativeFrom(self, relativeFrom):
|
|
relative = SideBarItem(relativeFrom, os.path.isdir(relativeFrom))
|
|
path = self.pathSystem().replace(relative.pathSystem(), '', 1).replace('\\', '/')
|
|
if path == '':
|
|
return '.'
|
|
else:
|
|
return re.sub('^/+', '', path)
|
|
|
|
def forCwdSystemPathRelativeFromRecursive(self, relativeFrom):
|
|
relative = SideBarItem(relativeFrom, os.path.isdir(relativeFrom))
|
|
path = self.pathSystem().replace(relative.pathSystem(), '', 1).replace('\\', '/')
|
|
if path == '':
|
|
return '.'
|
|
else:
|
|
if self.isDirectory():
|
|
return re.sub('^/+', '', path)+'/'
|
|
else:
|
|
return re.sub('^/+', '', path)
|
|
|
|
def dirnameSystem(self):
|
|
import sys
|
|
return self.dirname().encode(sys.getfilesystemencoding())
|
|
|
|
def dirnameCreate(self):
|
|
try:
|
|
os.makedirs(self.dirname())
|
|
except:
|
|
pass
|
|
|
|
def name(self):
|
|
branch, leaf = os.path.split(self.path())
|
|
return leaf;
|
|
|
|
def nameSystem(self):
|
|
import sys
|
|
return self.name().encode(sys.getfilesystemencoding())
|
|
|
|
def nameEncoded(self):
|
|
import urllib
|
|
return urllib.quote(self.name().encode('utf-8'));
|
|
|
|
def namePretty(self):
|
|
return self.name().replace(self.extension(), '').replace('-', ' ').replace('_', ' ').strip();
|
|
|
|
def open(self):
|
|
if sublime.platform() == 'osx':
|
|
import subprocess
|
|
subprocess.Popen(['open', '-a', self.nameSystem()], cwd=self.dirnameSystem())
|
|
elif sublime.platform() == 'windows':
|
|
import subprocess
|
|
subprocess.Popen([self.nameSystem()], cwd=self.dirnameSystem(), shell=True)
|
|
else:
|
|
desktop.open(self.path())
|
|
|
|
def edit(self):
|
|
return sublime.active_window().open_file(self.path())
|
|
|
|
def isDirectory(self):
|
|
return self._is_directory
|
|
|
|
def isFile(self):
|
|
return self.isDirectory() == False
|
|
|
|
def contentUTF8(self):
|
|
import codecs
|
|
return codecs.open(self.path(), 'r', 'utf-8').read()
|
|
|
|
def contentBinary(self):
|
|
return file(self.path(), "rb").read()
|
|
|
|
def contentBase64(self):
|
|
return 'data:'+self.mime()+';base64,'+(file(self.path(), "rb").read().encode("base64").replace('\n', ''))
|
|
|
|
def reveal(self):
|
|
sublime.active_window().run_command("open_dir", {"dir": self.dirname(), "file": self.name()} )
|
|
|
|
def write(self, content):
|
|
file(self.path(), 'w+').write(content)
|
|
|
|
def mime(self):
|
|
import mimetypes
|
|
return mimetypes.guess_type(self.path())[0] or 'application/octet-stream'
|
|
|
|
def extension(self):
|
|
return os.path.splitext('name'+self.name())[1].lower()
|
|
|
|
def exists(self):
|
|
return os.path.isdir(self.path()) or os.path.isfile(self.path())
|
|
|
|
def create(self):
|
|
if self.isDirectory():
|
|
self.dirnameCreate()
|
|
os.makedirs(self.path())
|
|
else:
|
|
self.dirnameCreate()
|
|
self.write('')
|
|
|
|
def copy(self, location, replace = False):
|
|
location = SideBarItem(location, os.path.isdir(location));
|
|
if location.exists() and replace == False:
|
|
return False
|
|
elif location.exists() and location.isFile():
|
|
os.remove(location.path())
|
|
|
|
location.dirnameCreate();
|
|
if self.isDirectory():
|
|
if location.exists():
|
|
self.copy_recursive(self.path(), location.path())
|
|
else:
|
|
shutil.copytree(self.path(), location.path())
|
|
else:
|
|
shutil.copy2(self.path(), location.path())
|
|
return True
|
|
|
|
def copy_recursive(self, _from, _to):
|
|
|
|
if os.path.isfile(_from) or os.path.islink(_from):
|
|
try:
|
|
os.makedirs(os.path.dirname(_to));
|
|
except:
|
|
pass
|
|
if os.path.exists(_to):
|
|
os.remove(_to)
|
|
shutil.copy2(_from, _to)
|
|
else:
|
|
try:
|
|
os.makedirs(_to);
|
|
except:
|
|
pass
|
|
for content in os.listdir(_from):
|
|
__from = os.path.join(_from, content)
|
|
__to = os.path.join(_to, content)
|
|
self.copy_recursive(__from, __to)
|
|
|
|
def move(self, location, replace = False):
|
|
location = SideBarItem(location, os.path.isdir(location));
|
|
if location.exists() and replace == False:
|
|
if self.path().lower() == location.path().lower():
|
|
pass
|
|
else:
|
|
return False
|
|
elif location.exists() and location.isFile():
|
|
os.remove(location.path())
|
|
|
|
if self.path().lower() == location.path().lower():
|
|
location.dirnameCreate();
|
|
os.rename(self.path(), location.path()+'.sublime-temp')
|
|
os.rename(location.path()+'.sublime-temp', location.path())
|
|
self._move_moveViews(self.path(), location.path())
|
|
else:
|
|
location.dirnameCreate();
|
|
if location.exists():
|
|
self.move_recursive(self.path(), location.path())
|
|
else:
|
|
os.rename(self.path(), location.path())
|
|
self._move_moveViews(self.path(), location.path())
|
|
return True
|
|
|
|
def move_recursive(self, _from, _to):
|
|
if os.path.isfile(_from) or os.path.islink(_from):
|
|
try:
|
|
os.makedirs(os.path.dirname(_to));
|
|
except:
|
|
pass
|
|
if os.path.exists(_to):
|
|
os.remove(_to)
|
|
os.rename(_from, _to)
|
|
else:
|
|
try:
|
|
os.makedirs(_to);
|
|
except:
|
|
pass
|
|
for content in os.listdir(_from):
|
|
__from = os.path.join(_from, content)
|
|
__to = os.path.join(_to, content)
|
|
self.move_recursive(__from, __to)
|
|
os.rmdir(_from)
|
|
|
|
def _move_moveViews(self, old, location):
|
|
for window in sublime.windows():
|
|
active_view = window.active_view()
|
|
views = []
|
|
for view in window.views():
|
|
if view.file_name():
|
|
views.append(view)
|
|
views.reverse();
|
|
for view in views:
|
|
if old == view.file_name():
|
|
active_view = self._move_moveView(window, view, location, active_view)
|
|
elif view.file_name().find(old+'\\') == 0:
|
|
active_view = self._move_moveView(window, view, view.file_name().replace(old+'\\', location+'\\', 1), active_view)
|
|
elif view.file_name().find(old+'/') == 0:
|
|
active_view = self._move_moveView(window, view, view.file_name().replace(old+'/', location+'/', 1), active_view)
|
|
|
|
def _move_moveView(self, window, view, location, active_view):
|
|
if active_view == view:
|
|
is_active_view = True
|
|
else:
|
|
is_active_view = False
|
|
|
|
options = Object()
|
|
|
|
options.scroll = view.viewport_position()
|
|
|
|
options.selections = [[item.a, item.b] for item in view.sel()]
|
|
|
|
options.marks = [[item.a, item.b] for item in view.get_regions("mark")]
|
|
|
|
options.bookmarks = [[item.a, item.b] for item in view.get_regions("bookmarks")]
|
|
|
|
if int(sublime.version()) >= 2167:
|
|
options.folds = [[item.a, item.b] for item in view.folded_regions()]
|
|
else:
|
|
options.folds = [[item.a, item.b] for item in view.unfold(sublime.Region(0, view.size()))]
|
|
|
|
options.syntax = view.settings().get('syntax')
|
|
|
|
try:
|
|
_window = window or view.window() or sublime.active_window()
|
|
options.position = _window.get_view_index(view)
|
|
except:
|
|
options.position = False
|
|
|
|
window.focus_view(view)
|
|
if view.is_dirty():
|
|
options.content = view.substr(sublime.Region(0, view.size()))
|
|
view.window().run_command('revert')
|
|
else:
|
|
options.content = False
|
|
|
|
_view = view
|
|
view = window.open_file(location)
|
|
window.focus_view(_view)
|
|
window.run_command('close')
|
|
|
|
sublime.set_timeout(lambda: self._move_restoreView(view, options, window), 200)
|
|
|
|
if is_active_view:
|
|
window.focus_view(view)
|
|
return view
|
|
else:
|
|
window.focus_view(active_view)
|
|
return active_view
|
|
|
|
def _move_restoreView(self, view, options, window):
|
|
if view.is_loading():
|
|
sublime.set_timeout(lambda: self._move_restoreView(view, options, window), 100)
|
|
else:
|
|
if options.content != False:
|
|
edit = view.begin_edit()
|
|
view.replace(edit, sublime.Region(0, view.size()), options.content);
|
|
view.sel().clear()
|
|
view.sel().add(sublime.Region(0))
|
|
view.end_edit(edit)
|
|
|
|
if options.position != False:
|
|
try:
|
|
_window = window or view.window() or sublime.active_window()
|
|
group, index = options.position
|
|
_window.set_view_index(view, group, index)
|
|
except:
|
|
pass
|
|
|
|
if options.syntax:
|
|
view.settings().set('syntax', options.syntax);
|
|
|
|
for r in options.folds:
|
|
view.fold(sublime.Region(r[0], r[1]))
|
|
|
|
view.sel().clear()
|
|
for r in options.selections:
|
|
view.sel().add(sublime.Region(r[0], r[1]))
|
|
|
|
rs = []
|
|
for r in options.marks:
|
|
rs.append(sublime.Region(r[0], r[1]))
|
|
if len(rs):
|
|
view.add_regions("mark", rs, "mark", "dot", sublime.HIDDEN | sublime.PERSISTENT)
|
|
|
|
rs = []
|
|
for r in options.bookmarks:
|
|
rs.append(sublime.Region(r[0], r[1]))
|
|
if len(rs):
|
|
view.add_regions("bookmarks", rs, "bookmarks", "bookmark", sublime.HIDDEN | sublime.PERSISTENT)
|
|
|
|
view.set_viewport_position(options.scroll, False)
|
|
|
|
def close_associated_buffers(self):
|
|
path = self.path()
|
|
closed_items = []
|
|
for window in sublime.windows():
|
|
active_view = window.active_view()
|
|
views = []
|
|
for view in window.views():
|
|
if view.file_name():
|
|
views.append(view)
|
|
views.reverse();
|
|
for view in views:
|
|
if path == view.file_name():
|
|
if view.window():
|
|
closed_items.append([view.file_name(), view.window(), view.window().get_view_index(view)])
|
|
if len(window.views()) == 1:
|
|
window.new_file()
|
|
window.focus_view(view)
|
|
window.run_command('revert')
|
|
window.run_command('close')
|
|
elif view.file_name().find(path+'\\') == 0:
|
|
if view.window():
|
|
closed_items.append([view.file_name(), view.window(), view.window().get_view_index(view)])
|
|
if len(window.views()) == 1:
|
|
window.new_file()
|
|
window.focus_view(view)
|
|
window.run_command('revert')
|
|
window.run_command('close')
|
|
elif view.file_name().find(path+'/') == 0:
|
|
if view.window():
|
|
closed_items.append([view.file_name(), view.window(), view.window().get_view_index(view)])
|
|
if len(window.views()) == 1:
|
|
window.new_file()
|
|
window.focus_view(view)
|
|
window.run_command('revert')
|
|
window.run_command('close')
|
|
|
|
# try to repaint
|
|
try:
|
|
window.focus_view(active_view)
|
|
window.focus_view(window.active_view())
|
|
except:
|
|
try:
|
|
window.focus_view(window.active_view())
|
|
except:
|
|
pass
|
|
return closed_items |