Skip to content

Commit

Permalink
Version 0.5.0
Browse files Browse the repository at this point in the history
- Abandon storing favs in project settings file, but store the settings
in a file in the same directory as project settings.
- Force refresh of session if project cannot be found and try to locate
project again.
  • Loading branch information
facelessuser committed Mar 25, 2012
1 parent 525fe28 commit c654074
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 67 deletions.
41 changes: 39 additions & 2 deletions favorite_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,17 @@

import sublime
import sublime_plugin
from os.path import join, exists
from os.path import join, exists, normpath
from favorites import Favorites

Favs = Favorites(join(sublime.packages_path(), 'User', 'favorite_files_list.json'))


class Refresh:
dummy_file = normpath(join(sublime.packages_path(), 'FavoriteFiles', 'refresh.txt'))
on = False


class CleanOrphanedFavoritesCommand(sublime_plugin.WindowCommand):
def run(self):
# Clean out all dead links
Expand Down Expand Up @@ -310,11 +315,43 @@ def run(self):
sublime.error_message("No favorites to remove!")


class FavoritesForceRefreshListenerCommand(sublime_plugin.EventListener):
def on_post_save(self, view):
if Refresh.on:
path = view.file_name()
if path != None:
if normpath(view.file_name()) == Refresh.dummy_file:
# Close refresh file if more than one view is open
if len(view.window().views()) > 1:
sublime.set_timeout(lambda: sublime.active_window().run_command("close_file"), 100)
# Attempt toggle again
sublime.set_timeout(lambda: sublime.active_window().run_command("toggle_per_project_favorites"), 300)


class TogglePerProjectFavoritesCommand(sublime_plugin.WindowCommand):
def save(self, view):
if Refresh.on:
path = view.file_name()
if path != None:
if normpath(view.file_name()) == Refresh.dummy_file:
view.run_command('save')

def run(self):
refresh = True
if Refresh.on:
Refresh.on = False
refresh = False
# Toggle per pojects
win_id = self.window.id()
Favs.toggle_per_projects(win_id)
if Favs.toggle_per_projects(win_id):
if refresh:
view = self.window.open_file(Refresh.dummy_file)
if view != None:
Refresh.on = True
self.window.focus_view(view)
sublime.set_timeout(lambda: self.save(view), 100)
else:
sublime.error_message('Could not find a project file!')

