Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

- rework how styles are assinged to brackets

- update bh_core.sublime-settings to handle new style changes and other
changes
- fix Scope Bracket mapping issue
- change "invalid" setting to "unmatched"
- make sure always storing selections
- tab stop shortcut is now defined in Default.sublime-keymap instead of
in Example.sulbime-keymap
- due to rework change tag example shortcuts to refrence "angle" type
brackets instead of "tag"
- update bracket plugins references to "angle" type brackets instead of
"tag" where applicable
- make small fixes and adjustments to bh_wrapping.sublime-settings
- update rubykeywords.py to reflect changes in bracket plugins in
regards to styles
- tags.py now gets tag style from bh_core.sublime-settings
- provide command palette command file for bracket plugin commands
- provide menu under Preferences->Packages to access preference files
and keymap files
- provide menu under Tools->Packages for BracketHighlighter plugin
commands
- update readme
commit a9ad520d1d12f47b3a99efec7c063631624f6699 1 parent 6e49ba5
Isaac Muse authored
143 Default.sublime-commands
View
@@ -0,0 +1,143 @@
+[
+ // Search to end of file for bracket
+ {
+ "caption": "BracketHighlighter: Match Brackets (ignore threshold)",
+ "command": "bh_key",
+ "args": {"lines" : true}
+ },
+ // Remove brackets
+ {
+ "caption": "BracketHighlighter: Remove Brackets",
+ "command": "bh_remove_brackets"
+ },
+ // Go to left bracket
+ {
+ "caption": "BracketHighlighter: Jump to Left Bracket",
+ "command": "bh_key",
+ "args":
+ {
+ "lines" : true,
+ "plugin":
+ {
+ "type": ["__all__"],
+ "command": "bh_modules.bracketselect",
+ "args": {"select": "left"}
+ }
+ }
+ },
+ // Go to right bracket
+ {
+ "caption": "BracketHighlighter: Jump to Right Bracket",
+ "command": "bh_key",
+ "args":
+ {
+ "lines" : true,
+ "plugin":
+ {
+ "type": ["__all__"],
+ "command": "bh_modules.bracketselect",
+ "args": {"select": "right"}
+ }
+ }
+ },
+ // Select text between brackets
+ {
+ "keys": "BracketHighlighter: Select Bracket Content",
+ "command": "bh_key",
+ "args":
+ {
+ "lines" : true,
+ "plugin":
+ {
+ "type": ["__all__"],
+ "command": "bh_modules.bracketselect"
+ }
+ }
+ },
+ // Fold contents between brackets
+ {
+ "caption": "BracketHighlighter: Fold Bracket Content",
+ "command": "bh_key",
+ "args":
+ {
+ "plugin": {
+ "type": ["__all__"],
+ "command" : "bh_modules.foldbracket"
+ }
+ }
+ },
+ { "caption": "-" },
+ // Toggle between string and regex escape mode for string brackets
+ {
+ "caption": "BracketHighlighter: Toggle String Bracket Escape Mode",
+ "command": "bh_toggle_string_escape_mode"
+ },
+ { "caption": "-" },
+ // Select tag name of HTML/XML tag (both opening name and closing)
+ {
+ "caption": "BracketHighlighter: Select Tag Name (closing and opening)",
+ "command": "bh_key",
+ "args":
+ {
+ "plugin":
+ {
+ "type": ["angle"],
+ "command": "bh_modules.tagnameselect"
+ }
+ }
+ },
+ // Select the attribute to the right of the cursor (will wrap inside the tag)
+ {
+ "caption": "BracketHighlighter: Select Next Attribute (right)",
+ "command": "bh_key",
+ "args":
+ {
+ "plugin":
+ {
+ "type": ["angle"],
+ "command": "bh_modules.tagattrselect",
+ "args": {"direction": "right"}
+ }
+ }
+ },
+ // Select the attribute to the left of the cursor (will wrap inside the tag)
+ {
+ "caption": "BracketHighlighter: Select Next Attribute (left)",
+ "command": "bh_key",
+ "args":
+ {
+ "plugin":
+ {
+ "type": ["angle"],
+ "command": "bh_modules.tagattrselect",
+ "args": {"direction": "left"}
+ }
+ }
+ },
+ { "caption": "-" },
+ // Convert single quote string to double quoted string and vice versa
+ // Will handle escaping or unescaping quotes within the string
+ {
+ "caption": "BracketHighlighter: Swap Quotes",
+ "command": "bh_key",
+ "args":
+ {
+ "lines" : true,
+ "plugin":
+ {
+ "type": ["single_quote", "double_quote", "py_single_quote", "py_double_quote"],
+ "command": "bh_modules.swapquotes"
+ }
+ }
+ },
+ // Not implemented yet
+ {
+ "caption": "BracketHighlighter: Swap Brackets (NOT IMPLEMENTED)",
+ "command": "swap_brackets"
+ },
+ // Surround selection with brackets from quick panel
+ {
+ "caption": "BracketHighlighter: Wrap Selections with Brackets",
+ "command": "wrap_brackets"
+ }
+]
16 Default.sublime-keymap
View
@@ -0,0 +1,16 @@
+[
+ // Navigate tabstops in wrapped selection
+ {
+ "keys": ["tab"],
+ "command": "bh_next_wrap_sel",
+ "context":
+ [
+ {
+ "operand": true,
+ "operator": "equal",
+ "match_all": true,
+ "key": "bh_wrapping"
+ }
+ ]
+ }
+]
20 Example.sublime-keymap
View
@@ -70,7 +70,7 @@
{
"plugin":
{
- "type": ["tag"],
+ "type": ["angle"],
"command": "bh_modules.tagnameselect"
}
}
@@ -83,7 +83,7 @@
{
"plugin":
{
- "type": ["tag"],
+ "type": ["angle"],
"command": "bh_modules.tagattrselect",
"args": {"direction": "right"}
}
@@ -97,7 +97,7 @@
{
"plugin":
{
- "type": ["tag"],
+ "type": ["angle"],
"command": "bh_modules.tagattrselect",
"args": {"direction": "left"}
}
@@ -139,19 +139,5 @@
{
"keys": ["ctrl+alt+super+w"],
"command": "wrap_brackets"
- },
- // Navigate tabstops in wrapped selection
- {
- "keys": ["tab"],
- "command": "bh_next_wrap_sel",
- "context":
- [
- {
- "operand": true,
- "operator": "equal",
- "match_all": true,
- "key": "bh_wrapping"
- }
- ]
}
]
237 Main.sublime-menu
View
@@ -0,0 +1,237 @@
+[
+ {
+ "id": "tools",
+ "caption": "Tools",
+ "children":
+ [
+ {
+ "id": "packages",
+ "caption": "Packages",
+ "children":
+ [
+ {
+ "id": "brackethighlighter",
+ "caption": "BracketHighlighter",
+ "children":
+ [
+ // Search to end of file for bracket
+ {
+ "caption": "Match Brackets (ignore threshold)",
+ "command": "bh_key",
+ "args": {"lines" : true}
+ },
+ // Remove brackets
+ {
+ "caption": "Remove Brackets",
+ "command": "bh_remove_brackets"
+ },
+ // Go to left bracket
+ {
+ "caption": "Jump to Left Bracket",
+ "command": "bh_key",
+ "args":
+ {
+ "lines" : true,
+ "plugin":
+ {
+ "type": ["__all__"],
+ "command": "bh_modules.bracketselect",
+ "args": {"select": "left"}
+ }
+ }
+ },
+ // Go to right bracket
+ {
+ "caption": "Jump to Right Bracket",
+ "command": "bh_key",
+ "args":
+ {
+ "lines" : true,
+ "plugin":
+ {
+ "type": ["__all__"],
+ "command": "bh_modules.bracketselect",
+ "args": {"select": "right"}
+ }
+ }
+ },
+ // Select text between brackets
+ {
+ "keys": "Select Bracket Content",
+ "command": "bh_key",
+ "args":
+ {
+ "lines" : true,
+ "plugin":
+ {
+ "type": ["__all__"],
+ "command": "bh_modules.bracketselect"
+ }
+ }
+ },
+ // Fold contents between brackets
+ {
+ "caption": "Fold Bracket Content",
+ "command": "bh_key",
+ "args":
+ {
+ "plugin": {
+ "type": ["__all__"],
+ "command" : "bh_modules.foldbracket"
+ }
+ }
+ },
+ { "caption": "-" },
+ // Toggle between string and regex escape mode for string brackets
+ {
+ "caption": "Toggle String Bracket Escape Mode",
+ "command": "bh_toggle_string_escape_mode"
+ },
+ { "caption": "-" },
+ // Select tag name of HTML/XML tag (both opening name and closing)
+ {
+ "caption": "Select Tag Name (closing and opening)",
+ "command": "bh_key",
+ "args":
+ {
+ "plugin":
+ {
+ "type": ["angle"],
+ "command": "bh_modules.tagnameselect"
+ }
+ }
+ },
+ // Select the attribute to the right of the cursor (will wrap inside the tag)
+ {
+ "caption": "Select Next Attribute (right)",
+ "command": "bh_key",
+ "args":
+ {
+ "plugin":
+ {
+ "type": ["angle"],
+ "command": "bh_modules.tagattrselect",
+ "args": {"direction": "right"}
+ }
+ }
+ },
+ // Select the attribute to the left of the cursor (will wrap inside the tag)
+ {
+ "caption": "Select Next Attribute (left)",
+ "command": "bh_key",
+ "args":
+ {
+ "plugin":
+ {
+ "type": ["angle"],
+ "command": "bh_modules.tagattrselect",
+ "args": {"direction": "left"}
+ }
+ }
+ },
+ { "caption": "-" },
+ // Convert single quote string to double quoted string and vice versa
+ // Will handle escaping or unescaping quotes within the string
+ {
+ "caption": "Swap Quotes",
+ "command": "bh_key",
+ "args":
+ {
+ "lines" : true,
+ "plugin":
+ {
+ "type": ["single_quote", "double_quote", "py_single_quote", "py_double_quote"],
+ "command": "bh_modules.swapquotes"
+ }
+ }
+ },
+ // Not implemented yet
+ {
+ "caption": "Swap Brackets (NOT IMPLEMENTED)",
+ "command": "swap_brackets"
+ },
+ // Surround selection with brackets from quick panel
+ {
+ "caption": "Wrap Selections with Brackets",
+ "command": "wrap_brackets"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "caption": "Preferences",
+ "mnemonic": "n",
+ "id": "preferences",
+ "children":
+ [
+ {
+ "caption": "Package Settings",
+ "mnemonic": "P",
+ "id": "package-settings",
+ "children":
+ [
+ {
+ "caption": "Bracket Highlighter",
+ "children":
+ [
+ {
+ "command": "open_file",
+ "args": {"file": "${packages}/BracketHighlighter/bh_core.sublime-settings"},
+ "caption": "Bracket Settings – Default"
+ },
+ {
+ "command": "open_file",
+ "args": {"file": "${packages}/BracketHighlighter/bh_wrapping.sublime-settings"},
+ "caption": "Wrap Settings – Default"
+ },
+ {
+ "command": "open_file",
+ "args": {"file": "${packages}/User/bh_core.sublime-settings"},
+ "caption": "Bracket Settings – User"
+ },
+ {
+ "command": "open_file",
+ "args": {"file": "${packages}/User/bh_wrapping.sublime-settings"},
+ "caption": "Wrap Settings – User"
+ },
+ { "caption": "-" },
+ {
+ "command": "open_file",
+ "args": {"file": "${packages}/BracketHighlighter/Example.sublime-keymap"},
+ "caption": "Example Key Bindings"
+ },
+ {
+ "command": "open_file",
+ "args": {
+ "file": "${packages}/User/Default (Windows).sublime-keymap",
+ "platform": "Windows"
+ },
+ "caption": "Key Bindings – User"
+ },
+ {
+ "command": "open_file",
+ "args": {
+ "file": "${packages}/User/Default (OSX).sublime-keymap",
+ "platform": "OSX"
+ },
+ "caption": "Key Bindings – User"
+ },
+ {
+ "command": "open_file",
+ "args": {
+ "file": "${packages}/User/Default (Linux).sublime-keymap",
+ "platform": "Linux"
+ },
+ "caption": "Key Bindings – User"
+ },
+ { "caption": "-" }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+]
186 bh_core.py
View
@@ -13,6 +13,18 @@
BH_MATCH_TYPE_NONE = 0
BH_MATCH_TYPE_SELECTION = 1
BH_MATCH_TYPE_EDIT = 2
+DEFAULT_STYLES = {
+ "default": {
+ "icon": "dot",
+ "color": "brackethighlighter.default",
+ "style": "underline"
+ },
+ "unmatched": {
+ "icon": "question",
+ "color": "brackethighlighter.unmatched",
+ "style": "outline"
+ }
+}
def underline(regions):
@@ -68,14 +80,13 @@ def select_bracket_style(option):
return style
-def select_bracket_icons(option, settings):
+def select_bracket_icons(option, icon_path):
icon = ""
small_icon = ""
open_icon = ""
small_open_icon = ""
close_icon = ""
small_close_icon = ""
- icon_path = settings.get("icon_path", "Theme - Default").replace('\\', '/').strip('/')
# Icon exist?
if not option == "none" and not option == "":
if exists(normpath(join(sublime.packages_path(), icon_path, option + ".png"))):
@@ -252,48 +263,44 @@ def _get_bracket(self, bracket_code, match_type):
class BracketDefinition(object):
- def __init__(self, bracket, settings, default_highlight):
+ def __init__(self, bracket):
self.name = bracket["name"]
- self.color = bracket.get("color", default_highlight["color"])
- self.selections = []
- self.open_selections = []
- self.close_selections = []
+ self.style = bracket.get("style", "default")
self.compare = bracket.get("compare")
self.find_in_sub_search = bracket.get("find_in_sub_search", False)
self.post_match = bracket.get("post_match")
self.scope_exclude_exceptions = bracket.get("scope_exclude_exceptions", [])
self.scope_exclude = bracket.get("scope_exclude", [])
- self.style = select_bracket_style(bracket.get("style", default_highlight["style"]))
- self.underline = self.style & sublime.DRAW_EMPTY_AS_OVERWRITE
- (
- self.icon, self.small_icon, self.open_icon,
- self.small_open_icon, self.close_icon, self.small_close_icon
- ) = select_bracket_icons(bracket.get("icon", default_highlight["icon"]), settings)
self.ignore_string_escape = bracket.get("ignore_string_escape", False)
- self.no_icon = ""
class ScopeDefinition(object):
- def __init__(self, bracket, settings, default_highlight):
+ def __init__(self, bracket):
+ self.style = bracket.get("style", "default")
self.open = re.compile("\\A" + bracket.get("open", "."), re.MULTILINE | re.IGNORECASE)
self.close = re.compile(bracket.get("close", ".") + "\\Z", re.MULTILINE | re.IGNORECASE)
- self.selections = []
- self.open_selections = []
- self.close_selections = []
self.name = bracket["name"]
- self.color = bracket.get("color", default_highlight["color"])
sub_search = bracket.get("sub_bracket_search", "false")
self.sub_search_only = sub_search == "only"
self.sub_search = self.sub_search_only == True or sub_search == "true"
self.compare = bracket.get("compare")
self.post_match = bracket.get("post_match")
self.scopes = bracket["scopes"]
- self.style = select_bracket_style(bracket.get("style", default_highlight["style"]))
+
+
+class StyleDefinition(object):
+ def __init__(self, name, style, default_highlight, icon_path):
+ self.name = name
+ self.selections = []
+ self.open_selections = []
+ self.close_selections = []
+ self.color = style.get("color", default_highlight["color"])
+ self.style = select_bracket_style(style.get("style", default_highlight["style"]))
self.underline = self.style & sublime.DRAW_EMPTY_AS_OVERWRITE
(
self.icon, self.small_icon, self.open_icon,
self.small_open_icon, self.close_icon, self.small_close_icon
- ) = select_bracket_icons(bracket.get("icon", default_highlight["icon"]), settings)
+ ) = select_bracket_icons(style.get("icon", default_highlight["icon"]), icon_path)
self.no_icon = ""
@@ -350,33 +357,17 @@ def setup(self, override_thresh=False, count_lines=False, adj_only=None, ignore=
self.auto_selection_threshold = int(self.settings.get("auto_selection_threshold", 10))
self.no_multi_select_icons = bool(self.settings.get("no_multi_select_icons", False))
self.count_lines = count_lines
- self.default_string_escape_mode = self.settings.get('bracket_string_escape_mode', "string")
- self.default_highlight = {
- "icon": self.settings.get("default_icon", "dot"),
- "style": self.settings.get("default_style", "underline"),
- "color": self.settings.get("default_color", "brackethighlighter.default")
- }
+ self.default_string_escape_mode = str(self.settings.get('bracket_string_escape_mode', "string"))
+ self.show_unmatched = bool(self.settings.get("show_unmatched", True))
# Init bracket objects
self.bracket_types = self.settings.get("brackets", [])
- incomplete = self.settings.get(
- "incomplete",
- {
- "icon": "dot",
- "color": "keyword",
- "style": "outline",
- "scope_exclude": [],
- "enabled": True
- }
- )
- incomplete["name"] = "incomplete"
- self.incomplete = BracketDefinition(incomplete, self.settings, self.default_highlight)
self.scope_types = self.settings.get("scope_brackets", [])
# Init selection params
self.use_selection_threshold = True
- self.selection_threshold = self.settings.get("search_threshold", 5000)
+ self.selection_threshold = int(self.settings.get("search_threshold", 5000))
self.new_select = False
self.loaded_modules = set([])
@@ -390,6 +381,23 @@ def setup(self, override_thresh=False, count_lines=False, adj_only=None, ignore=
for t in plugin["type"]:
self.transform.add(t)
+ def init_bracket_regions(self):
+ self.bracket_regions = {}
+ styles = self.settings.get("bracket_styles", DEFAULT_STYLES)
+ icon_path = self.settings.get("icon_path", "Theme - Default").replace('\\', '/').strip('/')
+ # Make sure default and unmatched styles in styles
+ for key, value in DEFAULT_STYLES.items():
+ if key not in styles:
+ styles[key] = value
+ continue
+ for k, v in value.items():
+ if k not in styles[key]:
+ styles[key][k] = v
+ # Initialize styles
+ default_settings = styles["default"]
+ for k, v in styles.items():
+ self.bracket_regions[k] = StyleDefinition(k, v, default_settings, icon_path)
+
def init_brackets(self, language):
self.find_regex = "(?:"
self.index_open = {}
@@ -402,10 +410,7 @@ def init_brackets(self, language):
self.multi_select = False
scopes = {}
loaded_modules = self.loaded_modules.copy()
- current_brackets = []
-
- # Initialize brackets
- self.incomplete.selections = []
+ # current_brackets = []
for params in self.bracket_types:
if (
@@ -420,10 +425,10 @@ def init_brackets(self, language):
if params["open"] is not None and params["close"] is not None:
try:
load_modules(params, loaded_modules)
- entry = BracketDefinition(params, self.settings, self.default_highlight)
+ entry = BracketDefinition(params)
self.brackets.append(entry)
self.find_regex += params["open"] + "|" + params["close"] + "|"
- current_brackets.append(entry.name)
+ # current_brackets.append(entry.name)
except Exception, e:
print e
@@ -441,7 +446,7 @@ def init_brackets(self, language):
if params["open"] is not None and params["close"] is not None:
try:
load_modules(params, loaded_modules)
- entry = ScopeDefinition(params, self.settings, self.default_highlight)
+ entry = ScopeDefinition(params)
for x in entry.scopes:
if x not in scopes:
scopes[x] = scope_count
@@ -449,7 +454,7 @@ def init_brackets(self, language):
self.scopes.append({"name": x, "brackets": [entry]})
else:
self.scopes[scopes[x]]["brackets"].append(entry)
- current_brackets.append(entry.name)
+ # current_brackets.append(entry.name)
except Exception, e:
print e
@@ -457,7 +462,7 @@ def init_brackets(self, language):
# print self.find_regex[0:len(self.find_regex) - 1] + ")"
self.pattern = re.compile(self.find_regex[0:len(self.find_regex) - 1] + ")", re.MULTILINE | re.IGNORECASE)
self.enabled = True
- self.view.settings().set("bh_registered_brackets", current_brackets)
+ # self.view.settings().set("bh_registered_brackets", current_brackets)
def init_match(self):
self.chars = 0
@@ -466,33 +471,13 @@ def init_match(self):
language = basename(syntax).replace('.tmLanguage', '').lower() if syntax != None else "plain text"
if language != self.view_tracker[0] or self.view.id() != self.view_tracker[1]:
+ self.init_bracket_regions()
self.init_brackets(language)
else:
- for b in (self.brackets + [self.incomplete]):
- b.selections = []
- b.open_selections = []
- b.close_selections = []
- for s in self.scopes:
- for b in s["brackets"]:
- b.selections = []
- b.open_selections = []
- b.close_selections = []
-
- def get_bracket_type(self, name, begin, end):
- entry = None
- count = 0
- for b in (self.brackets + [self.incomplete]):
- if b.name == name:
- entry = BracketEntry(begin, end, count)
- count += 1
- count = 0
- for s in self.scopes:
- sub_count = 0
- for b in s["brackets"]:
- if b.name == name:
- entry = ScopeEntry(begin, end, count, sub_count)
- sub_count += 1
- return entry
+ for r in self.bracket_regions.values():
+ r.selections = []
+ r.open_selections = []
+ r.close_selections = []
def unique(self):
id_view = self.view.id()
@@ -539,15 +524,10 @@ def highlight(self, view):
icon_type = "small_icon" if self.view.line_height() < 16 else "icon"
open_icon_type = "small_open_icon" if self.view.line_height() < 16 else "open_icon"
close_icon_type = "small_close_icon" if self.view.line_height() < 16 else "close_icon"
- for b in (self.brackets + [self.incomplete]):
- self.highlight_regions("bh_" + b.name, icon_type, "selections", b, regions)
- self.highlight_regions("bh_" + b.name + "_open", open_icon_type, "open_selections", b, regions)
- self.highlight_regions("bh_" + b.name + "_close", close_icon_type, "close_selections", b, regions)
- for s in self.scopes:
- for b in s["brackets"]:
- self.highlight_regions("bh_" + b.name, icon_type, "selections", b, regions)
- self.highlight_regions("bh_" + b.name + "_open", open_icon_type, "open_selections", b, regions)
- self.highlight_regions("bh_" + b.name + "_close", close_icon_type, "close_selections", b, regions)
+ for name, r in self.bracket_regions.items():
+ self.highlight_regions("bh_" + name, icon_type, "selections", r, regions)
+ self.highlight_regions("bh_" + name + "_open", open_icon_type, "open_selections", r, regions)
+ self.highlight_regions("bh_" + name + "_close", close_icon_type, "close_selections", r, regions)
self.view.settings().set("bh_regions", regions)
def get_search_bfr(self, sel):
@@ -615,14 +595,15 @@ def match(self, view, force_match=True):
def save_incomplete_regions(self, left, right, regions):
found = left if left is not None else right
- bracket = self.incomplete
+ bracket = self.bracket_regions["unmatched"]
if bracket.underline:
bracket.selections += underline((found.toregion(),))
else:
bracket.selections += [found.toregion()]
self.store_sel(regions)
- def save_regions(self, left, right, bracket, regions):
+ def save_regions(self, left, right, regions):
+ bracket = self.bracket_regions.get(self.bracket_style, self.bracket_regions["default"])
lines = abs(self.view.rowcol(right.begin)[0] - self.view.rowcol(left.end)[0] + 1)
if self.count_lines:
self.chars += abs(right.begin - left.end)
@@ -653,7 +634,7 @@ def sub_search(self, sel, search_window, bfr, scope=None):
# Matched brackets
if left is not None and right is not None and bracket is not None:
- self.save_regions(left, right, bracket, regions)
+ self.save_regions(left, right, regions)
return True
return False
@@ -670,9 +651,9 @@ def find_scopes(self, bfr, sel):
return True
if left is not None and right is not None:
- self.save_regions(left, right, bracket, regions)
+ self.save_regions(left, right, regions)
return True
- elif left is not None or right is not None:
+ elif (left is not None or right is not None) and self.show_invalid:
self.save_incomplete_regions(left, right, regions)
return True
return False
@@ -689,12 +670,15 @@ def find_matches(self, bfr, sel):
# Matched brackets
if left is not None and right is not None and bracket is not None:
- self.save_regions(left, right, bracket, regions)
+ self.save_regions(left, right, regions)
# Unmatched brackets
- elif left is not None or right is not None:
+ elif (left is not None or right is not None) and self.show_unmatched:
self.save_incomplete_regions(left, right, regions)
+ else:
+ self.store_sel(regions)
+
def escaped(self, pt, ignore_string_escape, scope):
if not ignore_string_escape:
return False
@@ -774,22 +758,20 @@ def scope_post_match(self, left, right, center, bfr):
else:
return left, right
+ self.bracket_style = bracket.style
+
if bracket.post_match is not None:
try:
- lbracket, rbracket, bracket_name = bracket.post_match(
+ lbracket, rbracket, self.bracket_style = bracket.post_match(
self.view,
bracket.name,
+ bracket.style,
BracketRegion(left.begin, left.end) if left is not None else None,
BracketRegion(right.begin, right.end) if right is not None else None,
center,
bfr,
self.search_window
)
- if bracket_name != bracket.name:
- left = self.get_bracket_type(bracket_name, lbracket.begin, lbracket.end) if lbracket is not None else None
- right = self.get_bracket_type(bracket_name, rbracket.begin, rbracket.end) if rbracket is not None else None
- if left is not None or right is not None:
- return left, right
left = ScopeEntry(lbracket.begin, lbracket.end, bracket_scope, bracket_type) if lbracket is not None else None
right = ScopeEntry(rbracket.begin, rbracket.end, bracket_scope, bracket_type) if rbracket is not None else None
@@ -807,22 +789,21 @@ def post_match(self, left, right, center, bfr):
else:
return left, right
+ self.bracket_style = bracket.style
+
if bracket.post_match is not None:
try:
- lbracket, rbracket, bracket_name = bracket.post_match(
+ lbracket, rbracket, self.bracket_style = bracket.post_match(
self.view,
bracket.name,
+ bracket.style,
BracketRegion(left.begin, left.end) if left is not None else None,
BracketRegion(right.begin, right.end) if right is not None else None,
center,
bfr,
self.search_window
)
- if bracket_name != bracket.name:
- left = self.get_bracket_type(bracket_name, lbracket.begin, lbracket.end) if lbracket is not None else None
- right = self.get_bracket_type(bracket_name, rbracket.begin, rbracket.end) if rbracket is not None else None
- if left is not None or right is not None:
- return left, right
+
left = BracketEntry(lbracket.begin, lbracket.end, bracket_type) if lbracket is not None else None
right = BracketEntry(rbracket.begin, rbracket.end, bracket_type) if rbracket is not None else None
except:
@@ -885,6 +866,7 @@ def match_scope_brackets(self, bfr, sel):
break
if extent is None:
+ scope_count += 1
continue
# Search the bracket patterns of this scope
183 bh_core.sublime-settings
View
@@ -2,34 +2,25 @@
// Path to find icons at
"icon_path": "BracketHighlighter/icons",
- // Global defaults to use if a bracket does not define its own
- "default_icon": "dot",
- "default_style": "underline",
- "default_color": "brackethighlighter.default",
-
// When only either the left or right bracket can be found
- // this defines how to highlight the single bracket.
- "incomplete" : {
- "icon": "question",
- "color": "brackethighlighter.invalid",
- "style": "outline",
- "enabled": true
- },
+ // this defines if the unmatched bracket should be shown.
+ "show_unmatched" : true,
- // Brackets that are defined by a common scope
+ // Rules that define find and matching brackets
+ // that are contained in a common scope.
// Useful for bracket pairs that are the same but
// share a common scope. Brackets are found by
// Finding the extent of the scope and using regex
// to look at the beginning and end to identify bracket.
+ // Use only if they cannot be targeted with traditional bracket
+ // rules.
"scope_brackets": [
// Quotes
{
"name": "py_single_quote",
"open": "u?r?((?:'')?')",
"close": "((?:'')?')",
- "icon": "single_quote",
- "color": "brackethighlighter.quote",
- "style": "underline",
+ "style": "single_quote",
"scopes": ["string"],
"language_filter": "whitelist",
"language_list": ["Python"],
@@ -40,9 +31,7 @@
"name": "py_double_quote",
"open": "u?r?((?:\"\")?\")",
"close": "((?:\"\")?\")",
- "icon": "double_quote",
- "color": "brackethighlighter.quote",
- "style": "underline",
+ "style": "double_quote",
"scopes": ["string"],
"language_filter": "whitelist",
"language_list": ["Python"],
@@ -53,9 +42,7 @@
"name": "single_quote",
"open": "(')",
"close": "(')",
- "icon": "single_quote",
- "color": "brackethighlighter.quote",
- "style": "underline",
+ "style": "single_quote",
"scopes": ["string"],
"language_filter": "blacklist",
"language_list": ["Plain text"],
@@ -66,9 +53,7 @@
"name": "double_quote",
"open": "(\")",
"close": "(\")",
- "icon": "double_quote",
- "color": "brackethighlighter.quote",
- "style": "underline",
+ "style": "double_quote",
"scopes": ["string"],
"language_filter": "blacklist",
"language_list": ["Plain text"],
@@ -80,9 +65,7 @@
"name": "jsregex",
"open": " *(/)",
"close": "(/)[igm]*",
- "icon": "star",
- "color": "brackethighlighter.quote",
- "style": "underline",
+ "style": "regex",
"scopes": ["string"],
"language_filter": "whitelist",
"language_list": ["JavaScript"],
@@ -93,9 +76,7 @@
"name": "perlregex",
"open": "(?:m|s|tr)(.|\n)",
"close": "(.|\n)(?:[igmos]*)",
- "icon": "star",
- "color": "brackethighlighter.quote",
- "style": "underline",
+ "style": "regex",
"scopes": ["string.regexp"],
"language_filter": "whitelist",
"language_list": ["Perl"],
@@ -106,9 +87,7 @@
"name": "rubyregex",
"open": " *(/)",
"close": "(/)[imxo]*",
- "icon": "star",
- "color": "brackethighlighter.quote",
- "style": "underline",
+ "style": "regex",
"scopes": ["string"],
"language_filter": "whitelist",
"language_list": ["Ruby"],
@@ -120,9 +99,7 @@
"name": "mditalic",
"open": "(\\*|_)",
"close": "(\\*|_)",
- "icon": "dot",
- "color": "brackethighlighter.curly",
- "style": "underline",
+ "style": "default",
"scopes": ["markup.italic"],
"language_filter": "whitelist",
"language_list": ["Markdown"],
@@ -133,9 +110,7 @@
"name": "mdbold",
"open": "(\\*\\*|__)",
"close": "(\\*\\*|__)",
- "icon": "dot",
- "color": "keyword",
- "style": "underline",
+ "style": "default",
"scopes": ["markup.bold"],
"language_filter": "whitelist",
"language_list": ["Markdown"],
@@ -143,8 +118,11 @@
"enabled": true
}
],
- // Regex search of file buffer for brackets.
- // Once all are found, the closet pair wrapped around
+
+ // Rule definitions for finding and matching brackets.
+ // Brackets are found by using regex and can use scope
+ // qualifiers exclude certain matches.
+ // Once all matches are found, the closest pair surrounding
// the cursor are selected.
"brackets": [
// Basic brackets
@@ -152,9 +130,7 @@
"name": "curly",
"open": "(\\{)",
"close": "(\\})",
- "icon": "curly_bracket",
- "color": "brackethighlighter.curly",
- "style": "underline",
+ "style": "curly",
"scope_exclude": ["string", "comment"],
"scope_exclude_exceptions": ["string.other.math.block.environment.latex"],
"language_filter": "blacklist",
@@ -167,9 +143,7 @@
"name": "round",
"open": "(\\()",
"close": "(\\))",
- "icon": "round_bracket",
- "color": "brackethighlighter.round",
- "style": "underline",
+ "style": "round",
"scope_exclude_exceptions": ["string.other.math.block.environment.latex"],
"scope_exclude": ["string", "comment"],
"language_filter": "blacklist",
@@ -182,9 +156,7 @@
"name": "square",
"open": "(\\[)",
"close": "(\\])",
- "icon": "square_bracket",
- "color": "brackethighlighter.square",
- "style": "underline",
+ "style": "square",
"scope_exclude": ["string", "comment"],
"scope_exclude_exceptions": ["string.other.math.block.environment.latex"],
"language_filter": "blacklist",
@@ -193,39 +165,24 @@
"ignore_string_escape": true,
"enabled": true
},
- // HTML Tags
- {
- "name": "tag",
- "open": "(<)",
- "close": "(>)",
- "icon": "tag",
- "color": "brackethighlighter.tag",
- "style": "outline",
- "language_filter": "whitelist",
- "scope_exclude": ["string", "comment", "keyword.operator"],
- "language_list": ["HTML", "HTML 5", "XML", "PHP", "HTML+CFML", "ColdFusion", "ColdFusionCFC"],
- "plugin_library": "bh_modules.tags",
- "enabled": true
- },
+ // Angle brackets and tags
{
"name": "angle",
"open": "(<)",
"close": "(>)",
- "icon": "angle_bracket",
- "color": "brackethighlighter.angle",
- "style": "underline",
+ "style": "angle",
"scope_exclude": ["string", "comment", "keyword.operator"],
"language_filter": "whitelist",
"language_list": ["HTML", "HTML 5", "XML", "PHP", "HTML+CFML", "ColdFusion", "ColdFusionCFC"],
+ "plugin_library": "bh_modules.tags",
"enabled": true
},
+ // CSSedit groups
{
"name": "cssedit_groups",
"open": "(/\\* *@group .*\\*/)",
"close": "(/\\* *@end *\\*/)",
- "icon": "dot",
- "color": "brackethighlighter.curly",
- "style": "underline",
+ "style": "default",
"scope_exclude": [],
"language_filter": "whitelist",
"language_list": ["CSS"],
@@ -236,9 +193,7 @@
"name": "ruby",
"open": "(^\\s*\\b(?:if|until|unless|while|begin|class|module|def\\b\\s*[a-zA-Z_]+)|do)\\b",
"close": "\\b(end)\\b",
- "icon": "dot",
- "color": "keyword",
- "style": "underline",
+ "style": "default",
"scope_exclude": ["string", "comment"],
"plugin_library": "bh_modules.rubykeywords",
"language_filter": "whitelist",
@@ -250,9 +205,7 @@
"name": "c_compile_switch",
"open": "(\\#(?:if|ifdef|ifndef))\\b",
"close": "(\\#endif)\\b",
- "icon": "dot",
- "color": "keyword",
- "style": "underline",
+ "style": "default",
"scope_exclude": ["string", "comment"],
"language_filter": "whitelist",
"language_list": ["C++", "C"],
@@ -260,6 +213,75 @@
}
],
+ // Define region highlight styles
+ "bracket_styles": {
+ // "default" and "unmatched" styles are special
+ // styles. If they are not defined here,
+ // they will be generated internally with
+ // internal defaults.
+
+ // "default" style defines attributes that
+ // will be used for any style that does not
+ // explicitly define that attribute. So if
+ // a style does not define a color, it will
+ // use the color from the "default" style.
+ "default": {
+ "icon": "dot",
+ "color": "brackethighlighter.default",
+ "style": "underline"
+ },
+
+ // This particular style is used to highlight
+ // unmatched bracekt pairs. It is a special
+ // style.
+ "unmatched": {
+ "icon": "question",
+ // "color": "brackethighlighter.unmatched",
+ "style": "outline"
+ },
+ // User defined region styles
+ "curly": {
+ "icon": "curly_bracket"
+ // "color": "brackethighlighter.curly",
+ // "style": "underline"
+ },
+ "round": {
+ "icon": "round_bracket"
+ // "color": "brackethighlighter.round",
+ // "style": "underline"
+ },
+ "square": {
+ "icon": "square_bracket"
+ // "color": "brackethighlighter.square",
+ // "style": "underline"
+ },
+ "angle": {
+ "icon": "angle_bracket"
+ // "color": "brackethighlighter.angle",
+ // "style": "underline"
+ },
+ "tag": {
+ "icon": "tag",
+ // "color": "brackethighlighter.tag",
+ "style": "outline"
+ },
+ "single_quote": {
+ "icon": "single_quote"
+ // "color": "brackethighlighter.quote",
+ // "style": "underline"
+ },
+ "double_quote": {
+ "icon": "double_quote"
+ // "color": "brackethighlighter.quote",
+ // "style": "underline"
+ },
+ "regex": {
+ "icon": "regex"
+ // "color": "brackethighlighter.quote",
+ // "style": "underline"
+ }
+ },
+
// Match brackets only when the cursor is touching the inside of the bracket
"match_only_adjacent": false,
@@ -275,12 +297,15 @@
// Disable gutter icons when doing multi-select
"no_multi_select_icons": false,
- // Tag Match Settings
+ /* Plugin settings */
+
+ // Style to use for matched tags
+ "tag_style": "tag",
+
// Determine which style of tag-matching to use in which syntax
"tag_mode": {
"xhtml": ["XML"],
"html": ["HTML", "HTML 5", "PHP"],
"cfml": ["HTML+CFML", "ColdFusion", "ColdFusionCFC"]
}
-
}
6 bh_modules/bracketselect.py
View
@@ -7,19 +7,19 @@ def run(self, edit, name, select=''):
left, right = self.left, self.right
first, last = left.end, right.begin
if select == 'left':
- if name == "tag" and left.size() > 1:
+ if name == "angle" and left.size() > 1:
first, last = left.begin + 1, left.begin + 1
else:
first, last = left.end, left.end
elif select == 'right':
if left.end != right.end:
- if name == "tag" and left.size() > 1:
+ if name == "angle" and left.size() > 1:
first, last = right.begin + 1, right.begin + 1
else:
first, last = right.begin, right.begin
else:
# There is no second bracket, so just select the first
- if name == "tag" and left.size() > 1:
+ if name == "angle" and left.size() > 1:
first, last = left.begin + 1, left.begin + 1
else:
first, last = right.end, right.end
4 bh_modules/rubykeywords.py
View
@@ -1,7 +1,7 @@
import re
-def post_match(view, name, first, second, center, bfr, threshold):
+def post_match(view, name, style, first, second, center, bfr, threshold):
if first is not None:
# Strip whitespace from the beginning of first bracket
open_bracket = bfr[first.begin:first.end]
@@ -9,4 +9,4 @@ def post_match(view, name, first, second, center, bfr, threshold):
m = re.match(r"^(\s*\b)[\w\W]*", open_bracket)
if m:
first = first.move(first.begin + m.end(1), first.end)
- return first, second, name
+ return first, second, style
2  bh_modules/tagattrselect.py
View
@@ -3,7 +3,7 @@
class SelectAttr(bh_plugin.BracketPluginCommand):
def run(self, edit, name, direction='right'):
- if name != "tag" or self.left.size() <= 1:
+ if name != "angle" or self.left.size() <= 1:
return
tag_name = '[\w\:\-]+'
attr_name = '([\w\-:]+)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:\'((?:\\.|[^\'])*)\')|([^>\s]+)))?'
2  bh_modules/tagnameselect.py
View
@@ -3,7 +3,7 @@
class TagNameSelect(bh_plugin.BracketPluginCommand):
def run(self, edit, name):
- if name == "tag" and self.left.size() > 1:
+ if name == "angle" and self.left.size() > 1:
tag_name = '[\w\:\-\.]+'
region1 = self.view.find(tag_name, self.left.begin)
region2 = self.view.find(tag_name, self.right.begin)
25 bh_modules/tags.py
View
@@ -32,7 +32,7 @@ def compare_languge(language, lang_list):
def get_tag_mode(view, tag_mode_config):
- default_mode = "html"
+ default_mode = None
syntax = view.settings().get('syntax')
language = basename(syntax).replace('.tmLanguage', '').lower() if syntax != None else "plain text"
for mode in ["html", "xhtml", "cfml"]:
@@ -41,24 +41,21 @@ def get_tag_mode(view, tag_mode_config):
return default_mode
-def post_match(view, name, first, second, center, bfr, threshold):
+def post_match(view, name, style, first, second, center, bfr, threshold):
left, right = first, second
threshold = [0, len(bfr)] if threshold is None else threshold
- tag_mode = get_tag_mode(view, sublime.load_settings("bh_core.sublime-settings").get("tag_mode", {}))
+ tag_settings = sublime.load_settings("bh_core.sublime-settings")
+ tag_mode = get_tag_mode(view, tag_settings.get("tag_mode", {}))
+ tag_style = tag_settings.get("tag_style", "angle")
+ bracket_style = style
- if first is not None:
- bracket_name = name
+ if first is not None and tag_mode is not None:
matcher = TagMatch(view, bfr, threshold, first, second, center, tag_mode)
left, right = matcher.match()
- if matcher.no_tag:
- if "angle" in view.settings().get("bh_registered_brackets", []):
- bracket_name = "angle"
- else:
- if "angle" in view.settings().get("bh_registered_brackets", []):
- bracket_name = "angle"
- else:
- bracket_name = second.name
- return left, right, bracket_name
+ if not matcher.no_tag:
+ bracket_style = tag_style
+
+ return left, right, bracket_style
class TagSearch(object):
3  bh_wrapping.sublime-settings
View
@@ -21,7 +21,7 @@
]
},
{
- "enabled": true, "language_list": ["HTML", "HTML 5", "XML", "PHP", "ColdFusion", "ColdFusionCFC"], "language_filter": "whitelist", "entries": [
+ "enabled": true, "language_list": ["HTML", "HTML 5", "XML", "PHP", "HTML+CFML", "ColdFusion", "ColdFusionCFC"], "language_filter": "whitelist", "entries": [
{"name": "HTML/XML Tag", "brackets": ["<${BH_SEL:NAME}>", "</${BH_SEL:NAME}>"]},
{"name": "HTML/XML Tag - Block", "brackets": ["<${BH_SEL:NAME}>", "</${BH_SEL:NAME}>"], "insert_style": "block"},
{"name": "HTML/XML Tag - Block Indent", "brackets": ["<${BH_SEL:NAME}>", "</${BH_SEL:NAME}>"], "insert_style": "indent_block"}
@@ -40,7 +40,6 @@
{"name": "C/C++: #if, #elif", "brackets": ["#if (${BH_SEL:/* CONDITION */})", "#elif (${BH_TAB:/* CONDITION */})\n${BH_TAB:/* CODE */}\n#endif"], "insert_style": "block"},
{"name": "C/C++: #ifdef", "brackets": ["#ifdef ${BH_SEL:/* DEFINE */}", "#endif"], "insert_style": "block"},
{"name": "C/C++: #ifdef, #else", "brackets": ["#ifdef ${BH_SEL:/* DEFINE */}", "#else\n${BH_TAB:/* CODE */}\n#endif"], "insert_style": "block"},
- {"name": "C/C++: #ifdef, #else", "brackets": ["#ifdef ${BH_SEL:/* DEFINE */}", "#else\n${BH_TAB:/* CODE */}\n#endif"], "insert_style": "block"},
{"name": "C/C++: #ifndef", "brackets": ["#ifndef ${BH_SEL:/* DEFINE */}", "#endif"], "insert_style": "block"},
{"name": "C/C++: #ifndef, #else", "brackets": ["#ifndef ${BH_SEL:/* DEFINE */}", "#else\n${BH_TAB:/* CODE */}\n#endif"], "insert_style": "block"}
]
8 readme.md
View
@@ -1,12 +1,16 @@
# About
-This is a fork of pyparadigm's SublimeBrackets and SublimeTagmatcher (both are no longer available). I forked this to fix some issues I had and to add some features I wanted. I also wanted to improve the efficiency of the matching. This cuts down on the parallel searching that is now streamlined in one search. Since then, many new features have been added as well.
+This is a fork of pyparadigm's _SublimeBrackets_ and _SublimeTagmatcher_ (both are no longer available). I forked this to fix some issues I had and to add some features I wanted. I also wanted to improve the efficiency of the matching. This cuts down on the parallel searching that is now streamlined in one search. Since then, many new features have been added as well.
-![Options Screenshot](https://github.com/facelessuser/BracketHighlighter/raw/master/example.png)
+<img src="http://dl.dropbox.com/u/342698/BracketHighlighter/Example1.png" border="0">
# TODO
- Bracket Swap Plugin
- Documentation
+# Credits
+- pyparadigm: for his original efforrts with SublimeBrackets and SublimeTagmatcher which has which originally BracketHighlighter was built off of and the inspiration behind the current implementation.
+- BoundInCode: for his Tag icon
+
# Version 1.9.0
- Add experimental CFML support (defaulted off)
- Add auto-detection of self-closing tags (defaulted on)
Please sign in to comment.
Something went wrong with that request. Please try again.