Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v2.2.1 #399

Merged
merged 15 commits into from
Jan 3, 2017
Prev Previous commit
Next Next commit
more folding and heading navigation support
related to #171
  • Loading branch information
felixhao28 committed Dec 12, 2016
commit b20fa1590021ec929515b823336e8ac4d57b2842
25 changes: 25 additions & 0 deletions Default (Linux).sublime-keymap
Original file line number Diff line number Diff line change
Expand Up @@ -599,5 +599,30 @@
{ "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true },
{ "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true }
]
},
{ "keys": ["ctrl+shift+tab"], "command": "show_fold_all_sections", "context":
[
{ "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true }
]
},
{ "keys": ["ctrl+;"], "command": "goto_previous_heading", "args": {"same_level": true}, "context":
[
{ "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true }
]
},
{ "keys": ["ctrl+."], "command": "goto_next_heading", "args": {"same_level": true}, "context":
[
{ "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true }
]
},
{ "keys": ["ctrl+shift+;"], "command": "goto_previous_heading", "args": {"same_level": false}, "context":
[
{ "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true }
]
},
{ "keys": ["ctrl+shift+."], "command": "goto_next_heading", "args": {"same_level": false}, "context":
[
{ "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true }
]
}
]
25 changes: 25 additions & 0 deletions Default (OSX).sublime-keymap
Original file line number Diff line number Diff line change
Expand Up @@ -604,5 +604,30 @@
{ "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true },
{ "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true }
]
},
{ "keys": ["super+shift+tab"], "command": "show_fold_all_sections", "context":
[
{ "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true }
]
},
{ "keys": ["super+;"], "command": "goto_previous_heading", "args": {"same_level": true}, "context":
[
{ "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true }
]
},
{ "keys": ["super+."], "command": "goto_next_heading", "args": {"same_level": true}, "context":
[
{ "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true }
]
},
{ "keys": ["super+shift+;"], "command": "goto_previous_heading", "args": {"same_level": false}, "context":
[
{ "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true }
]
},
{ "keys": ["super+shift+."], "command": "goto_next_heading", "args": {"same_level": false}, "context":
[
{ "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true }
]
}
]
25 changes: 25 additions & 0 deletions Default (Windows).sublime-keymap
Original file line number Diff line number Diff line change
Expand Up @@ -599,5 +599,30 @@
{ "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true },
{ "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true }
]
},
{ "keys": ["ctrl+shift+tab"], "command": "show_fold_all_sections", "context":
[
{ "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true }
]
},
{ "keys": ["ctrl+;"], "command": "goto_previous_heading", "args": {"same_level": true}, "context":
[
{ "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true }
]
},
{ "keys": ["ctrl+."], "command": "goto_next_heading", "args": {"same_level": true}, "context":
[
{ "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true }
]
},
{ "keys": ["ctrl+shift+;"], "command": "goto_previous_heading", "args": {"same_level": false}, "context":
[
{ "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true }
]
},
{ "keys": ["ctrl+shift+."], "command": "goto_next_heading", "args": {"same_level": false}, "context":
[
{ "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true }
]
}
]
56 changes: 56 additions & 0 deletions Default.sublime-commands
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,61 @@
{
"caption": "MarkdownEditing: Toggle Folding Current Section",
"command": "fold_section"
},
{
"caption": "MarkdownEditing: Fold Level 1 Sections",
"command": "fold_all_sections", "args" :
{
"target_level" : 1
}
},
{
"caption": "MarkdownEditing: Fold Level 2 Sections",
"command": "fold_all_sections", "args" :
{
"target_level" : 2
}
},
{
"caption": "MarkdownEditing: Fold Level 3 Sections",
"command": "fold_all_sections", "args" :
{
"target_level" : 3
}
},
{
"caption": "MarkdownEditing: Fold Level 4 Sections",
"command": "fold_all_sections", "args" :
{
"target_level" : 4
}
},
{
"caption": "MarkdownEditing: Find Next Heading (Same or higher level)",
"command": "goto_next_heading", "args" :
{
"same_level" : true
}
},
{
"caption": "MarkdownEditing: Find Next Heading (Any level)",
"command": "goto_next_heading", "args" :
{
"same_level" : false
}
},
{
"caption": "MarkdownEditing: Find Previous Heading (Same or higher level)",
"command": "goto_previous_heading", "args" :
{
"same_level" : true
}
},
{
"caption": "MarkdownEditing: Find Previous Heading (Any level)",
"command": "goto_previous_heading", "args" :
{
"same_level" : false
}
}
]
143 changes: 130 additions & 13 deletions folding.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,42 @@
except ImportError:
from mdeutils import *


def getFoldedRegion(view, reg):
for i in view.folded_regions():
if i.contains(reg):
return i
return None


def all_headings(view):
text = view.substr(sublime.Region(0, view.size()))
it = re.finditer(r'^(#{1,6}(?!#))|^(-{3,}|={3,})', text, re.M)
for m in it:
if re.match(r'^(-{3,}|={3,})$', m.group()):
title_end = m.start() - 1
title_begin = text.rfind('\n', 0, title_end) + 1
title_end = m.end() + 1
level = 2 if text[m.start()] == '-' else 1
else:
title_begin = m.end()
title_end = re.search('(' + m.group() + ')?(\n|$)', text[title_begin:]).start() + title_begin
title_begin = m.start()
level = m.end() - m.start()
yield (title_begin, title_end, level)


class FoldSectionCommand(MDETextCommand):

def run(self, edit):
view = self.view
sections = []
shouldUnfold = False
for sel in view.sel():
text = view.substr(sublime.Region(0, view.size()))
it = re.finditer(r'^(#{1,6}(?!#))|^(-{3,}|={3,})', text, re.M)
section_start = -1
section_end = view.size() - 1
section_level = 0
for m in it:
if re.match(r'^(-{3,}|={3,})$', m.group()):
title_end = m.start() - 1
title_begin = text.rfind('\n', 0, title_end) + 1
title_end = m.end() + 1
level = 2 if text[m.start()] == '-' else 1
else:
title_begin = m.end()
title_end = re.search('(' + m.group() + ')?(\n|$)', text[title_begin:]).start() + title_begin
title_begin = m.start()
level = m.end() - m.start()
for (title_begin, title_end, level) in all_headings(view):
if title_begin <= sel.a:
section_start = title_end
section_level = level
Expand All @@ -55,4 +62,114 @@ def run(self, edit):
view.unfold(reg)
else:
view.fold(reg)
sublime.status_message('%d region%s %sfolded' % (len(sections), 's' if len(sections) > 1 else '', 'un' if shouldUnfold else ''))


class ShowFoldAllSectionsCommand(MDETextCommand):

def run(self, edit):
view = self.view
options = [
'Unfold all',
'Fold Level 1 Sections',
'Fold Level 2 Sections',
'Fold Level 3 Sections',
'Fold Level 4 Sections'
]
view.window().show_quick_panel(options, self.run_command)

def run_command(self, value):
view = self.view
if value >= 1 and value <= 4:
view.run_command('fold_all_sections', {'target_level': value + 1})
elif value == 0:
view.run_command('unfold_all')


class FoldAllSectionsCommand(MDETextCommand):

def run(self, edit, target_level):
view = self.view
view.run_command('unfold_all')
section_start = -1
section_end = view.size() - 1
n_sections = 0
for (title_begin, title_end, level) in all_headings(view):
if level <= target_level:
if section_start > 0:
section_end = title_begin - 1
reg = sublime.Region(section_start, section_end)
view.fold(reg)
n_sections += 1
section_start = -1
if level == target_level:
section_start = title_end
if section_start >= 0:
reg = sublime.Region(section_start, view.size() - 1)
view.fold(reg)
n_sections += 1
sublime.status_message('%d region%s folded' % (n_sections, 's' if n_sections > 1 else ''))


class GotoNextHeadingCommand(MDETextCommand):

def run(self, edit, same_level=True):
view = self.view
new_sel = []
for sel in view.sel():
section_level = 0
found = False
for (title_begin, title_end, level) in all_headings(view):
if title_begin <= sel.a:
section_level = level
elif not same_level or section_level >= level:
found = True
break
if found:
new_sel.append(sublime.Region(title_begin, title_end))
if len(new_sel) == 0:
sublime.status_message('No heading can be found')
else:
view.sel().clear()
for region in new_sel:
view.sel().add(region)
view.show(region)


class GotoPreviousHeadingCommand(MDETextCommand):

def run(self, edit, same_level=True):
view = self.view
new_sel = []
max_level = 0
last_level = 0
found = False
for sel in view.sel():
prev = {}
for (title_begin, title_end, level) in all_headings(view):
max_level = max(max_level, level)
if title_end < sel.a:
for lvl in range(level, max_level + 1):
prev[lvl] = (title_begin, title_end)
last_level = level
else:
found = True
break
if found:
if same_level:
while level not in prev and level > 0:
level -= 1
if level > 0 and level in prev:
new_sel.append(sublime.Region(prev[level][0], prev[level][1]))
else:
if last_level > 0 and last_level in prev:
new_sel.append(sublime.Region(prev[last_level][0], prev[last_level][1]))
elif max_level > 0:
new_sel.append(sublime.Region(title_begin, title_end))
if len(new_sel) == 0:
sublime.status_message('No heading can be found')
else:
view.sel().clear()
for region in new_sel:
view.sel().add(region)
view.show(region)