def is_enabled(self):
return sublime.load_settings("favorite_files.sublime-settings").get("enable_per_projects", False)
2 changes: 1 addition & 1 deletion favorite_files.sublime-settings
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"enable_per_projects": false
"enable_per_projects": true
}
87 changes: 23 additions & 64 deletions favorites.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
Copyright (c) 2012 Isaac Muse <isaacmuse@gmail.com>
'''
import sublime
from os.path import exists, basename, getmtime, join, normpath
from os.path import exists, basename, getmtime, join, normpath, splitext
import json
import sys

Expand All @@ -19,7 +19,6 @@
class FavObj:
files = {}
projects = set([])
project_settings = {}
last_access = 0
global_file = ""
file_name = ""
Expand All @@ -46,32 +45,25 @@ def is_project_tracked(cls, obj, win_id):
return True if win_id != None and win_id in obj.projects else False

@classmethod
def is_project_enabled(cls, obj, win_id):
def project_adjust(cls, obj, win_id):
enabled = cls.is_project_tracked(obj, win_id)
if enabled:
project = cls.get_project(win_id)
if project != None:
project_favs = splitext(project)[0] + "-favs.json"
# Make sure project is the new target
if project != obj.file_name:
obj.file_name = project
if project_favs != obj.file_name:
obj.file_name = project_favs
obj.last_access = 0
# If project does not exist
# Revert to global
if not exists(obj.file_name):
obj.file_name = obj.global_file
obj.last_access = 0
obj.project_settings.clear()
obj.projects.remove(win_id)
enabled = False
elif not FavFileMgr.is_global_file(obj):
obj.file_name = obj.global_file
obj.project_settings.clear()
obj.last_access = 0
return enabled

@classmethod
def has_project(cls, win_id):
project = cls.get_project(win_id)
return project != None
return True if project != None else False

@classmethod
def get_project(cls, win_id):
Expand All @@ -90,12 +82,18 @@ def get_project(cls, win_id):
if w['window_id'] == win_id:
if "workspace_name" in w:
if sublime.platform() == "windows":
# Account for windows specific formatting
project = normpath(w["workspace_name"].lstrip("/").replace("/", ":/", 1))
else:
project = w["workspace_name"]
break
except:
pass

# Throw out empty project names
if project == None or project == "" or not exists(project):
project = None

return project


Expand Down Expand Up @@ -127,18 +125,10 @@ def clean_orphaned_favorites(cls, file_list):
def create_favorite_list(cls, obj, file_list, force=False):
errors = False

if not cls.is_global_file(obj):
# For per project favorites write the project settings
obj.project_settings['settings']['favorite_files'] = file_list
l = obj.project_settings
else:
# For Globals, just write the favorites
l = file_list

if not exists(obj.file_name) or force:
try:
# Save as a JSON file
j = json.dumps(l, sort_keys=True, indent=4, separators=(',', ': '))
j = json.dumps(file_list, sort_keys=True, indent=4, separators=(',', ': '))
with open(obj.file_name, 'w') as f:
f.write(j + "\n")
obj.last_access = getmtime(obj.file_name)
Expand All @@ -148,39 +138,7 @@ def create_favorite_list(cls, obj, file_list, force=False):
return errors

@classmethod
def load_project_favorites(cls, obj, clean=False):
errors = False
try:
with open(obj.file_name, "r") as f:
# Allow C style comments and be forgiving of trailing commas
content = sanitize_json(f.read(), True)
j = json.loads(content)
obj.project_settings = j
if not "settings" in j:
j['settings'] = {}
file_list = {"version": 1, "files": [], "groups": {}}
cls.create_favorite_list(obj, file_list, force=True)
elif not "favorite_files" in j["settings"]:
file_list = {"version": 1, "files": [], "groups": {}}
cls.create_favorite_list(obj, file_list, force=True)
else:
file_list = j['settings']['favorite_files']
if not "version" in file_list or file_list["version"] < FAVORITE_LIST_VERSION:
j['settings']['favorite_files'] = cls.update_list_format(file_list)
cls.create_favorite_list(obj, file_list, force=True)
if clean:
j['settings']['favorite_files'] = cls.clean_orphaned_favorites(file_list)
cls.create_favorite_list(obj, file_list, force=True)
# Update internal list and access times
obj.last_access = getmtime(obj.file_name)
obj.files = file_list
except:
errors = True
sublime.error_message('Failed to load %s!' % basename(obj.file_name))
return errors

@classmethod
def load_global_favorites(cls, obj, clean=False):
def load_favorites(cls, obj, clean=False):
errors = False
try:
with open(obj.file_name, "r") as f:
Expand Down Expand Up @@ -212,22 +170,19 @@ def load_favorite_files(cls, obj, force=False, clean=False, win_id=None):
errors = False

# Is project enabled
is_project = FavProjects.is_project_enabled(obj, win_id)
FavProjects.project_adjust(obj, win_id)

if not exists(obj.file_name) and not is_project:
if not exists(obj.file_name):
# Create file list if it doesn't exist
if cls.create_favorite_list(obj, {"version": 1, "files": [], "groups": {}}, force=True):
sublime.error_message('Failed to cerate favorite_files_list.json!')
sublime.error_message('Failed to cerate %s!' % basename(obj.file_name))
errors = True
else:
force = True

# Only reload if file has been written since last access (or if forced reload)
if not errors and (force or getmtime(obj.file_name) != obj.last_access):
if not is_project:
errors = cls.load_global_favorites(obj, clean=clean)
else:
errors = cls.load_project_favorites(obj, clean=clean)
errors = cls.load_favorites(obj, clean=clean)
return errors


Expand All @@ -246,6 +201,7 @@ def save(self, force=False):
return FavFileMgr.create_favorite_list(self.obj, self.obj.files, force=force)

def toggle_per_projects(self, win_id):
errors = False
# Clean out closed windows
FavProjects.prune_projects(self.obj)

Expand All @@ -254,6 +210,9 @@ def toggle_per_projects(self, win_id):
else:
if FavProjects.has_project(win_id):
self.obj.projects.add(win_id)
else:
errors = True
return errors

def remove_group(self, s):
# Remove a group
Expand Down
4 changes: 4 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ The above copyright notice and this permission notice shall be included in all c

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

# Version 0.5.0
- Abandon storing favs in project settings file, but store the settings in a file in the same directory as project settings.
- Force refresh of session if project cannot be found and try to locate project again.

# Version 0.4.0
- Added code to support per project favorites (disabled by default due to circumstances where project cannot be determined)

Expand Down
10 changes: 10 additions & 0 deletions refresh.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
______ _ __ _______ __
/ ____/___ __ ______ _____(_) /____ / ____(_) /__ _____
/ /_ / __ `/ | / / __ \/ ___/ / __/ _ \ / /_ / / / _ \/ ___/
/ __/ / /_/ /| |/ / /_/ / / / / /_/ __/ / __/ / / / __(__ )
/_/ \__,_/ |___/\____/_/ /_/\__/\___/ /_/ /_/_/\___/____/

Attemping to refresh session...

This view is used to refresh your session in order to find the project file if it exists.
To prevent the window from closing, this view will remain open if only one view remains.

0 comments on commit c654074

Please sign in to comment.