Skip to content

Commit

Permalink
Add editor: fold at level <level> commands (#19750)
Browse files Browse the repository at this point in the history
Closes #5142

Note that I only moved the cursor to the top of the file so it wouldn't
jump - the commands work no matter where you are in the file.


https://github.com/user-attachments/assets/78c74ca6-5c17-477c-b5d1-97c5665e44b0

Also, is VS Code doing this right thing here? or is it busted?


https://github.com/user-attachments/assets/8c503b50-9671-4221-b9f8-1e692fe8cd9a

Release Notes:

- Added `editor: fold at level <level>` commands. macOS: `cmd-k,
cmd-<number>`, Linux: `ctrl-k, ctrl-<number>`.

---------

Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
  • Loading branch information
JosephTLyons and osiewicz authored Oct 25, 2024
1 parent 7d0a7af commit 507929c
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 7 deletions.
9 changes: 9 additions & 0 deletions assets/keymaps/default-linux.json
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,15 @@
"ctrl-k ctrl-l": "editor::ToggleFold",
"ctrl-k ctrl-[": "editor::FoldRecursive",
"ctrl-k ctrl-]": "editor::UnfoldRecursive",
"ctrl-k ctrl-1": ["editor::FoldAtLevel", { "level": 1 }],
"ctrl-k ctrl-2": ["editor::FoldAtLevel", { "level": 2 }],
"ctrl-k ctrl-3": ["editor::FoldAtLevel", { "level": 3 }],
"ctrl-k ctrl-4": ["editor::FoldAtLevel", { "level": 4 }],
"ctrl-k ctrl-5": ["editor::FoldAtLevel", { "level": 5 }],
"ctrl-k ctrl-6": ["editor::FoldAtLevel", { "level": 6 }],
"ctrl-k ctrl-7": ["editor::FoldAtLevel", { "level": 7 }],
"ctrl-k ctrl-8": ["editor::FoldAtLevel", { "level": 8 }],
"ctrl-k ctrl-9": ["editor::FoldAtLevel", { "level": 9 }],
"ctrl-k ctrl-0": "editor::FoldAll",
"ctrl-k ctrl-j": "editor::UnfoldAll",
"ctrl-space": "editor::ShowCompletions",
Expand Down
10 changes: 9 additions & 1 deletion assets/keymaps/default-macos.json
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,15 @@
"alt-cmd-]": "editor::UnfoldLines",
"cmd-k cmd-l": "editor::ToggleFold",
"cmd-k cmd-[": "editor::FoldRecursive",
"cmd-k cmd-]": "editor::UnfoldRecursive",
"cmd-k cmd-1": ["editor::FoldAtLevel", { "level": 1 }],
"cmd-k cmd-2": ["editor::FoldAtLevel", { "level": 2 }],
"cmd-k cmd-3": ["editor::FoldAtLevel", { "level": 3 }],
"cmd-k cmd-4": ["editor::FoldAtLevel", { "level": 4 }],
"cmd-k cmd-5": ["editor::FoldAtLevel", { "level": 5 }],
"cmd-k cmd-6": ["editor::FoldAtLevel", { "level": 6 }],
"cmd-k cmd-7": ["editor::FoldAtLevel", { "level": 7 }],
"cmd-k cmd-8": ["editor::FoldAtLevel", { "level": 8 }],
"cmd-k cmd-9": ["editor::FoldAtLevel", { "level": 9 }],
"cmd-k cmd-0": "editor::FoldAll",
"cmd-k cmd-j": "editor::UnfoldAll",
"ctrl-space": "editor::ShowCompletions",
Expand Down
5 changes: 5 additions & 0 deletions crates/editor/src/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ pub struct DeleteToPreviousWordStart {
pub ignore_newlines: bool,
}

#[derive(PartialEq, Clone, Deserialize, Default)]
pub struct FoldAtLevel {
pub level: u32,
}
impl_actions!(
editor,
[
Expand Down Expand Up @@ -182,6 +186,7 @@ impl_actions!(
ToggleCodeActions,
ToggleComments,
UnfoldAt,
FoldAtLevel
]
);

Expand Down
41 changes: 35 additions & 6 deletions crates/editor/src/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10728,15 +10728,44 @@ impl Editor {
self.fold_ranges(fold_ranges, true, cx);
}

fn fold_at_level(&mut self, fold_at: &FoldAtLevel, cx: &mut ViewContext<Self>) {
let fold_at_level = fold_at.level;
let snapshot = self.buffer.read(cx).snapshot(cx);
let mut fold_ranges = Vec::new();
let mut stack = vec![(0, snapshot.max_buffer_row().0, 1)];

while let Some((mut start_row, end_row, current_level)) = stack.pop() {
while start_row < end_row {
match self.snapshot(cx).foldable_range(MultiBufferRow(start_row)) {
Some(foldable_range) => {
let nested_start_row = foldable_range.0.start.row + 1;
let nested_end_row = foldable_range.0.end.row;

if current_level == fold_at_level {
fold_ranges.push(foldable_range);
}

if current_level <= fold_at_level {
stack.push((nested_start_row, nested_end_row, current_level + 1));
}

start_row = nested_end_row + 1;
}
None => start_row += 1,
}
}
}

self.fold_ranges(fold_ranges, true, cx);
}

pub fn fold_all(&mut self, _: &actions::FoldAll, cx: &mut ViewContext<Self>) {
let mut fold_ranges = Vec::new();
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
let snapshot = self.buffer.read(cx).snapshot(cx);

for row in 0..display_map.max_buffer_row().0 {
if let Some((foldable_range, fold_text)) =
display_map.foldable_range(MultiBufferRow(row))
{
fold_ranges.push((foldable_range, fold_text));
for row in 0..snapshot.max_buffer_row().0 {
if let Some(foldable_range) = self.snapshot(cx).foldable_range(MultiBufferRow(row)) {
fold_ranges.push(foldable_range);
}
}

Expand Down
1 change: 1 addition & 0 deletions crates/editor/src/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ impl EditorElement {
register_action(view, cx, Editor::open_url);
register_action(view, cx, Editor::open_file);
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_at);
register_action(view, cx, Editor::fold_recursive);
Expand Down

0 comments on commit 507929c

Please sign in to comment.