├── .sublime
├── Default.sublime-commands
├── Default.sublime-keymap
└── Main.sublime-menu
├── Plist.hidden-tmTheme
├── Plist.py
├── README.md
├── changelog
└── install.txt
├── messages.json
├── popups
├── header.html
├── help.css
├── help.html
├── info.css
└── info.html
└── syntax
└── Plist.sublime-syntax
/.sublime/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [{
2 | "caption": "Packages UI",
3 | "command": "packages_ui"
4 | }]
5 |
--------------------------------------------------------------------------------
/.sublime/Default.sublime-keymap:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "keys": ["t"],
4 | "command": "toggle_pack",
5 | "context": [{"key": "selector", "operator": "equal", "operand": "text.plist"}]
6 | }, {
7 | "keys": ["r"],
8 | "command": "renderlist",
9 | "context": [{"key": "selector", "operator": "equal", "operand": "text.plist"}]
10 | }, {
11 | "keys": ["i"],
12 | "command": "show_info",
13 | "context": [{"key": "selector", "operator": "equal", "operand": "text.plist"}]
14 | }, {
15 | "keys": ["+"],
16 | "command": "change_font_size",
17 | "context": [{"key": "selector", "operator": "equal", "operand": "text.plist"}],
18 | "args": {"plus": true}
19 | }, {
20 | "keys": ["-"],
21 | "command": "change_font_size",
22 | "context": [{"key": "selector", "operator": "equal", "operand": "text.plist"}],
23 | "args": {"plus": false}
24 | }, {
25 | "keys": ["0"],
26 | "command": "change_font_size",
27 | "context": [{"key": "selector", "operator": "equal", "operand": "text.plist"}],
28 | "args": {"plus": "reset"}
29 | }, {
30 | "keys": ["?"],
31 | "command": "toggle_popup_help",
32 | "context": [{"key": "selector", "operator": "equal", "operand": "text.plist"}]
33 | }, {
34 | "keys": ["h"],
35 | "command": "open_homepage",
36 | "context": [{"key": "selector", "operator": "equal", "operand": "text.plist"}]
37 | }
38 | ]
--------------------------------------------------------------------------------
/.sublime/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [{
2 | "caption": "Preferences",
3 | "mnemonic": "n",
4 | "id": "preferences",
5 | "children":
6 | [
7 | {
8 | "caption": "Packages UI",
9 | "mnemonic": "P",
10 | "id": "packages-ui",
11 | "command": "packages_ui"
12 | }
13 | ]
14 | }]
--------------------------------------------------------------------------------
/Plist.hidden-tmTheme:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | name
6 | Notebook
7 | settings
8 |
9 |
10 | settings
11 |
12 | background#212121
13 | caret#d3d0c8
14 | foreground#d3d0c8
15 | invisibles#EAE3C9
16 | lineHighlight#353535
17 | selection#000000
18 | popupCss
19 |
23 |
24 |
25 |
26 | name
27 | help symbol
28 | scope
29 | punctuation.definition.help.symbol
30 | settings
31 |
32 | foreground
33 | #5A5EF8
34 | fontStyle
35 |
36 |
37 |
38 |
39 | name
40 | help title
41 | scope
42 | punctuation.definition.help.title
43 | settings
44 |
45 | foreground
46 | #AFAFAF
47 | fontStyle
48 |
49 |
50 |
51 |
52 | name
53 | enabled bullet
54 | scope
55 | punctuation.definition.bullet.enabled.pack
56 | settings
57 |
58 | foreground
59 | #3D916B
60 | fontStyle
61 | bold
62 |
63 |
64 |
65 | name
66 | enabled name
67 | scope
68 | punctuation.definition.pack.name.enabled
69 | settings
70 |
71 | foreground
72 | #3D916B
73 | fontStyle
74 | bold
75 |
76 |
77 |
78 | name
79 | disabled bullet
80 | scope
81 | punctuation.definition.bullet.disabled.pack
82 | settings
83 |
84 | foreground
85 | #B4B4B4
86 | fontStyle
87 |
88 |
89 |
90 |
91 | name
92 | disabled name
93 | scope
94 | punctuation.definition.pack.name.disabled
95 | settings
96 |
97 | foreground
98 | #B4B4B4
99 | fontStyle
100 |
101 |
102 |
103 |
104 | uuid
105 | FE674D9A-27B3-4A5A-84F7-1CC67BD27531
106 |
107 |
108 |
--------------------------------------------------------------------------------
/Plist.py:
--------------------------------------------------------------------------------
1 | import sublime
2 | import sublime_plugin
3 | import re
4 | import zipfile
5 | import json
6 | import os
7 | import webbrowser
8 |
9 | bullet_enabled = '✔'
10 | bullet_disabled = '☐'
11 | reg = r"\s{4}(?:("+bullet_enabled+"|"+bullet_disabled+"))(\s)(.+?(?=\s{5,}))(\s+)(\s|\|)(\s+)(?:("+bullet_enabled+"|"+bullet_disabled+"))(\s)(.+?(?=\s{3,}))"
12 |
13 | class ChangeFontSizeCommand(sublime_plugin.WindowCommand):
14 | def run(self, plus):
15 | plistView = None
16 | window = sublime.active_window()
17 | for view in window.views():
18 | vset = view.settings()
19 | if vset.get("plist.interface") == 'plist':
20 | plistView = view
21 | if plistView:
22 | if plus == 'reset':
23 | return plistView.settings().set("font_size", 12)
24 |
25 | oldSize = plistView.settings().get("font_size")
26 | newSize = oldSize + (1 if plus else -1)
27 | if newSize < 4 or newSize > 20:
28 | return
29 | plistView.settings().set("font_size", newSize)
30 |
31 | class PackagesUiCommand(sublime_plugin.WindowCommand):
32 | def run(self):
33 | plistView = None
34 | window = sublime.active_window()
35 | for view in window.views():
36 | vset = view.settings()
37 | if vset.get("plist.interface") == 'plist':
38 | plistView = view
39 |
40 | if plistView:
41 | window.focus_view(plistView)
42 | else:
43 | plistView = self.create_view()
44 |
45 | plistView.run_command("renderlist")
46 |
47 | def create_view(self):
48 | view = self.window.new_file()
49 |
50 | view.settings().set('color_scheme', "Packages/PackagesUI/Plist.hidden-tmTheme")
51 | view.settings().set("plist.interface", 'plist')
52 | view.settings().set('highlight_line', True)
53 | view.settings().set("line_numbers", True)
54 | view.settings().set("font_size", 12)
55 | view.settings().set("spell_check", False)
56 | view.settings().set("scroll_past_end", False)
57 | view.settings().set("draw_centered", False)
58 | view.settings().set("line_padding_bottom", 2)
59 | view.settings().set("line_padding_top", 2)
60 | view.settings().set("caret_style", "solid")
61 | view.settings().set("tab_size", 4)
62 | # view.settings().set("rulers", [65, 127])
63 | view.settings().set("default_encoding", "UTF-8")
64 | view.settings().set("show_minimap", False)
65 | view.settings().set("word_wrap", False)
66 | view.set_syntax_file('Packages/PackagesUI/syntax/Plist.sublime-syntax')
67 | view.set_scratch(True)
68 | view.set_name(bullet_enabled + " Packages UI")
69 |
70 | self.disable_other_plugins(view)
71 |
72 | return view
73 |
74 |
75 | def disable_other_plugins(self, view):
76 | if sublime.load_settings("Plist.sublime-settings").get("vintageous_friendly", False) is False:
77 | view.settings().set("__vi_external_disable", False)
78 |
79 | class RenderlistCommand(sublime_plugin.TextCommand):
80 | def run(self, edit):
81 | print('[Packages UI] render')
82 | self.view.set_read_only(False)
83 | selections = self.view.sel()
84 | full_region = sublime.Region(0, self.view.size())
85 | self.view.replace(edit, full_region, '')
86 |
87 | sett = sublime.load_settings('Package Control.sublime-settings')
88 | user_s = sublime.load_settings('Preferences.sublime-settings')
89 |
90 | installed_packages = sett.get('installed_packages', [])
91 | ignored_packages = user_s.get('ignored_packages', [])
92 |
93 | plistA = []
94 |
95 | for index, pack in enumerate(installed_packages):
96 | nshan = bullet_disabled if pack in ignored_packages else bullet_enabled
97 | pname = u" {nshan} {packName}".format(packName=pack, nshan=nshan)
98 | nameLen = len(pname)
99 | space = " "*(60-int(nameLen))
100 | e = "\n" if (index + 1) % 2 == 0 else " |"
101 | l = u"{pname}{space}{e}".format(pname=pname,space=space, e=e)
102 | plistA.append(l)
103 |
104 | self.view.insert(edit, 0, "".join(plistA))
105 |
106 | header = sublime.load_resource("Packages/PackagesUI/popups/header.html")
107 | header += "\n" + "="*127 + "\n"
108 | self.view.insert(edit, 0, header)
109 | self.view.set_read_only(True)
110 |
111 | pt = self.view.text_point(3, 0)
112 | self.view.sel().clear()
113 | self.view.sel().add(sublime.Region(pt))
114 | self.view.show(pt)
115 |
116 | def replace_last(source_string, replace_what, replace_with):
117 | head, _sep, tail = source_string.rpartition(replace_what)
118 | return head + replace_with + tail
119 |
120 | class TogglePackCommand(sublime_plugin.TextCommand):
121 | def run(self, edit):
122 | packs = []
123 | for cursor in self.view.sel():
124 | pack = None
125 | (row,col) = self.view.rowcol(cursor.begin())
126 | leftPack = col < 66;
127 | line_regions = self.view.lines(cursor)
128 | for line_region in line_regions:
129 | string = self.view.substr(line_region)
130 | match = re.match(reg, string)
131 | if not match:
132 | continue
133 | pack = match.group(3 if leftPack else 9)
134 | nshan = bullet_disabled if match.group(1 if leftPack else 7) == bullet_enabled else bullet_enabled
135 |
136 | if leftPack:
137 | string = string.replace(match.group(1 if leftPack else 7), nshan, 1)
138 | else:
139 | string = replace_last(string, match.group(1 if leftPack else 7), nshan)
140 |
141 | if pack and pack not in packs:
142 | packs.append(pack)
143 | self.toggle(pack, self.view)
144 | self.view.set_read_only(False)
145 | self.view.replace(edit, line_region, string)
146 | self.view.set_read_only(True)
147 |
148 | def toggle(self, pack, view):
149 | user_s = sublime.load_settings('Preferences.sublime-settings')
150 | ignored_packages = user_s.get('ignored_packages', [])
151 |
152 | if pack in ignored_packages: # disabled
153 | ignored_packages.remove(pack)
154 | else:
155 | ignored_packages.append(pack)
156 |
157 | save_list_setting(user_s, 'Preferences.sublime-settings', "ignored_packages", ignored_packages)
158 |
159 | class openHomepageCommand(sublime_plugin.TextCommand):
160 | def run(self, edit):
161 | view = self.view
162 | popupCont = []
163 | packs = []
164 | for cursor in view.sel():
165 | pack = None
166 | (row,col) = view.rowcol(cursor.begin())
167 | leftPack = col < 66;
168 | line_regions = view.lines(cursor)
169 | for line_region in line_regions:
170 | string = view.substr(line_region)
171 | match = re.match(reg, string)
172 | if not match:
173 | continue
174 | pack = match.group(3 if leftPack else 9)
175 |
176 | if pack and pack not in packs:
177 | info = getPackInfo(pack)
178 | url = info.get('url', False)
179 | if url:
180 | webbrowser.open_new_tab(url)
181 |
182 |
183 | class showInfoCommand(sublime_plugin.TextCommand):
184 | def run(self, edit):
185 | view = self.view
186 | popupCont = []
187 | packs = []
188 | for cursor in view.sel():
189 | pack = None
190 | (row,col) = view.rowcol(cursor.begin())
191 | leftPack = col < 66;
192 | line_regions = view.lines(cursor)
193 | for line_region in line_regions:
194 | string = view.substr(line_region)
195 | match = re.match(reg, string)
196 | if not match:
197 | continue
198 |
199 | pack = match.group(3 if leftPack else 9)
200 |
201 | if pack and pack not in packs:
202 | info = getPackInfo(pack)
203 | infoToShow = [
204 | "
Name: " + pack + "
",
205 | "Version: " + info.get('version', '') + "
",
206 | "" + info.get('description', '') + "
"
207 | ]
208 | packs.append(pack)
209 | popupCont.append("".join(infoToShow))
210 |
211 | if popupCont:
212 | css = sublime.load_resource("Packages/PackagesUI/popups/info.css")
213 | html = sublime.load_resource("Packages/PackagesUI/popups/info.html").format(css=css, content="
".join(popupCont))
214 | view.show_popup(html, 0, -1, max_width=500, max_height=600, on_navigate=webbrowser.open_new_tab)
215 |
216 | class TogglePopupHelpCommand(sublime_plugin.TextCommand):
217 | def run(self, edit, view_name = "help"):
218 | css = sublime.load_resource("Packages/PackagesUI/popups/help.css")
219 | html = sublime.load_resource("Packages/PackagesUI/popups/" + view_name + ".html").format(css=css)
220 | self.view.show_popup(html, 0, -1, max_width=600, max_height=600)
221 |
222 | def save_list_setting(settings, filename, name, new_value, old_value=None):
223 | new_value = list(set(new_value))
224 | new_value = sorted(new_value, key=lambda s: s.lower())
225 |
226 | if old_value is not None:
227 | if old_value == new_value:
228 | return
229 |
230 | settings.set(name, new_value)
231 | sublime.save_settings(filename)
232 |
233 | def getPackInfo(package):
234 | package_location = os.path.join(sublime.installed_packages_path(), package + ".sublime-package")
235 |
236 | if not os.path.exists(package_location):
237 | package_location = os.path.join(os.path.dirname(sublime.packages_path()), "Packages", package)
238 |
239 | with open(os.path.join(package_location, "package-metadata.json")) as pack:
240 | data = json.load(pack)
241 | return data
242 |
243 | if not os.path.isdir(package_location):
244 | return False
245 |
246 | if package_location:
247 | with zipfile.ZipFile(sublime.installed_packages_path() + '/' + package + '.sublime-package', "r") as z:
248 | file = z.read('package-metadata.json')
249 | d = json.loads(file.decode("utf-8"))
250 | return d
251 | return False
252 |
253 |
254 |
255 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Packages UI
2 | ================
3 |
4 | This plugin provides you a comfortable interface for Sublime Text packages
5 |
6 | Sometimes it might be useful to know which packages are enabled or disabled and also get some short information about every single package. For that purpose you can use Packages UI. This is a very simple and easy tool that helps you to control (enabled/disabled) your plugins.
7 |
8 | ## Usage
9 |
10 | Preferences -> Packages UI
11 |
12 | **NOTE:** Use your mouse or up and down arrows to navigate in list of packages
13 |
14 | [t] toggle package
15 |
16 | [h] open home page
17 |
18 | [i] show info
19 |
20 | [r] refresh view
21 |
22 | [+] increase font size
23 |
24 | [-] decrease font size
25 |
26 | [0] reset font size
27 |
28 | [?] help
29 |
30 |
31 |
32 | ## Screenshots
33 |
34 | 
35 |
36 | 
37 |
38 |
--------------------------------------------------------------------------------
/changelog/install.txt:
--------------------------------------------------------------------------------
1 | Packages UI
2 | ===============================
3 |
4 | If you like this plugin, "Star" it on ---> https://github.com/unknownuser88/PackagesUI <---
5 |
6 | This plugin provides you a comfortable interface for Sublime Text packages
7 |
8 | Sometimes it might be useful to know which packages are enabled or disabled and also get some short information about every single package. For that purpose you can use Packages UI. This is a very simple and easy tool that helps you to control (enabled/disabled) your plugins.
9 |
10 | ## Usage
11 |
12 | Preferences -> Packages UI
13 |
14 | NOTE: Use your mouse or up and down arrows to navigate in list of packages
15 |
16 | [t] toggle package
17 | [h] open home page
18 | [i] show info
19 | [r] refresh view
20 | [+] increase font size
21 | [-] decrease font size
22 | [0] reset font size
23 | [?] help
--------------------------------------------------------------------------------
/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "install": "changelog/install.txt"
3 | }
--------------------------------------------------------------------------------
/popups/header.html:
--------------------------------------------------------------------------------
1 | ====================== [t] toggle package [r] refresh view
2 | PACKAGES [h] open home page [?] help
3 | ====================== [i] show info
--------------------------------------------------------------------------------
/popups/help.css:
--------------------------------------------------------------------------------
1 | h2 {
2 | margin-top: 0;
3 | }
4 | h3 {
5 | margin-top: 5px;
6 | margin-bottom: 5px;
7 | }
8 | ul {
9 | margin: 0;
10 | padding: 5px 20px 20px;
11 | }
12 |
--------------------------------------------------------------------------------
/popups/help.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 | Actions
9 |
10 | t toggle package
11 | h open home page
12 | i show info
13 | r refresh view
14 | + increase font size
15 | - decrease font size
16 | 0 reset font size
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/popups/info.css:
--------------------------------------------------------------------------------
1 | html{
2 | background-color:#000000
3 | }
4 | body{
5 | background-color:#000000
6 | }
7 | .mainTitle{
8 | font-size:20px;
9 | font-weight: bold;
10 | padding: 5px 155px;
11 | margin:0 0 10px 0;
12 | }
13 |
14 | .row{
15 | margin: 0;
16 | padding: 0px 20px
17 | }
18 | .title{
19 | font-size:15px;
20 | }
21 | .desc{
22 | font-size:12px;
23 | color:#B0A7FF;
24 | padding:0 20px
25 | }
26 | .val{
27 | font-size:15px;
28 | color:#BDBDBD;
29 | padding:0 5px
30 | }
31 | .version{
32 | font-size:13px;
33 | }
34 | .hInfo{
35 | font-size:11px;
36 | color:#A24141
37 | }
--------------------------------------------------------------------------------
/popups/info.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | Info
7 | {content}
8 |
9 |
10 | * Click on package name to open home page
11 |
12 |
13 |
--------------------------------------------------------------------------------
/syntax/Plist.sublime-syntax:
--------------------------------------------------------------------------------
1 | %YAML 1.2
2 | ---
3 | name: Plist
4 | hidden: true
5 | file_extensions:
6 | - plist
7 | scope: text.plist
8 | contexts:
9 | main:
10 | - match: '(\[)([A-Za-z\,\.\-\?\+\-\/]+)(\])'
11 | scope: meta.item.pack.help
12 | captures:
13 | 2: punctuation.definition.help.symbol
14 |
15 | - match: '\s{4}(?:(✔))(\s)(.+?(?=\s{3,}))'
16 | scope: meta.item.pack.name.enabled
17 | captures:
18 | 1: punctuation.definition.bullet.enabled.pack
19 | 3: punctuation.definition.pack.name.enabled
20 | - match: '\s{4}(?:(☐))(\s)(.+?(?=\s{3,}))'
21 | scope: meta.item.pack.name.disabled
22 | captures:
23 | 1: punctuation.definition.bullet.disabled.pack
24 | 3: punctuation.definition.pack.name.disabled
25 |
--------------------------------------------------------------------------------