Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ Files that were visited in the last minute will not be closed. (customize from s

- Close unrelated tabs to a user input directory.

- List of files that don't be closed (ignore_files list)

##Installation
### Now available through [Package Control](http://wbond.net/sublime_packages/package_control)!
The easiest method is through [Package Control](http://wbond.net/sublime_packages/package_control). Open the command palette with <kbd>Ctrl</kbd><kbd>Shift</kbd><kbd>P</kbd> (Windows/Linux) or <kbd>⌘</kbd><kbd>Shift</kbd><kbd>P</kbd> (OSX) and type `pci` or `packconin` or whatever you like to get `Package Control: Install` showing. Click or hit <kbd>Enter</kbd>, type in `less` or `less tabs` ... and then hit <kbd>Enter</kbd>.
Expand Down
68 changes: 63 additions & 5 deletions lessTabs.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
import sublime, sublime_plugin, os, time, re
from datetime import datetime

def is_ignored(path):
if path is None:
return False

ignore_patterns = sublime.load_settings("lessTabs.sublime-settings").get('ignore_files')
if len(ignore_patterns) > 0:
for pattern in ignore_patterns:
if path and re.search(pattern, path) is not None:
return True
return False

class WM:
def get_project_folder(window):
project_folders = []
project_folders = []
if ( WM.has_project(window) ):
for folder_data in window.project_data()["folders"]:
project_folders.append(folder_data['path'])
Expand All @@ -15,7 +27,7 @@ def has_project(window):
def file_belongs_to_path(buffer, parent_folders, related_paths):
file_in_project = False
path = buffer.file_name()

if ( path ):
file_dir = os.path.dirname(path)
if ( not file_dir in related_paths ):
Expand All @@ -30,22 +42,33 @@ def file_belongs_to_path(buffer, parent_folders, related_paths):
return file_in_project, related_paths

def close_buffer(window, buffer):
active_view = sublime.active_window().active_view()
window.focus_view(buffer)
window.run_command('close_file')
# return to current
window.focus_view(active_view)


class lessTabsCommand(sublime_plugin.WindowCommand):
def run(self):
SETTINGS = sublime.load_settings("lessTabs.sublime-settings")
modified_ls = int(SETTINGS.get('modified_life_span'))
accessed_ls = int(SETTINGS.get('accessed_life_span'))
minimum_tabs = int(SETTINGS.get('minimum_tabs'))

if len(sublime.active_window().views()) <= minimum_tabs:
return


now = time.time()
active_view = sublime.active_window().active_view()

for buffer in self.window.views():
path = buffer.file_name()

if is_ignored(path):
continue

if (
buffer != active_view
and not buffer.is_loading()
Expand All @@ -54,21 +77,24 @@ def run(self):
and path
and os.path.exists(path)
and now - os.path.getmtime(path) > modified_ls
and now - os.path.getatime(path) > accessed_ls
and path in lessTabsEvents.tab_acces_time
and now - lessTabsEvents.tab_acces_time[path] > accessed_ls
):
WM.close_buffer(self.window, buffer)


class lessTabsCloseProjectUnrelatedCommand(sublime_plugin.WindowCommand):
def run(self):

window = self.window

if ( WM.has_project(window) ):
related_paths = []
project_folders = WM.get_project_folder(window)

for buffer in window.views():
if is_ignored(buffer.file_name()):
continue

file_in_project, related_paths = WM.file_belongs_to_path(buffer, project_folders, related_paths)

if ( not file_in_project ):
Expand All @@ -85,6 +111,9 @@ def on_done(self, input):
if ( os.path.exists(input) ):
related_paths = []
for buffer in self.window.views():
if is_ignored(buffer.file_name()):
continue

file_in_dir, related_paths = WM.file_belongs_to_path(buffer, [input], related_paths)

if ( not file_in_dir ):
Expand All @@ -99,11 +128,14 @@ def run(self):
window = self.window
active_view = window.active_view()
file_path = active_view.file_name()

if ( file_path ):
if ( file_path and os.path.exists(file_path) ):
related_paths = []
for buffer in window.views():
if is_ignored(buffer.file_name()):
continue

file_in_dir, related_paths = WM.file_belongs_to_path(buffer, [os.path.dirname(file_path)], related_paths)

if ( not file_in_dir ):
Expand All @@ -115,6 +147,32 @@ def run(self):


class lessTabsEvents(sublime_plugin.EventListener):
tab_acces_time = {}
def on_new(self, view):
if ( sublime.load_settings("lessTabs.sublime-settings").get("close_on_open_new") ):
sublime.active_window().run_command("less_tabs")

def on_activated(self, view):
self.updateAccessTime(view)

# async, becasue to close tab we must switch on it and get infinity loop
sublime.set_timeout_async(self.close, 100)

# when we close tab we must set last access time on it
def on_deactivated(self, view):
self.updateAccessTime(view)

def updateAccessTime(self, view = None):
if view is not None:
filename = view.file_name()
if filename is not None:
lessTabsEvents.tab_acces_time[filename] = time.time()

def close(self):
sublime.active_window().run_command("less_tabs")


def on_close(self, view):
filename = view.file_name()
if filename is not None and filename in lessTabsEvents.tab_acces_time:
del lessTabsEvents.tab_acces_time[filename]
10 changes: 8 additions & 2 deletions lessTabs.sublime-settings
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,11 @@
"accessed_life_span": 60,

// If true the command of closing tabs will be executed when a new tab is opened
"close_on_open_new" : false
}
"close_on_open_new" : false,

// List of patterns for files that won't be closed on their time is come, e.g. ["\\.todo$", "README"]
"ignore_files": [],

// Number of minimum tabs that will always be opened
"minimum_tabs" : 6
}
1 change: 1 addition & 0 deletions package-metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"url": "https://github.com/webArtisan/lessTabs", "description": "Sublime Text 3 package to close old, unused and unrelated tabs", "version": "2013.08.02.10.13.04"}