mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-22 09:26:19 +04:00
commands: Add goto first non-whitespace char of line
This commit is contained in:
parent
b873fb9897
commit
48df05b16d
@ -133,6 +133,7 @@ ## Goto mode
|
||||
| e | Go to the end of the file |
|
||||
| h | Go to the start of the line |
|
||||
| l | Go to the end of the line |
|
||||
| s | Go to first non-whitespace character of the line |
|
||||
| t | Go to the top of the screen |
|
||||
| m | Go to the middle of the screen |
|
||||
| b | Go to the bottom of the screen |
|
||||
|
@ -18,16 +18,8 @@
|
||||
mod transaction;
|
||||
pub mod words;
|
||||
|
||||
pub(crate) fn find_first_non_whitespace_char2(line: RopeSlice) -> Option<usize> {
|
||||
// find first non-whitespace char
|
||||
for (start, ch) in line.chars().enumerate() {
|
||||
// TODO: could use memchr with chunks?
|
||||
if ch != ' ' && ch != '\t' && ch != '\n' {
|
||||
return Some(start);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
pub fn find_first_non_whitespace_char2(line: RopeSlice) -> Option<usize> {
|
||||
line.chars().position(|ch| !ch.is_whitespace())
|
||||
}
|
||||
pub(crate) fn find_first_non_whitespace_char(text: RopeSlice, line_num: usize) -> Option<usize> {
|
||||
let line = text.line(line_num);
|
||||
|
@ -1,5 +1,6 @@
|
||||
use helix_core::{
|
||||
comment, coords_at_pos, find_root, graphemes, indent, match_brackets,
|
||||
comment, coords_at_pos, find_first_non_whitespace_char2, find_root, graphemes, indent,
|
||||
match_brackets,
|
||||
movement::{self, Direction},
|
||||
object, pos_at_coords,
|
||||
regex::{self, Regex},
|
||||
@ -216,6 +217,24 @@ pub fn move_line_start(cx: &mut Context) {
|
||||
doc.set_selection(view.id, selection);
|
||||
}
|
||||
|
||||
pub fn move_first_nonwhitespace(cx: &mut Context) {
|
||||
let (view, doc) = cx.current();
|
||||
|
||||
let selection = doc.selection(view.id).transform(|range| {
|
||||
let text = doc.text();
|
||||
let line_idx = text.char_to_line(range.head);
|
||||
|
||||
if let Some(pos) = find_first_non_whitespace_char2(text.line(line_idx)) {
|
||||
let pos = pos + text.line_to_char(line_idx);
|
||||
Range::new(pos, pos)
|
||||
} else {
|
||||
range
|
||||
}
|
||||
});
|
||||
|
||||
doc.set_selection(view.id, selection);
|
||||
}
|
||||
|
||||
// TODO: move vs extend could take an extra type Extend/Move that would
|
||||
// Range::new(if Move { pos } if Extend { range.anchor }, pos)
|
||||
// since these all really do the same thing
|
||||
@ -421,6 +440,24 @@ pub fn extend_prev_char(cx: &mut Context) {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn extend_first_nonwhitespace(cx: &mut Context) {
|
||||
let (view, doc) = cx.current();
|
||||
|
||||
let selection = doc.selection(view.id).transform(|range| {
|
||||
let text = doc.text();
|
||||
let line_idx = text.char_to_line(range.head);
|
||||
|
||||
if let Some(pos) = find_first_non_whitespace_char2(text.line(line_idx)) {
|
||||
let pos = pos + text.line_to_char(line_idx);
|
||||
Range::new(range.anchor, pos)
|
||||
} else {
|
||||
range
|
||||
}
|
||||
});
|
||||
|
||||
doc.set_selection(view.id, selection);
|
||||
}
|
||||
|
||||
pub fn replace(cx: &mut Context) {
|
||||
// need to wait for next key
|
||||
cx.on_next_key(move |cx, event| {
|
||||
@ -1288,6 +1325,8 @@ pub fn goto_mode(cx: &mut Context) {
|
||||
(_, 'y') => goto_type_definition(cx),
|
||||
(_, 'r') => goto_reference(cx),
|
||||
(_, 'i') => goto_implementation(cx),
|
||||
(Mode::Normal, 's') => move_first_nonwhitespace(cx),
|
||||
(Mode::Select, 's') => extend_first_nonwhitespace(cx),
|
||||
|
||||
(_, 't') | (_, 'm') | (_, 'b') => {
|
||||
let (view, doc) = cx.current();
|
||||
|
Loading…
Reference in New Issue
Block a user