From 994eb2feab6d9754824381b95d33432565109499 Mon Sep 17 00:00:00 2001 From: Isaac Muse Date: Sat, 4 Nov 2017 11:41:07 -0600 Subject: [PATCH] Feature/hashed color syntax (#45) * Handle hashed syntax highlighting when parsing * Rework scheme merging * Show hashed colors and rework scheme results * Show hashed foreground selectors * Fix doc errors * Update version and changelog * Only assign gradient if available --- CHANGES.md | 8 +++ lib/color_scheme_matcher.py | 140 ++++++++++++++++++++++++++++-------- messages.json | 2 +- messages/recent.md | 2 +- mkdocs.yml | 25 +++---- popup.j2 | 30 ++++++-- scope_hunter.py | 80 +++++++++++++++++---- support.py | 2 +- 8 files changed, 226 insertions(+), 63 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 8e1bb95..53e7f2d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,11 @@ +# ScopeHunter 2.10.0 + +Nov 4, 2017 + +- **NEW**: Add support `.sublime-color-scheme` hashed syntax highlighting. +- **FIX**: Copy of color entries. +- **FIX**: `.sublime-color-scheme` merge logic. + # ScopeHunter 2.9.3 Oct 30, 2017 diff --git a/lib/color_scheme_matcher.py b/lib/color_scheme_matcher.py index a705406..fdc16ce 100644 --- a/lib/color_scheme_matcher.py +++ b/lib/color_scheme_matcher.py @@ -38,7 +38,6 @@ GLOBAL_OPTIONS = "globals" if int(sublime.version()) >= 3152 else "defaults" # XML -IS_XML_RE = re.compile(br'^[\r\n\s]*<') XML_COMMENT_RE = re.compile(br"^[\r\n\s]*[\s\r\n]*|") # For new Sublime format @@ -309,7 +308,10 @@ def sublime_format_path(pth): class SchemeColors( namedtuple( 'SchemeColors', - ['fg', 'fg_simulated', 'bg', "bg_simulated", "style", "fg_selector", "bg_selector", "style_selectors"], + [ + 'fg', 'fg_simulated', 'bg', "bg_simulated", "style", "color_gradient", + "fg_selector", "bg_selector", "style_selectors", "color_gradient_selector" + ], verbose=False ) ): @@ -330,19 +332,17 @@ def __init__(self, scheme_file, color_filter=None): self.color_scheme = path.normpath(scheme_file) self.scheme_file = path.basename(self.color_scheme) - content = sublime.load_binary_resource(sublime_format_path(self.color_scheme)) - if scheme_file.lower().endswith(('.tmtheme', '.hidden-tmtheme')) or IS_XML_RE.match(content) is not None: + if NEW_SCHEMES and scheme_file.endswith('.sublime-color-scheme'): + self.legacy = False + self.scheme_obj = { + 'variables': {}, + GLOBAL_OPTIONS: {}, + 'rules': [] + } + else: + content = sublime.load_binary_resource(sublime_format_path(self.color_scheme)) self.legacy = True self.convert_format(readPlistFromBytes(XML_COMMENT_RE.sub(b'', content))) - else: - self.legacy = False - self.scheme_obj = sublime.decode_value(content.decode('utf-8')) - if 'variables' not in self.scheme_obj: - self.scheme_obj['variables'] = {} - if GLOBAL_OPTIONS not in self.scheme_obj: - self.scheme_obj[GLOBAL_OPTIONS] = {} - if 'rules' not in self.scheme_obj: - self.scheme_obj['rules'] = [] self.overrides = [] if NEW_SCHEMES: self.merge_overrides() @@ -386,21 +386,26 @@ def convert_format(self, obj): def merge_overrides(self): """Merge override schemes.""" - current_file = sublime_format_path(self.color_scheme) + package_overrides = [] + user_overrides = [] for override in sublime.find_resources('%s.sublime-color-scheme' % path.splitext(self.scheme_file)[0]): - if override != current_file: - ojson = sublime.decode_value(sublime.load_resource(override)) + if override.startswith('Packages/User/'): + user_overrides.append(override) + else: + package_overrides.append(override) + for override in (package_overrides + user_overrides): + ojson = sublime.decode_value(sublime.load_resource(override)) - for k, v in ojson.get('variables', {}).items(): - self.scheme_obj['variables'][k] = v + for k, v in ojson.get('variables', {}).items(): + self.scheme_obj['variables'][k] = v - for k, v in ojson.get(GLOBAL_OPTIONS, {}).items(): - self.scheme_obj[GLOBAL_OPTIONS][k] = v + for k, v in ojson.get(GLOBAL_OPTIONS, {}).items(): + self.scheme_obj[GLOBAL_OPTIONS][k] = v - for item in ojson.get('rules', []): - self.scheme_obj['rules'].append(item) + for item in ojson.get('rules', []): + self.scheme_obj['rules'].append(item) - self.overrides.append(override) + self.overrides.append(override) def filter(self, scheme): """Dummy filter call that does nothing.""" @@ -458,15 +463,29 @@ def parse_scheme(self): scolor = None style = [] if scope is not None: + # Foreground color color = item.get('foreground', None) - if color is not None: + if isinstance(color, list): + # Hashed Syntax Highlighting + for index, c in enumerate(color): + color[index] = translate_color(COLOR_RE.match(c.strip()), self.variables, {}) + elif isinstance(color, str): color = translate_color(COLOR_RE.match(color.strip()), self.variables, {}) + else: + color = None + # Background color bgcolor = item.get('background', None) - if bgcolor is not None: + if isinstance(bgcolor, str): bgcolor = translate_color(COLOR_RE.match(bgcolor.strip()), self.variables, {}) + else: + bgcolor = None + # Selection foreground color scolor = item.get('selection_foreground', None) - if scolor is not None: + if isinstance(scolor, str): scolor = translate_color(COLOR_RE.match(scolor.strip()), self.variables, {}) + else: + scolor = None + # Font style if FONT_STYLE in item: for s in item.get(FONT_STYLE, '').split(' '): if s == "bold" or s == "italic": # or s == "underline": @@ -478,7 +497,10 @@ def parse_scheme(self): def add_entry(self, name, scope, color, bgcolor, scolor, style): """Add color entry.""" - if color is not None: + color_gradient = None + if isinstance(color, list): + fg, fg_sim, color_gradient = self.process_color_gradient(color) + elif color is not None: fg, fg_sim = self.process_color(color) else: fg, fg_sim = None, None @@ -497,6 +519,7 @@ def add_entry(self, name, scope, color, bgcolor, scolor, style): "scope": scope, "color": fg, "color_simulated": fg_sim, + "color_gradient": color_gradient, "bgcolor": bg, "bgcolor_simulated": bg_sim, "selection_color": sfg, @@ -504,6 +527,37 @@ def add_entry(self, name, scope, color, bgcolor, scolor, style): "style": style } + def process_color_gradient(self, colors, simple_strip=False, bground=None): + """ + Strip transparency from the color gradient list. + + Transparency can be stripped in one of two ways: + - Simply mask off the alpha channel. + - Apply the alpha channel to the color essential getting the color seen by the eye. + """ + + gradient = [] + + for color in colors: + if color is None or color.strip() == "": + continue + + if not color.startswith('#'): + continue + + rgba = RGBA(color.replace(" ", "")) + if not simple_strip: + if bground is None: + bground = self.special_colors['background']['color_simulated'] + rgba.apply_alpha(bground if bground != "" else "#FFFFFF") + + gradient.append((color, rgba.get_rgb())) + if gradient: + color, color_sim = gradient[0] + return color, color_sim, gradient + else: + return None, None, None + def process_color(self, color, simple_strip=False, bground=None): """ Strip transparency from the color value. @@ -565,6 +619,8 @@ def guess_color(self, scope_key, selected=False, explicit_background=False): color = self.special_colors['foreground']['color'] color_sim = self.special_colors['foreground']['color_simulated'] + color_gradient = None + color_gradient_selector = None bgcolor = self.special_colors['background']['color'] if not explicit_background else None bgcolor_sim = self.special_colors['background']['color_simulated'] if not explicit_background else None scolor = self.special_colors['selection_foreground']['color'] @@ -577,6 +633,7 @@ def guess_color(self, scope_key, selected=False, explicit_background=False): if scope_key in self.matched: color = self.matched[scope_key]["color"] color_sim = self.matched[scope_key]["color_simulated"] + color_gradient = self.matched[scope_key]["color_gradient"] style = self.matched[scope_key]["style"] bgcolor = self.matched[scope_key]["bgcolor"] bgcolor_sim = self.matched[scope_key]["bgcolor_simulated"] @@ -587,18 +644,31 @@ def guess_color(self, scope_key, selected=False, explicit_background=False): bg_selector = selectors["background"] scolor_selector = selectors["scolor"] style_selectors = selectors["style"] + color_gradient_selector = selectors['color_gradient'] else: best_match_bg = 0 best_match_fg = 0 best_match_style = 0 best_match_sfg = 0 + best_match_fg_gradient = 0 for key in self.colors: match = sublime.score_selector(scope_key, key) - if self.colors[key]["color"] is not None and match > best_match_fg: + if ( + not self.colors[key]['color_gradient'] and + self.colors[key]["color"] is not None and + match > best_match_fg + ): best_match_fg = match color = self.colors[key]["color"] color_sim = self.colors[key]["color_simulated"] color_selector = SchemeSelectors(self.colors[key]["name"], self.colors[key]["scope"]) + if ( + self.colors[key]["color"] is not None and + match > best_match_fg_gradient + ): + best_match_fg_gradient = match + color_gradient = self.colors[key]["color_gradient"] + color_gradient_selector = SchemeSelectors(self.colors[key]["name"], self.colors[key]["scope"]) if self.colors[key]["selection_color"] is not None and match > best_match_sfg: best_match_sfg = match scolor = self.colors[key]["selection_color"] @@ -627,6 +697,10 @@ def guess_color(self, scope_key, selected=False, explicit_background=False): else: style = ' '.join(style) + if not isinstance(color_gradient, list): + color_gradient = None + color_gradient_selector = None + self.matched[scope_key] = { "color": color, "bgcolor": bgcolor, @@ -634,12 +708,14 @@ def guess_color(self, scope_key, selected=False, explicit_background=False): "color_simulated": color_sim, "bgcolor_simulated": bgcolor_sim, "scolor_simulated": scolor_sim, + "color_gradient": color_gradient, "style": style, "selectors": { "color": color_selector, "background": bg_selector, "scolor": scolor_selector, - "style": style_selectors + "style": style_selectors, + "color_gradient": color_gradient_selector } } @@ -648,12 +724,14 @@ def guess_color(self, scope_key, selected=False, explicit_background=False): color = scolor color_sim = scolor_sim color_selector = scolor_selector + color_gradient = None + color_gradient_selector = None if self.special_colors['selection']['color']: bgcolor = self.special_colors['selection']['color'] bgcolor_sim = self.special_colors['selection']['color_simulated'] bg_selector = SchemeSelectors("selection", "selection") return SchemeColors( - color, color_sim, bgcolor, bgcolor_sim, style, - color_selector, bg_selector, style_selectors + color, color_sim, bgcolor, bgcolor_sim, style, color_gradient, + color_selector, bg_selector, style_selectors, color_gradient_selector ) diff --git a/messages.json b/messages.json index 7e2e320..b71289a 100644 --- a/messages.json +++ b/messages.json @@ -1,3 +1,3 @@ { - "2.9.0": "messages/recent.md" + "2.10.0": "messages/recent.md" } diff --git a/messages/recent.md b/messages/recent.md index d7a42d5..de039ba 100644 --- a/messages/recent.md +++ b/messages/recent.md @@ -1,4 +1,4 @@ -# RegReplace 2.9.0 +# RegReplace 2.10.0 New release! diff --git a/mkdocs.yml b/mkdocs.yml index 4d6fd51..ceb8865 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -7,6 +7,19 @@ copyright: | Copyright © 2012 - 2017 Isaac Muse
emoji provided free by EmojiOne +docs_dir: docs/src/markdown +theme: + name: material + custom_dir: docs/theme + palette: + primary: blue + accent: blue + logo: + icon: description + font: + text: Roboto + code: Roboto Mono + pages: - About ScopeHunter: index.md - Installation: installation.md @@ -14,12 +27,6 @@ pages: - Contributing & Support: contributing.md - License: license.md -docs_dir: docs/src/markdown - -theme: material -docs_dir: docs/src/markdown -theme_dir: docs/theme - markdown_extensions: - markdown.extensions.toc: slugify: !!python/name:pymdownx.slugs.uslugify @@ -65,12 +72,6 @@ markdown_extensions: - pymdownx.details: extra: - palette: - primary: blue - accent: blue - font: - text: Roboto - code: Roboto Mono social: - type: github link: https://github.com/facelessuser diff --git a/popup.j2 b/popup.j2 index b07d53f..526cd7e 100644 --- a/popup.j2 +++ b/popup.j2 @@ -24,6 +24,16 @@ **fg (simulated alpha):**{: .keyword} {{plugin.fg_sim_preview}} {{plugin.fg_sim_color}} [(copy)](copy-fg-sim:{{plugin.fg_sim_index}}){: .small} + {% endif %} + {% if plugin.fg_hash %} +**hashed fg:**{: .keyword} {{plugin.fg_hash_preview}} {{plugin.fg_hash_color}} +[(copy)](copy-fg-hash:{{plugin.fg_hash_index}}){: .small} + + {% endif %} + {% if plugin.fg_hash_sim %} +**hashed fg (simulated alpha):**{: .keyword} {{plugin.fg_hash_sim_preview}} {{plugin.fg_hash_sim_color}} +[(copy)](copy-fg-hash-sim:{{plugin.fg_hash_sim_index}}){: .small} + {% endif %} **bg:**{: .keyword} {{plugin.bg_preview}} {{plugin.bg_color}} [(copy)](copy-bg:{{plugin.bg_index}}){: .small} @@ -48,6 +58,16 @@ **fg scope:**{: .keyword} {{plugin.fg_scope}} [(copy)](copy-fg-sel-scope:{{plugin.fg_scope_index}}){: .small} + {% if plugin.fg_hash_name %} +**hashed fg name:**{: .keyword} {{plugin.fg_hash_name}} +[(copy)](copy-fg-hash-sel-name:{{plugin.fg_hash_name_index}}){: .small} + + {% endif %} + {% if plugin.fg_hash_scope %} +**hashed fg scope:**{: .keyword} {{plugin.fg_hash_scope}} +[(copy)](copy-fg-hash-sel-scope:{{plugin.fg_hash_scope_index}}){: .small} + + {% endif %} {% if plugin.bg_name %} **bg name:**{: .keyword} {{plugin.bg_name}} [(copy)](copy-bg-sel-name:{{plugin.bg_name_index}}){: .small} @@ -83,12 +103,14 @@ **syntax:**{: .keyword} [{{plugin.syntax}}](syntax) [(copy)](copy-syntax:{{plugin.syntax_index}}){: .small} -**scheme:**{: .keyword} [{{plugin.scheme}}](scheme) + {% if plugin.scheme %} +**tmTheme:**{: .keyword} [{{plugin.scheme}}](scheme) [(copy)](copy-scheme:{{plugin.scheme_index}}){: .small} + {% endif %} -{% for item in plugin.overrides %} -**override scheme {{loop.index}}:**{: .keyword} [{{item}}](override:{{plugin.overrides_index}}:{{loop.index}}) + {% for item in plugin.overrides %} +**Scheme {{loop.index}}:**{: .keyword} [{{item}}](override:{{plugin.overrides_index}}:{{loop.index}}) [(copy)](copy-overrides:{{plugin.overrides_index}}:{{loop.index}}){: .small} -{% endfor %} + {% endfor %} {% endif %} diff --git a/scope_hunter.py b/scope_hunter.py index 61703c0..bf9c509 100644 --- a/scope_hunter.py +++ b/scope_hunter.py @@ -70,9 +70,13 @@ BOLD_SCOPE_KEY = "Bold Scope" ITALIC_NAME_KEY = "Italic Name" ITALIC_SCOPE_KEY = "Italic Scope" -SCHEME_KEY = "Scheme File" +SCHEME_KEY = "tmTheme File" SYNTAX_KEY = "Syntax File" -OVERRIDE_SCHEME_KEY = "Override Scheme" +OVERRIDE_SCHEME_KEY = "Scheme" +HASHED_FG_KEY = "Hashed Fg" +HASHED_FG_SIM_KEY = "Hashed Fg (Simulated Alpha)" +HASHED_FG_NAME_KEY = "Hashed Fg Name" +HASHED_FG_SCOPE_KEY = "Hashed Fg Scope" def log(msg): @@ -179,13 +183,19 @@ def get_color_box(self, color, key, index): padding += int(self.view.settings().get('line_padding_bottom', 0)) box_height = int(self.view.line_height()) - padding - 2 check_size = int((box_height - 4) / 4) + if isinstance(color, list): + box_width = box_height * (len(color) if len(color) >= 1 else 1) + colors = [c.upper() for c in color] + else: + box_width = box_height + colors = [color.upper()] if check_size < 2: check_size = 2 self.template_vars['%s_preview' % key] = mdpopups.color_box( - [color], border, border2, height=box_height, - width=box_height, border_size=2, check_size=check_size + colors, border, border2, height=box_height, + width=box_width, border_size=2, check_size=check_size ) - self.template_vars['%s_color' % key] = color.upper() + self.template_vars['%s_color' % key] = ', '.join(colors) self.template_vars['%s_index' % key] = index def get_extents(self, pt): @@ -255,18 +265,31 @@ def get_scope(self, pt): return scope - def get_appearance(self, color, color_sim, bgcolor, bgcolor_sim, style): + def get_appearance(self, color, color_sim, bgcolor, bgcolor_sim, style, color_gradient): """Get colors of foreground, background, and simulated transparency colors.""" self.scope_bfr.append(ENTRY % (FG_KEY + ":", color)) if self.show_simulated and len(color) == 9 and not color.lower().endswith('ff'): self.scope_bfr.append(ENTRY % (FG_SIM_KEY + ":", color_sim)) + colors = [] + colors_sim = [] + show_sim = False + if color_gradient: + for c, cs in color_gradient: + colors.append(c) + if len(cs) == 9 and not cs.lower().endswith('ff'): + show_sim = True + colors_sim.append(cs) + self.scope_bfr.append(ENTRY % (HASHED_FG_KEY + ":", ', '.join(colors))) + if self.show_simulated and show_sim: + self.scope_bfr.append(ENTRY % (HASHED_FG_SIM_KEY + ":", ', '.join(colors_sim))) + self.scope_bfr.append(ENTRY % (BG_KEY + ":", bgcolor)) if self.show_simulated and len(bgcolor) == 9 and not bgcolor.lower().endswith('ff'): self.scope_bfr.append(ENTRY % (BG_SIM_KEY + ":", bgcolor_sim)) - self.scope_bfr.append(ENTRY % (STYLE_KEY + ":", style)) + self.scope_bfr.append(ENTRY % (STYLE_KEY + ":", "normal" if not style else style)) if self.show_popup: self.template_vars['appearance'] = True @@ -274,6 +297,12 @@ def get_appearance(self, color, color_sim, bgcolor, bgcolor_sim, style): if self.show_simulated and len(color) == 9 and not color.lower().endswith('ff'): self.template_vars['fg_sim'] = True self.get_color_box(color_sim, 'fg_sim', self.next_index()) + if color_gradient: + self.template_vars['fg_hash'] = True + self.get_color_box(colors, 'fg_hash', self.next_index()) + if self.show_simulated and show_sim: + self.template_vars['fg_hash_sim'] = True + self.get_color_box(colors_sim, 'fg_hash_sim', self.next_index()) self.get_color_box(bgcolor, 'bg', self.next_index()) if self.show_simulated and len(bgcolor) == 9 and not bgcolor.lower().endswith('ff'): self.template_vars['bg_sim'] = True @@ -312,9 +341,11 @@ def get_scheme_syntax(self): self.overrides = scheme_matcher.overrides self.scheme_file = scheme_matcher.color_scheme.replace('\\', '/') + is_tmtheme = not self.scheme_file.endswith('.sublime-color-scheme') self.syntax_file = self.view.settings().get('syntax') self.scope_bfr.append(ENTRY % (SYNTAX_KEY + ":", self.syntax_file)) - self.scope_bfr.append(ENTRY % (SCHEME_KEY + ":", self.scheme_file)) + if is_tmtheme: + self.scope_bfr.append(ENTRY % (SCHEME_KEY + ":", self.scheme_file)) text = [] for idx, override in enumerate(self.overrides, 1): text.append(ENTRY % (OVERRIDE_SCHEME_KEY + (" %d:" % idx), override)) @@ -324,16 +355,20 @@ def get_scheme_syntax(self): self.template_vars['files'] = True self.template_vars["syntax"] = self.syntax_file self.template_vars["syntax_index"] = self.next_index() - self.template_vars["scheme"] = self.scheme_file - self.template_vars["scheme_index"] = self.next_index() + if is_tmtheme: + self.template_vars["scheme"] = self.scheme_file + self.template_vars["scheme_index"] = self.next_index() self.template_vars["overrides"] = self.overrides self.template_vars["overrides_index"] = self.next_index() - def get_selectors(self, color_selector, bg_selector, style_selectors): + def get_selectors(self, color_selector, bg_selector, style_selectors, color_gradient_selector): """Get the selectors used to determine color and/or style.""" self.scope_bfr.append(ENTRY % (FG_NAME_KEY + ":", color_selector.name)) self.scope_bfr.append(ENTRY % (FG_SCOPE_KEY + ":", color_selector.scope)) + if color_gradient_selector: + self.scope_bfr.append(ENTRY % (HASHED_FG_NAME_KEY + ":", color_gradient_selector.name)) + self.scope_bfr.append(ENTRY % (HASHED_FG_SCOPE_KEY + ":", color_gradient_selector.scope)) self.scope_bfr.append(ENTRY % (BG_NAME_KEY + ":", bg_selector.name)) self.scope_bfr.append(ENTRY % (BG_SCOPE_KEY + ":", bg_selector.scope)) if style_selectors["bold"].name != "" or style_selectors["bold"].scope != "": @@ -350,6 +385,11 @@ def get_selectors(self, color_selector, bg_selector, style_selectors): self.template_vars['fg_name_index'] = self.next_index() self.template_vars['fg_scope'] = color_selector.scope self.template_vars['fg_scope_index'] = self.next_index() + if color_gradient_selector: + self.template_vars['fg_hash_name'] = color_gradient_selector.name + self.template_vars['fg_hash_name_index'] = self.next_index() + self.template_vars['fg_hash_scope'] = color_gradient_selector.scope + self.template_vars['fg_hash_scope_index'] = self.next_index() self.template_vars['bg_name'] = bg_selector.name self.template_vars['bg_name_index'] = self.next_index() self.template_vars['bg_scope'] = bg_selector.scope @@ -386,12 +426,18 @@ def get_info(self, pt): bg_selector = match.bg_selector color_selector = match.fg_selector style_selectors = match.style_selectors + color_gradient = match.color_gradient + color_gradient_selector = match.color_gradient_selector + + # if match.color_gradient is not None: + # color = self.view.style_for_scope(scope)["foreground"] + # color_sim = color if self.appearance_info: - self.get_appearance(color, color_sim, bgcolor, bgcolor_sim, style) + self.get_appearance(color, color_sim, bgcolor, bgcolor_sim, style, color_gradient) if self.selector_info: - self.get_selectors(color_selector, bg_selector, style_selectors) + self.get_selectors(color_selector, bg_selector, style_selectors, color_gradient_selector) except Exception: log("Evaluating theme failed! Ignoring theme related info.") debug(str(traceback.format_exc())) @@ -446,6 +492,10 @@ def on_navigate(self, href): copy_data(self.scope_bfr, FG_KEY, index) elif key == 'copy-fg-sim': copy_data(self.scope_bfr, FG_SIM_KEY, index) + elif key == 'copy-fg-hash': + copy_data(self.scope_bfr, HASHED_FG_KEY, index) + elif key == 'copy-fg-hash-sim': + copy_data(self.scope_bfr, HASHED_FG_SIM_KEY, index) elif key == 'copy-bg': copy_data(self.scope_bfr, BG_KEY, index) elif key == 'copy-bg-sim': @@ -456,6 +506,10 @@ def on_navigate(self, href): copy_data(self.scope_bfr, FG_NAME_KEY, index) elif key == 'copy-fg-sel-scope': copy_data(self.scope_bfr, FG_SCOPE_KEY, index) + elif key == 'copy-fg-hash-sel-name': + copy_data(self.scope_bfr, HASHED_FG_NAME_KEY, index) + elif key == 'copy-fg-hash-sel-scope': + copy_data(self.scope_bfr, HASHED_FG_SCOPE_KEY, index) elif key == 'copy-bg-sel-name': copy_data(self.scope_bfr, BG_NAME_KEY, index) elif key == 'copy-bg-sel-scope': diff --git a/support.py b/support.py index 89638eb..b7454de 100644 --- a/support.py +++ b/support.py @@ -5,7 +5,7 @@ import webbrowser import re -__version__ = "2.9.3" +__version__ = "2.10.0" __pc_name__ = 'ScopeHunter'