commands: Implement expand_selection.

This commit is contained in:
Blaž Hrastnik 2021-02-22 15:50:41 +09:00
parent 33c67f1388
commit 6cfb1acb9d
4 changed files with 48 additions and 1 deletions

View File

@ -5,6 +5,7 @@
mod history;
pub mod indent;
pub mod macros;
pub mod object;
mod position;
pub mod register;
pub mod selection;

32
helix-core/src/object.rs Normal file
View File

@ -0,0 +1,32 @@
use crate::{Range, RopeSlice, Selection, Syntax};
use smallvec::smallvec;
// TODO: to contract_selection we'd need to store the previous ranges before expand.
// Maybe just contract to the first child node?
pub fn expand_selection(syntax: &Syntax, text: RopeSlice, selection: &Selection) -> Selection {
let tree = syntax.root_layer.tree.as_ref().unwrap();
selection.transform(|range| {
let from = text.char_to_byte(range.from());
let to = text.char_to_byte(range.to());
// find parent of a descendant that matches the range
let parent = match tree
.root_node()
.descendant_for_byte_range(from, to)
.and_then(|node| node.parent())
{
Some(parent) => parent,
None => return range,
};
let from = text.byte_to_char(parent.start_byte());
let to = text.byte_to_char(parent.end_byte());
if range.head < range.anchor {
Range::new(to, from)
} else {
Range::new(from, to)
}
})
}

View File

@ -1,6 +1,7 @@
use helix_core::{
comment, graphemes,
indent::TAB_WIDTH,
object,
regex::{self, Regex},
register, selection,
state::{Direction, Granularity, State},
@ -1023,3 +1024,15 @@ pub fn toggle_comments(cx: &mut Context) {
doc.apply(&transaction);
}
// tree sitter node selection
pub fn expand_selection(cx: &mut Context) {
let doc = cx.doc();
if let Some(syntax) = &doc.syntax {
let text = doc.text().slice(..);
let selection = object::expand_selection(syntax, text, doc.selection());
doc.set_selection(selection);
}
}

View File

@ -164,10 +164,11 @@ pub fn default() -> Keymaps {
vec![alt!('s')] => commands::split_selection_on_newline,
vec![shift!('S')] => commands::split_selection,
vec![key!(';')] => commands::collapse_selection,
// TODO should be alt(;)
vec![alt!(';')] => commands::flip_selections,
vec![key!('%')] => commands::select_all,
vec![key!('x')] => commands::select_line,
// TODO: figure out what key to use
vec![key!('[')] => commands::expand_selection,
vec![key!('/')] => commands::search,
vec![key!('n')] => commands::search_next,
vec![key!('*')] => commands::search_selection,