Permalink
Browse files

Better fold functions command

  • Loading branch information...
trishume committed Jun 12, 2017
1 parent e024d85 commit 7c9a06f449bd862a406b453d4ac4d7c93ec49289
Showing with 68 additions and 2 deletions.
  1. +2 −2 Default (OSX).sublime-keymap
  2. +66 −0 sublimetect.py
@@ -8,8 +8,8 @@
// { "keys": ["super+v"], "command": "paste_and_indent" },
// { "keys": ["super+shift+v"], "command": "paste" },
// ====== Viewing
{ "keys": ["super+k", "super+b"], "command": "fold_scopes" },
{ "keys": ["ctrl+,"], "command": "fold_scopes" },
{ "keys": ["super+k", "super+b"], "command": "fold_functions" },
{ "keys": ["ctrl+,"], "command": "fold_functions" },
// ====== Editing
// convenience cmd replications for continuous holding
{ "keys": ["ctrl+z"], "command": "undo" },
View
@@ -1,4 +1,62 @@
import sublime, sublime_plugin
import re
INDENT_RE = re.compile('^\s*')
def line_indent(view, row):
pt = view.text_point(row,0)
line = view.full_line(pt)
content = view.substr(line)
if len(content) <= 1:
return 10000 # blank lines have arbitrarily high indent
start,end = INDENT_RE.match(content).span(0)
return end-start
def find_function_bodies(view, decls):
last_row, last_col = view.rowcol(view.size())
fold_regions = []
for decl in decls:
line_region = view.full_line(decl)
start_row, _ = view.rowcol(decl.a)
end_row, _ = view.rowcol(decl.b)
fn_indent = line_indent(view, start_row)
# find lines until closed indent
cur_row = end_row+1
while True:
if cur_row == last_row:
break
indent = line_indent(view, cur_row)
if indent <= fn_indent:
break
cur_row += 1
# compute region
if (cur_row - end_row) > 1:
final_line = view.full_line(view.text_point(cur_row, 0))
if final_line.size() > 4:
# for languages like python, or when the end is otherwise long
# collapse just before the closing bit
end_pt = view.text_point(cur_row-1,0)
else:
final_line_indent = line_indent(view, cur_row)
end_pt = view.text_point(cur_row, final_line_indent)
fold_regions.append(sublime.Region(line_region.b-1, end_pt))
return fold_regions
def find_all_functions(view):
if view.score_selector(0,'source.rust') > 0:
fn_bodies = view.find_by_selector('meta.function meta.block')
folds = [sublime.Region(r.a+1,r.b-1) for r in fn_bodies]
else:
fn_decls = view.find_by_selector('meta.function, entity.name.function')
folds = find_function_bodies(view, fn_decls)
did_fold = view.fold(folds)
if not did_fold: # already folded, toggle off
view.unfold(folds)
class SelectLineCommand(sublime_plugin.TextCommand):
def is_selection_lines(self):
@@ -42,3 +100,11 @@ def run(self, edit, **args):
did_fold = self.view.fold(folds)
if not did_fold: # already folded, toggle off
self.view.unfold(folds)
class FoldFunctionsCommand(sublime_plugin.TextCommand):
def run(self, edit):
folds = find_all_functions(self.view)
# print("folding " + len(folds))
did_fold = self.view.fold(folds)
if not did_fold: # already folded, toggle off
self.view.unfold(folds)

0 comments on commit 7c9a06f

Please sign in to comment.