diff --git a/assets/keymaps/vim.json b/assets/keymaps/vim.json index 8b2a728df3..3d6648a79a 100644 --- a/assets/keymaps/vim.json +++ b/assets/keymaps/vim.json @@ -404,7 +404,8 @@ "shift-b": "vim::CurlyBrackets", "<": "vim::AngleBrackets", ">": "vim::AngleBrackets", - "a": "vim::Argument" + "a": "vim::Argument", + "f": "vim::OutlineObject" } }, { diff --git a/crates/languages/src/rust/outline.scm b/crates/languages/src/rust/outline.scm index 3012995e2a..f0f631c2d2 100644 --- a/crates/languages/src/rust/outline.scm +++ b/crates/languages/src/rust/outline.scm @@ -31,7 +31,8 @@ (visibility_modifier)? @context (function_modifiers)? @context "fn" @context - name: (_) @name) @item + name: (_) @name + body: (_ "{" @open (_)* "}" @close)) @item (function_signature_item (visibility_modifier)? @context diff --git a/crates/vim/src/object.rs b/crates/vim/src/object.rs index 9f8e8366a7..d75406020b 100644 --- a/crates/vim/src/object.rs +++ b/crates/vim/src/object.rs @@ -4,7 +4,7 @@ use crate::{motion::right, state::Mode, Vim}; use editor::{ display_map::{DisplaySnapshot, ToDisplayPoint}, movement::{self, FindRange}, - Bias, DisplayPoint, Editor, + Bias, DisplayPoint, Editor, ToOffset, }; use itertools::Itertools; @@ -29,6 +29,7 @@ pub enum Object { AngleBrackets, Argument, Tag, + OutlineObject, } #[derive(Clone, Deserialize, PartialEq)] @@ -54,7 +55,8 @@ actions!( CurlyBrackets, AngleBrackets, Argument, - Tag + Tag, + OutlineObject ] ); @@ -100,6 +102,9 @@ pub fn register(editor: &mut Editor, cx: &mut ViewContext) { Vim::action(editor, cx, |vim, _: &Argument, cx| { vim.object(Object::Argument, cx) }); + Vim::action(editor, cx, |vim, _: &OutlineObject, cx| { + vim.object(Object::OutlineObject, cx) + }); } impl Vim { @@ -129,7 +134,8 @@ impl Object { | Object::AngleBrackets | Object::CurlyBrackets | Object::SquareBrackets - | Object::Argument => true, + | Object::Argument + | Object::OutlineObject => true, } } @@ -144,7 +150,8 @@ impl Object { | Object::SquareBrackets | Object::Tag | Object::CurlyBrackets - | Object::AngleBrackets => true, + | Object::AngleBrackets + | Object::OutlineObject => true, } } @@ -167,7 +174,8 @@ impl Object { | Object::AngleBrackets | Object::VerticalBars | Object::Tag - | Object::Argument => Mode::Visual, + | Object::Argument + | Object::OutlineObject => Mode::Visual, Object::Paragraph => Mode::VisualLine, } } @@ -215,6 +223,7 @@ impl Object { surrounding_markers(map, relative_to, around, self.is_multiline(), '<', '>') } Object::Argument => argument(map, relative_to, around), + Object::OutlineObject => outline_object(map, selection.start, selection.end, around), } } @@ -564,6 +573,32 @@ fn argument( } } +fn outline_object( + map: &DisplaySnapshot, + start: DisplayPoint, + end: DisplayPoint, + around: bool, +) -> Option> { + println!("outline object!!!!"); + let start_offset = start.to_offset(&map, Bias::Left); + let end_offset = end.to_offset(&map, Bias::Left); + let (_buffer_id, symbols) = map.buffer_snapshot.symbols_containing(start_offset, None)?; + for symbol in symbols.iter().rev() { + let range = if around { + &symbol.range + } else { + dbg!(symbol.body_range.as_ref()).unwrap_or(&symbol.range) + }; + let start = range.start.to_offset(&map.buffer_snapshot); + let end = range.end.to_offset(&map.buffer_snapshot); + if start < start_offset && end > end_offset { + return Some(start.to_display_point(&map)..end.to_display_point(&map)); + } + } + dbg!("none"); + return None; +} + fn sentence( map: &DisplaySnapshot, relative_to: DisplayPoint,