77 lines
3.3 KiB
Python
77 lines
3.3 KiB
Python
import os
|
|
|
|
import sublime
|
|
import sublime_plugin
|
|
|
|
|
|
class compilegitignoreCommand(sublime_plugin.WindowCommand):
|
|
_file_listing = None
|
|
_search_path = None
|
|
|
|
def _delayed_init(self):
|
|
# Put off init until first run to save resources
|
|
if not self._file_listing:
|
|
self._search_path = os.path.join(sublime.packages_path(), 'Gitignore', 'gitignore')
|
|
# Deprecating zipfile package support (sorry!)
|
|
# It didn't really support unzipped overrides. This will, but I guess an update would wipe it out?
|
|
# This won't recurse, sorry! I would if we had pathlib!
|
|
# Also, I suppose it's vulnerable to directories ending in .gitignore
|
|
self._file_listing = sorted(f[:-10] for f in os.listdir(self._search_path) if f.endswith('.gitignore'))
|
|
# A set would be much more efficient, but a sorted list is way nicer to display
|
|
# Might be able to use a sorted dict key set, but it's iffy
|
|
|
|
def _run_selection(self):
|
|
# Gotta do some scoping tricks to maintain the list through the callbacks
|
|
selection = []
|
|
# Just gotta keep a copy :(
|
|
# You COULD stitch iterators together ['Done'], [x for x in self._list_items if x not in selection]
|
|
# BUT then the selection indices are off
|
|
listing = self._file_listing.copy()
|
|
|
|
def selection_callback(index):
|
|
if index < 0:
|
|
# User cancel
|
|
pass
|
|
elif selection and index == 0:
|
|
# Done!
|
|
self._write_file(selection)
|
|
else:
|
|
# user selected something from the list
|
|
selection.append(listing[index])
|
|
del listing[index]
|
|
# Could do some fancy stitching.... but could also not!
|
|
if len(selection) == 1:
|
|
listing.insert(0, 'Done')
|
|
self.window.show_quick_panel(listing, selection_callback)
|
|
|
|
self.window.show_quick_panel(listing, selection_callback) # sublime.KEEP_OPEN_ON_FOCUS_LOST ?
|
|
|
|
def run(self):
|
|
self._delayed_init()
|
|
self._run_selection()
|
|
|
|
def _write_file(self, chosen_files):
|
|
export = []
|
|
for name in chosen_files:
|
|
# if the file disappeared, post-indexing, it's not our fault.
|
|
with open(os.path.join(self._search_path, name + '.gitignore'), 'r') as f:
|
|
export.append(' '.join(('###', name, '###')))
|
|
export.append(f.read())
|
|
|
|
export = '\n\n'.join(export)
|
|
# An unconstrained (r)strip may be bad?
|
|
# For example, the MacOS one has '.Icon\r\r', which strip would mangle if it was at the end of the list
|
|
# (and sublime mangles if you open it which drives me crazy when I try to add to it)
|
|
# The gitignore syntax file doesn't mention line endings at all, which is rude.
|
|
if not export.endswith('\n'):
|
|
export += '\n'
|
|
view = sublime.active_window().new_file()
|
|
# Wild, we can't inject text in a new window without an edit object, so it has to be a second command(??)
|
|
view.run_command('writegitignore', {'text': export})
|
|
|
|
|
|
class writegitignoreCommand(sublime_plugin.TextCommand):
|
|
def run(self, edit, **kwargs):
|
|
self.view.insert(edit, 0, kwargs['text'])
|
|
self.view.set_name('.gitignore')
|