feat(ST2.EditorPackages): bump up all packages
- Refresh PackageCache with latest versions of everything
@@ -8,15 +8,16 @@ class AbacusCommand(sublime_plugin.TextCommand):
|
||||
perform a series of replacements.
|
||||
"""
|
||||
def run(self, edit):
|
||||
candidates = []
|
||||
separators = sublime.load_settings("Abacus.sublime-settings").get("com.khiltd.abacus.separators")
|
||||
indentor = Template("$indentation$left_col")
|
||||
lg_aligner = Template("$left_col$separator")
|
||||
rg_aligner = Template("$left_col$gutter$separator_padding$separator")
|
||||
candidates = []
|
||||
separators = sublime.load_settings("Abacus.sublime-settings").get("com.khiltd.abacus.separators")
|
||||
syntax_specific = self.view.settings().get("com.khiltd.abacus.separators", [])
|
||||
indentor = Template("$indentation$left_col")
|
||||
lg_aligner = Template("$left_col$separator")
|
||||
rg_aligner = Template("$left_col$gutter$separator_padding$separator")
|
||||
|
||||
#Run through the separators accumulating alignment candidates
|
||||
#starting with the longest ones i.e. '==' before '='.
|
||||
longest_first = self.sort_separators(separators)
|
||||
longest_first = self.sort_separators(syntax_specific + [sep for sep in separators if sep["token"] not in [t["token"] for t in syntax_specific]])
|
||||
|
||||
#Favor those that lean right so assignments with slice notation in them
|
||||
#get handled sanely
|
||||
@@ -118,10 +119,10 @@ class AbacusCommand(sublime_plugin.TextCommand):
|
||||
potential_matches = [m for m in token_matcher.finditer(collapsed)]
|
||||
|
||||
if debug:
|
||||
print "Pattern:"
|
||||
print token_matcher.pattern
|
||||
print "Matches:"
|
||||
print potential_matches
|
||||
print("Pattern:")
|
||||
print(token_matcher.pattern)
|
||||
print("Matches:")
|
||||
print(potential_matches)
|
||||
|
||||
if len(potential_matches):
|
||||
#Split on the first/last occurrence of the token
|
||||
|
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"com.khiltd.abacus.separators":
|
||||
[
|
||||
{
|
||||
"token": "=>",
|
||||
"gravity": "right",
|
||||
"preserve_indentation": true
|
||||
}
|
||||
]
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"com.khiltd.abacus.separators":
|
||||
[
|
||||
{
|
||||
"token": "=>",
|
||||
"gravity": "right",
|
||||
"preserve_indentation": true
|
||||
}
|
||||
]
|
||||
}
|
@@ -1 +1 @@
|
||||
{"url": "https://github.com/khiltd/Abacus", "version": "2013.01.11.00.24.46", "description": "An Alignment Plugin for Sublime Text 2 that actually works `\u2318\u2325^ ]`"}
|
||||
{"url": "https://github.com/khiltd/Abacus", "version": "2013.07.23.05.22.38", "description": "An Alignment Plugin for Sublime Text 2 that actually works `\u2318\u2325^ ]`"}
|
@@ -1,5 +1,8 @@
|
||||
# BlockCursorEverywhere #
|
||||
|
||||
I apologize, but this is no longer updated. I don't even use it anymore because of API limitations. I recommend looking at the original repo by netpro2k.
|
||||
|
||||
|
||||

|
||||
|
||||
It can become very difficult to keep track of your cursor location. This is solved by having a "block" cursor, which is very easy to spot no matter where it is on screen. Unfortunately, Sublime Text 2 does not (yet) support this feature natively. This Plugin mimics this functionality by highlighting the area behind the cursor whenever it moves (similar to how you might highlight syntax errors, or color a comment).
|
||||
|
@@ -19,7 +19,8 @@ class BlockCursorEverywhere(sublime_plugin.EventListener):
|
||||
view.erase_regions('BlockCursorListener')
|
||||
|
||||
def on_selection_modified(self, view):
|
||||
if view.settings().get('is_widget') or not("Vintage" in view.settings().get('ignored_packages') or view.settings().get('command_mode')):
|
||||
no_vintage = view.settings().get('ignored_packages') is None or "Vintage" in view.settings().get('ignored_packages')
|
||||
if view.settings().get('is_widget') or not(no_vintage or view.settings().get('command_mode')):
|
||||
view.erase_regions('BlockCursorListener')
|
||||
return
|
||||
self.show_block_cursor(view)
|
||||
|
@@ -1 +1 @@
|
||||
{"url": "https://github.com/ingshtrom/BlockCursorEverywhere", "version": "2013.01.20.10.51.30", "description": "Sublime Text 2 plugin to mimic a block cursor in Vintage command mode."}
|
||||
{"url": "https://github.com/ingshtrom/BlockCursorEverywhere", "version": "2013.08.02.15.49.34", "description": "Sublime Text 2 plugin to mimic a block cursor in Vintage command mode."}
|
@@ -3,7 +3,7 @@ import sublime
|
||||
import sublime_plugin
|
||||
from time import time, sleep
|
||||
import thread
|
||||
import re
|
||||
import ure
|
||||
from bh_plugin import BracketPlugin, BracketRegion, ImportModule
|
||||
from collections import namedtuple
|
||||
import traceback
|
||||
@@ -398,8 +398,8 @@ class ScopeDefinition(object):
|
||||
"""
|
||||
|
||||
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.open = ure.compile("\\A" + bracket.get("open", "."), ure.MULTILINE | ure.IGNORECASE)
|
||||
self.close = ure.compile(bracket.get("close", ".") + "\\Z", ure.MULTILINE | ure.IGNORECASE)
|
||||
self.name = bracket["name"]
|
||||
sub_search = bracket.get("sub_bracket_search", "false")
|
||||
self.sub_search_only = sub_search == "only"
|
||||
@@ -537,7 +537,7 @@ class BhCore(object):
|
||||
self.last_id_view = None
|
||||
self.last_id_sel = None
|
||||
self.view_tracker = (None, None)
|
||||
self.ignore_threshold = override_thresh
|
||||
self.ignore_threshold = override_thresh or bool(self.settings.get("ignore_threshold", False))
|
||||
self.adj_only = adj_only if adj_only is not None else bool(self.settings.get("match_only_adjacent", False))
|
||||
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))
|
||||
@@ -668,8 +668,8 @@ class BhCore(object):
|
||||
"(?:%s)\n" % '|'.join(self.find_regex) +
|
||||
"(?:%s)" % '|'.join(self.sub_find_regex)
|
||||
)
|
||||
self.sub_pattern = re.compile("(?:%s)" % '|'.join(self.sub_find_regex), re.MULTILINE | re.IGNORECASE)
|
||||
self.pattern = re.compile("(?:%s)" % '|'.join(self.find_regex), re.MULTILINE | re.IGNORECASE)
|
||||
self.sub_pattern = ure.compile("(?:%s)" % '|'.join(self.sub_find_regex), ure.MULTILINE | ure.IGNORECASE)
|
||||
self.pattern = ure.compile("(?:%s)" % '|'.join(self.find_regex), ure.MULTILINE | ure.IGNORECASE)
|
||||
self.enabled = True
|
||||
|
||||
def init_match(self):
|
||||
@@ -810,9 +810,13 @@ class BhCore(object):
|
||||
|
||||
if view == None:
|
||||
return
|
||||
|
||||
view.settings().set("BracketHighlighterBusy", True)
|
||||
|
||||
if not GLOBAL_ENABLE:
|
||||
for region_key in view.settings().get("bh_regions", []):
|
||||
view.erase_regions(region_key)
|
||||
view.settings().set("BracketHighlighterBusy", False)
|
||||
return
|
||||
|
||||
if self.keycommand:
|
||||
@@ -834,11 +838,13 @@ class BhCore(object):
|
||||
|
||||
# Nothing to search for
|
||||
if not self.enabled:
|
||||
view.settings().set("BracketHighlighterBusy", False)
|
||||
return
|
||||
|
||||
# Abort if selections are beyond the threshold
|
||||
if self.use_selection_threshold and num_sels >= self.selection_threshold:
|
||||
self.highlight(view)
|
||||
view.settings().set("BracketHighlighterBusy", False)
|
||||
return
|
||||
|
||||
multi_select_count = 0
|
||||
@@ -859,6 +865,7 @@ class BhCore(object):
|
||||
self.highlight(view)
|
||||
if self.count_lines:
|
||||
sublime.status_message('In Block: Lines ' + str(self.lines) + ', Chars ' + str(self.chars))
|
||||
view.settings().set("BracketHighlighterBusy", False)
|
||||
|
||||
def save_incomplete_regions(self, left, right, regions):
|
||||
"""
|
||||
@@ -926,7 +933,9 @@ class BhCore(object):
|
||||
|
||||
if left is not None and right is not None:
|
||||
bracket = self.brackets[left.type]
|
||||
left, right, regions = self.run_plugin(bracket.name, left, right, regions)
|
||||
left, right, regions, nobracket = self.run_plugin(bracket.name, left, right, regions)
|
||||
if nobracket:
|
||||
return True
|
||||
|
||||
# Matched brackets
|
||||
if left is not None and right is not None and bracket is not None:
|
||||
@@ -946,7 +955,7 @@ class BhCore(object):
|
||||
regions = [sublime.Region(sel.a, sel.b)]
|
||||
|
||||
if left is not None and right is not None:
|
||||
left, right, regions = self.run_plugin(bracket.name, left, right, regions)
|
||||
left, right, regions, _ = self.run_plugin(bracket.name, left, right, regions)
|
||||
if left is None and right is None:
|
||||
self.store_sel(regions)
|
||||
return True
|
||||
@@ -971,7 +980,7 @@ class BhCore(object):
|
||||
|
||||
if left is not None and right is not None:
|
||||
bracket = self.brackets[left.type]
|
||||
left, right, regions = self.run_plugin(bracket.name, left, right, regions)
|
||||
left, right, regions, _ = self.run_plugin(bracket.name, left, right, regions)
|
||||
|
||||
# Matched brackets
|
||||
if left is not None and right is not None and bracket is not None:
|
||||
@@ -1113,16 +1122,17 @@ class BhCore(object):
|
||||
|
||||
lbracket = BracketRegion(left.begin, left.end)
|
||||
rbracket = BracketRegion(right.begin, right.end)
|
||||
nobracket = False
|
||||
|
||||
if (
|
||||
("__all__" in self.transform or name in self.transform) and
|
||||
self.plugin != None and
|
||||
self.plugin.is_enabled()
|
||||
):
|
||||
lbracket, rbracket, regions = self.plugin.run_command(self.view, name, lbracket, rbracket, regions)
|
||||
lbracket, rbracket, regions, nobracket = self.plugin.run_command(self.view, name, lbracket, rbracket, regions)
|
||||
left = left.move(lbracket.begin, lbracket.end) if lbracket is not None else None
|
||||
right = right.move(rbracket.begin, rbracket.end) if rbracket is not None else None
|
||||
return left, right, regions
|
||||
return left, right, regions, nobracket
|
||||
|
||||
def match_scope_brackets(self, bfr, sel):
|
||||
"""
|
||||
|
@@ -9,9 +9,10 @@
|
||||
// this defines if the unmatched bracket should be shown.
|
||||
"show_unmatched" : true,
|
||||
|
||||
// High visibilty style and color for high visibility mode
|
||||
// High visibility style and color for high visibility mode
|
||||
// (solid|outline|underline)
|
||||
"high_visibility_style": "outline",
|
||||
|
||||
// (scope|__default__|__bracket__)
|
||||
"high_visibility_color": "__bracket__",
|
||||
|
||||
@@ -21,6 +22,9 @@
|
||||
// Character threshold to search
|
||||
"search_threshold": 5000,
|
||||
|
||||
// Ignore threshold
|
||||
"ignore_threshold": false,
|
||||
|
||||
// Set mode for string escapes to ignore (regex|string)
|
||||
"bracket_string_escape_mode": "string",
|
||||
|
||||
@@ -215,15 +219,26 @@
|
||||
"find_in_sub_search": "only",
|
||||
"enabled": false
|
||||
},
|
||||
// Angle
|
||||
// PHP Angle
|
||||
{
|
||||
"name": "angle",
|
||||
"open": "(<)",
|
||||
"close": "(>)",
|
||||
"name": "php_angle",
|
||||
"open": "(<\\?)(?:php)?",
|
||||
"close": "(\\?>)",
|
||||
"style": "angle",
|
||||
"scope_exclude": ["string", "comment", "keyword.operator"],
|
||||
"language_filter": "whitelist",
|
||||
"language_list": ["HTML", "HTML 5", "XML", "PHP", "HTML+CFML", "ColdFusion", "ColdFusionCFC"],
|
||||
"language_list": ["HTML", "HTML 5", "PHP"],
|
||||
"enabled": true
|
||||
},
|
||||
// Angle
|
||||
{
|
||||
"name": "angle",
|
||||
"open": "(<)(?!\\?)",
|
||||
"close": "(?<!\\?)(>)",
|
||||
"style": "angle",
|
||||
"scope_exclude": ["string", "comment", "keyword.operator", "source.ruby.rails.embedded.html", "source.ruby.embedded.html"],
|
||||
"language_filter": "whitelist",
|
||||
"language_list": ["HTML", "HTML 5", "XML", "PHP", "HTML (Rails)", "HTML (Jinja Templates)", "HTML (Twig)", "HTML+CFML", "ColdFusion", "ColdFusionCFC"],
|
||||
"plugin_library": "bh_modules.tags",
|
||||
"enabled": true
|
||||
},
|
||||
@@ -238,16 +253,29 @@
|
||||
"language_list": ["CSS"],
|
||||
"enabled": true
|
||||
},
|
||||
// Ruby embedded HTML
|
||||
{
|
||||
"name": "ruby_embedded_html",
|
||||
"open": "((?:(?<=<%)|(?<=^))\\s*\\b(?:if|case|until|unless|while|begin|class|module|def\\b[\\p{Ll}\\p{Lu}]*)|\\bdo)\\b",
|
||||
"close": "\\b(end)\\b",
|
||||
"style": "default",
|
||||
"scope_exclude": ["text.html", "source", "comment", "string"],
|
||||
"scope_exclude_exceptions": ["source.ruby.rails.embedded.html", "source.ruby.embedded.html"],
|
||||
"plugin_library": "bh_modules.rubykeywords",
|
||||
"language_filter": "whitelist",
|
||||
"language_list": ["HTML", "HTML 5", "PHP", "HTML (Rails)"],
|
||||
"enabled": true
|
||||
},
|
||||
// Ruby conditional statements
|
||||
{
|
||||
"name": "ruby",
|
||||
"open": "(^\\s*\\b(?:if|case|until|unless|while|begin|class|module|def\\b\\s*[a-zA-Z_\\d]+)|\\bdo)\\b",
|
||||
"open": "(^\\s*\\b(?:if|case|until|unless|while|begin|class|module|def\\b[\\p{Ll}\\p{Lu}]*)|\\bdo)\\b",
|
||||
"close": "\\b(end)\\b",
|
||||
"style": "default",
|
||||
"scope_exclude": ["string", "comment"],
|
||||
"plugin_library": "bh_modules.rubykeywords",
|
||||
"language_filter": "whitelist",
|
||||
"language_list": ["Ruby", "Ruby on Rails", "HTML (Rails)"],
|
||||
"language_list": ["Ruby", "Ruby on Rails"],
|
||||
"enabled": true
|
||||
},
|
||||
// C/C++ compile switches
|
||||
@@ -300,6 +328,8 @@
|
||||
// use the color from the "default" style.
|
||||
"default": {
|
||||
"icon": "dot",
|
||||
// BH1's original default color for reference
|
||||
// "color": "entity.name.class",
|
||||
"color": "brackethighlighter.default",
|
||||
"style": "underline"
|
||||
},
|
||||
@@ -366,7 +396,7 @@
|
||||
// Determine which style of tag-matching to use in which syntax
|
||||
"tag_mode": {
|
||||
"xhtml": ["XML"],
|
||||
"html": ["HTML", "HTML 5", "PHP"],
|
||||
"html": ["HTML", "HTML 5", "PHP", "HTML (Jinja Templates)", "HTML (Rails)", "HTML (Twig)"],
|
||||
"cfml": ["HTML+CFML", "ColdFusion", "ColdFusionCFC"]
|
||||
}
|
||||
}
|
||||
|
@@ -35,6 +35,7 @@ class BracketRemove(bh_plugin.BracketPluginCommand):
|
||||
|
||||
self.left = None
|
||||
self.right = None
|
||||
self.nobracket = True
|
||||
|
||||
|
||||
def plugin():
|
||||
|
@@ -6,25 +6,38 @@ DEFAULT_TAGS = ["cfml", "html", "angle"]
|
||||
|
||||
class SelectBracket(bh_plugin.BracketPluginCommand):
|
||||
def run(self, edit, name, select='', tags=DEFAULT_TAGS):
|
||||
current_left, current_right = self.selection[0].begin(), self.selection[0].end()
|
||||
left, right = self.left, self.right
|
||||
first, last = left.end, right.begin
|
||||
if select == 'left':
|
||||
if name in tags and left.size() > 1:
|
||||
first, last = left.begin + 1, left.begin + 1
|
||||
if first == current_left and last == current_right:
|
||||
first, last = left.begin, left.begin
|
||||
else:
|
||||
first, last = left.end, left.end
|
||||
if first == current_left and last == current_right:
|
||||
first, last = left.begin, left.begin
|
||||
elif select == 'right':
|
||||
if left.end != right.end:
|
||||
if name in tags and left.size() > 1:
|
||||
first, last = right.begin + 1, right.begin + 1
|
||||
if first == current_left and last == current_right:
|
||||
first, last = right.end, right.end
|
||||
else:
|
||||
first, last = right.begin, right.begin
|
||||
if first == current_left and last == current_right:
|
||||
first, last = right.end, right.end
|
||||
else:
|
||||
# There is no second bracket, so just select the first
|
||||
if name in tags and left.size() > 1:
|
||||
first, last = left.begin + 1, left.begin + 1
|
||||
else:
|
||||
first, last = right.end, right.end
|
||||
if first == current_left and last == current_right:
|
||||
first, last = right.end, right.end
|
||||
elif first == current_left and last == current_right:
|
||||
first, last = left.begin, right.end
|
||||
|
||||
self.selection = [sublime.Region(first, last)]
|
||||
|
||||
|
@@ -5,8 +5,9 @@ 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]
|
||||
print (open_bracket)
|
||||
if open_bracket != "do":
|
||||
m = re.match(r"^(\s*\b)[\w\W]*", open_bracket)
|
||||
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, style
|
||||
|
@@ -6,8 +6,14 @@ BracketRemove = ImpMod.import_from("bh_modules.bracketremove", "BracketRemove")
|
||||
class SwapBrackets(BracketRemove):
|
||||
def run(self, edit, name, remove_content=False, remove_indent=False, remove_block=False):
|
||||
offset = self.left.toregion().size()
|
||||
self.selection = [sublime.Region(self.left.begin, self.right.begin - offset)]
|
||||
selection = [sublime.Region(self.left.begin, self.right.begin - offset)]
|
||||
left = self.left.move(self.left.end, self.left.end)
|
||||
right = self.right.move(self.right.begin, self.right.begin)
|
||||
super(SwapBrackets, self).run(edit, name)
|
||||
self.selection = selection
|
||||
self.left = left
|
||||
self.right = right
|
||||
self.nobracket = False
|
||||
|
||||
|
||||
def plugin():
|
||||
|
@@ -115,16 +115,18 @@ class BracketPlugin(object):
|
||||
setattr(plugin, "right", right)
|
||||
setattr(plugin, "view", view)
|
||||
setattr(plugin, "selection", selection)
|
||||
setattr(plugin, "nobracket", False)
|
||||
edit = view.begin_edit()
|
||||
self.args["edit"] = edit
|
||||
self.args["name"] = name
|
||||
try:
|
||||
nobracket = False
|
||||
plugin.run(**self.args)
|
||||
left, right, selection = plugin.left, plugin.right, plugin.selection
|
||||
left, right, selection, nobracket = plugin.left, plugin.right, plugin.selection, plugin.nobracket
|
||||
except Exception:
|
||||
print "BracketHighlighter: Plugin Run Error:\n%s" % str(traceback.format_exc())
|
||||
view.end_edit(edit)
|
||||
return left, right, selection
|
||||
return left, right, selection, nobracket
|
||||
|
||||
|
||||
class BracketPluginCommand(object):
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import sublime
|
||||
import sublime_plugin
|
||||
import bh_wrapping
|
||||
|
||||
@@ -14,6 +15,13 @@ class SwapBrackets(bh_wrapping.WrapBrackets):
|
||||
|
||||
|
||||
class SwapBracketsCommand(sublime_plugin.WindowCommand):
|
||||
def finalize(self, callback):
|
||||
if self.view is not None:
|
||||
if not self.view.settings().get("BracketHighlighterBusy", False):
|
||||
callback()
|
||||
else:
|
||||
sublime.set_timeout(lambda: self.finalize(callback), 100)
|
||||
|
||||
def swap_brackets(self, value):
|
||||
if value < 0:
|
||||
return
|
||||
@@ -29,7 +37,10 @@ class SwapBracketsCommand(sublime_plugin.WindowCommand):
|
||||
}
|
||||
}
|
||||
)
|
||||
self.wrap.wrap(value)
|
||||
|
||||
self.view = self.window.active_view()
|
||||
|
||||
sublime.set_timeout(lambda: self.finalize(lambda: self.wrap.wrap(value)), 100)
|
||||
|
||||
def run(self):
|
||||
view = self.window.active_view()
|
||||
|
Before Width: | Height: | Size: 217 B After Width: | Height: | Size: 420 B |
Before Width: | Height: | Size: 155 B After Width: | Height: | Size: 341 B |
Before Width: | Height: | Size: 143 B After Width: | Height: | Size: 288 B |
Before Width: | Height: | Size: 155 B After Width: | Height: | Size: 342 B |
Before Width: | Height: | Size: 138 B After Width: | Height: | Size: 279 B |
Before Width: | Height: | Size: 191 B After Width: | Height: | Size: 364 B |
Before Width: | Height: | Size: 108 B After Width: | Height: | Size: 371 B |
Before Width: | Height: | Size: 118 B After Width: | Height: | Size: 297 B |
Before Width: | Height: | Size: 220 B After Width: | Height: | Size: 292 B |
Before Width: | Height: | Size: 215 B After Width: | Height: | Size: 246 B |
Before Width: | Height: | Size: 242 B After Width: | Height: | Size: 443 B |
Before Width: | Height: | Size: 173 B After Width: | Height: | Size: 331 B |
Before Width: | Height: | Size: 156 B After Width: | Height: | Size: 299 B |
Before Width: | Height: | Size: 173 B After Width: | Height: | Size: 334 B |
Before Width: | Height: | Size: 145 B After Width: | Height: | Size: 302 B |
Before Width: | Height: | Size: 211 B After Width: | Height: | Size: 359 B |
Before Width: | Height: | Size: 167 B After Width: | Height: | Size: 248 B |
Before Width: | Height: | Size: 148 B After Width: | Height: | Size: 221 B |
Before Width: | Height: | Size: 158 B After Width: | Height: | Size: 383 B |
Before Width: | Height: | Size: 125 B After Width: | Height: | Size: 302 B |
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 288 B |
Before Width: | Height: | Size: 163 B After Width: | Height: | Size: 414 B |
Before Width: | Height: | Size: 133 B After Width: | Height: | Size: 296 B |
Before Width: | Height: | Size: 134 B After Width: | Height: | Size: 305 B |
Before Width: | Height: | Size: 169 B After Width: | Height: | Size: 378 B |
Before Width: | Height: | Size: 133 B After Width: | Height: | Size: 291 B |
Before Width: | Height: | Size: 134 B After Width: | Height: | Size: 279 B |
Before Width: | Height: | Size: 167 B After Width: | Height: | Size: 354 B |
Before Width: | Height: | Size: 176 B After Width: | Height: | Size: 325 B |
Before Width: | Height: | Size: 158 B After Width: | Height: | Size: 298 B |
Before Width: | Height: | Size: 125 B After Width: | Height: | Size: 302 B |
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 307 B |
Before Width: | Height: | Size: 270 B After Width: | Height: | Size: 414 B |
Before Width: | Height: | Size: 188 B After Width: | Height: | Size: 319 B |
Before Width: | Height: | Size: 148 B After Width: | Height: | Size: 325 B |
Before Width: | Height: | Size: 190 B After Width: | Height: | Size: 334 B |
Before Width: | Height: | Size: 147 B After Width: | Height: | Size: 312 B |
Before Width: | Height: | Size: 206 B After Width: | Height: | Size: 394 B |
Before Width: | Height: | Size: 137 B After Width: | Height: | Size: 373 B |
Before Width: | Height: | Size: 111 B After Width: | Height: | Size: 295 B |
Before Width: | Height: | Size: 104 B After Width: | Height: | Size: 248 B |
Before Width: | Height: | Size: 141 B After Width: | Height: | Size: 383 B |
Before Width: | Height: | Size: 114 B After Width: | Height: | Size: 290 B |
Before Width: | Height: | Size: 103 B After Width: | Height: | Size: 229 B |
Before Width: | Height: | Size: 124 B After Width: | Height: | Size: 300 B |
Before Width: | Height: | Size: 114 B After Width: | Height: | Size: 290 B |
Before Width: | Height: | Size: 103 B After Width: | Height: | Size: 234 B |
Before Width: | Height: | Size: 124 B After Width: | Height: | Size: 310 B |
Before Width: | Height: | Size: 101 B After Width: | Height: | Size: 247 B |
Before Width: | Height: | Size: 97 B After Width: | Height: | Size: 205 B |
Before Width: | Height: | Size: 111 B After Width: | Height: | Size: 196 B |
Before Width: | Height: | Size: 98 B After Width: | Height: | Size: 206 B |
Before Width: | Height: | Size: 112 B After Width: | Height: | Size: 196 B |
Before Width: | Height: | Size: 127 B After Width: | Height: | Size: 236 B |
Before Width: | Height: | Size: 244 B After Width: | Height: | Size: 344 B |
Before Width: | Height: | Size: 166 B After Width: | Height: | Size: 284 B |
Before Width: | Height: | Size: 306 B After Width: | Height: | Size: 477 B |
Before Width: | Height: | Size: 215 B After Width: | Height: | Size: 370 B |
@@ -1 +1 @@
|
||||
{"url": "https://github.com/facelessuser/BracketHighlighter", "version": "2013.03.27.09.00.08", "description": "Bracket and tag highlighter for Sublime Text 2"}
|
||||
{"url": "https://github.com/facelessuser/BracketHighlighter", "version": "2013.09.15.18.40.20", "description": "Bracket and tag highlighter for Sublime Text 2"}
|
@@ -1,3 +1,22 @@
|
||||
# Table of Contents
|
||||
- [About](#about)
|
||||
- [Sublime Text 3 Support?](#sublime-text-3-support)
|
||||
- [Overview](#overview)
|
||||
- [Feature List](#feature-list)
|
||||
- [General Use](#general-use)
|
||||
- [Built-in Supported brackets](#built-in-supported-brackets)
|
||||
- [Additional Features](#additional-features)
|
||||
- [Bracket Plugin](#bracket-plugin)
|
||||
- [Shortcuts](#shortcuts)
|
||||
- [Customizing BracketHighligher](#costumizing-brackethighlighter)
|
||||
- [Configuring Brackets](#cnfiguring-brackets)
|
||||
- [Configuring Highlight Style](#configuring-highlight-style)
|
||||
- [Bracket Plugin API](#bracket-plugin-api)
|
||||
- ['Defintion' Plugins](#definition-plugins)
|
||||
- [Run Instance Plugins](#run-instance-plugins)
|
||||
- [Credits](#credits)
|
||||
- [Changelog](#changelog)
|
||||
|
||||
# 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, I have rewritten the entire code base to bring more flexibility, speed, and features.
|
||||
|
||||
@@ -9,7 +28,7 @@ ST3 support is found here (at the present time): https://github.com/facelessuse
|
||||
## Overview
|
||||
Bracket Highlighter matches a variety of brackets such as: ```[]```, ```()```, ```{}```, ```""```, ```''```, ```<tag></tag>```, and even custom brackets.
|
||||
|
||||
# FeatureList
|
||||
# Feature List
|
||||
- Customizable to highlight almost any bracket
|
||||
- Customizable bracket highlight style
|
||||
- High visibility bracket highlight mode
|
||||
@@ -23,7 +42,7 @@ Bracket Highlighter matches a variety of brackets such as: ```[]```, ```()```, `
|
||||
- Bracket plugins that can jump between bracket ends, select content, remove brackets and/or content, wrap selectios with brackets, swap brackets, swap quotes (handling quote escaping between the main quotes), fold/unfold conent between brackets, toggle through tag attribute selecection, select both the opening and closing tag name to change both simultaneously.
|
||||
|
||||
# General Use
|
||||
In general BracketHighligher (BH) will automatically highlight brackets (or defined bracket like start and end blocks) its between. By default, BH will but opening and closing icons in the gutter of the corresponding line containing open or closising bracket. BH, by default, will underline the closing and opening bracket as well.
|
||||
In general, BracketHighligher (BH) will highlight brackets (or defined bracket like start and end blocks) surrounding the cursor. By default, BH will put opening and closing icons in the gutter of the corresponding line containing open or closising bracket. BH, by default, will underline the closing and opening bracket as well.
|
||||
|
||||
## Built-in Supported brackets
|
||||
Currently BH supports the following brackets out of the box:
|
||||
@@ -70,7 +89,7 @@ These are the basic settings you can change:
|
||||
// this defines if the unmatched bracket should be shown.
|
||||
"show_unmatched" : true,
|
||||
|
||||
// High visibilty style and color for high visibility mode
|
||||
// High visibility style and color for high visibility mode
|
||||
// (solid|outline|underline)
|
||||
"high_visibility_style": "outline",
|
||||
// (scope|__default__|__bracket__)
|
||||
@@ -93,7 +112,7 @@ These are the basic settings you can change:
|
||||
```
|
||||
|
||||
### Bracket Plugins
|
||||
Bh is also extendable via plugins and provides an number of plugins by default. See ```Bracket Plugins``` to learn more about the included plugins.
|
||||
Bh is also extendable via plugins and provides an number of plugins by default. See [Bracket Plugins](#bracket-plugins) to learn more about the included plugins.
|
||||
|
||||
## Bracket Plugin
|
||||
BH provides a number of built in Bracket Plugins that take advantage of BH's matching to provide additional features. Most plugin features are available via the Tools->Packages->BracketHighlighter menu or the command palette. To see how to configure shortcuts, see the ```Example.sublime-settings``` file.
|
||||
@@ -108,10 +127,10 @@ Removes the surrounding brackets.
|
||||
Folds the content of the current surrounding brackets.
|
||||
|
||||
### Swap Quotes Plugin
|
||||
Swap the quotes style of surrounding quotes from double to single or vice versa. It also handlings escaping and unescaping of sub quotes.
|
||||
Swap the quotes style of surrounding quotes from double to single or vice versa. It also handles escaping and unescaping of sub quotes.
|
||||
|
||||
### Tag Plugin
|
||||
Plugin used to help highlight tags
|
||||
Plugin used to help highlight tags.
|
||||
|
||||
Additional tag settings found in ```bh_core.sublime-settings```:
|
||||
```javascript
|
||||
@@ -150,7 +169,7 @@ By default BH provides no shortcuts to avoid shortcut conflicts, but you can vie
|
||||
BH is extremely flexible and be customized and extended to fit a User's needs. The first step is to copy the ```bh_core.sublime-settings``` to your ```User``` folder.
|
||||
|
||||
## Configuring Brackets
|
||||
BH has been written to allow users to define any brackets they would like to have highlighted. There are two kinds of brackets you can define ```scope_brackets``` (search file for scope regions and then use regex to test for opening and closing brackets) and ```brackets``` (use regex to find opening and closing brackets). ```bracket``` type should usually be the preferred type. ```scope_brackets``` are usually used for brackets whose opening and closing are the same and not distinguishable form one another by regex; scope brackets must be contained in a continuous scope region like string for quotes etc.
|
||||
BH has been written to allow users to define any brackets they would like to have highlighted. There are two kinds of brackets you can define: ```scope_brackets``` (search file for scope regions and then use regex to test for opening and closing brackets) and ```brackets``` (use regex to find opening and closing brackets). ```bracket``` should usually be the preferred type. ```scope_brackets``` are usually used for brackets whose opening and closing are the same and not distinguishable form one another by regex; scope brackets must be contained in a continuous scope region like string for quotes etc.
|
||||
|
||||
### Configuring Brackets
|
||||
Brackets are defined under ```brackets``` in ```bh_core.sublime-settings```.
|
||||
@@ -228,7 +247,7 @@ Python Single Quote bracket will be used as an eample (not all options are shown
|
||||
- **plugin_library (optional)**: defines plugin to use for determining matches (see Bracket Plugin API for more info on matching plugins)
|
||||
|
||||
## Configuring Highlight Style
|
||||
Each bracket definition (described in ```Configuring Scope Brackets``` and ```Configuring Brackets```) has a ```style``` setting that you give a style definition to. Style definitions are defined under ```bracket_styles``` in ```bh_core.sublime-settings```.
|
||||
Each bracket definition (described in [Configuring Scope Brackets](#configuring-scope-brackets) and [Configuring Brackets](#configuring-brackets)) has a ```style``` setting that you give a style definition to. Style definitions are defined under ```bracket_styles``` in ```bh_core.sublime-settings```.
|
||||
|
||||
There are two special style definitions whose names are reserved: ```default``` and ```unmatched```, but you can configure them. All other custom style definitions follow the same pattern (see ```curly``` below and compare to the special style defintions; format is the same) All custom styles follow this pattern. See description below:
|
||||
|
||||
@@ -260,7 +279,8 @@ There are two special style definitions whose names are reserved: ```default```
|
||||
},
|
||||
```
|
||||
|
||||
- **icon**: icon to show in gutter. Available options are (angle|round|curly|square|tag|star|dot|bookmark|question|quote|double_quote|single_quote|single_quote_offset|double_quote_offset|none)
|
||||
- **icon**: icon to show in gutter. Available options are (angle|round|curly|square|tag|star|dot|bookmark|question|quote|double_quote|single_quote|single_quote_offset|
|
||||
double_quote_offset|none)
|
||||
- **color**: scope to define color
|
||||
- **style**: higlight style. Available options are (solid|outline|underline|none)
|
||||
|
||||
@@ -316,7 +336,7 @@ Methods of BracketRegion:
|
||||
These are plugins that are attached to the bracket definition and aid in processing the brackets. These kids of plugins have two methods you can provide ```post_match``` and/or ```compare```.
|
||||
|
||||
### compare
|
||||
```compare``` is run when comparing the opening bracket with closing brackets. This allows you to provide logic to accept or regect a the pairing of an opening bracket with a closing bracket. You should not change the text in the view during this operation.
|
||||
```compare``` is run when comparing the opening bracket with closing brackets. This allows you to provide logic to accept or reject the pairing of an opening bracket with a closing bracket. You should not change the text in the view during this operation.
|
||||
|
||||
The ```compare``` method receives the following paramters:
|
||||
|
||||
@@ -463,8 +483,10 @@ def plugin():
|
||||
- pyparadigm: for his original efforts with SublimeBrackets and SublimeTagmatcher which originally BracketHighlighter was built off of and the inspiration behind the current implementation.
|
||||
- BoundInCode: for his Tag icon
|
||||
|
||||
# Version 2.0.0
|
||||
# Changelog
|
||||
|
||||
#### Version 2.0.0
|
||||
- Re-write of BracketHighlighter
|
||||
|
||||
# Version Older
|
||||
#### Older Versions
|
||||
- See [Complete Changelog](https://github.com/facelessuser/BracketHighlighter/blob/BH2/CHANGELOG.md)
|
||||
|
@@ -0,0 +1,207 @@
|
||||
"""
|
||||
ure - unicode re
|
||||
|
||||
A simple script that wraps the re interface with methods to handle unicode properties.
|
||||
Patterns will all have re.UNICODE enabled and unicode property formats will be replaced
|
||||
with the unicode characters in that category.
|
||||
|
||||
Example:
|
||||
r"\p{Ll}\p{Lu}"
|
||||
|
||||
Licensed under MIT
|
||||
Copyright (c) 2013 Isaac Muse <isaacmuse@gmail.com>
|
||||
"""
|
||||
import re
|
||||
import sys
|
||||
from os.path import dirname
|
||||
try:
|
||||
import unicodedata
|
||||
except:
|
||||
sys.path.append(dirname(sys.executable))
|
||||
import unicodedata
|
||||
|
||||
PY3 = sys.version_info[0] >= 3
|
||||
uchr = chr if PY3 else unichr
|
||||
|
||||
DEBUG = re.DEBUG
|
||||
I = re.I
|
||||
IGNORECASE = re.IGNORECASE
|
||||
L = re.L
|
||||
LOCALE = re.LOCALE
|
||||
M = re.M
|
||||
MULTILINE = re.MULTILINE
|
||||
S = re.S
|
||||
DOTALL = re.DOTALL
|
||||
U = re.U
|
||||
UNICODE = re.UNICODE
|
||||
X = re.X
|
||||
VERBOSE = re.VERBOSE
|
||||
escape = re.escape
|
||||
purge = re.purge
|
||||
|
||||
_unicode_properties = None
|
||||
_unicode_key_pattern = None
|
||||
|
||||
|
||||
def _build_unicode_property_table(unicode_range):
|
||||
"""
|
||||
Build property table for unicode range.
|
||||
"""
|
||||
table = {}
|
||||
p = None
|
||||
for i in range(*unicode_range):
|
||||
try:
|
||||
c = uchr(i)
|
||||
p = unicodedata.category(c)
|
||||
except:
|
||||
continue
|
||||
if p[0] not in table:
|
||||
table[p[0]] = {}
|
||||
if p[1] not in table[p[0]]:
|
||||
table[p[0]][p[1]] = []
|
||||
table[p[0]][p[1]].append(c)
|
||||
|
||||
# Join as one string
|
||||
for k1, v1 in table.items():
|
||||
for k2, v2 in v1.items():
|
||||
v1[k2] = ''.join(v2)
|
||||
|
||||
return table
|
||||
|
||||
|
||||
def _build_unicode_key_pattern():
|
||||
"""
|
||||
Build regex key pattern
|
||||
"""
|
||||
unicode_prop = r"\p\{(%s)\}"
|
||||
unicode_keys = []
|
||||
for k1, v1 in _unicode_properties.items():
|
||||
unicode_keys.append("%s(?:%s)" % (k1, "|".join(v1.keys())))
|
||||
return re.compile(unicode_prop % "|".join(unicode_keys), re.UNICODE)
|
||||
|
||||
|
||||
def _init_unicode():
|
||||
"""
|
||||
Prepare unicode property tables and key pattern
|
||||
"""
|
||||
global _unicode_properties
|
||||
global _unicode_key_pattern
|
||||
_unicode_properties = _build_unicode_property_table((0x0000, 0x10FFFF))
|
||||
_unicode_key_pattern = _build_unicode_key_pattern()
|
||||
|
||||
|
||||
def find_char_groups(s):
|
||||
"""
|
||||
Find character groups
|
||||
"""
|
||||
pos = 0
|
||||
groups = []
|
||||
escaped = False
|
||||
found = False
|
||||
first = None
|
||||
for c in s:
|
||||
if c == "\\":
|
||||
escaped = not escaped
|
||||
elif escaped:
|
||||
escaped = False
|
||||
elif c == "[" and not found:
|
||||
found = True
|
||||
first = pos
|
||||
elif c == "]" and found:
|
||||
groups.append((first, pos))
|
||||
pos += 1
|
||||
return groups
|
||||
|
||||
|
||||
def get_unicode_category(prop):
|
||||
"""
|
||||
Retrieve the unicode category from the table
|
||||
"""
|
||||
p1, p2 = (prop[0], prop[1]) if len(prop) > 1 else (prop[0], None)
|
||||
return ''.join([x for x in _unicode_properties[p1].values()]) if p2 is None else _unicode_properties[p1][p2]
|
||||
|
||||
|
||||
def parse_unicode_properties(re_pattern):
|
||||
"""
|
||||
Replaces regex property notation with unicode values
|
||||
"""
|
||||
char_groups = find_char_groups(re_pattern)
|
||||
ure_pattern = re_pattern
|
||||
for p in reversed(list(_unicode_key_pattern.finditer(re_pattern))):
|
||||
v = get_unicode_category(p.group(1))
|
||||
brackets = True
|
||||
if v is None:
|
||||
continue
|
||||
for g in char_groups:
|
||||
if p.start(0) >= g[0] and p.end(0) <= g[1]:
|
||||
brackets = False
|
||||
break
|
||||
if brackets:
|
||||
v = "[" + v + "]"
|
||||
ure_pattern = ure_pattern[:p.start(0) - 1] + v + ure_pattern[p.end(0): len(ure_pattern)]
|
||||
return ure_pattern
|
||||
|
||||
|
||||
def compile(pattern, flags=0):
|
||||
"""
|
||||
compile after parsing unicode properties and set flag to unicode
|
||||
"""
|
||||
return re.compile(parse_unicode_properties(pattern), flags | re.UNICODE)
|
||||
|
||||
|
||||
def search(pattern, string, flags=0):
|
||||
"""
|
||||
search after parsing unicode properties and set flag to unicode
|
||||
"""
|
||||
re.search(parse_unicode_properties(pattern), string, flags | re.UNICODE)
|
||||
|
||||
|
||||
def match(pattern, string, flags=0):
|
||||
"""
|
||||
match after parsing unicode properties and set flag to unicode
|
||||
"""
|
||||
re.match(parse_unicode_properties(pattern), string, flags | re.UNICODE)
|
||||
|
||||
|
||||
def split(pattern, string, maxsplit=0, flags=0):
|
||||
"""
|
||||
split after parsing unicode properties and set flag to unicode
|
||||
"""
|
||||
re.split(parse_unicode_properties(pattern), string, maxsplit, flags | re.UNICODE)
|
||||
|
||||
|
||||
def findall(pattern, string, flags=0):
|
||||
"""
|
||||
findall after parsing unicode properties and set flag to unicode
|
||||
"""
|
||||
re.findall(parse_unicode_properties(pattern), string, flags | re.UNICODE)
|
||||
|
||||
|
||||
def finditer(pattern, string, flags=0):
|
||||
"""
|
||||
finditer after parsing unicode properties and set flag to unicode
|
||||
"""
|
||||
re.finditer(parse_unicode_properties(pattern), string, flags | re.UNICODE)
|
||||
|
||||
|
||||
def sub(pattern, repl, string, count=0, flags=0):
|
||||
"""
|
||||
sub after parsing unicode properties and set flag to unicode
|
||||
"""
|
||||
re.sub(parse_unicode_properties(pattern), repl, string, count, flags | re.UNICODE)
|
||||
|
||||
|
||||
def subn(pattern, repl, string, count=0, flags=0):
|
||||
"""
|
||||
subn after parsing unicode properties and set flag to unicode
|
||||
"""
|
||||
re.subn(parse_unicode_properties(pattern), repl, string, flags | re.UNICODE)
|
||||
|
||||
|
||||
_init_unicode()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Testing ure's unicode properties replacement")
|
||||
print(parse_unicode_properties(r"[\p{Ll}\p{Lu}]"))
|
||||
print(parse_unicode_properties(r"\p{Ll}\p{Lu}"))
|
@@ -0,0 +1,26 @@
|
||||
Copyright (c) 2012, Colin T.A. Gray
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation are those
|
||||
of the authors and should not be interpreted as representing official policies,
|
||||
either expressed or implied, of this project.
|
@@ -7,6 +7,8 @@ Some bracket manipulation, selection, and insertion commands.
|
||||
Installation
|
||||
------------
|
||||
|
||||
### Sublime Text 2
|
||||
|
||||
1. Using Package Control, install "Bracketeer"
|
||||
|
||||
Or:
|
||||
@@ -20,6 +22,13 @@ Or:
|
||||
2. clone this repo
|
||||
3. Install keymaps for the commands (see Example.sublime-keymap for my preferred keys)
|
||||
|
||||
### Sublime Text 3
|
||||
|
||||
1. Open the Sublime Text 2 Packages folder
|
||||
2. clone this repo, but use the `st3` branch
|
||||
|
||||
git clone -b st3 git@github.com:colinta/SublimeBracketeer
|
||||
|
||||
Commands
|
||||
--------
|
||||
|
||||
|
@@ -1 +1 @@
|
||||
{"url": "https://github.com/colinta/SublimeBracketeer", "version": "1.5.2", "description": "Some bracket manipulation, selection, and insertion commands."}
|
||||
{"url": "https://github.com/colinta/SublimeBracketeer", "version": "2013.07.09.15.11.00", "description": "Some bracket manipulation, selection, and insertion commands."}
|
@@ -0,0 +1,26 @@
|
||||
Copyright (c) 2012, Colin T.A. Gray
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation are those
|
||||
of the authors and should not be interpreted as representing official policies,
|
||||
either expressed or implied, of this project.
|
@@ -15,6 +15,8 @@ the full command-list below.
|
||||
Installation
|
||||
------------
|
||||
|
||||
### Sublime Text 2
|
||||
|
||||
1. Using Package Control, install "Clipboard Manager"
|
||||
|
||||
Or:
|
||||
@@ -28,6 +30,13 @@ Or:
|
||||
2. clone this repo
|
||||
3. Install keymaps for the commands (see Example.sublime-keymap for my preferred keys)
|
||||
|
||||
### Sublime Text 3
|
||||
|
||||
1. Open the Sublime Text 2 Packages folder
|
||||
2. clone this repo, but use the `st3` branch
|
||||
|
||||
git clone -b st3 git@github.com:colinta/SublimeClipboardManager
|
||||
|
||||
Commands
|
||||
--------
|
||||
|
||||
|
@@ -1 +1 @@
|
||||
{"url": "https://gist.github.com/1590661", "version": "1.2.3", "description": "A version of the Sublime Text 2 plugin at <http://www.sublimetext.com/forum/viewtopic.php?f=5&t=2260&start=0> that makes for TextMate-like clipboard history."}
|
||||
{"url": "https://gist.github.com/1590661", "version": "2013.07.09.15.13.48", "description": "A version of the Sublime Text 2 plugin at <http://www.sublimetext.com/forum/viewtopic.php?f=5&t=2260&start=0> that makes for TextMate-like clipboard history."}
|
@@ -6,6 +6,8 @@ It's heavily inspired by [Vim's EasyMotion](http://www.vim.org/scripts/script.ph
|
||||
|
||||
After pressing the EasyMotion shortcut (default `cmd-;`/`ctrl-;`), you then press the character that you'd like to jump to. EasyMotion will then replace all currently visible instances of that character with one of `a-zA-Z0-9`. Press the key for the one you want and your cursor will be moved right to it.
|
||||
|
||||
Here I'm pressing `cmd-;` followed by `f`. EasyMotion highlights the 6 visible "f" characters with `a-f`. I then press `d` to jump to the beginning of the `function`.
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -22,7 +24,7 @@ Then type `EasyMotion` and choose the EasyMotion plugin from the dropdown. Hit
|
||||
|
||||
Manual installation should be as easy as cloning this git repository into your Sublime `Packages` directory. On OSX:
|
||||
|
||||
cd ~/Application\ Support/Sublime\ Text\ 2/Packages
|
||||
cd ~/Library/Application\ Support/Sublime\ Text\ 2/Packages
|
||||
git clone git://github.com/tednaleid/sublime-EasyMotion.git EasyMotion
|
||||
|
||||
(The directory name underneath packages __must__ be `EasyMotion` and not `sublime-EasyMotion` for some preferences to get picked up)
|
||||
@@ -34,6 +36,16 @@ If you're interested in trying the next release of the plugin, you can switch yo
|
||||
|
||||
This branch will have features that are marked as fixed in the issue, but haven't yet been merged to `master`.
|
||||
|
||||
### Sublime Text 3 Experimental Support
|
||||
|
||||
There is experimental support for Sublime Text 3 on the `st3` branch that requires manual installation and the use of the `st3` branch.
|
||||
|
||||
cd ~/Library/Application\ Support/Sublime\ Text\ 3/Packages
|
||||
git clone git://github.com/tednaleid/sublime-EasyMotion.git EasyMotion
|
||||
cd EasyMotion
|
||||
git checkout st3
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
### Jump to any visible character
|
||||
|
@@ -1 +1 @@
|
||||
{"url": "https://github.com/tednaleid/sublime-EasyMotion", "version": "2013.03.26.20.46.50", "description": "Sublime Text 2 plugin to quickly jump to any character in the visible area of the active view."}
|
||||
{"url": "https://github.com/tednaleid/sublime-EasyMotion", "version": "2013.08.10.19.55.17", "description": "Sublime Text 2 plugin to quickly jump to any character in the visible area of the active view."}
|
@@ -44,7 +44,7 @@
|
||||
<key>bracketContentsForeground</key>
|
||||
<string>#000000</string>
|
||||
<key>bracketContentsOptions</key>
|
||||
<string>underline</string> -->
|
||||
<string>underline</string>
|
||||
|
||||
<key>tagsOptions</key>
|
||||
<string>stippled_underline</string>
|
||||
|
@@ -60,13 +60,13 @@ ANNOTATE_CLOSE = '''</span>'''
|
||||
|
||||
BODY_START = '''<body class="code_page code_text"><pre class="code_page">'''
|
||||
|
||||
FILE_INFO = '''<tr><td colspan="2"><div id="file_info"><span style="color: %(color)s">%(date_time)s %(file)s\n\n</span></div></td></tr>'''
|
||||
FILE_INFO = '''<tr><td colspan="2" style="background: %(bgcolor)s"><div id="file_info"><span style="color: %(color)s">%(date_time)s %(file)s\n\n</span></div></td></tr>'''
|
||||
|
||||
TABLE_START = '''<table cellspacing="0" cellpadding="0" class="code_page">'''
|
||||
|
||||
LINE = (
|
||||
'<tr>' +
|
||||
'<td valign="top" id="L_%(table)d_%(line_id)d" class="code_text code_gutter">' +
|
||||
'<td valign="top" id="L_%(table)d_%(line_id)d" class="code_text code_gutter" style="background: %(bgcolor)s">' +
|
||||
'<span style="color: %(color)s;">%(line)s </span>' +
|
||||
'</td>' +
|
||||
'<td valign="top" class="code_text code_line" style="background-color: %(pad_color)s;">' +
|
||||
@@ -500,6 +500,7 @@ class ExportHtml(object):
|
||||
html_line = LINE % {
|
||||
"line_id": num,
|
||||
"color": self.gfground,
|
||||
"bgcolor": self.gbground,
|
||||
"line": str(num).rjust(self.gutter_pad).replace(" ", ' '),
|
||||
"code_id": num,
|
||||
"code": line,
|
||||
@@ -578,12 +579,17 @@ class ExportHtml(object):
|
||||
'&': '&',
|
||||
'>': '>',
|
||||
'<': '<',
|
||||
'\t': ' ' * self.tab_size,
|
||||
' ': ' ',
|
||||
'\t': ' ' * self.tab_size,
|
||||
'\n': ''
|
||||
}
|
||||
|
||||
return ''.join(encode_table.get(c, c) for c in text).encode('ascii', 'xmlcharrefreplace')
|
||||
return re.sub(
|
||||
r'(?!\s($|\S))\s',
|
||||
' ',
|
||||
''.join(
|
||||
encode_table.get(c, c) for c in text
|
||||
).encode('ascii', 'xmlcharrefreplace')
|
||||
)
|
||||
|
||||
def get_annotations(self):
|
||||
annotations = get_annotations(self.view)
|
||||
@@ -789,6 +795,7 @@ class ExportHtml(object):
|
||||
date_time = time.strftime(self.date_time_format, self.time)
|
||||
the_html.write(
|
||||
FILE_INFO % {
|
||||
"bgcolor": self.bground,
|
||||
"color": self.fground,
|
||||
"date_time": date_time,
|
||||
"file": self.file_name if self.show_full_path else path.basename(self.file_name)
|
||||
|
@@ -1 +1 @@
|
||||
{"url": "https://github.com/facelessuser/ExportHtml", "version": "2013.03.29.23.39.49", "description": "Sublime Text - Export code to HTML for copying/printing/saving. Also, export code to BBCode for forum posts."}
|
||||
{"url": "https://github.com/facelessuser/ExportHtml", "version": "2013.05.24.14.57.59", "description": "Sublime Text - Export code to HTML for copying/printing/saving. Also, export code to BBCode for forum posts."}
|
@@ -0,0 +1,26 @@
|
||||
Copyright (c) 2012, Colin T.A. Gray
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation are those
|
||||
of the authors and should not be interpreted as representing official policies,
|
||||
either expressed or implied, of this project.
|
@@ -7,6 +7,8 @@ Shows diffs - also in an external diff tool - between the current file, or selec
|
||||
Installation
|
||||
------------
|
||||
|
||||
### Sublime Text 2
|
||||
|
||||
1. Using Package Control, install "FileDiffs"
|
||||
|
||||
Or:
|
||||
@@ -20,6 +22,13 @@ Or:
|
||||
2. clone this repo
|
||||
3. Install keymaps for the commands (see Example.sublime-keymap for my preferred keys)
|
||||
|
||||
### Sublime Text 3
|
||||
|
||||
1. Open the Sublime Text 2 Packages folder
|
||||
2. clone this repo, but use the `st3` branch
|
||||
|
||||
git clone -b st3 git@github.com:colinta/SublimeFileDiffs
|
||||
|
||||
Add External Diff Tool
|
||||
--------
|
||||
|
||||
|
@@ -101,6 +101,8 @@ class FileDiffCommand(sublime_plugin.TextCommand):
|
||||
self.diff_with_external(a, b, from_file, to_file)
|
||||
|
||||
if open_in_sublime:
|
||||
# fix diffs
|
||||
diffs = map(lambda line: (line and line[-1] == "\n") and line or line + "\n", diffs)
|
||||
self.diff_in_sublime(diffs)
|
||||
|
||||
def diff_with_external(self, a, b, from_file=None, to_file=None):
|
||||
|
@@ -1 +1 @@
|
||||
{"url": "https://github.com/spape/SublimeFileDiffs", "version": "1.5.0", "description": "Shows diffs - also in an external diff tool - between the current file, or selection(s) in the current file, and clipboard, another file, or unsaved changes."}
|
||||
{"url": "https://github.com/colinta/SublimeFileDiffs", "version": "2013.07.09.15.11.56", "description": "Shows diffs between the current file, or selection(s) in the current file, and clipboard, another file, or unsaved changes."}
|
@@ -82,11 +82,6 @@ class CompassThread(threading.Thread):
|
||||
global LivereloadFactory
|
||||
print 'compass compile ' + self.dirname
|
||||
|
||||
# autocreate config.rb for compass
|
||||
if not os.path.exists(os.path.join(self.dirname, "config.rb")):
|
||||
print "Generating config.rb"
|
||||
shutil.copy(os.path.join(sublime.packages_path(), "LiveReload","assets","config.rb"), self.dirname)
|
||||
|
||||
# compass compile
|
||||
p = subprocess.Popen(['compass compile ' + self.dirname.replace('\\','/')],shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT )
|
||||
if p.stdout.read() :
|
||||
@@ -433,4 +428,4 @@ class WSRequestHandler(SimpleHTTPRequestHandler):
|
||||
|
||||
def log_message(self, f, *args):
|
||||
# Save instead of printing
|
||||
self.last_message = f % args
|
||||
self.last_message = f % args
|
||||
|
@@ -1 +1 @@
|
||||
{"url": "https://github.com/dz0ny/LiveReload-sublimetext2", "version": "2013.03.07.03.08.21", "description": "LiveReload plugin for SublimeText"}
|
||||
{"url": "https://github.com/dz0ny/LiveReload-sublimetext2", "version": "2013.07.23.07.25.42", "description": "LiveReload plugin for SublimeText"}
|
@@ -0,0 +1,26 @@
|
||||
Changes in Markdown Preview
|
||||
===========================
|
||||
|
||||
## 1.0.3
|
||||
|
||||
* The `messages.json` should OK for this time.
|
||||
|
||||
## 1.0.2
|
||||
|
||||
* Fixes messages.json and changelog versions.
|
||||
|
||||
## 1.0.1
|
||||
|
||||
* Removed markdown2 parser for its not well maintained and buggy.
|
||||
* Make Python Markdown parser as default.
|
||||
* Split the preview commands for *Python Markdown* parser and *Github Flavored Markdown* parser.
|
||||
* Add markdown file build support, build parser are config via the origin `"parser"` settings.
|
||||
* Add this changlog file for both developpers and users.
|
||||
* Add messages.json which make display of `README.md` and `CHANGES.md`
|
||||
* Try use `Markdown Extended.tmLanguage` for cheat sheet if you installed `Markdown Extended`.
|
||||
|
||||
## 1.0.0
|
||||
|
||||
* Support for ST3.
|
||||
* Added Python Markdown parser.
|
||||
* CSS search first in markdown file directory and the the build-in.
|
@@ -1,28 +1,61 @@
|
||||
[
|
||||
{
|
||||
"caption": "Markdown Preview: preview in Browser",
|
||||
"caption": "Markdown Preview: Python Markdown: Preview in Browser",
|
||||
"command": "markdown_preview",
|
||||
"args": {
|
||||
"target": "browser"
|
||||
"target": "browser",
|
||||
"parser": "markdown"
|
||||
}
|
||||
},
|
||||
{
|
||||
"caption": "Markdown Preview: export HTML in Sublime Text",
|
||||
"caption": "Markdown Preview: Python Markdown: Export HTML in Sublime Text",
|
||||
"command": "markdown_preview",
|
||||
"args": {
|
||||
"target": "sublime"
|
||||
"target": "sublime",
|
||||
"parser": "markdown"
|
||||
}
|
||||
},
|
||||
{
|
||||
"caption": "Markdown Preview: copy to clipboard",
|
||||
"caption": "Markdown Preview: Python Markdown: Copy to Clipboard",
|
||||
"command": "markdown_preview",
|
||||
"args": {
|
||||
"target": "clipboard"
|
||||
"target": "clipboard",
|
||||
"parser": "markdown"
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
"caption": "Markdown Preview: Github Flavored Markdown: Preview in Browser",
|
||||
"command": "markdown_preview",
|
||||
"args": {
|
||||
"target": "browser",
|
||||
"parser": "github"
|
||||
}
|
||||
},
|
||||
{
|
||||
"caption": "Markdown Preview: open Markdown Cheat sheet",
|
||||
"caption": "Markdown Preview: Github Flavored Markdown: Export HTML in Sublime Text",
|
||||
"command": "markdown_preview",
|
||||
"args": {
|
||||
"target": "sublime",
|
||||
"parser": "github"
|
||||
}
|
||||
},
|
||||
{
|
||||
"caption": "Markdown Preview: Github Flavored Markdown: Copy to Clipboard",
|
||||
"command": "markdown_preview",
|
||||
"args": {
|
||||
"target": "clipboard",
|
||||
"parser": "github"
|
||||
}
|
||||
},
|
||||
{
|
||||
"caption": "Markdown Preview: Open Markdown Cheat sheet",
|
||||
"command": "markdown_cheatsheet",
|
||||
"args": {}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
]
|
||||
|
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"target": "markdown_build",
|
||||
"selector": "text.html.markdown",
|
||||
|
||||
"variants": [
|
||||
|
||||
{
|
||||
"target": "markdown_build_github",
|
||||
"name": "Build with Github API"
|
||||
}
|
||||
]
|
||||
}
|
@@ -1,31 +1,130 @@
|
||||
# -*- encoding: UTF-8 -*-
|
||||
import sublime
|
||||
import sublime_plugin
|
||||
import desktop
|
||||
import tempfile
|
||||
import markdown2
|
||||
|
||||
import os
|
||||
import sys
|
||||
import traceback
|
||||
import tempfile
|
||||
import re
|
||||
import json
|
||||
import urllib2
|
||||
import time
|
||||
import traceback
|
||||
|
||||
|
||||
settings = sublime.load_settings('MarkdownPreview.sublime-settings')
|
||||
if sublime.version() >= '3000':
|
||||
from . import desktop
|
||||
from . import markdown2
|
||||
from . import markdown
|
||||
from .helper import INSTALLED_DIRECTORY
|
||||
from urllib.request import urlopen
|
||||
from urllib.error import HTTPError, URLError
|
||||
|
||||
def Request(url, data, headers):
|
||||
''' Adapter for urllib2 used in ST2 '''
|
||||
import urllib.request
|
||||
return urllib.request.Request(url, data=data, headers=headers, method='POST')
|
||||
|
||||
else: # ST2
|
||||
import desktop
|
||||
import markdown2
|
||||
import markdown
|
||||
from helper import INSTALLED_DIRECTORY
|
||||
from urllib2 import Request, urlopen, HTTPError, URLError
|
||||
|
||||
_CANNOT_CONVERT = u'cannot convert markdown'
|
||||
|
||||
def getTempMarkdownPreviewPath(view):
|
||||
''' return a permanent full path of the temp markdown preview file '''
|
||||
|
||||
settings = sublime.load_settings('MarkdownPreview.sublime-settings')
|
||||
|
||||
tmp_filename = '%s.html' % view.id()
|
||||
tmp_fullpath = os.path.join(tempfile.gettempdir(), tmp_filename)
|
||||
if settings.get('path_tempfile'):
|
||||
tmp_fullpath = os.path.join(settings.get('path_tempfile'), tmp_filename)
|
||||
else:
|
||||
tmp_fullpath = os.path.join(tempfile.gettempdir(), tmp_filename)
|
||||
return tmp_fullpath
|
||||
|
||||
def save_utf8(filename, text):
|
||||
v = sublime.version()
|
||||
if v >= '3000':
|
||||
f = open(filename, 'w', encoding='utf-8')
|
||||
f.write(text)
|
||||
f.close()
|
||||
else: # 2.x
|
||||
f = open(filename, 'w')
|
||||
f.write(text.encode('utf-8'))
|
||||
f.close()
|
||||
|
||||
def load_utf8(filename):
|
||||
v = sublime.version()
|
||||
if v >= '3000':
|
||||
return open(filename, 'r', encoding='utf-8').read()
|
||||
else: # 2.x
|
||||
return open(filename, 'r').read().decode('utf-8')
|
||||
|
||||
def load_resource(name):
|
||||
''' return file contents for files within the package root folder '''
|
||||
v = sublime.version()
|
||||
if v >= '3000':
|
||||
filename = '/'.join(['Packages', INSTALLED_DIRECTORY, name])
|
||||
try:
|
||||
return sublime.load_resource(filename)
|
||||
except:
|
||||
print("Error while load_resource('%s')" % filename)
|
||||
traceback.print_exc()
|
||||
return ''
|
||||
|
||||
else: # 2.x
|
||||
filename = os.path.join(sublime.packages_path(), INSTALLED_DIRECTORY, name)
|
||||
|
||||
if not os.path.isfile(filename):
|
||||
print('Error while lookup resources file: %s', name)
|
||||
return ''
|
||||
|
||||
try:
|
||||
return open(filename, 'r').read().decode('utf-8')
|
||||
except:
|
||||
print("Error while load_resource('%s')" % filename)
|
||||
traceback.print_exc()
|
||||
return ''
|
||||
|
||||
def exists_resource(resource_file_path):
|
||||
if sublime.version() >= '3000':
|
||||
try:
|
||||
sublime.load_resource(resource_file_path)
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
else:
|
||||
filename = os.path.join(os.path.dirname(sublime.packages_path()), resource_file_path)
|
||||
return os.path.isfile(filename)
|
||||
|
||||
def new_scratch_view(window, text):
|
||||
''' create a new scratch view and paste text content
|
||||
return the new view
|
||||
'''
|
||||
|
||||
new_view = window.new_file()
|
||||
new_view.set_scratch(True)
|
||||
if sublime.version() >= '3000':
|
||||
new_view.run_command('append', {
|
||||
'characters': text,
|
||||
})
|
||||
else: # 2.x
|
||||
new_edit = new_view.begin_edit()
|
||||
new_view.insert(new_edit, 0, text)
|
||||
new_view.end_edit(new_edit)
|
||||
return new_view
|
||||
|
||||
class MarkdownPreviewListener(sublime_plugin.EventListener):
|
||||
''' auto update the output html if markdown file has already been converted once '''
|
||||
|
||||
def on_post_save(self, view):
|
||||
if view.file_name().endswith(tuple(settings.get('markdown_filetypes', (".md", ".markdown", ".mdown")))):
|
||||
settings = sublime.load_settings('MarkdownPreview.sublime-settings')
|
||||
filetypes = settings.get('markdown_filetypes')
|
||||
if filetypes and view.file_name().endswith(tuple(filetypes)):
|
||||
temp_file = getTempMarkdownPreviewPath(view)
|
||||
if os.path.isfile(temp_file):
|
||||
# reexec markdown conversion
|
||||
@@ -36,57 +135,107 @@ class MarkdownPreviewListener(sublime_plugin.EventListener):
|
||||
class MarkdownCheatsheetCommand(sublime_plugin.TextCommand):
|
||||
''' open our markdown cheat sheet in ST2 '''
|
||||
def run(self, edit):
|
||||
cheatsheet = os.path.join(sublime.packages_path(), 'Markdown Preview', 'sample.md')
|
||||
self.view.window().open_file(cheatsheet)
|
||||
lines = '\n'.join(load_resource('sample.md').splitlines())
|
||||
view = new_scratch_view(self.view.window(), lines)
|
||||
view.set_name("Markdown Cheatsheet")
|
||||
|
||||
# Set syntax file
|
||||
syntax_files = ["Packages/Markdown Extended/Syntaxes/Markdown Extended.tmLanguage", "Packages/Markdown/Markdown.tmLanguage"]
|
||||
for file in syntax_files:
|
||||
if exists_resource(file):
|
||||
view.set_syntax_file(file)
|
||||
break # Done if any syntax is set.
|
||||
|
||||
sublime.status_message('Markdown cheat sheet opened')
|
||||
|
||||
|
||||
class MarkdownPreviewCommand(sublime_plugin.TextCommand):
|
||||
''' preview file contents with python-markdown and your web browser '''
|
||||
|
||||
def getCSS(self):
|
||||
''' return the correct CSS file based on parser and settings '''
|
||||
config_parser = settings.get('parser')
|
||||
config_css = settings.get('css')
|
||||
class MarkdownCompiler():
|
||||
''' Do the markdown converting '''
|
||||
|
||||
styles = ''
|
||||
if config_css and config_css != 'default':
|
||||
styles += u"<link href='%s' rel='stylesheet' type='text/css'>" % config_css
|
||||
else:
|
||||
css_filename = 'markdown.css'
|
||||
if config_parser and config_parser == 'github':
|
||||
css_filename = 'github.css'
|
||||
# path via package manager
|
||||
css_path = os.path.join(sublime.packages_path(), 'Markdown Preview', css_filename)
|
||||
if not os.path.isfile(css_path):
|
||||
# path via git repo
|
||||
css_path = os.path.join(sublime.packages_path(), 'sublimetext-markdown-preview', css_filename)
|
||||
if not os.path.isfile(css_path):
|
||||
sublime.error_message('markdown.css file not found!')
|
||||
raise Exception("markdown.css file not found!")
|
||||
styles += u"<style>%s</style>" % open(css_path, 'r').read().decode('utf-8')
|
||||
def get_search_path_css(self):
|
||||
css_name = self.settings.get('css', 'default')
|
||||
if os.path.isabs(css_name):
|
||||
return u"<link href='%s' rel='stylesheet' type='text/css'>" % css_name
|
||||
|
||||
if settings.get('allow_css_overrides'):
|
||||
if css_name == 'default':
|
||||
css_name = 'github.css' if self.settings.get('parser', 'default') == 'github' else 'markdown.css'
|
||||
|
||||
# Try the local folder for css file.
|
||||
mdfile = self.view.file_name()
|
||||
if mdfile is not None:
|
||||
css_path = os.path.join(os.path.dirname(mdfile), css_name)
|
||||
if os.path.isfile(css_path):
|
||||
return u"<style>%s</style>" % load_utf8(css_path)
|
||||
|
||||
# Try the build-in css files.
|
||||
return u"<style>%s</style>" % load_resource(css_name)
|
||||
|
||||
def get_override_css(self):
|
||||
''' handls allow_css_overrides setting. '''
|
||||
|
||||
if self.settings.get('allow_css_overrides'):
|
||||
filename = self.view.file_name()
|
||||
filetypes = settings.get('markdown_filetypes')
|
||||
filetypes = self.settings.get('markdown_filetypes')
|
||||
|
||||
if filename and filetypes:
|
||||
for filetype in filetypes:
|
||||
if filename.endswith(filetype):
|
||||
css_filename = filename.rpartition(filetype)[0] + '.css'
|
||||
if (os.path.isfile(css_filename)):
|
||||
styles += u"<style>%s</style>" % open(css_filename, 'r').read().decode('utf-8')
|
||||
return u"<style>%s</style>" % load_utf8(css_filename)
|
||||
return ''
|
||||
|
||||
return styles
|
||||
def get_stylesheet(self):
|
||||
''' return the correct CSS file based on parser and settings '''
|
||||
return self.get_search_path_css() + self.get_override_css()
|
||||
|
||||
def get_contents(self, region):
|
||||
def get_javascript(self):
|
||||
js_files = self.settings.get('js')
|
||||
scripts = ''
|
||||
|
||||
if js_files is not None:
|
||||
# Ensure string values become a list.
|
||||
if isinstance(js_files, str) or isinstance(js_files, unicode):
|
||||
js_files = [js_files]
|
||||
# Only load scripts if we have a list.
|
||||
if isinstance(js_files, list):
|
||||
for js_file in js_files:
|
||||
if os.path.isabs(js_file):
|
||||
# Load the script inline to avoid cross-origin.
|
||||
scripts += u"<script>%s</script>" % load_utf8(js_file)
|
||||
else:
|
||||
scripts += u"<script type='text/javascript' src='%s'></script>" % js_file
|
||||
return scripts
|
||||
|
||||
def get_mathjax(self):
|
||||
''' return the MathJax script if enabled '''
|
||||
|
||||
if self.settings.get('enable_mathjax') is True:
|
||||
return load_resource('mathjax.html')
|
||||
return ''
|
||||
|
||||
def get_highlight(self):
|
||||
''' return the Highlight.js and css if enabled '''
|
||||
|
||||
highlight = ''
|
||||
if self.settings.get('enable_highlight') is True and self.settings.get('parser') == 'default':
|
||||
highlight += "<style>%s</style>" % load_resource('highlight.css')
|
||||
highlight += "<script>%s</script>" % load_resource('highlight.js')
|
||||
highlight += "<script>hljs.initHighlightingOnLoad();</script>"
|
||||
return highlight
|
||||
|
||||
|
||||
def get_contents(self, wholefile=False):
|
||||
''' Get contents or selection from view and optionally strip the YAML front matter '''
|
||||
region = sublime.Region(0, self.view.size())
|
||||
contents = self.view.substr(region)
|
||||
# use selection if any
|
||||
selection = self.view.substr(self.view.sel()[0])
|
||||
if selection.strip() != '':
|
||||
contents = selection
|
||||
if settings.get('strip_yaml_front_matter') and contents.startswith('---'):
|
||||
if not wholefile:
|
||||
# use selection if any
|
||||
selection = self.view.substr(self.view.sel()[0])
|
||||
if selection.strip() != '':
|
||||
contents = selection
|
||||
if self.settings.get('strip_yaml_front_matter') and contents.startswith('---'):
|
||||
title = ''
|
||||
title_match = re.search('(?:title:)(.+)', contents, flags=re.IGNORECASE)
|
||||
if title_match:
|
||||
@@ -110,39 +259,62 @@ class MarkdownPreviewCommand(sublime_plugin.TextCommand):
|
||||
html = RE_SOURCES.sub(tag_fix, html)
|
||||
return html
|
||||
|
||||
def convert_markdown(self, markdown):
|
||||
''' convert input markdown to HTML, with github or builtin parser '''
|
||||
config_parser = settings.get('parser')
|
||||
github_oauth_token = settings.get('github_oauth_token')
|
||||
def get_config_extensions(self, default_extensions):
|
||||
config_extensions = self.settings.get('enabled_extensions')
|
||||
if not config_extensions or config_extensions == 'default':
|
||||
return default_extensions
|
||||
if 'default' in config_extensions:
|
||||
config_extensions.remove( 'default' )
|
||||
config_extensions.extend( default_extensions )
|
||||
return config_extensions
|
||||
|
||||
def convert_markdown(self, markdown_text, parser):
|
||||
''' convert input markdown to HTML, with github or builtin parser '''
|
||||
|
||||
markdown_html = _CANNOT_CONVERT
|
||||
if parser == 'github':
|
||||
github_oauth_token = self.settings.get('github_oauth_token')
|
||||
|
||||
markdown_html = u'cannot convert markdown'
|
||||
if config_parser and config_parser == 'github':
|
||||
# use the github API
|
||||
sublime.status_message('converting markdown with github API...')
|
||||
try:
|
||||
github_mode = settings.get('github_mode', 'gfm')
|
||||
data = {"text": markdown, "mode": github_mode}
|
||||
json_data = json.dumps(data)
|
||||
github_mode = self.settings.get('github_mode', 'gfm')
|
||||
data = {
|
||||
"text": markdown_text,
|
||||
"mode": github_mode
|
||||
}
|
||||
headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
if github_oauth_token:
|
||||
headers['Authorization'] = "token %s" % github_oauth_token
|
||||
data = json.dumps(data).encode('utf-8')
|
||||
url = "https://api.github.com/markdown"
|
||||
sublime.status_message(url)
|
||||
request = urllib2.Request(url, json_data, {'Content-Type': 'application/json'})
|
||||
if github_oauth_token:
|
||||
request.add_header('Authorization', "token %s" % github_oauth_token)
|
||||
markdown_html = urllib2.urlopen(request).read().decode('utf-8')
|
||||
except urllib2.HTTPError, e:
|
||||
request = Request(url, data, headers)
|
||||
markdown_html = urlopen(request).read().decode('utf-8')
|
||||
except HTTPError:
|
||||
e = sys.exc_info()[1]
|
||||
if e.code == 401:
|
||||
sublime.error_message('github API auth failed. Please check your OAuth token.')
|
||||
else:
|
||||
sublime.error_message('github API responded in an unfashion way :/')
|
||||
except urllib2.URLError:
|
||||
except URLError:
|
||||
sublime.error_message('cannot use github API to convert markdown. SSL is not included in your Python installation')
|
||||
except:
|
||||
e = sys.exc_info()[1]
|
||||
print(e)
|
||||
traceback.print_exc()
|
||||
sublime.error_message('cannot use github API to convert markdown. Please check your settings.')
|
||||
else:
|
||||
sublime.status_message('converted markdown with github API successfully')
|
||||
else:
|
||||
|
||||
elif parser == 'markdown2':
|
||||
# convert the markdown
|
||||
markdown_html = markdown2.markdown(markdown, extras=['footnotes', 'toc', 'fenced-code-blocks', 'cuddled-lists'])
|
||||
enabled_extras = set(self.get_config_extensions(['footnotes', 'toc', 'fenced-code-blocks', 'cuddled-lists']))
|
||||
if self.settings.get("enable_mathjax") is True or self.settings.get("enable_highlight") is True:
|
||||
enabled_extras.add('code-friendly')
|
||||
markdown_html = markdown2.markdown(markdown_text, extras=list(enabled_extras))
|
||||
toc_html = markdown_html.toc_html
|
||||
if toc_html:
|
||||
toc_markers = ['[toc]', '[TOC]', '<!--TOC-->']
|
||||
@@ -151,41 +323,62 @@ class MarkdownPreviewCommand(sublime_plugin.TextCommand):
|
||||
|
||||
# postprocess the html from internal parser
|
||||
markdown_html = self.postprocessor(markdown_html)
|
||||
else:
|
||||
sublime.status_message('converting markdown with Python markdown...')
|
||||
config_extensions = self.get_config_extensions(['extra', 'toc'])
|
||||
markdown_html = markdown.markdown(markdown_text, extensions=config_extensions)
|
||||
markdown_html = self.postprocessor(markdown_html)
|
||||
|
||||
return markdown_html
|
||||
|
||||
def run(self, edit, target='browser'):
|
||||
region = sublime.Region(0, self.view.size())
|
||||
encoding = self.view.encoding()
|
||||
if encoding == 'Undefined':
|
||||
encoding = 'utf-8'
|
||||
elif encoding == 'Western (Windows 1252)':
|
||||
encoding = 'windows-1252'
|
||||
elif encoding == 'UTF-8 with BOM':
|
||||
encoding = 'utf-8'
|
||||
def get_title(self):
|
||||
title = self.view.name()
|
||||
if not title:
|
||||
fn = self.view.file_name()
|
||||
title = 'untitled' if not fn else os.path.splitext(os.path.basename(fn))[0]
|
||||
return '<title>%s</title>' % title
|
||||
|
||||
contents = self.get_contents(region)
|
||||
def run(self, view, parser, wholefile=False):
|
||||
''' return full html and body html for view. '''
|
||||
self.settings = sublime.load_settings('MarkdownPreview.sublime-settings')
|
||||
self.view = view
|
||||
|
||||
contents = self.get_contents(wholefile)
|
||||
|
||||
body = self.convert_markdown(contents, parser)
|
||||
|
||||
markdown_html = self.convert_markdown(contents)
|
||||
html = u'<!DOCTYPE html>'
|
||||
html += '<html><head><meta charset="utf-8">'
|
||||
html += self.get_stylesheet()
|
||||
html += self.get_javascript()
|
||||
html += self.get_highlight()
|
||||
html += self.get_mathjax()
|
||||
html += self.get_title()
|
||||
html += '</head><body>'
|
||||
html += body
|
||||
html += '</body>'
|
||||
html += '</html>'
|
||||
return html, body
|
||||
|
||||
full_html = u'<!DOCTYPE html>'
|
||||
full_html += '<html><head><meta charset="%s">' % encoding
|
||||
full_html += self.getCSS()
|
||||
full_html += '</head><body>'
|
||||
full_html += markdown_html
|
||||
full_html += '</body>'
|
||||
full_html += '</html>'
|
||||
|
||||
compiler = MarkdownCompiler()
|
||||
|
||||
|
||||
|
||||
class MarkdownPreviewCommand(sublime_plugin.TextCommand):
|
||||
def run(self, edit, parser='markdown', target='browser'):
|
||||
settings = sublime.load_settings('MarkdownPreview.sublime-settings')
|
||||
html, body = compiler.run(self.view, parser)
|
||||
|
||||
if target in ['disk', 'browser']:
|
||||
# check if LiveReload ST2 extension installed and add its script to the resulting HTML
|
||||
livereload_installed = ('LiveReload' in os.listdir(sublime.packages_path()))
|
||||
# build the html
|
||||
if livereload_installed:
|
||||
full_html += '<script>document.write(\'<script src="http://\' + (location.host || \'localhost\').split(\':\')[0] + \':35729/livereload.js?snipver=1"></\' + \'script>\')</script>'
|
||||
html += '<script>document.write(\'<script src="http://\' + (location.host || \'localhost\').split(\':\')[0] + \':35729/livereload.js?snipver=1"></\' + \'script>\')</script>'
|
||||
# update output html file
|
||||
tmp_fullpath = getTempMarkdownPreviewPath(self.view)
|
||||
tmp_html = open(tmp_fullpath, 'w')
|
||||
tmp_html.write(full_html.encode(encoding))
|
||||
tmp_html.close()
|
||||
save_utf8(tmp_fullpath, html)
|
||||
# now opens in browser if needed
|
||||
if target == 'browser':
|
||||
config_browser = settings.get('browser')
|
||||
@@ -205,13 +398,65 @@ class MarkdownPreviewCommand(sublime_plugin.TextCommand):
|
||||
sublime.status_message('Markdown preview launched in default html viewer')
|
||||
elif target == 'sublime':
|
||||
# create a new buffer and paste the output HTML
|
||||
new_view = self.view.window().new_file()
|
||||
new_view.set_scratch(True)
|
||||
new_edit = new_view.begin_edit()
|
||||
new_view.insert(new_edit, 0, markdown_html)
|
||||
new_view.end_edit(new_edit)
|
||||
new_scratch_view(self.view.window(), body)
|
||||
sublime.status_message('Markdown preview launched in sublime')
|
||||
elif target == 'clipboard':
|
||||
# clipboard copy the full HTML
|
||||
sublime.set_clipboard(full_html)
|
||||
sublime.set_clipboard(html)
|
||||
sublime.status_message('Markdown export copied to clipboard')
|
||||
|
||||
|
||||
class MarkdownBuildCommand(sublime_plugin.WindowCommand):
|
||||
def init_panel(self):
|
||||
if not hasattr(self, 'output_view'):
|
||||
if sublime.version() >= '3000':
|
||||
self.output_view = self.window.create_output_panel("markdown")
|
||||
else:
|
||||
self.output_view = self.window.get_output_panel("markdown")
|
||||
|
||||
def puts(self, message):
|
||||
message = message + '\n'
|
||||
if sublime.version() >= '3000':
|
||||
self.output_view.run_command('append', {'characters': message, 'force': True, 'scroll_to_end': True})
|
||||
else:
|
||||
selection_was_at_end = (len(self.output_view.sel()) == 1
|
||||
and self.output_view.sel()[0]
|
||||
== sublime.Region(self.output_view.size()))
|
||||
self.output_view.set_read_only(False)
|
||||
edit = self.output_view.begin_edit()
|
||||
self.output_view.insert(edit, self.output_view.size(), message)
|
||||
if selection_was_at_end:
|
||||
self.output_view.show(self.output_view.size())
|
||||
self.output_view.end_edit(edit)
|
||||
self.output_view.set_read_only(True)
|
||||
|
||||
def run(self):
|
||||
view = self.window.active_view()
|
||||
if not view:
|
||||
return
|
||||
start_time = time.time()
|
||||
|
||||
self.init_panel()
|
||||
|
||||
show_panel_on_build = sublime.load_settings("Preferences.sublime-settings").get("show_panel_on_build", True)
|
||||
if show_panel_on_build:
|
||||
self.window.run_command("show_panel", {"panel": "output.markdown"})
|
||||
|
||||
mdfile = view.file_name()
|
||||
if mdfile is None:
|
||||
self.puts("Can't build a unsaved markdown file.")
|
||||
return
|
||||
|
||||
self.puts("Compiling %s..." % mdfile)
|
||||
|
||||
html, body = compiler.run(view, 'markdown', True)
|
||||
|
||||
htmlfile = os.path.splitext(mdfile)[0]+'.html'
|
||||
self.puts(" ->"+htmlfile)
|
||||
save_utf8(htmlfile, html)
|
||||
|
||||
elapsed = time.time() - start_time
|
||||
if body == _CANNOT_CONVERT:
|
||||
self.puts(_CANNOT_CONVERT)
|
||||
self.puts("[Finished in %.1fs]" % (elapsed))
|
||||
sublime.status_message("Build finished")
|
||||
|
@@ -11,14 +11,50 @@
|
||||
"browser": "default",
|
||||
|
||||
/*
|
||||
Sets the default parser for converting markdown to html.
|
||||
Sets the parser used for build markdown to html.
|
||||
|
||||
NOTE: The parser setting is not for the preview commands now.
|
||||
The preivew have sperated commands for each parser markdown.
|
||||
|
||||
Warning for github API : if you have a ST2 linux build, Python is not built with SSL o it may not work
|
||||
|
||||
default - Use the builtin python-markdown2 parser
|
||||
default - The current default parser is python-markdown parser.
|
||||
markdown - Use the buildin python-markdown parser
|
||||
markdown2 - (Deprecated) Use the builtin python-markdown2 parser.
|
||||
github - User github API to convert markdown, so you can use GitHub flavored Markdown, see http://github.github.com/github-flavored-markdown/
|
||||
*/
|
||||
"parser": "default",
|
||||
|
||||
/*
|
||||
Enable or not mathjax support.
|
||||
*/
|
||||
"enable_mathjax": false,
|
||||
|
||||
/*
|
||||
Enable or not highlight.js support for syntax highlighting.
|
||||
*/
|
||||
"enable_highlight": false,
|
||||
|
||||
/*
|
||||
List of enabled extensions of the selected markdown parser.
|
||||
|
||||
You can get the full list of extensions at:
|
||||
* The markdown2 parser, the `default`: https://github.com/trentm/python-markdown2/wiki/Extras
|
||||
* The python markdown parser, the `markdown`: http://pythonhosted.org/Markdown/extensions/index.html
|
||||
|
||||
|
||||
default - use the default set of extensions, see table latter.
|
||||
[ "default", "def_list", ... ] - a list of extensions. Use "default" to include the default extensions.
|
||||
|
||||
Parser | "default" Values
|
||||
------------|---------------------------
|
||||
default | ["footnotes", "toc", "fenced-code-blocks", "cuddled-lists" ]
|
||||
markdown | ["extra", "toc"]
|
||||
github | extensions values are not used.
|
||||
|
||||
*/
|
||||
"enabled_extensions": "default",
|
||||
|
||||
/*
|
||||
Default mode for the github Markdon parser : markdown (documents) or gfm (comments)
|
||||
see http://developer.github.com/v3/markdown/#render-an-arbitrary-markdown-document
|
||||
@@ -46,11 +82,29 @@
|
||||
*/
|
||||
"allow_css_overrides": true,
|
||||
|
||||
/*
|
||||
Sets the JavaScript files to embed in the HTML
|
||||
|
||||
Set an array of URLs or filepaths to JavaScript files. Absolute filepaths will be loaded
|
||||
into the script tag; others will be set as the `src` attribute. The order of files in the
|
||||
array is the order in which they are embedded.
|
||||
*/
|
||||
// "js": ["http://example.com/script.js", "/path/to/script.js"],
|
||||
|
||||
/*
|
||||
Sets the supported filetypes for auto-reload on save
|
||||
*/
|
||||
"markdown_filetypes": [".md", ".markdown", ".mdown"],
|
||||
|
||||
/*
|
||||
Sets a custom temporary folder for MarkdownPreview-generated html files. Useful if you're
|
||||
using LiveReload and don't want to use the OS default. The directory must already exist.
|
||||
|
||||
Examples: /tmp/custom_folder (Linux/OSX)
|
||||
C:/TEMP/MYNOTES (Windows - note it's forward slash, even on Windows)
|
||||
*/
|
||||
// "path_tempfile": "/tmp/my_notes",
|
||||
|
||||
/*
|
||||
Strips the YAML front matter header and converts title to a heading
|
||||
*/
|
||||
|
@@ -1,9 +1,9 @@
|
||||
Sublime Text 2 MarkDown preview
|
||||
===============================
|
||||
Sublime Text 2/3 Markdown Preview
|
||||
=================================
|
||||
|
||||
A simple ST2 plugin to help you preview your markdown files quickly in you web browser.
|
||||
Preview your markdown files quickly in you web browser from sublime text 2/3.
|
||||
|
||||
You can use builtin [python-markdown2][0] parser (default) or use the [github markdown API][5] for the conversion (edit your settings to select it).
|
||||
You can use builtin [python-markdown][10] parser or use the [github markdown API][5] for the conversion.
|
||||
|
||||
**NOTE:** If you choose the GitHub API for conversion (set parser: github in your settings), your code will be sent through https to github for live conversion. You'll have [Github flavored markdown][6], syntax highlighting and EMOJI support for free :heart: :octocat: :gift:. If you make more than 60 calls a day, be sure to set your GitHub API key in the settings :)
|
||||
|
||||
@@ -11,42 +11,81 @@ You can use builtin [python-markdown2][0] parser (default) or use the [github ma
|
||||
|
||||
## Features :
|
||||
|
||||
- Markdown conversion via builtin Markdown Parser ([python-markdown2][0]) or via Github API : just choose in your settings.
|
||||
- Markdown preivew using the [Python-markdown][10] or the Github API just choose select the build commands.
|
||||
- Build markdown file using Sublime Text build system. The build parser are config via the `"parser"` config.
|
||||
- Browser preview auto reload on save if you have the [ST2 LiveReload plugin][7] installed.
|
||||
- Builtin parser : Support TOC, footnotes markdown extensions
|
||||
- CSS overriding if you need
|
||||
- Builtin parser : supports `abbr`, `attr_list`, `def_list`, `fenced_code`, `footnotes`, `tables`, `smart_strong` and `toc` markdown extensions.
|
||||
- CSS search path for local and build-in CSS files (always enabled) and/or CSS overriding if you need
|
||||
- YAML support thanks to @tommi
|
||||
- Clipboard selection and copy to clipboard thanks to @hexatrope
|
||||
- MathJax support : \\(\frac{\pi}{2}\\) thanks to @bps10
|
||||
|
||||
## Installation :
|
||||
|
||||
- you should use [sublime package manager][3]
|
||||
- use `cmd+shift+P` then `Package Control: Install Package`
|
||||
- look for `Markdown Preview` and install it.
|
||||
### Using [Package Control][3] (*Recommanded*)
|
||||
|
||||
For all Sublime Text 2/3 users we recommand installe via [Package Control][3].
|
||||
|
||||
1. [Install][11] Package Control if you haven't yet.
|
||||
2. Use `cmd+shift+P` then `Package Control: Install Package`
|
||||
3. Look for `Markdown Preview` and install it.
|
||||
|
||||
### Manual Install
|
||||
|
||||
1. Click the `Preferences > Browse Packages…` menu
|
||||
2. Browse up a folder and then into the `Installed Packages/` folder
|
||||
3. Download [zip package][12] rename it to `Markdown Preview.sublime-package` and copy it into the `Installed Packages/` directory
|
||||
4. Restart Sublime Text
|
||||
|
||||
## Usage :
|
||||
|
||||
### To preivew :
|
||||
|
||||
- optionnaly select some of your markdown for conversion
|
||||
- use `cmd+shift+P` then `Markdown Preview` to launch a preview
|
||||
- use `cmd+shift+P` then `Markdown Preview` to show the follow commands:
|
||||
- Markdown Preview: Python Markdown: Preview in Browser
|
||||
- Markdown Preview: Python Markdown: Export HTML in Sublime Text
|
||||
- Markdown Preview: Python Markdown: Copy to Clipboard
|
||||
- Markdown Preview: Github Flavored Markdown: Preview in Browser
|
||||
- Markdown Preview: Github Flavored Markdown: Export HTML in Sublime Text
|
||||
- Markdown Preview: Github Flavored Markdown: Copy to Clipboard
|
||||
- Markdown Preview: Open Markdown Cheat sheet
|
||||
- or bind some key in your user key binding, using a line like this one:
|
||||
`{ "keys": ["alt+m"], "command": "markdown_preview", "args": {"target": "browser"} },`
|
||||
`{ "keys": ["alt+m"], "command": "markdown_preview", "args": {"target": "browser", "parser":"markdown"} },`
|
||||
- once converted a first time, the output HTML will be updated on each file save (with LiveReload plugin)
|
||||
|
||||
## Uses :
|
||||
### To build :
|
||||
|
||||
- [python-markdown2][0] for markdown parsing **OR** the GitHub markdown API.
|
||||
- Just use `Ctrl+B` (Windows/Linux) or `cmd+B` (Mac) to build current file.
|
||||
|
||||
### To config :
|
||||
|
||||
Using Sublime Text menu: `Preferences`->`Package Settings`->`Markdown Preivew`
|
||||
|
||||
- `Settings - User` is where you change your serrings for Markdown Preview.
|
||||
- `Settings - Default` is a good reference with detail description for each setting.
|
||||
|
||||
|
||||
## Support :
|
||||
|
||||
- Any bugs about Markdown Preview please fell free to report [here][issue].
|
||||
- And you are welcome to fork and submit pullrequests.
|
||||
|
||||
|
||||
## Licence :
|
||||
|
||||
The code is available at github [https://github.com/revolunet/sublimetext-markdown-preview][2] under MIT licence : [http://revolunet.mit-license.org][4]
|
||||
The code is available at github [project][home] under [MIT licence][4].
|
||||
|
||||
[0]: https://github.com/trentm/python-markdown2
|
||||
[2]: https://github.com/revolunet/sublimetext-markdown-preview
|
||||
[3]: http://wbond.net/sublime_packages/package_control
|
||||
[home]: https://github.com/revolunet/sublimetext-markdown-preview
|
||||
[3]: https://sublime.wbond.net/
|
||||
[4]: http://revolunet.mit-license.org
|
||||
[5]: http://developer.github.com/v3/markdown
|
||||
[6]: http://github.github.com/github-flavored-markdown/
|
||||
[7]: https://github.com/dz0ny/LiveReload-sublimetext2
|
||||
[8]: https://github.com/revolunet/sublimetext-markdown-preview/issues/27#issuecomment-11772098
|
||||
[9]: https://github.com/revolunet/sublimetext-markdown-preview/issues/78#issuecomment-15644727
|
||||
[10]: https://github.com/waylan/Python-Markdown
|
||||
[11]: https://sublime.wbond.net/installation
|
||||
[12]: https://github.com/revolunet/sublimetext-markdown-preview/archive/master.zip
|
||||
[issue]: https://github.com/revolunet/sublimetext-markdown-preview/issues
|
@@ -116,7 +116,7 @@ except ImportError:
|
||||
opener.wait()
|
||||
return opener.poll() == 0
|
||||
|
||||
import commands
|
||||
import subprocess
|
||||
|
||||
# Private functions.
|
||||
|
||||
@@ -136,7 +136,7 @@ def _is_xfce():
|
||||
# XFCE detection involves testing the output of a program.
|
||||
|
||||
try:
|
||||
return _readfrom(_get_x11_vars() + "xprop -root _DT_SAVE_MODE", shell=1).strip().endswith(' = "xfce4"')
|
||||
return _readfrom(_get_x11_vars() + "xprop -root _DT_SAVE_MODE", shell=1).decode("utf-8").strip().endswith(' = "xfce4"')
|
||||
except OSError:
|
||||
return 0
|
||||
|
||||
@@ -144,7 +144,7 @@ def _is_x11():
|
||||
|
||||
"Return whether the X Window System is in use."
|
||||
|
||||
return os.environ.has_key("DISPLAY")
|
||||
return "DISPLAY" in os.environ
|
||||
|
||||
# Introspection functions.
|
||||
|
||||
@@ -155,14 +155,14 @@ def get_desktop():
|
||||
environment. If no environment could be detected, None is returned.
|
||||
"""
|
||||
|
||||
if os.environ.has_key("KDE_FULL_SESSION") or \
|
||||
os.environ.has_key("KDE_MULTIHEAD"):
|
||||
if "KDE_FULL_SESSION" in os.environ or \
|
||||
"KDE_MULTIHEAD" in os.environ:
|
||||
return "KDE"
|
||||
elif os.environ.has_key("GNOME_DESKTOP_SESSION_ID") or \
|
||||
os.environ.has_key("GNOME_KEYRING_SOCKET"):
|
||||
elif "GNOME_DESKTOP_SESSION_ID" in os.environ or \
|
||||
"GNOME_KEYRING_SOCKET" in os.environ:
|
||||
return "GNOME"
|
||||
elif os.environ.has_key("MATE_DESKTOP_SESSION_ID") or \
|
||||
os.environ.has_key("MATE_KEYRING_SOCKET"):
|
||||
elif "MATE_DESKTOP_SESSION_ID" in os.environ or \
|
||||
"MATE_KEYRING_SOCKET" in os.environ:
|
||||
return "MATE"
|
||||
elif sys.platform == "darwin":
|
||||
return "Mac OS X"
|
||||
@@ -222,7 +222,7 @@ def is_standard():
|
||||
launching.
|
||||
"""
|
||||
|
||||
return os.environ.has_key("DESKTOP_LAUNCH")
|
||||
return "DESKTOP_LAUNCH" in os.environ
|
||||
|
||||
# Activity functions.
|
||||
|
||||
@@ -255,7 +255,7 @@ def open(url, desktop=None, wait=0):
|
||||
desktop_in_use = use_desktop(desktop)
|
||||
|
||||
if desktop_in_use == "standard":
|
||||
arg = "".join([os.environ["DESKTOP_LAUNCH"], commands.mkarg(url)])
|
||||
arg = "".join([os.environ["DESKTOP_LAUNCH"], subprocess.mkarg(url)])
|
||||
return _run(arg, 1, wait)
|
||||
|
||||
elif desktop_in_use == "Windows":
|
||||
@@ -277,13 +277,16 @@ def open(url, desktop=None, wait=0):
|
||||
elif desktop_in_use == "Mac OS X":
|
||||
cmd = ["open", url]
|
||||
|
||||
elif desktop_in_use == "X11" and os.environ.has_key("BROWSER"):
|
||||
elif desktop_in_use == "X11" and "BROWSER" in os.environ:
|
||||
cmd = [os.environ["BROWSER"], url]
|
||||
|
||||
elif desktop_in_use == "X11":
|
||||
cmd = ["xdg-open", url]
|
||||
|
||||
# Finish with an error where no suitable desktop was identified.
|
||||
|
||||
else:
|
||||
raise OSError, "Desktop '%s' not supported (neither DESKTOP_LAUNCH nor os.startfile could be used)" % desktop_in_use
|
||||
raise OSError("Desktop '%s' not supported (neither DESKTOP_LAUNCH nor os.startfile could be used)" % desktop_in_use)
|
||||
|
||||
return _run(cmd, 0, wait)
|
||||
|
||||
|