I think this would be a quick helpful thing to have available with many open files.
+1 for my interest.
I think this would be a quick helpful thing to have available with many open files.
+1 for my interest.
+1 ā¦ I want this too. I always end up working on 20+ files no matter how hard I try to keep closing them and at that point the tabs become unreadable and locating an open file would be simple if it was alpha sorted.
I suppose it wouldnāt be impossible to create a TextCommand that closes all open files, re-opens them in a specific sorted order, and returns to the previous cursor position.
Easier, and perhaps more convenient, is to create a command that shows a quick panel listing the currently open files in a particular order, and allows you to switch to a selected file. This way, the SideBar will continue to list files in the order they were opened.
I quite like this ideaā¦ might give it a bash. Added: However, Ctrl-P and other menu options seem to almost cover this anyway(?).
Hereās a rough and ready version (for Windows):
[code]import sublime, sublime_plugin, os
open_files = ]
full_files = ]
class OrderedFilesCommand(sublime_plugin.TextCommand):
def run(self, edit):
global open_files
global full_files
open_files = ]
full_files = ]
for vw in self.view.window().views():
head, tail = os.path.split(vw.file_name())
open_files.append(tail)
full_files.append((tail, head))
open_files.sort()
full_files.sort()
self.view.window().show_quick_panel(open_files, self.on_done_choosing)
def on_done_choosing(self, index):
if index != -1:
win = self.view.window()
win.open_file(full_files[index][1] + '\\' + full_files[index][0])[/code]
Assign it a shortcut key and it will open a quick panel listing files in alphabetical order. Select the file to activate it.
Amending ā\ā to ā/ā should get it to work with other osās, but Iām sure thereās a property like āfile_separatorā that will make it work in both.
Itās not as neat as I would like, but not bad for a first attempt. It will be possible to amend it so that a different shortcut would show the list in, for example, last modified order. Andy.
This is much neater and doesnāt require the file separator character:
[code]import sublime, sublime_plugin, os
open_files = ]
their_view = ]
class OrderedFilesCommand(sublime_plugin.TextCommand):
def run(self, edit):
global open_files
global their_view
open_files = ]
their_view = ]
for vw in self.view.window().views():
head, tail = os.path.split(vw.file_name())
open_files.append(tail)
their_view.append((tail, vw))
open_files.sort()
their_view.sort()
self.view.window().show_quick_panel(open_files, self.on_done_choosing)
def on_done_choosing(self, index):
if index != -1:
win = self.view.window()
win.focus_view(their_view[index][1])[/code]
I would prefer to only use one list. But if I have a list of tuples, how can I pass this as an array of strings - using only the first of the 2 tuple-elements?
And finally
[code]import sublime, sublime_plugin, os
file_views = ]
class OrderedFilesCommand(sublime_plugin.TextCommand):
def run(self, edit):
global file_views
file_views = ]
for vw in self.view.window().views():
head, tail = os.path.split(vw.file_name())
file_views.append((tail, vw))
file_views.sort()
self.view.window().show_quick_panel([x for (x, y) in file_views], self.on_chosen)
def on_chosen(self, index):
if index != -1:
win = self.view.window()
win.focus_view(file_views[index][1])[/code]
You can sort the tabs every time a new tab is opened or finish loading. That way the list will stay sorted always.
How do we sort tabs? Presumably thereās a Command for that . Although, this wonāt stop me finishing my work
This last/latest(?) version will display the files in either alphabetical or modified date order. If using modified date order, the date-time also appears in the quick panel.
[code]import sublime, sublime_plugin, os, datetime
from operator import itemgetter
file_views = ]
class OrderedFilesCommand(sublime_plugin.TextCommand):
def run(self, edit, index):
global file_views
file_views = ]
for vw in self.view.window().views():
head, tail = os.path.split(vw.file_name())
modified = os.path.getmtime(vw.file_name())
file_views.append((tail, vw, modified))
file_views.sort(key = itemgetter(index))
print file_views
if index == 2:
self.view.window().show_quick_panel([x + ā ā +
(datetime.datetime.fromtimestamp(z)).strftime("%d-%m-%y %H:%M")
for (x, y, z) in file_views], self.on_chosen)
else:
self.view.window().show_quick_panel([x for (x, y, z) in file_views],
self.on_chosen)
def on_chosen(self, index):
if index != -1:
win = self.view.window()
win.focus_view(file_views[index][1])[/code]
Iāve assigned key bindings:
{ "keys": "ctrl+alt+x"], "command": "ordered_files", "args": { "index": 0 } },
{ "keys": "ctrl+alt+c"], "command": "ordered_files", "args": { "index": 2 } }
where index == 2 sorts by modified date.
Iāve been playing with ārjust(50 - len(x))ā to try and align the date-times to the right, but itās misbehaving a little. Andy.
Added: Doh! Why āpiddle with paddingā when I can just put the timestamp first
[code]import sublime, sublime_plugin, os, datetime
from operator import itemgetter
file_views = ]
class OrderedFilesCommand(sublime_plugin.TextCommand):
def run(self, edit, index):
global file_views
file_views = ]
for vw in self.view.window().views():
head, tail = os.path.split(vw.file_name())
modified = os.path.getmtime(vw.file_name())
file_views.append((tail, vw, modified))
file_views.sort(key = itemgetter(index))
print file_views
if index == 2:
self.view.window().show_quick_panel(
(datetime.datetime.fromtimestamp(z)).strftime("%d-%m-%y %H:%M ") + x
for (x, y, z) in file_views], self.on_chosen)
else:
self.view.window().show_quick_panel([x for (x, y, z) in file_views],
self.on_chosen)
def on_chosen(self, index):
if index != -1:
win = self.view.window()
win.focus_view(file_views[index][1])[/code]
Now perfect. Signing off.
There is an API method to set the position of a tab in the tabbar with set_view_index. Example to move the current view to group 0 in position 0
You can check current view_index with
[quote]
group, index = sublime.active_window().get_view_index(sublime.active_window().active_view())
print group
print index[/quote]
Thank you tito. This could be an additional feature to the one Iāve built. Andy.
Inspired/ encouraged by tito, the following will sort tabs alphabetically. My previous code was case-sensitive, whereas this is not. It should also sort within each existing group - although I havenāt tried this.
[code]import sublime, sublime_plugin, os
class SortTabsCommand(sublime_plugin.TextCommand):
def run(self, edit):
file_views = ]
for vw in self.view.window().views():
head, tail = os.path.split(vw.file_name())
file_views.append((tail, vw))
file_views.sort(key = lambda (tail, ): tail.lower())
win = self.view.window()
for index, (, vw) in enumerate(file_views):
group, _ = win.get_view_index(vw)
win.set_view_index(vw, group, index)[/code]
Added: Careful! It doesnāt work with more than one group as yet.
Now we can work with more than one group (if you use such thingsā¦)
[code]import sublime, sublime_plugin, os
from operator import itemgetter
class SortTabsCommand(sublime_plugin.TextCommand):
def run(self, edit):
file_views = ]
win = self.view.window()
curr_view = win.active_view()
for vw in win.views():
head, tail = os.path.split(vw.file_name())
group, _ = win.get_view_index(vw)
file_views.append((tail.lower(), vw, group))
file_views.sort(key = itemgetter(2, 0))
for index, (_, vw, group) in enumerate(file_views):
if not index:
prev_group = group
moving_index = 0
elif group > prev_group:
moving_index = 0
prev_group = group
else:
moving_index += 1
win.set_view_index(vw, group, moving_index)
win.focus_view(curr_view)[/code]
Iām interested into having a āsort tabsā package. In rare occasions is useful, please add it to github. if you can add it to the sublime organization better.
Iāve put it on Gist for the moment. Oops, try this https://gist.github.com/1995067
This final (again) version of OrderedFiles.py is now case-insensitive:
[code]import sublime, sublime_plugin, os, datetime
from operator import itemgetter
file_views = ]
class OrderedFilesCommand(sublime_plugin.TextCommand):
def run(self, edit, index):
global file_views
file_views = ]
for vw in self.view.window().views():
head, tail = os.path.split(vw.file_name())
modified = os.path.getmtime(vw.file_name())
file_views.append((tail, vw, modified))
if index == 0:
file_views.sort(key = lambda (tail, Doh, Dur): tail.lower())
else:
file_views.sort(key = itemgetter(2))
if index == 2:
self.view.window().show_quick_panel(
(datetime.datetime.fromtimestamp(z)).strftime("%d-%m-%y %H:%M ") + x
for (x, y, z) in file_views], self.on_chosen)
else:
self.view.window().show_quick_panel([x for (x, y, z) in file_views],
self.on_chosen)
def on_chosen(self, index):
if index != -1:
win = self.view.window()
win.focus_view(file_views[index][1])[/code]
OrderedFiles.py is more sensible as a WindowCommand, and Iāve *tidied *the code a little.
[code]import sublime_plugin
from os import path
from operator import itemgetter
from datetime import datetime
class OrderedFilesCommand(sublime_plugin.WindowCommand):
def run(self, index):
OF = OrderedFilesCommand
OF.file_views = ]
win = self.window
for vw in win.views():
head, tail = path.split(vw.file_name())
modified = path.getmtime(vw.file_name())
OF.file_views.append((tail, vw, modified))
if index == 0: # sort by file name (case-insensitive)
OF.file_views.sort(key = lambda (tail, _, Doh): tail.lower())
win.show_quick_panel([x for (x, y, z) in OF.file_views], self.on_chosen)
else: # sort by modified date (index == 2)
OF.file_views.sort(key = itemgetter(2))
win.show_quick_panel(
(datetime.fromtimestamp(z)).strftime("%d-%m-%y %H:%M ") + x
for (x, y, z) in OF.file_views], self.on_chosen)
def on_chosen(self, index):
if index != -1:
self.window.focus_view(OrderedFilesCommand.file_views[index][1])[/code]
No previous poster has come back about this, so Iāve no idea if anyone is finding it useful (I am )
I was thinking itās (probably) possible to expand it such that typing a single number will jump to that (numbered) file: ā(1) somefile.extā. But having more than 10 files open might make it a little cumbersomeā¦ But still, you could just type a second number . A more complex solution would be to have a ākeyā letter(s) highlighted (I believe? this is possible in the quick panelā¦) to cause the file to be focused.
But I wonāt bother unless someone expresses an interest . Andy.
How does one use this? Do you copy and save to a file call OrderedFiles.py? Does it have to go in any particular folder in the packages directory?
The file doesnāt have to be named āOrderedFiles.pyā, although it seems sensible to do so.
Great thanks. But how do I actually sort? Iāve tried adding the key bindings:
{ "keys": "ctrl+alt+x"], "command": "ordered_files", "args": { "index": 0 } },
{ "keys": "ctrl+alt+c"], "command": "ordered_files", "args": { "index": 2 } }
But nothing happens.
@skube. Every key-binding must be separated by a comma, except the last one.
{ "keys": "ctrl+alt+x"], "command": "ordered_files", "args": { "index": 0 } },
{ "keys": "ctrl+alt+c"], "command": "ordered_files", "args": { "index": 2 } } << bet you need to add a comma!
Otherwise, press the key-combination and then Ctrl-apostrophe to open the Console and see if there is an error message.