Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The Great Line Ending & Cursor Range Cleanup #376

Merged
Merged
Show file tree
Hide file tree
Changes from 49 commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
c1b0a71
Change the `Range` type and associated functions to gap indexing.
cessen Jun 25, 2021
d070747
Add `Range` methods for various kinds of validation.
cessen Jun 26, 2021
77a266e
Better validation method APIs for `Range`.
cessen Jun 28, 2021
0ae522f
Clean up `Selection` to not use so many allocations.
cessen Jun 28, 2021
7c7be6d
Make `Selection`'s normalize and transform methods self-consuming only.
cessen Jun 30, 2021
e725957
Ensure a minimum selection width on commands that need it.
cessen Jul 1, 2021
2224a15
Merge branch 'master' into great_line_ending_and_cursor_range_cleanup
cessen Jul 2, 2021
230248b
Fix a couple additional `unused` warnings after merge.
cessen Jul 2, 2021
22dca3b
Allow last line in file to lack a line break character.
cessen Jul 2, 2021
7961a13
Make new documents empty, rather than starting with a line ending.
cessen Jul 2, 2021
28627f9
Fix empty document test.
cessen Jul 2, 2021
28d2d68
Make horizontal selection movement work properly.
cessen Jul 2, 2021
6e15c9b
Make vertical selection movement work properly.
cessen Jul 6, 2021
85d5b39
Merge branch 'master' into great_line_ending_and_cursor_range_cleanup
cessen Jul 6, 2021
753f7f3
Implement `Range::put()` which manages range movements and extensions.
cessen Jul 8, 2021
b4c59b4
Update surround commands to work with gap indexing.
cessen Jul 8, 2021
a77274e
Merge branch 'master' into great_line_ending_and_cursor_range_cleanup
cessen Jul 17, 2021
954314a
Update change-case commands to work with gap indexing.
cessen Jul 17, 2021
c2fd55e
Update extend_line command to work with gap indexing.
cessen Jul 17, 2021
6c038bb
Update word selection/navigation to work with gap indexing.
cessen Jul 19, 2021
e462f32
Merge branch 'master' into great_line_ending_and_cursor_range_cleanup
cessen Jul 19, 2021
1a9ae72
Fix last line number being drawn in the status bar.
cessen Jul 19, 2021
079d4ed
Properly fix `last_line` view calculation.
cessen Jul 19, 2021
b0311f4
Fixed primary cursor position calculation to use 1-width semantics.
cessen Jul 19, 2021
e98d669
Handle edge case in `range_to_target()` correctly.
cessen Jul 19, 2021
13b0784
Fix extend line behavior.
cessen Jul 20, 2021
c400a60
Fix `Selection::push()` to make the pushed range primary.
cessen Jul 20, 2021
1792dc6
Make search work a little nicer when there are already selections.
cessen Jul 20, 2021
1910fa7
Fix incorrect line hihglight when a selection is at the end of a line.
cessen Jul 20, 2021
e8a3980
Fix line-wise `p` pasting before the current line instead of after.
cessen Jul 20, 2021
1c6b558
Fix various bugs related to goto-end-of-line command.
cessen Jul 20, 2021
c9300ec
Fix comment toggle command also sometimes toggling the next line.
cessen Jul 20, 2021
1194fc8
Use new `Range::line_range()` method in more places, as appropriate.
cessen Jul 20, 2021
d5534a6
Merge branch 'master' into great_line_ending_and_cursor_range_cleanup
cessen Jul 20, 2021
c848ed7
Fixes for misc bugs with view movement.
cessen Jul 21, 2021
198fe40
Don't insert a final line ending on file load/reload.
cessen Jul 21, 2021
bc85c85
Fix selections not being modified quite correctly with text edits.
cessen Jul 21, 2021
063aa94
Fix yank not working with internally zero-width ranges.
cessen Jul 21, 2021
7d07704
Fix append mode not editing correctly.
cessen Jul 21, 2021
673338b
Use `Range::line_range()` in some more places I missed.
cessen Jul 22, 2021
5841954
Calculate the line that the range head is on correctly.
cessen Jul 22, 2021
fd684ef
Revert display-width-based vertical cursor movement.
cessen Jul 22, 2021
ffb8057
Fix ocassional panic when matching brackets.
cessen Jul 23, 2021
ad814b8
Fix append mode, and make insertion always happen at head of range.
cessen Jul 23, 2021
427ae6a
Put selection in separate variable in commands code.
cessen Jul 24, 2021
4359404
Merge branch 'master' into great_line_ending_and_cursor_range_cleanup
cessen Jul 24, 2021
8f43dc4
Fix surround replace command replacing the wrong position on the right.
cessen Jul 24, 2021
2072349
Fixed find_till_char and find_char commands.
cessen Jul 24, 2021
f96b8b7
Switch to a cleaner range-head moving abstraction.
cessen Jul 24, 2021
0883b4f
Collect some common patterns into methods on `Range`.
cessen Jul 26, 2021
01247ac
Start searches at the right side of the block cursor.
cessen Jul 26, 2021
5ee6ba5
Address some PR comments.
cessen Jul 26, 2021
f62ec6e
Merge branch 'master' into great_line_ending_and_cursor_range_cleanup
cessen Jul 26, 2021
b2c76dc
Improve `Range` documentation and organization.
cessen Jul 27, 2021
5229c53
Add unit tests for some of the new `Range` methods.
cessen Jul 27, 2021
84f8167
Use `match` for branching on the `Direction` enum in more places.
cessen Jul 27, 2021
aead4e6
Minor cleanup of the vertical movement code.
cessen Jul 27, 2021
a873e71
Merge branch 'master' into great_line_ending_and_cursor_range_cleanup
cessen Jul 28, 2021
cd7302f
Enforce cursor/selection invariants in one place.
cessen Jul 28, 2021
285aba2
Fix bug with `/` searching after non-ascii characters.
cessen Jul 28, 2021
e4d41d0
Fix typo in comment.
cessen Jul 29, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions helix-core/src/comment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ pub fn toggle_line_comments(doc: &Rope, selection: &Selection, token: Option<&st
let comment = Tendril::from(format!("{} ", token));

for selection in selection {
let start = text.char_to_line(selection.from());
let end = text.char_to_line(selection.to());
let (start, end) = selection.line_range(text);
let lines = start..end + 1;
let (commented, skipped, min) = find_line_comment(&token, text, lines.clone());

Expand Down
23 changes: 21 additions & 2 deletions helix-core/src/graphemes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ pub fn nth_prev_grapheme_boundary(slice: RopeSlice, char_idx: usize, n: usize) -
}

/// Finds the previous grapheme boundary before the given char position.
#[must_use]
#[inline(always)]
pub fn prev_grapheme_boundary(slice: RopeSlice, char_idx: usize) -> usize {
nth_prev_grapheme_boundary(slice, char_idx, 1)
}
Expand Down Expand Up @@ -117,21 +119,38 @@ pub fn nth_next_grapheme_boundary(slice: RopeSlice, char_idx: usize, n: usize) -
}

