diff options
Diffstat (limited to 'plugins/snippets/snippets/Library.py')
-rw-r--r--[-rwxr-xr-x] | plugins/snippets/snippets/Library.py | 1892 |
1 files changed, 946 insertions, 946 deletions
diff --git a/plugins/snippets/snippets/Library.py b/plugins/snippets/snippets/Library.py index 5b3773ae..f1520822 100755..100644 --- a/plugins/snippets/snippets/Library.py +++ b/plugins/snippets/snippets/Library.py @@ -27,973 +27,973 @@ import xml.etree.ElementTree as et from Helper import * class NamespacedId: - def __init__(self, namespace, id): - if not id: - self.id = None - else: - if namespace: - self.id = namespace + '-' - else: - self.id = 'global-' - - self.id += id + def __init__(self, namespace, id): + if not id: + self.id = None + else: + if namespace: + self.id = namespace + '-' + else: + self.id = 'global-' + + self.id += id class SnippetData: - PROPS = {'tag': '', 'text': '', 'description': 'New snippet', - 'accelerator': '', 'drop-targets': ''} + PROPS = {'tag': '', 'text': '', 'description': 'New snippet', + 'accelerator': '', 'drop-targets': ''} - def __init__(self, node, library): - self.priv_id = node.attrib.get('id') + def __init__(self, node, library): + self.priv_id = node.attrib.get('id') - self.set_library(library) - self.valid = False - self.set_node(node) + self.set_library(library) + self.valid = False + self.set_node(node) - def can_modify(self): - return (self.library and (isinstance(self.library(), SnippetsUserFile))) + def can_modify(self): + return (self.library and (isinstance(self.library(), SnippetsUserFile))) - def set_library(self, library): - if library: - self.library = weakref.ref(library) - else: - self.library = None + def set_library(self, library): + if library: + self.library = weakref.ref(library) + else: + self.library = None + + self.id = NamespacedId(self.language(), self.priv_id).id + + def set_node(self, node): + if self.can_modify(): + self.node = node + else: + self.node = None + + self.init_snippet_data(node) + + def init_snippet_data(self, node): + if node == None: + return + + self.override = node.attrib.get('override') - self.id = NamespacedId(self.language(), self.priv_id).id + self.properties = {} + props = SnippetData.PROPS.copy() + + # Store all properties present + for child in node: + if child.tag in props: + del props[child.tag] + + # Normalize accelerator + if child.tag == 'accelerator' and child.text != None: + keyval, mod = Gtk.accelerator_parse(child.text) + + if Gtk.accelerator_valid(keyval, mod): + child.text = Gtk.accelerator_name(keyval, mod) + else: + child.text = '' - def set_node(self, node): if self.can_modify(): - self.node = node - else: - self.node = None - - self.init_snippet_data(node) - - def init_snippet_data(self, node): - if node == None: - return - - self.override = node.attrib.get('override') - - self.properties = {} - props = SnippetData.PROPS.copy() - - # Store all properties present - for child in node: - if child.tag in props: - del props[child.tag] - - # Normalize accelerator - if child.tag == 'accelerator' and child.text != None: - keyval, mod = Gtk.accelerator_parse(child.text) - - if Gtk.accelerator_valid(keyval, mod): - child.text = Gtk.accelerator_name(keyval, mod) - else: - child.text = '' - - if self.can_modify(): - self.properties[child.tag] = child - else: - self.properties[child.tag] = child.text or '' - - # Create all the props that were not found so we stay consistent - for prop in props: - if self.can_modify(): - child = et.SubElement(node, prop) - - child.text = props[prop] - self.properties[prop] = child - else: - self.properties[prop] = props[prop] - - self.check_validation() - - def check_validation(self): - if not self['tag'] and not self['accelerator'] and not self['drop-targets']: - return False - - library = Library() - keyval, mod = Gtk.accelerator_parse(self['accelerator']) - - self.valid = library.valid_tab_trigger(self['tag']) and \ - (not self['accelerator'] or library.valid_accelerator(keyval, mod)) - - def _format_prop(self, prop, value): - if prop == 'drop-targets' and value != '': - return re.split('\\s*[,;]\\s*', value) + self.properties[child.tag] = child else: - return value - - def __getitem__(self, prop): - if prop in self.properties: - if self.can_modify(): - return self._format_prop(prop, self.properties[prop].text or '') - else: - return self._format_prop(prop, self.properties[prop] or '') - - return self._format_prop(prop, '') - - def __setitem__(self, prop, value): - if not prop in self.properties: - return - - if isinstance(value, list): - value = ','.join(value) - - if not self.can_modify() and self.properties[prop] != value: - # ohoh, this is not can_modify, but it needs to be changed... - # make sure it is transfered to the changes file and set all the - # fields. - # This snippet data container will effectively become the container - # for the newly created node, but transparently to whoever uses - # it - self._override() - - if self.can_modify() and self.properties[prop].text != value: - if self.library(): - self.library().tainted = True - - oldvalue = self.properties[prop].text - self.properties[prop].text = value - - if prop == 'tag' or prop == 'accelerator' or prop == 'drop-targets': - container = Library().container(self.language()) - container.prop_changed(self, prop, oldvalue) - - self.check_validation() - - def language(self): - if self.library and self.library(): - return self.library().language - else: - return None - - def is_override(self): - return self.override and Library().overridden[self.override] - - def to_xml(self): - return self._create_xml() - - def _create_xml(self, parent=None, update=False, attrib={}): - # Create a new node - if parent != None: - element = et.SubElement(parent, 'snippet', attrib) - else: - element = et.Element('snippet') - - # Create all the properties - for p in self.properties: - prop = et.SubElement(element, p) - prop.text = self[p] - - if update: - self.properties[p] = prop - - return element - - def _override(self): - # Find the user file - target = Library().get_user_library(self.language()) - - # Create a new node there with override - element = self._create_xml(target.root, True, {'override': self.id}) - - # Create an override snippet data, feed it element so that it stores - # all the values and then set the node to None so that it only contains - # the values in .properties - override = SnippetData(element, self.library()) - override.set_node(None) - override.id = self.id - - # Set our node to the new element - self.node = element - - # Set the override to our id - self.override = self.id - self.id = None - - # Set the new library - self.set_library(target) - - # The library is tainted because we added this snippet - target.tainted = True - - # Add the override - Library().overridden[self.override] = override - - def revert(self, snippet): - userlib = self.library() - self.set_library(snippet.library()) - - userlib.remove(self.node) - - self.set_node(None) - - # Copy the properties - self.properties = snippet.properties - - # Set the id - self.id = snippet.id - - # Reset the override flag - self.override = None + self.properties[child.tag] = child.text or '' + + # Create all the props that were not found so we stay consistent + for prop in props: + if self.can_modify(): + child = et.SubElement(node, prop) + + child.text = props[prop] + self.properties[prop] = child + else: + self.properties[prop] = props[prop] + + self.check_validation() + + def check_validation(self): + if not self['tag'] and not self['accelerator'] and not self['drop-targets']: + return False + + library = Library() + keyval, mod = Gtk.accelerator_parse(self['accelerator']) + + self.valid = library.valid_tab_trigger(self['tag']) and \ + (not self['accelerator'] or library.valid_accelerator(keyval, mod)) + + def _format_prop(self, prop, value): + if prop == 'drop-targets' and value != '': + return re.split('\\s*[,;]\\s*', value) + else: + return value + + def __getitem__(self, prop): + if prop in self.properties: + if self.can_modify(): + return self._format_prop(prop, self.properties[prop].text or '') + else: + return self._format_prop(prop, self.properties[prop] or '') + + return self._format_prop(prop, '') + + def __setitem__(self, prop, value): + if not prop in self.properties: + return + + if isinstance(value, list): + value = ','.join(value) + + if not self.can_modify() and self.properties[prop] != value: + # ohoh, this is not can_modify, but it needs to be changed... + # make sure it is transfered to the changes file and set all the + # fields. + # This snippet data container will effectively become the container + # for the newly created node, but transparently to whoever uses + # it + self._override() + + if self.can_modify() and self.properties[prop].text != value: + if self.library(): + self.library().tainted = True + + oldvalue = self.properties[prop].text + self.properties[prop].text = value + + if prop == 'tag' or prop == 'accelerator' or prop == 'drop-targets': + container = Library().container(self.language()) + container.prop_changed(self, prop, oldvalue) + + self.check_validation() + + def language(self): + if self.library and self.library(): + return self.library().language + else: + return None + + def is_override(self): + return self.override and Library().overridden[self.override] + + def to_xml(self): + return self._create_xml() + + def _create_xml(self, parent=None, update=False, attrib={}): + # Create a new node + if parent != None: + element = et.SubElement(parent, 'snippet', attrib) + else: + element = et.Element('snippet') + + # Create all the properties + for p in self.properties: + prop = et.SubElement(element, p) + prop.text = self[p] + + if update: + self.properties[p] = prop + + return element + + def _override(self): + # Find the user file + target = Library().get_user_library(self.language()) + + # Create a new node there with override + element = self._create_xml(target.root, True, {'override': self.id}) + + # Create an override snippet data, feed it element so that it stores + # all the values and then set the node to None so that it only contains + # the values in .properties + override = SnippetData(element, self.library()) + override.set_node(None) + override.id = self.id + + # Set our node to the new element + self.node = element + + # Set the override to our id + self.override = self.id + self.id = None + + # Set the new library + self.set_library(target) + + # The library is tainted because we added this snippet + target.tainted = True + + # Add the override + Library().overridden[self.override] = override + + def revert(self, snippet): + userlib = self.library() + self.set_library(snippet.library()) + + userlib.remove(self.node) + + self.set_node(None) + + # Copy the properties + self.properties = snippet.properties + + # Set the id + self.id = snippet.id + + # Reset the override flag + self.override = None class SnippetsTreeBuilder(et.TreeBuilder): - def __init__(self, start=None, end=None): - et.TreeBuilder.__init__(self) - self.set_start(start) - self.set_end(end) - - def set_start(self, start): - self._start_cb = start - - def set_end(self, end): - self._end_cb = end - - def start(self, tag, attrs): - result = et.TreeBuilder.start(self, tag, attrs) - - if self._start_cb: - self._start_cb(result) - - return result - - def end(self, tag): - result = et.TreeBuilder.end(self, tag) - - if self._end_cb: - self._end_cb(result) - - return result + def __init__(self, start=None, end=None): + et.TreeBuilder.__init__(self) + self.set_start(start) + self.set_end(end) + + def set_start(self, start): + self._start_cb = start + + def set_end(self, end): + self._end_cb = end + + def start(self, tag, attrs): + result = et.TreeBuilder.start(self, tag, attrs) + + if self._start_cb: + self._start_cb(result) + + return result + + def end(self, tag): + result = et.TreeBuilder.end(self, tag) + + if self._end_cb: + self._end_cb(result) + + return result class LanguageContainer: - def __init__(self, language): - self.language = language - self.snippets = [] - self.snippets_by_prop = {'tag': {}, 'accelerator': {}, 'drop-targets': {}} - self.accel_group = Gtk.AccelGroup() - self._refs = 0 - - def _add_prop(self, snippet, prop, value=0): - if value == 0: - value = snippet[prop] - - if not value or value == '': - return - - snippets_debug('Added ', prop ,' ', value, ' to ', str(self.language)) - - if prop == 'accelerator': - keyval, mod = Gtk.accelerator_parse(value) - self.accel_group.connect(keyval, mod, 0, \ - Library().accelerator_activated) - - snippets = self.snippets_by_prop[prop] - - if not isinstance(value, list): - value = [value] - - for val in value: - if val in snippets: - snippets[val].append(snippet) - else: - snippets[val] = [snippet] - - def _remove_prop(self, snippet, prop, value=0): - if value == 0: - value = snippet[prop] - - if not value or value == '': - return - - snippets_debug('Removed ', prop, ' ', value, ' from ', str(self.language)) - - if prop == 'accelerator': - keyval, mod = Gtk.accelerator_parse(value) - self.accel_group.disconnect_key(keyval, mod) - - snippets = self.snippets_by_prop[prop] - - if not isinstance(value, list): - value = [value] - - for val in value: - try: - snippets[val].remove(snippet) - except: - True - - def append(self, snippet): - tag = snippet['tag'] - accelerator = snippet['accelerator'] - - self.snippets.append(snippet) - - self._add_prop(snippet, 'tag') - self._add_prop(snippet, 'accelerator') - self._add_prop(snippet, 'drop-targets') - - return snippet - - def remove(self, snippet): - try: - self.snippets.remove(snippet) - except: - True - - self._remove_prop(snippet, 'tag') - self._remove_prop(snippet, 'accelerator') - self._remove_prop(snippet, 'drop-targets') - - def prop_changed(self, snippet, prop, oldvalue): - snippets_debug('PROP CHANGED (', prop, ')', oldvalue) - - self._remove_prop(snippet, prop, oldvalue) - self._add_prop(snippet, prop) - - def from_prop(self, prop, value): - snippets = self.snippets_by_prop[prop] - - if prop == 'drop-targets': - s = [] - - # FIXME: change this to use - # matevfs.mime_type_get_equivalence when it comes - # available - for key, val in snippets.items(): - if not value.startswith(key): - continue - - for snippet in snippets[key]: - if not snippet in s: - s.append(snippet) - - return s - else: - if value in snippets: - return snippets[value] - else: - return [] - - def ref(self): - self._refs += 1 - - return True - - def unref(self): - if self._refs > 0: - self._refs -= 1 - - return self._refs != 0 + def __init__(self, language): + self.language = language + self.snippets = [] + self.snippets_by_prop = {'tag': {}, 'accelerator': {}, 'drop-targets': {}} + self.accel_group = Gtk.AccelGroup() + self._refs = 0 + + def _add_prop(self, snippet, prop, value=0): + if value == 0: + value = snippet[prop] + + if not value or value == '': + return + + snippets_debug('Added ', prop ,' ', value, ' to ', str(self.language)) + + if prop == 'accelerator': + keyval, mod = Gtk.accelerator_parse(value) + self.accel_group.connect(keyval, mod, 0, \ + Library().accelerator_activated) + + snippets = self.snippets_by_prop[prop] + + if not isinstance(value, list): + value = [value] + + for val in value: + if val in snippets: + snippets[val].append(snippet) + else: + snippets[val] = [snippet] + + def _remove_prop(self, snippet, prop, value=0): + if value == 0: + value = snippet[prop] + + if not value or value == '': + return + + snippets_debug('Removed ', prop, ' ', value, ' from ', str(self.language)) + + if prop == 'accelerator': + keyval, mod = Gtk.accelerator_parse(value) + self.accel_group.disconnect_key(keyval, mod) + + snippets = self.snippets_by_prop[prop] + + if not isinstance(value, list): + value = [value] + + for val in value: + try: + snippets[val].remove(snippet) + except: + True + + def append(self, snippet): + tag = snippet['tag'] + accelerator = snippet['accelerator'] + + self.snippets.append(snippet) + + self._add_prop(snippet, 'tag') + self._add_prop(snippet, 'accelerator') + self._add_prop(snippet, 'drop-targets') + + return snippet + + def remove(self, snippet): + try: + self.snippets.remove(snippet) + except: + True + + self._remove_prop(snippet, 'tag') + self._remove_prop(snippet, 'accelerator') + self._remove_prop(snippet, 'drop-targets') + + def prop_changed(self, snippet, prop, oldvalue): + snippets_debug('PROP CHANGED (', prop, ')', oldvalue) + + self._remove_prop(snippet, prop, oldvalue) + self._add_prop(snippet, prop) + + def from_prop(self, prop, value): + snippets = self.snippets_by_prop[prop] + + if prop == 'drop-targets': + s = [] + + # FIXME: change this to use + # matevfs.mime_type_get_equivalence when it comes + # available + for key, val in snippets.items(): + if not value.startswith(key): + continue + + for snippet in snippets[key]: + if not snippet in s: + s.append(snippet) + + return s + else: + if value in snippets: + return snippets[value] + else: + return [] + + def ref(self): + self._refs += 1 + + return True + + def unref(self): + if self._refs > 0: + self._refs -= 1 + + return self._refs != 0 class SnippetsSystemFile: - def __init__(self, path=None): - self.path = path - self.loaded = False - self.language = None - self.ok = True - self.need_id = True - - def load_error(self, message): - sys.stderr.write("An error occurred loading " + self.path + ":\n") - sys.stderr.write(message + "\nSnippets in this file will not be " \ - "available, please correct or remove the file.\n") - - def _add_snippet(self, element): - if not self.need_id or element.attrib.get('id'): - self.loading_elements.append(element) - - def set_language(self, element): - self.language = element.attrib.get('language') - - if self.language: - self.language = self.language.lower() - - def _set_root(self, element): - self.set_language(element) - - def _preprocess_element(self, element): - if not self.loaded: - if not element.tag == "snippets": - self.load_error("Root element should be `snippets' instead " \ - "of `%s'" % element.tag) - return False - else: - self._set_root(element) - self.loaded = True - elif element.tag != 'snippet' and not self.insnippet: - self.load_error("Element should be `snippet' instead of `%s'" \ - % element.tag) - return False - else: - self.insnippet = True - - return True - - def _process_element(self, element): - if element.tag == 'snippet': - self._add_snippet(element) - self.insnippet = False - - return True - - def ensure(self): - if not self.ok or self.loaded: - return - - self.load() - - def parse_xml(self, readsize=16384): - if not self.path: - return - - elements = [] - - builder = SnippetsTreeBuilder( \ - lambda node: elements.append((node, True)), \ - lambda node: elements.append((node, False))) - - parser = et.XMLTreeBuilder(target=builder) - self.insnippet = False - - try: - f = open(self.path, "r") - - while True: - data = f.read(readsize) - - if not data: - break - - parser.feed(data) - - for element in elements: - yield element - - del elements[:] - - f.close() - except IOError: - self.ok = False - - def load(self): - if not self.ok: - return - - snippets_debug("Loading library (" + str(self.language) + "): " + \ - self.path) - - self.loaded = False - self.ok = False - self.loading_elements = [] - - for element in self.parse_xml(): - if element[1]: - if not self._preprocess_element(element[0]): - del self.loading_elements[:] - return - else: - if not self._process_element(element[0]): - del self.loading_elements[:] - return - - for element in self.loading_elements: - snippet = Library().add_snippet(self, element) - - del self.loading_elements[:] - self.ok = True - - # This function will get the language for a file by just inspecting the - # root element of the file. This is provided so that a cache can be built - # for which file contains which language. - # It returns the name of the language - def ensure_language(self): - if not self.loaded: - self.ok = False - - for element in self.parse_xml(256): - if element[1]: - if element[0].tag == 'snippets': - self.set_language(element[0]) - self.ok = True - - break - - def unload(self): - snippets_debug("Unloading library (" + str(self.language) + "): " + \ - self.path) - self.language = None - self.loaded = False - self.ok = True + def __init__(self, path=None): + self.path = path + self.loaded = False + self.language = None + self.ok = True + self.need_id = True + + def load_error(self, message): + sys.stderr.write("An error occurred loading " + self.path + ":\n") + sys.stderr.write(message + "\nSnippets in this file will not be " \ + "available, please correct or remove the file.\n") + + def _add_snippet(self, element): + if not self.need_id or element.attrib.get('id'): + self.loading_elements.append(element) + + def set_language(self, element): + self.language = element.attrib.get('language') + + if self.language: + self.language = self.language.lower() + + def _set_root(self, element): + self.set_language(element) + + def _preprocess_element(self, element): + if not self.loaded: + if not element.tag == "snippets": + self.load_error("Root element should be `snippets' instead " \ + "of `%s'" % element.tag) + return False + else: + self._set_root(element) + self.loaded = True + elif element.tag != 'snippet' and not self.insnippet: + self.load_error("Element should be `snippet' instead of `%s'" \ + % element.tag) + return False + else: + self.insnippet = True + + return True + + def _process_element(self, element): + if element.tag == 'snippet': + self._add_snippet(element) + self.insnippet = False + + return True + + def ensure(self): + if not self.ok or self.loaded: + return + + self.load() + + def parse_xml(self, readsize=16384): + if not self.path: + return + + elements = [] + + builder = SnippetsTreeBuilder( \ + lambda node: elements.append((node, True)), \ + lambda node: elements.append((node, False))) + + parser = et.XMLTreeBuilder(target=builder) + self.insnippet = False + + try: + f = open(self.path, "r") + + while True: + data = f.read(readsize) + + if not data: + break + + parser.feed(data) + + for element in elements: + yield element + + del elements[:] + + f.close() + except IOError: + self.ok = False + + def load(self): + if not self.ok: + return + + snippets_debug("Loading library (" + str(self.language) + "): " + \ + self.path) + + self.loaded = False + self.ok = False + self.loading_elements = [] + + for element in self.parse_xml(): + if element[1]: + if not self._preprocess_element(element[0]): + del self.loading_elements[:] + return + else: + if not self._process_element(element[0]): + del self.loading_elements[:] + return + + for element in self.loading_elements: + snippet = Library().add_snippet(self, element) + + del self.loading_elements[:] + self.ok = True + + # This function will get the language for a file by just inspecting the + # root element of the file. This is provided so that a cache can be built + # for which file contains which language. + # It returns the name of the language + def ensure_language(self): + if not self.loaded: + self.ok = False + + for element in self.parse_xml(256): + if element[1]: + if element[0].tag == 'snippets': + self.set_language(element[0]) + self.ok = True + + break + + def unload(self): + snippets_debug("Unloading library (" + str(self.language) + "): " + \ + self.path) + self.language = None + self.loaded = False + self.ok = True class SnippetsUserFile(SnippetsSystemFile): - def __init__(self, path=None): - SnippetsSystemFile.__init__(self, path) - self.tainted = False - self.need_id = False - - def _set_root(self, element): - SnippetsSystemFile._set_root(self, element) - self.root = element - - def add_prop(self, node, tag, data): - if data[tag]: - prop = et.SubElement(node, tag) - prop.text = data[tag] - - return prop - else: - return None - - def new_snippet(self, properties=None): - if (not self.ok) or self.root == None: - return None - - element = et.SubElement(self.root, 'snippet') - - if properties: - for prop in properties: - sub = et.SubElement(element, prop) - sub.text = properties[prop] - - self.tainted = True - - return Library().add_snippet(self, element) - - def set_language(self, element): - SnippetsSystemFile.set_language(self, element) - - filename = os.path.basename(self.path).lower() - - if not self.language and filename == "global.xml": - self.modifier = True - elif self.language and filename == self.language + ".xml": - self.modifier = True - else: - self.modifier = False - - def create_root(self, language): - if self.loaded: - snippets_debug('Not creating root, already loaded') - return - - if language: - root = et.Element('snippets', {'language': language}) - self.path = os.path.join(Library().userdir, language.lower() + '.xml') - else: - root = et.Element('snippets') - self.path = os.path.join(Library().userdir, 'global.xml') - - self._set_root(root) - self.loaded = True - self.ok = True - self.tainted = True - self.save() - - def remove(self, element): - try: - self.root.remove(element) - self.tainted = True - except: - return - - try: - first = self.root[0] - except: - # No more elements, this library is useless now - Library().remove_library(self) - - def save(self): - if not self.ok or self.root == None or not self.tainted: - return - - path = os.path.dirname(self.path) - - try: - if not os.path.isdir(path): - os.makedirs(path, 0755) - except OSError: - # TODO: this is bad... - sys.stderr.write("Error in making dirs\n") - - try: - write_xml(self.root, self.path, ('text', 'accelerator')) - self.tainted = False - except IOError: - # Couldn't save, what to do - sys.stderr.write("Could not save user snippets file to " + \ - self.path + "\n") - - def unload(self): - SnippetsSystemFile.unload(self) - self.root = None + def __init__(self, path=None): + SnippetsSystemFile.__init__(self, path) + self.tainted = False + self.need_id = False + + def _set_root(self, element): + SnippetsSystemFile._set_root(self, element) + self.root = element + + def add_prop(self, node, tag, data): + if data[tag]: + prop = et.SubElement(node, tag) + prop.text = data[tag] + + return prop + else: + return None + + def new_snippet(self, properties=None): + if (not self.ok) or self.root == None: + return None + + element = et.SubElement(self.root, 'snippet') + + if properties: + for prop in properties: + sub = et.SubElement(element, prop) + sub.text = properties[prop] + + self.tainted = True + + return Library().add_snippet(self, element) + + def set_language(self, element): + SnippetsSystemFile.set_language(self, element) + + filename = os.path.basename(self.path).lower() + + if not self.language and filename == "global.xml": + self.modifier = True + elif self.language and filename == self.language + ".xml": + self.modifier = True + else: + self.modifier = False + + def create_root(self, language): + if self.loaded: + snippets_debug('Not creating root, already loaded') + return + + if language: + root = et.Element('snippets', {'language': language}) + self.path = os.path.join(Library().userdir, language.lower() + '.xml') + else: + root = et.Element('snippets') + self.path = os.path.join(Library().userdir, 'global.xml') + + self._set_root(root) + self.loaded = True + self.ok = True + self.tainted = True + self.save() + + def remove(self, element): + try: + self.root.remove(element) + self.tainted = True + except: + return + + try: + first = self.root[0] + except: + # No more elements, this library is useless now + Library().remove_library(self) + + def save(self): + if not self.ok or self.root == None or not self.tainted: + return + + path = os.path.dirname(self.path) + + try: + if not os.path.isdir(path): + os.makedirs(path, 0755) + except OSError: + # TODO: this is bad... + sys.stderr.write("Error in making dirs\n") + + try: + write_xml(self.root, self.path, ('text', 'accelerator')) + self.tainted = False + except IOError: + # Couldn't save, what to do + sys.stderr.write("Could not save user snippets file to " + \ + self.path + "\n") + + def unload(self): + SnippetsSystemFile.unload(self) + self.root = None class Singleton(object): - _instance = None - - def __new__(cls, *args, **kwargs): - if not cls._instance: - cls._instance = super(Singleton, cls).__new__( - cls, *args, **kwargs) - cls._instance.__init_once__() - - return cls._instance - -class Library(Singleton): - def __init_once__(self): - self._accelerator_activated_cb = [] - self.loaded = False - self.check_buffer = Gtk.TextBuffer() - - def set_dirs(self, userdir, systemdirs): - self.userdir = userdir - self.systemdirs = systemdirs - - self.libraries = {} - self.containers = {} - self.overridden = {} - self.loaded_ids = [] - - self.loaded = False - - def add_accelerator_callback(self, cb): - self._accelerator_activated_cb.append(cb) - - def remove_accelerator_callback(self, cb): - self._accelerator_activated_cb.remove(cb) - - def accelerator_activated(self, group, obj, keyval, mod): - ret = False - - for cb in self._accelerator_activated_cb: - ret = cb(group, obj, keyval, mod) - - if ret: - break - - return ret - - def add_snippet(self, library, element): - container = self.container(library.language) - overrided = self.overrided(library, element) - - if overrided: - overrided.set_library(library) - snippets_debug('Snippet is overriden: ' + overrided['description']) - return None - - snippet = SnippetData(element, library) - - if snippet.id in self.loaded_ids: - snippets_debug('Not added snippet ' + str(library.language) + \ - '::' + snippet['description'] + ' (duplicate)') - return None - - snippet = container.append(snippet) - snippets_debug('Added snippet ' + str(library.language) + '::' + \ - snippet['description']) - - if snippet and snippet.override: - self.add_override(snippet) - - if snippet.id: - self.loaded_ids.append(snippet.id) - - return snippet - - def container(self, language): - language = self.normalize_language(language) - - if not language in self.containers: - self.containers[language] = LanguageContainer(language) - - return self.containers[language] - - def get_user_library(self, language): - target = None - - if language in self.libraries: - for library in self.libraries[language]: - if isinstance(library, SnippetsUserFile) and library.modifier: - target = library - elif not isinstance(library, SnippetsUserFile): - break - - if not target: - # Create a new user file then - snippets_debug('Creating a new user file for language ' + \ - str(language)) - target = SnippetsUserFile() - target.create_root(language) - self.add_library(target) - - return target - - def new_snippet(self, language, properties=None): - language = self.normalize_language(language) - library = self.get_user_library(language) - - return library.new_snippet(properties) - - def revert_snippet(self, snippet): - # This will revert the snippet to the one it overrides - if not snippet.can_modify() or not snippet.override in self.overridden: - # It can't be reverted, shouldn't happen, but oh.. - return - - # The snippet in self.overriden only contains the property contents and - # the library it belongs to - revertto = self.overridden[snippet.override] - del self.overridden[snippet.override] - - if revertto: - snippet.revert(revertto) - - if revertto.id: - self.loaded_ids.append(revertto.id) - - def remove_snippet(self, snippet): - if not snippet.can_modify() or snippet.is_override(): - return - - # Remove from the library - userlib = snippet.library() - userlib.remove(snippet.node) - - # Remove from the container - container = self.containers[userlib.language] + _instance = None + + def __new__(cls, *args, **kwargs): + if not cls._instance: + cls._instance = super(Singleton, cls).__new__( + cls, *args, **kwargs) + cls._instance.__init_once__() + + return cls._instance + +class Library(Singleton): + def __init_once__(self): + self._accelerator_activated_cb = [] + self.loaded = False + self.check_buffer = Gtk.TextBuffer() + + def set_dirs(self, userdir, systemdirs): + self.userdir = userdir + self.systemdirs = systemdirs + + self.libraries = {} + self.containers = {} + self.overridden = {} + self.loaded_ids = [] + + self.loaded = False + + def add_accelerator_callback(self, cb): + self._accelerator_activated_cb.append(cb) + + def remove_accelerator_callback(self, cb): + self._accelerator_activated_cb.remove(cb) + + def accelerator_activated(self, group, obj, keyval, mod): + ret = False + + for cb in self._accelerator_activated_cb: + ret = cb(group, obj, keyval, mod) + + if ret: + break + + return ret + + def add_snippet(self, library, element): + container = self.container(library.language) + overrided = self.overrided(library, element) + + if overrided: + overrided.set_library(library) + snippets_debug('Snippet is overriden: ' + overrided['description']) + return None + + snippet = SnippetData(element, library) + + if snippet.id in self.loaded_ids: + snippets_debug('Not added snippet ' + str(library.language) + \ + '::' + snippet['description'] + ' (duplicate)') + return None + + snippet = container.append(snippet) + snippets_debug('Added snippet ' + str(library.language) + '::' + \ + snippet['description']) + + if snippet and snippet.override: + self.add_override(snippet) + + if snippet.id: + self.loaded_ids.append(snippet.id) + + return snippet + + def container(self, language): + language = self.normalize_language(language) + + if not language in self.containers: + self.containers[language] = LanguageContainer(language) + + return self.containers[language] + + def get_user_library(self, language): + target = None + + if language in self.libraries: + for library in self.libraries[language]: + if isinstance(library, SnippetsUserFile) and library.modifier: + target = library + elif not isinstance(library, SnippetsUserFile): + break + + if not target: + # Create a new user file then + snippets_debug('Creating a new user file for language ' + \ + str(language)) + target = SnippetsUserFile() + target.create_root(language) + self.add_library(target) + + return target + + def new_snippet(self, language, properties=None): + language = self.normalize_language(language) + library = self.get_user_library(language) + + return library.new_snippet(properties) + + def revert_snippet(self, snippet): + # This will revert the snippet to the one it overrides + if not snippet.can_modify() or not snippet.override in self.overridden: + # It can't be reverted, shouldn't happen, but oh.. + return + + # The snippet in self.overriden only contains the property contents and + # the library it belongs to + revertto = self.overridden[snippet.override] + del self.overridden[snippet.override] + + if revertto: + snippet.revert(revertto) + + if revertto.id: + self.loaded_ids.append(revertto.id) + + def remove_snippet(self, snippet): + if not snippet.can_modify() or snippet.is_override(): + return + + # Remove from the library + userlib = snippet.library() + userlib.remove(snippet.node) + + # Remove from the container + container = self.containers[userlib.language] + container.remove(snippet) + + def overrided(self, library, element): + id = NamespacedId(library.language, element.attrib.get('id')).id + + if id in self.overridden: + snippet = SnippetData(element, None) + snippet.set_node(None) + + self.overridden[id] = snippet + return snippet + else: + return None + + def add_override(self, snippet): + snippets_debug('Add override:', snippet.override) + if not snippet.override in self.overridden: + self.overridden[snippet.override] = None + + def add_library(self, library): + library.ensure_language() + + if not library.ok: + snippets_debug('Library in wrong format, ignoring') + return False + + snippets_debug('Adding library (' + str(library.language) + '): ' + \ + library.path) + + if library.language in self.libraries: + # Make sure all the user files are before the system files + if isinstance(library, SnippetsUserFile): + self.libraries[library.language].insert(0, library) + else: + self.libraries[library.language].append(library) + else: + self.libraries[library.language] = [library] + + return True + + def remove_library(self, library): + if not library.ok: + return + + if library.path and os.path.isfile(library.path): + os.unlink(library.path) + + try: + self.libraries[library.language].remove(library) + except KeyError: + True + + container = self.containers[library.language] + + for snippet in list(container.snippets): + if snippet.library() == library: container.remove(snippet) - - def overrided(self, library, element): - id = NamespacedId(library.language, element.attrib.get('id')).id - - if id in self.overridden: - snippet = SnippetData(element, None) - snippet.set_node(None) - - self.overridden[id] = snippet - return snippet - else: - return None - - def add_override(self, snippet): - snippets_debug('Add override:', snippet.override) - if not snippet.override in self.overridden: - self.overridden[snippet.override] = None - - def add_library(self, library): - library.ensure_language() - - if not library.ok: - snippets_debug('Library in wrong format, ignoring') - return False - - snippets_debug('Adding library (' + str(library.language) + '): ' + \ - library.path) - - if library.language in self.libraries: - # Make sure all the user files are before the system files - if isinstance(library, SnippetsUserFile): - self.libraries[library.language].insert(0, library) - else: - self.libraries[library.language].append(library) + + def add_user_library(self, path): + library = SnippetsUserFile(path) + return self.add_library(library) + + def add_system_library(self, path): + library = SnippetsSystemFile(path) + return self.add_library(library) + + def find_libraries(self, path, searched, addcb): + snippets_debug("Finding in: " + path) + + if not os.path.isdir(path): + return searched + + files = os.listdir(path) + searched.append(path) + + for f in files: + f = os.path.realpath(os.path.join(path, f)) + + # Determine what language this file provides snippets for + if os.path.isfile(f): + addcb(f) + + return searched + + def normalize_language(self, language): + if language: + return language.lower() + + return language + + def remove_container(self, language): + for snippet in self.containers[language].snippets: + if snippet.id in self.loaded_ids: + self.loaded_ids.remove(snippet.id) + + if snippet.override in self.overridden: + del self.overridden[snippet.override] + + del self.containers[language] + + def get_accel_group(self, language): + language = self.normalize_language(language) + container = self.container(language) + + self.ensure(language) + return container.accel_group + + def save(self, language): + language = self.normalize_language(language) + + if language in self.libraries: + for library in self.libraries[language]: + if isinstance(library, SnippetsUserFile): + library.save() else: - self.libraries[library.language] = [library] - - return True - - def remove_library(self, library): - if not library.ok: - return - - if library.path and os.path.isfile(library.path): - os.unlink(library.path) - - try: - self.libraries[library.language].remove(library) - except KeyError: - True - - container = self.containers[library.language] - - for snippet in list(container.snippets): - if snippet.library() == library: - container.remove(snippet) - - def add_user_library(self, path): - library = SnippetsUserFile(path) - return self.add_library(library) - - def add_system_library(self, path): - library = SnippetsSystemFile(path) - return self.add_library(library) - - def find_libraries(self, path, searched, addcb): - snippets_debug("Finding in: " + path) - - if not os.path.isdir(path): - return searched - - files = os.listdir(path) - searched.append(path) - - for f in files: - f = os.path.realpath(os.path.join(path, f)) - - # Determine what language this file provides snippets for - if os.path.isfile(f): - addcb(f) - - return searched - - def normalize_language(self, language): - if language: - return language.lower() - - return language - - def remove_container(self, language): - for snippet in self.containers[language].snippets: - if snippet.id in self.loaded_ids: - self.loaded_ids.remove(snippet.id) - - if snippet.override in self.overridden: - del self.overridden[snippet.override] - - del self.containers[language] - - def get_accel_group(self, language): - language = self.normalize_language(language) - container = self.container(language) - - self.ensure(language) - return container.accel_group - - def save(self, language): - language = self.normalize_language(language) - - if language in self.libraries: - for library in self.libraries[language]: - if isinstance(library, SnippetsUserFile): - library.save() - else: - break - - def ref(self, language): - language = self.normalize_language(language) - - snippets_debug('Ref:', language) - self.container(language).ref() - - def unref(self, language): - language = self.normalize_language(language) - - snippets_debug('Unref:', language) - - if language in self.containers: - if not self.containers[language].unref() and \ - language in self.libraries: - - for library in self.libraries[language]: - library.unload() - - self.remove_container(language) - - def ensure(self, language): - self.ensure_files() - language = self.normalize_language(language) - - # Ensure language as well as the global snippets (None) - for lang in (None, language): - if lang in self.libraries: - # Ensure the container exists - self.container(lang) - - for library in self.libraries[lang]: - library.ensure() - - def ensure_files(self): - if self.loaded: - return - - searched = [] - searched = self.find_libraries(self.userdir, searched, \ - self.add_user_library) - - for d in self.systemdirs: - searched = self.find_libraries(d, searched, \ - self.add_system_library) + break - self.loaded = True + def ref(self, language): + language = self.normalize_language(language) + + snippets_debug('Ref:', language) + self.container(language).ref() + + def unref(self, language): + language = self.normalize_language(language) + + snippets_debug('Unref:', language) + + if language in self.containers: + if not self.containers[language].unref() and \ + language in self.libraries: + + for library in self.libraries[language]: + library.unload() + + self.remove_container(language) + + def ensure(self, language): + self.ensure_files() + language = self.normalize_language(language) + + # Ensure language as well as the global snippets (None) + for lang in (None, language): + if lang in self.libraries: + # Ensure the container exists + self.container(lang) + + for library in self.libraries[lang]: + library.ensure() + + def ensure_files(self): + if self.loaded: + return + + searched = [] + searched = self.find_libraries(self.userdir, searched, \ + self.add_user_library) + + for d in self.systemdirs: + searched = self.find_libraries(d, searched, \ + self.add_system_library) + + self.loaded = True + + def valid_accelerator(self, keyval, mod): + mod &= Gtk.accelerator_get_default_mod_mask() + + return (mod and (Gdk.keyval_to_unicode(keyval) or \ + keyval in range(Gdk.KEY_F1, Gdk.KEY_F12 + 1))) + + def valid_tab_trigger(self, trigger): + if not trigger: + return True + + if trigger.isdigit(): + return False + + self.check_buffer.set_text(trigger) + + start, end = self.check_buffer.get_bounds() + text = self.check_buffer.get_text(start, end, False) + + s = start.copy() + e = end.copy() + + end.backward_word_start() + start.forward_word_end() + + return (s.equal(end) and e.equal(start)) or (len(text) == 1 and not (text.isalnum() or text.isspace())) + + # Snippet getters + # =============== + def _from_prop(self, prop, value, language=None): + self.ensure_files() + + result = [] + language = self.normalize_language(language) + + if not language in self.containers: + return [] + + self.ensure(language) + result = self.containers[language].from_prop(prop, value) + + if len(result) == 0 and language and None in self.containers: + result = self.containers[None].from_prop(prop, value) + + return result + + # Get snippets for a given language + def get_snippets(self, language=None): + self.ensure_files() + language = self.normalize_language(language) + + if not language in self.libraries: + return [] + + snippets = [] + self.ensure(language) + + return list(self.containers[language].snippets) + + # Get snippets for a given accelerator + def from_accelerator(self, accelerator, language=None): + return self._from_prop('accelerator', accelerator, language) + + # Get snippets for a given tag + def from_tag(self, tag, language=None): + return self._from_prop('tag', tag, language) + + # Get snippets for a given drop target + def from_drop_target(self, drop_target, language=None): + return self._from_prop('drop-targets', drop_target, language) - def valid_accelerator(self, keyval, mod): - mod &= Gtk.accelerator_get_default_mod_mask() - - return (mod and (Gdk.keyval_to_unicode(keyval) or \ - keyval in range(Gdk.KEY_F1, Gdk.KEY_F12 + 1))) - - def valid_tab_trigger(self, trigger): - if not trigger: - return True - - if trigger.isdigit(): - return False - - self.check_buffer.set_text(trigger) - - start, end = self.check_buffer.get_bounds() - text = self.check_buffer.get_text(start, end, False) - - s = start.copy() - e = end.copy() - - end.backward_word_start() - start.forward_word_end() - - return (s.equal(end) and e.equal(start)) or (len(text) == 1 and not (text.isalnum() or text.isspace())) - - # Snippet getters - # =============== - def _from_prop(self, prop, value, language=None): - self.ensure_files() - - result = [] - language = self.normalize_language(language) - - if not language in self.containers: - return [] - - self.ensure(language) - result = self.containers[language].from_prop(prop, value) - - if len(result) == 0 and language and None in self.containers: - result = self.containers[None].from_prop(prop, value) - - return result - - # Get snippets for a given language - def get_snippets(self, language=None): - self.ensure_files() - language = self.normalize_language(language) - - if not language in self.libraries: - return [] - - snippets = [] - self.ensure(language) - - return list(self.containers[language].snippets) - - # Get snippets for a given accelerator - def from_accelerator(self, accelerator, language=None): - return self._from_prop('accelerator', accelerator, language) - - # Get snippets for a given tag - def from_tag(self, tag, language=None): - return self._from_prop('tag', tag, language) - - # Get snippets for a given drop target - def from_drop_target(self, drop_target, language=None): - return self._from_prop('drop-targets', drop_target, language) - -# ex:ts=8:et: +# ex:ts=4:et: |