def is_global_folded(self): """Check if all headlines are folded. """ region, level = headline.find_headline(self.view, 0, \ headline.ANY_LEVEL, True) # Treating no heeadline as folded, since unfolded all makes # no harm in this situation. if is_region_void(region): return True point = region.a # point can be zero while (point is not None and region): region = headline.region_of_content_of_headline_at_point(self.view, \ point) if not is_region_void(region): point = region.b if not self.is_region_totally_folded(region): return False else: region, level = headline.find_headline(self.view, point, \ headline.ANY_LEVEL, \ True, skip_headline_at_point=True) if not is_region_void(region): point = region.a return True
def headline_and_level_at_point(view, from_point, search_above_and_down=False): """Return the current headline and level. If from_point is inside a headline, then return the headline and level. Otherwise depends on the argument it might search above and down. """ line_region = view.line(from_point) line_content = view.substr(line_region) # Update the level in case it's headline.ANY_LEVEL level = _extract_level_from_headline(line_content) # Search above and down if level is None and search_above_and_down: # Search above headline_region, _ = find_headline(view,\ from_point,\ ANY_LEVEL, False, skip_folded=True) if not is_region_void(headline_region): line_content, level = headline_and_level_at_point(view,\ headline_region.a) # Search down if level is None: headline_region, _ = find_headline(view,\ from_point,\ ANY_LEVEL, True, skip_folded=True) if not is_region_void(headline_region): line_content, level = headline_and_level_at_point(view, headline_region.a) return line_content, level
def run(self, edit, forward=True, same_level=True): """Move between headlines, forward or backward. If same_level is true, only move to headline with the same level or higher level. """ new_sel = [] if same_level: level_type = headline.MATCH_PARENT else: level_type = headline.MATCH_ANY for region in self.view.sel(): if same_level: _, level = headline.headline_and_level_at_point(self.view, region.a, search_above_and_down=True) if level is None: return else: level = headline.ANY_LEVEL match_region, _ = headline.find_headline( self.view, region.a, level, forward, level_type, skip_headline_at_point=True, skip_folded=True ) if is_region_void(match_region): return new_sel.append(sublime.Region(match_region.a, match_region.a)) self.adjust_view(new_sel)
def fold_all(self): region, level = headline.find_headline(self.view, \ 0, \ headline.ANY_LEVEL, \ True) # At this point, headline region is sure to exist, otherwise it would be # treated as gobal folded. (self.is_global_folded() would return True) point = region.a # point can be zero while (point is not None and region): region = headline.region_of_content_of_headline_at_point(self.view, \ point) if not is_region_void(region): point = region.b self.view.fold(sublime.Region(region.a - 1, region.b)) region, level = headline.find_headline(self.view, point, \ headline.ANY_LEVEL, True, \ skip_headline_at_point=True) if not is_region_void(region): point = region.a self.adjust_cursors_and_view()
def unfold_yet_fold_subheads(self, region, level): """Unfold the region while keeping the subheadlines folded.""" ## First unfold all self.view.unfold(region) ## Fold subheads child_headline_region, _ = headline.find_headline(self.view, region.a, level, True, \ headline.MATCH_CHILD) while (not is_region_void(child_headline_region) and child_headline_region.b <= region.b): child_content_region = headline.region_of_content_of_headline_at_point(self.view, child_headline_region.a) if child_content_region is not None: self.view.fold(sublime.Region(child_content_region.a - 1, child_content_region.b)) search_start_point = child_content_region.b else: search_start_point = child_headline_region.b child_headline_region, _ = headline.find_headline(self.view, \ search_start_point, level, True, \ headline.MATCH_CHILD, skip_headline_at_point=True)
def region_of_content_of_headline_at_point(view, from_point): """Extract the region of the content of under current headline.""" _, level = headline_and_level_at_point(view, from_point) if level == None: return None if is_content_empty_at_point(view, from_point): return None line_num, _ = view.rowcol(from_point) content_line_start_point = view.text_point(line_num + 1, 0) next_headline, _ = find_headline(view, \ content_line_start_point, \ level, \ True, \ MATCH_PARENT) if not is_region_void(next_headline): end_pos = next_headline.a - 1 else: end_pos = view.size() return sublime.Region(content_line_start_point, end_pos)
def find_headline(view, from_point, level, forward=True, \ match_type=MATCH_ANY, skip_headline_at_point=False, \ skip_folded=False): """Return the region of the next headline or EOF. Parameters ---------- view: sublime.view from_point: int From which to find. level: int The headline level to match. forward: boolean Search forward or backward match_type: int MATCH_SILBING, MATCH_PARENT, MATCH_CHILD or MATCH_ANY. skip_headline_at_point: boolean When searching whether skip the headline at point skip_folded: boolean Whether to skip the folded region Returns ------- match_region: int Matched region, or None if not found. match_level: int The level of matched headline, or None if not found. """ if skip_headline_at_point: # Move the point to the next line if we are # current in a headline already. from_point = _get_new_point_if_already_in_headline(view, from_point, forward) re_string = _get_re_string(level, match_type) if forward: match_region = view.find(re_string, from_point) else: all_match_regions = view.find_all(re_string) match_region = _nearest_region_among_matches_from_point(view, \ all_match_regions, \ from_point, \ False, \ skip_folded) if skip_folded: while (_is_region_folded(match_region, view)): from_point = match_region.b match_region = view.find(re_string, from_point) if not is_region_void(match_region): if not is_scope_headline(view, match_region.a): return find_headline(view, match_region.a, level, forward, \ match_type, True, skip_folded) else: ## Extract the level of matched headlines according to the region headline = view.substr(match_region) match_level = _extract_level_from_headline(headline) else: match_level = None return (match_region, match_level)