/// Finds the next grapheme boundary after the given char position.
#[must_use]
#[inline(always)]
pub fn next_grapheme_boundary(slice: RopeSlice, char_idx: usize) -> usize {
nth_next_grapheme_boundary(slice, char_idx, 1)
}

/// Returns the passed char index if it's already a grapheme boundary,
/// or the next grapheme boundary char index if not.
pub fn ensure_grapheme_boundary(slice: RopeSlice, char_idx: usize) -> usize {
#[must_use]
#[inline]
pub fn ensure_grapheme_boundary_next(slice: RopeSlice, char_idx: usize) -> usize {
if char_idx == 0 {
0
char_idx
} else {
next_grapheme_boundary(slice, char_idx - 1)
}
}

/// Returns the passed char index if it's already a grapheme boundary,
/// or the prev grapheme boundary char index if not.
#[must_use]
#[inline]
pub fn ensure_grapheme_boundary_prev(slice: RopeSlice, char_idx: usize) -> usize {
if char_idx == slice.len_chars() {
char_idx
} else {
prev_grapheme_boundary(slice, char_idx + 1)
}
}

/// Returns whether the given char position is a grapheme boundary.
#[must_use]
pub fn is_grapheme_boundary(slice: RopeSlice, char_idx: usize) -> bool {
// Bounds check
debug_assert!(char_idx <= slice.len_chars());
Expand Down
7 changes: 7 additions & 0 deletions helix-core/src/line_ending.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,13 @@ pub fn line_end_char_index(slice: &RopeSlice, line: usize) -> usize {
.unwrap_or(0)
}

/// Fetches line `line_idx` from the passed rope slice, sans any line ending.
pub fn line_without_line_ending<'a>(slice: &'a RopeSlice, line_idx: usize) -> RopeSlice<'a> {
let start = slice.line_to_char(line_idx);
let end = line_end_char_index(slice, line_idx);
slice.slice(start..end)
}

/// Returns the char index of the end of the given RopeSlice, not including
/// any final line ending.
pub fn rope_end_without_line_ending(slice: &RopeSlice) -> usize {
Expand Down
7 changes: 4 additions & 3 deletions helix-core/src/match_brackets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ pub fn find(syntax: &Syntax, doc: &Rope, pos: usize) -> Option<usize> {
return None;
}

let start_byte = node.start_byte();
let len = doc.len_bytes();
if start_byte >= len {
let start_byte = node.start_byte();
let end_byte = node.end_byte() - 1; // it's end exclusive
if start_byte >= len || end_byte >= len {
return None;
}
let end_byte = node.end_byte() - 1; // it's end exclusive

let start_char = doc.byte_to_char(start_byte);
let end_char = doc.byte_to_char(end_byte);

Expand Down
Loading