def __init__(self, view, bfr, threshold, first, second, center, outside_adj, mode): """Prepare tag match object.""" tag_settings = sublime.load_settings('bh_tag.sublime-settings') self.view = view self.bfr = bfr self.mode = mode self.tag_open = process_tag_pattern( tag_settings.get("start_tag")[mode], { "attributes": tag_settings.get('attributes', {}).get(mode, ''), "tag_name": tag_settings.get('tag_name', {}).get(mode, '') } ) self.tag_close = process_tag_pattern( tag_settings.get("end_tag")[mode] ) try: self.optional_tags = bre.compile_search(tag_settings.get('optional_tag_patterns')[self.mode], bre.I) except Exception: self.optional_tags = None try: self.void_tags = bre.compile_search(tag_settings.get('void_tag_patterns')[self.mode], bre.I) except Exception: self.void_tags = None try: self.self_closing_tags = bre.compile_search(tag_settings.get('self_closing_tag_patterns')[self.mode], bre.I) except Exception: self.self_closing_tags = None tag, tag_type, tag_end = self.get_first_tag(first[0]) self.left, self.right = None, None self.window = None self.no_tag = False if outside_adj: if first[0] == center: center += 1 elif center == tag_end: center -= 1 if tag and first[0] < center < tag_end: if tag.single: self.left = tag self.right = tag else: if tag_type == "open": self.left = tag self.window = (tag_end, len(bfr) if threshold is None else threshold[1]) else: self.right = tag self.window = (0 if threshold is None else threshold[0], first[0]) else: self.left = first self.right = second self.no_tag = True
def run(self, edit): """Parse the regex panel, and if okay, run the test entry in the active view.""" obj, test = ConvertPythonSrc2Obj().convert(self.view.substr(sublime.Region(0, self.view.size()))) # Something went wrong. if test is None or obj is None: return # Ensure test command is valid. if not self.process_test_cmd(test): return # Copy all regex rules that are to be included in the test sequence test_rules = {} rules = sublime.load_settings('reg_replace_rules.sublime-settings').get('replacements', {}) for x in test['replacements']: if x in rules: test_rules[x] = rules[x] # Ensure the bare minimum items are in the current test rule # and ensure the regex (if any) compiles. # If all is well, execute the command. if not obj.get('name'): error('A valid name must be provided!') elif obj.get('scope') is None and obj.get('find') is None: error('A valid find pattern or scope must be provided!') else: try: if obj.get('find') is not None: if obj.get('selection_inputs', False): pass elif obj.get('literal', False): flags = 0 pattern = re.escape(obj['find']) if obj.get('literal_ignorecase', False): flags = re.I re.compile(pattern, flags) else: extend = sublime.load_settings( 'reg_replace.sublime-settings' ).get('extended_back_references', False) if extend: bre.compile_search(obj['find']) else: re.compile(obj['find']) test_rules[obj['name']] = obj settings = sublime.load_settings('reg_replace_test.sublime-settings') settings.set('format', '3.2') settings.set('replacements', test_rules) window = sublime.active_window() if window is not None: view = window.active_view() if view is not None: test["use_test_buffer"] = True view.run_command('reg_replace', test) except Exception as e: error('Regex compile failed!\n\n%s' % str(e))
def run(self, edit): """Parse the regex panel, and if okay, run the test entry in the active view.""" obj, test = ConvertPythonSrc2Obj().convert(self.view.substr(sublime.Region(0, self.view.size()))) # Something went wrong. if test is None or obj is None: return # Ensure test command is valid. if not self.process_test_cmd(test): return # Copy all regex rules that are to be included in the test sequence test_rules = {} rules = sublime.load_settings('reg_replace_rules.sublime-settings').get('replacements', {}) for x in test['replacements']: if x in rules: test_rules[x] = rules[x] # Ensure the bare minimum items are in the current test rule # and ensure the regex (if any) compiles. # If all is well, execute the command. if not obj.get('name'): error('A valid name must be provided!') elif obj.get('scope') is None and obj.get('find') is None: error('A valid find pattern or scope must be provided!') else: try: if obj.get('find') is not None: if obj.get('literal', False): flags = 0 pattern = re.escape(obj['find']) if obj.get('literal_ignorecase', False): flags = re.I re.compile(pattern, flags) else: extend = sublime.load_settings( 'reg_replace.sublime-settings' ).get('extended_back_references', False) if extend: bre.compile_search(obj['find']) else: re.compile(obj['find']) test_rules[obj['name']] = obj settings = sublime.load_settings('reg_replace_test.sublime-settings') settings.set('format', '3.0') settings.set('replacements', test_rules) window = sublime.active_window() if window is not None: view = window.active_view() if view is not None: test["use_test_buffer"] = True view.run_command('reg_replace', test) except Exception as e: error('Regex compile failed!\n\n%s' % str(e))
def regex_findall(self, find, flags, replace, extractions, literal=False, sel=None): """Findall with regex.""" regions = [] offset = 0 if sel is not None: offset = sel.begin() bfr = self.view.substr(sublime.Region(offset, sel.end())) else: bfr = self.view.substr(sublime.Region(0, self.view.size())) flags |= re.MULTILINE if literal: find = re.escape(find) if self.extend and not literal: pattern = bre.compile_search(find, flags) self.template = bre.compile_replace(pattern, replace) else: pattern = re.compile(find, flags) for m in pattern.finditer(bfr): regions.append(sublime.Region(offset + m.start(0), offset + m.end(0))) if self.plugin is not None: extractions.append(self.on_replace(m)) else: extractions.append(self.expand(m, replace)) return regions
def process_tag_pattern(pattern, variables=None): """Process the tag pattern.""" if variables is None: variables = {} if isinstance(pattern, str): pattern = bre.compile_search(pattern % variables, bre.I | bre.M) return pattern
def __init__(self, bracket): """Setup the bracket object by reading the passed in dictionary.""" self.style = bracket.get("style", BH_STYLE) self.open = bre.compile_search("\\A" + bracket.get("open", ""), bre.MULTILINE | bre.IGNORECASE) self.close = bre.compile_search( bracket.get("close", "") + "\\Z", bre.MULTILINE | bre.IGNORECASE) self.name = bracket["name"] sub_search = bracket.get("sub_bracket_search", BH_SUB_BRACKET) self.sub_search_only = sub_search == "only" self.sub_search = self.sub_search_only is True or sub_search == "true" self.compare = bracket.get("compare", BH_COMPARE_MATCH) self.post_match = bracket.get("post_match", BH_POST_MATCH) self.validate = bracket.get("validate", BH_VALIDATE_MATCH) self.scopes = bracket["scopes"] self.highlighting = bracket.get("highlighting", BH_HIGHLIGHTING) self.enabled = True if self.open.groups != 1 or self.close.groups != 1: self.enabled = False
def run(self, edit): """Parse the regex panel, and if okay, insert/replace entry in settings.""" obj = ConvertPythonSrc2Obj().convert( self.view.substr(sublime.Region(0, self.view.size())))[0] if obj is None: return if not obj.get('name'): error('A valid name must be provided!') elif obj.get('scope') is None and obj.get('find') is None: error('A valid find pattern or scope must be provided!') elif not self.is_existing_name(obj['name']): try: if obj.get('find') is not None: if obj.get('selection_inputs', False): pass elif obj.get('literal', False): flags = 0 pattern = re.escape(obj['find']) if obj.get('literal_ignorecase', False): flags = re.I re.compile(pattern, flags) else: extend = sublime.load_settings( 'reg_replace.sublime-settings').get( 'extended_back_references', False) if extend: bre.compile_search(obj['find']) else: re.compile(obj['find']) settings = sublime.load_settings( 'reg_replace_rules.sublime-settings') rules = settings.get('replacements', {}) rules[obj['name']] = obj settings.set('replacements', rules) sublime.save_settings('reg_replace_rules.sublime-settings') self.view.settings().set('regreplace.name', obj['name']) except Exception as e: error('Regex compile failed!\n\n%s' % str(e))
def __init__(self, bracket): """Setup the bracket object by reading the passed in dictionary.""" self.style = bracket.get("style", BH_STYLE) self.open = bre.compile_search( "\\A" + bracket.get("open", ""), bre.MULTILINE | bre.IGNORECASE ) self.close = bre.compile_search( bracket.get("close", "") + "\\Z", bre.MULTILINE | bre.IGNORECASE ) self.name = bracket["name"] sub_search = bracket.get("sub_bracket_search", BH_SUB_BRACKET) self.sub_search_only = sub_search == "only" self.sub_search = self.sub_search_only is True or sub_search == "true" self.compare = bracket.get("compare", BH_COMPARE_MATCH) self.post_match = bracket.get("post_match", BH_POST_MATCH) self.validate = bracket.get("validate", BH_VALIDATE_MATCH) self.scopes = bracket["scopes"] self.highlighting = bracket.get("highlighting", BH_HIGHLIGHTING) self.enabled = True if self.open.groups != 1 or self.close.groups != 1: self.enabled = False
def run(self, edit): """Parse the regex panel, and if okay, insert/replace entry in settings.""" obj = ConvertPythonSrc2Obj().convert(self.view.substr(sublime.Region(0, self.view.size())))[0] if obj is None: return if not obj.get('name'): error('A valid name must be provided!') elif obj.get('scope') is None and obj.get('find') is None: error('A valid find pattern or scope must be provided!') elif not self.is_existing_name(obj['name']): try: if obj.get('find') is not None: if obj.get('literal', False): flags = 0 pattern = re.escape(obj['find']) if obj.get('literal_ignorecase', False): flags = re.I re.compile(pattern, flags) else: extend = sublime.load_settings( 'reg_replace.sublime-settings' ).get('extended_back_references', False) if extend: bre.compile_search(obj['find']) else: re.compile(obj['find']) settings = sublime.load_settings('reg_replace_rules.sublime-settings') rules = settings.get('replacements', {}) rules[obj['name']] = obj settings.set('replacements', rules) sublime.save_settings('reg_replace_rules.sublime-settings') self.view.settings().set('regreplace.name', obj['name']) except Exception as e: error('Regex compile failed!\n\n%s' % str(e))
def get_tag_mode(view, tag_mode_config): """Get the tag mode.""" default_mode = None syntax = view.settings().get('syntax') language = splitext(basename(syntax))[0].lower() if syntax is not None else "plain text" if isinstance(tag_mode_config, list): for item in tag_mode_config: if isinstance(item, dict) and compare_languge(language, item.get('syntax', [])): first_line = item.get('first_line', '') if first_line: size = view.size() - 1 if size > 256: size = 256 if ( isinstance(first_line, str) and bre.compile_search(first_line, bre.I).match(view.substr(sublime.Region(0, size))) ): return item.get('mode', default_mode) else: return item.get('mode', default_mode) return default_mode
def apply_scope_regex(self, string, re_find, replace, greedy_replace, multi): """Apply regex on a scope.""" replaced = 0 extraction = string scope_repl = ScopeRepl(self.plugin, replace, self.expand, self.on_replace) if self.extend: pattern = bre.compile_search(re_find) self.template = bre.compile_replace(pattern, replace) else: pattern = re.compile(re_find) if multi and not self.find_only and self.action is None: extraction, replaced = self.apply_multi_pass_scope_regex( pattern, extraction, scope_repl.repl, greedy_replace ) else: if greedy_replace: extraction, replaced = pattern.subn(scope_repl.repl, string) else: extraction, replaced = pattern.subn(scope_repl.repl, string, 1) return extraction, replaced
def parse_bracket_definition(self, language, loaded_modules): """Parse the bracket definition.""" names = [] subnames = [] find_regex = [] sub_find_regex = [] self.sub_pattern = None self.pattern = None for params in self.bracket_rules: if is_valid_definition(params, language): try: bh_plugin.load_modules(params, loaded_modules) entry = BracketDefinition(params) if not self.check_compare and entry.compare is not None: self.check_compare = True if not self.check_validate and entry.validate is not None: self.check_validate = True if not self.check_post_match and entry.post_match is not None: self.check_post_match = True if not self.highlighting and entry.highlighting is not None: self.highlighting = True self.brackets.append(entry) if not entry.find_in_sub_search_only: find_regex.append(params["open"]) find_regex.append(params["close"]) names.append(params["name"]) else: find_regex.append(r"([^\s\S])") find_regex.append(r"([^\s\S])") if entry.find_in_sub_search: sub_find_regex.append(params["open"]) sub_find_regex.append(params["close"]) subnames.append(params["name"]) else: sub_find_regex.append(r"([^\s\S])") sub_find_regex.append(r"([^\s\S])") except Exception as e: log(e) if len(self.brackets): self.brackets = tuple(self.brackets) debug( "Bracket Pattern: (%s)\n" % ','.join(names) + " (Opening|Closing): (?:%s)\n" % '|'.join(find_regex) ) debug( "SubBracket Pattern: (%s)\n" % ','.join(subnames) + " (Opening|Closing): (?:%s)\n" % '|'.join(sub_find_regex) ) self.sub_pattern = bre.compile_search("(?:%s)" % '|'.join(sub_find_regex), bre.MULTILINE | bre.IGNORECASE) self.pattern = bre.compile_search("(?:%s)" % '|'.join(find_regex), bre.MULTILINE | bre.IGNORECASE) if ( self.sub_pattern.groups != len(sub_find_regex) or self.pattern.groups != len(find_regex) ): if self.sub_pattern.groups != len(sub_find_regex): log( BRACKET_ERROR % ( len(sub_find_regex), 'sub-pattern', self.sub_pattern.groups, "(?:%s)" % '|'.join(sub_find_regex) ) ) if self.pattern.groups != len(find_regex): log( BRACKET_ERROR % ( len(find_regex), 'pattern', self.pattern.groups, "(?:%s)" % '|'.join(find_regex) ) ) self.brackets = [] self.sub_pattern = None self.pattern = None
def scope_apply(self, pattern): """Find and replace based on scope.""" # Initialize replacement variables replaced = 0 regions = [] # Grab pattern definitions scope = pattern['scope'] find = pattern['find'] if 'find' in pattern else None replace = pattern['replace'] if 'replace' in pattern else '\\0' greedy_scope = bool(pattern['greedy_scope']) if 'greedy_scope' in pattern else True greedy_replace = bool(pattern['greedy_replace']) if 'greedy_replace' in pattern else True case = bool(pattern['case']) if 'case' in pattern else True multi = bool(pattern['multi_pass_regex']) if 'multi_pass_regex' in pattern else False literal = bool(pattern['literal']) if 'literal' in pattern else False dotall = bool(pattern['dotall']) if 'dotall' in pattern else False self.plugin = pattern.get("plugin", None) self.plugin_args = pattern.get("args", {}) if scope is None or scope == '': return replace if self.selection_only: sels = self.view.sel() sel_start = [] sel_size = [] for s in sels: sel_start.append(s.begin()) sel_size.append(s.size()) regions = self.view.find_by_selector(scope) if self.selection_only: regions = self.filter_by_selection(regions)[0] # Find supplied? if find is not None: # Compile regex: Ignore case flag? if not literal: try: flags = 0 if not case: flags |= re.IGNORECASE if dotall: flags |= re.DOTALL if self.extend: re_find = bre.compile_search(find, flags) else: re_find = re.compile(find, flags) except Exception as err: print(str(traceback.format_exc())) error('REGEX ERROR: %s' % str(err)) return replaced # Greedy Scope? if greedy_scope: replaced = self.greedy_scope_replace(regions, re_find, replace, greedy_replace, multi) else: replaced = self.non_greedy_scope_replace(regions, re_find, replace, greedy_replace, multi) else: if greedy_scope: replaced = self.greedy_scope_literal_replace(regions, find, replace, greedy_replace) else: replaced = self.non_greedy_scope_literal_replace(regions, find, replace, greedy_replace) else: replaced = self.select_scope_regions(regions, greedy_scope) if self.selection_only: new_sels = [] count = 0 offset = 0 for s in sels: r = sublime.Region(sel_start[count] + offset, s.end()) new_sels.append(r) offset += r.size() - sel_size[count] count += 1 sels.clear() sels.add_all(new_sels) return replaced