Skip to content

Commit

Permalink
Better fold functions command
Browse files Browse the repository at this point in the history
  • Loading branch information
trishume committed Jun 12, 2017
1 parent e024d85 commit 7c9a06f
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 2 deletions.
4 changes: 2 additions & 2 deletions Default (OSX).sublime-keymap
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
// { "keys": ["super+v"], "command": "paste_and_indent" }, // { "keys": ["super+v"], "command": "paste_and_indent" },
// { "keys": ["super+shift+v"], "command": "paste" }, // { "keys": ["super+shift+v"], "command": "paste" },
// ====== Viewing // ====== Viewing
{ "keys": ["super+k", "super+b"], "command": "fold_scopes" }, { "keys": ["super+k", "super+b"], "command": "fold_functions" },
{ "keys": ["ctrl+,"], "command": "fold_scopes" }, { "keys": ["ctrl+,"], "command": "fold_functions" },
// ====== Editing // ====== Editing
// convenience cmd replications for continuous holding // convenience cmd replications for continuous holding
{ "keys": ["ctrl+z"], "command": "undo" }, { "keys": ["ctrl+z"], "command": "undo" },
Expand Down
66 changes: 66 additions & 0 deletions sublimetect.py
Original file line number Original file line Diff line number Diff line change
@@ -1,4 +1,62 @@
import sublime, sublime_plugin 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): class SelectLineCommand(sublime_plugin.TextCommand):
def is_selection_lines(self): def is_selection_lines(self):
Expand Down Expand Up @@ -42,3 +100,11 @@ def run(self, edit, **args):
did_fold = self.view.fold(folds) did_fold = self.view.fold(folds)
if not did_fold: # already folded, toggle off if not did_fold: # already folded, toggle off
self.view.unfold(folds) 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.