From c5d15fd0653b90c5567912d0554bca946f643e1f Mon Sep 17 00:00:00 2001 From: Cole Miller Date: Tue, 3 Dec 2024 23:23:16 -0500 Subject: [PATCH] Add FoldFunctionBodies editor action (#21504) Related to #19424 This uses the new text object support, so will only work for languages that have `textobjects.scm`. It does not integrate with indentation-based folding for now, and the syntax-based folds don't have matching fold markers in the gutter (unless they are folded). Release Notes: - Add an editor action to fold all function bodies Co-authored-by: Conrad --- crates/editor/src/actions.rs | 1 + crates/editor/src/editor.rs | 17 +++++++++++++++++ crates/editor/src/element.rs | 1 + crates/language/src/buffer.rs | 8 ++++++++ 4 files changed, 27 insertions(+) diff --git a/crates/editor/src/actions.rs b/crates/editor/src/actions.rs index a67dd55055..9a00f1efca 100644 --- a/crates/editor/src/actions.rs +++ b/crates/editor/src/actions.rs @@ -248,6 +248,7 @@ gpui::actions!( FindAllReferences, Fold, FoldAll, + FoldFunctionBodies, FoldRecursive, FoldSelectedRanges, ToggleFold, diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 2e6274ef8a..3901ba47aa 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -11097,6 +11097,23 @@ impl Editor { self.fold_creases(fold_ranges, true, cx); } + pub fn fold_function_bodies( + &mut self, + _: &actions::FoldFunctionBodies, + cx: &mut ViewContext, + ) { + let snapshot = self.buffer.read(cx).snapshot(cx); + let Some((_, _, buffer)) = snapshot.as_singleton() else { + return; + }; + let creases = buffer + .function_body_fold_ranges(0..buffer.len()) + .map(|range| Crease::simple(range, self.display_map.read(cx).fold_placeholder.clone())) + .collect(); + + self.fold_creases(creases, true, cx); + } + pub fn fold_recursive(&mut self, _: &actions::FoldRecursive, cx: &mut ViewContext) { let mut to_fold = Vec::new(); let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 975f1b8bf0..a82820f265 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -342,6 +342,7 @@ impl EditorElement { register_action(view, cx, Editor::fold); register_action(view, cx, Editor::fold_at_level); register_action(view, cx, Editor::fold_all); + register_action(view, cx, Editor::fold_function_bodies); register_action(view, cx, Editor::fold_at); register_action(view, cx, Editor::fold_recursive); register_action(view, cx, Editor::toggle_fold); diff --git a/crates/language/src/buffer.rs b/crates/language/src/buffer.rs index f3b6cb51ad..67b33ebd56 100644 --- a/crates/language/src/buffer.rs +++ b/crates/language/src/buffer.rs @@ -3355,6 +3355,14 @@ impl BufferSnapshot { }) } + pub fn function_body_fold_ranges( + &self, + within: Range, + ) -> impl Iterator> + '_ { + self.text_object_ranges(within, TreeSitterOptions::default()) + .filter_map(|(range, obj)| (obj == TextObject::InsideFunction).then_some(range)) + } + /// For each grammar in the language, runs the provided /// [`tree_sitter::Query`] against the given range. pub fn matches(