Files
Sublime-Text/Packages/Gitignore/gitignore.py
2025-03-08 19:29:14 +01:00

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')