mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-22 17:36:19 +04:00
parent
5a344a3ae5
commit
c17dcb8633
@ -45,7 +45,10 @@ pub fn move_vertically(
|
||||
|
||||
let new_line = match dir {
|
||||
Direction::Backward => row.saturating_sub(count),
|
||||
Direction::Forward => std::cmp::min(row.saturating_add(count), text.len_lines() - 2),
|
||||
Direction::Forward => std::cmp::min(
|
||||
row.saturating_add(count),
|
||||
text.len_lines().saturating_sub(2),
|
||||
),
|
||||
};
|
||||
|
||||
// convert to 0-indexed, subtract another 1 because len_chars() counts \n
|
||||
|
@ -383,7 +383,7 @@ pub fn split_on_matches(
|
||||
// TODO: retain range direction
|
||||
|
||||
let end = text.byte_to_char(start_byte + mat.start());
|
||||
result.push(Range::new(start, end - 1));
|
||||
result.push(Range::new(start, end.saturating_sub(1)));
|
||||
start = text.byte_to_char(start_byte + mat.end());
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,8 @@ fn insert(&mut self, fragment: Tendril) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.len_after += fragment.len();
|
||||
// Avoiding std::str::len() to account for UTF-8 characters.
|
||||
self.len_after += fragment.chars().count();
|
||||
|
||||
let new_last = match self.changes.as_mut_slice() {
|
||||
[.., Insert(prev)] | [.., Insert(prev), Delete(_)] => {
|
||||
@ -754,4 +755,21 @@ fn combine_with_empty() {
|
||||
use Operation::*;
|
||||
assert_eq!(changes.changes, &[Insert("a".into())]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn combine_with_utf8() {
|
||||
const TEST_CASE: &'static str = "Hello, これはヒレクスエディターです!";
|
||||
|
||||
let empty = Rope::from("");
|
||||
let mut a = ChangeSet::new(&empty);
|
||||
|
||||
let mut b = ChangeSet::new(&empty);
|
||||
b.insert(TEST_CASE.into());
|
||||
|
||||
let changes = a.compose(b);
|
||||
|
||||
use Operation::*;
|
||||
assert_eq!(changes.changes, &[Insert(TEST_CASE.into())]);
|
||||
assert_eq!(changes.len_after, TEST_CASE.chars().count());
|
||||
}
|
||||
}
|
||||
|
@ -669,7 +669,7 @@ fn _search(doc: &mut Document, view: &mut View, contents: &str, regex: &Regex, e
|
||||
return;
|
||||
}
|
||||
|
||||
let head = end - 1;
|
||||
let head = end;
|
||||
|
||||
let selection = if extend {
|
||||
selection.clone().push(Range::new(start, head))
|
||||
@ -749,7 +749,9 @@ pub fn select_line(cx: &mut Context) {
|
||||
|
||||
let line = text.char_to_line(pos.head);
|
||||
let start = text.line_to_char(line);
|
||||
let end = text.line_to_char(line + count).saturating_sub(1);
|
||||
let end = text
|
||||
.line_to_char(std::cmp::min(doc.text().len_lines(), line + count))
|
||||
.saturating_sub(1);
|
||||
|
||||
doc.set_selection(view.id, Selection::single(start, end));
|
||||
}
|
||||
|
@ -341,7 +341,7 @@ pub fn render_buffer(
|
||||
let info: Style = theme.get("info");
|
||||
let hint: Style = theme.get("hint");
|
||||
|
||||
for (i, line) in (view.first_line..last_line).enumerate() {
|
||||
for (i, line) in (view.first_line..=last_line).enumerate() {
|
||||
use helix_core::diagnostic::Severity;
|
||||
if let Some(diagnostic) = doc.diagnostics.iter().find(|d| d.line == line) {
|
||||
surface.set_stringn(
|
||||
|
@ -114,7 +114,7 @@ pub fn render_prompt(&self, area: Rect, surface: &mut Surface, cx: &mut Context)
|
||||
let selected_color = theme.get("ui.menu.selected");
|
||||
// completion
|
||||
|
||||
let max_col = area.width / BASE_WIDTH;
|
||||
let max_col = std::cmp::max(1, area.width / BASE_WIDTH);
|
||||
let height = ((self.completion.len() as u16 + max_col - 1) / max_col);
|
||||
let completion_area = Rect::new(
|
||||
area.x,
|
||||
|
@ -106,7 +106,7 @@ pub fn ensure_cursor_in_view(&mut self, doc: &Document) {
|
||||
/// Calculates the last visible line on screen
|
||||
#[inline]
|
||||
pub fn last_line(&self, doc: &Document) -> usize {
|
||||
let height = self.area.height.saturating_sub(1); // - 1 for statusline
|
||||
let height = self.area.height.saturating_sub(2); // - 2 for statusline
|
||||
std::cmp::min(
|
||||
self.first_line + height as usize,
|
||||
doc.text().len_lines() - 1,
|
||||
|
Loading…
Reference in New Issue
Block a user