mirror of
https://github.com/helix-editor/helix.git
synced 2025-04-06 20:37:44 +03:00
Optimize rendering by using Ropey::byte_slice
This avoids costly conversions via byte_to_char (which are then reversed back into bytes internally in Ropey). Reduces time spent in slice/byte_to_char from ~24% to ~5%.
This commit is contained in:
parent
c6bd105484
commit
59f05088b9
5 changed files with 16 additions and 17 deletions
10
Cargo.lock
generated
10
Cargo.lock
generated
|
@ -862,10 +862,10 @@ checksum = "8c31b5c4033f8fdde8700e4657be2c497e7288f01515be52168c631e2e4d4086"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ropey"
|
name = "ropey"
|
||||||
version = "1.3.2"
|
version = "1.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/cessen/ropey#38531e083f8cf5c5b1aeb328361895fb5a9b867c"
|
||||||
checksum = "e6b9aa65bcd9f308d37c7158b4a1afaaa32b8450213e20c9b98e7d5b3cc2fec3"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"smallvec",
|
"smallvec",
|
||||||
|
"str_indices",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1031,6 +1031,12 @@ version = "1.0.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d44a3643b4ff9caf57abcee9c2c621d6c03d9135e0d8b589bd9afb5992cb176a"
|
checksum = "d44a3643b4ff9caf57abcee9c2c621d6c03d9135e0d8b589bd9afb5992cb176a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "str_indices"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "283baa48c486e4c5e27b4d92c435db9eaceac236a74dab5e3293570e2c3fa4aa"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.88"
|
version = "1.0.88"
|
||||||
|
|
|
@ -15,7 +15,8 @@ include = ["src/**/*", "README.md"]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
helix-loader = { version = "0.6", path = "../helix-loader" }
|
helix-loader = { version = "0.6", path = "../helix-loader" }
|
||||||
|
|
||||||
ropey = "1.3"
|
# ropey = "1.3"
|
||||||
|
ropey = { git = "https://github.com/cessen/ropey" }
|
||||||
smallvec = "1.8"
|
smallvec = "1.8"
|
||||||
smartstring = "1.0.0"
|
smartstring = "1.0.0"
|
||||||
unicode-segmentation = "1.9"
|
unicode-segmentation = "1.9"
|
||||||
|
|
|
@ -333,10 +333,7 @@ impl<'a> Iterator for RopeGraphemes<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if a < self.cur_chunk_start {
|
if a < self.cur_chunk_start {
|
||||||
let a_char = self.text.byte_to_char(a);
|
Some(self.text.byte_slice(a..b))
|
||||||
let b_char = self.text.byte_to_char(b);
|
|
||||||
|
|
||||||
Some(self.text.slice(a_char..b_char))
|
|
||||||
} else {
|
} else {
|
||||||
let a2 = a - self.cur_chunk_start;
|
let a2 = a - self.cur_chunk_start;
|
||||||
let b2 = b - self.cur_chunk_start;
|
let b2 = b - self.cur_chunk_start;
|
||||||
|
|
|
@ -576,9 +576,7 @@ pub struct Syntax {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn byte_range_to_str(range: std::ops::Range<usize>, source: RopeSlice) -> Cow<str> {
|
fn byte_range_to_str(range: std::ops::Range<usize>, source: RopeSlice) -> Cow<str> {
|
||||||
let start_char = source.byte_to_char(range.start);
|
Cow::from(source.byte_slice(range))
|
||||||
let end_char = source.byte_to_char(range.end);
|
|
||||||
Cow::from(source.slice(start_char..end_char))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Syntax {
|
impl Syntax {
|
||||||
|
@ -1197,9 +1195,7 @@ impl<'a> TextProvider<'a> for RopeProvider<'a> {
|
||||||
type I = ChunksBytes<'a>;
|
type I = ChunksBytes<'a>;
|
||||||
|
|
||||||
fn text(&mut self, node: Node) -> Self::I {
|
fn text(&mut self, node: Node) -> Self::I {
|
||||||
let start_char = self.0.byte_to_char(node.start_byte());
|
let fragment = self.0.byte_slice(node.start_byte()..node.end_byte());
|
||||||
let end_char = self.0.byte_to_char(node.end_byte());
|
|
||||||
let fragment = self.0.slice(start_char..end_char);
|
|
||||||
ChunksBytes {
|
ChunksBytes {
|
||||||
chunks: fragment.chunks(),
|
chunks: fragment.chunks(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,6 +183,7 @@ impl EditorView {
|
||||||
.highlight_iter(text.slice(..), Some(range), None)
|
.highlight_iter(text.slice(..), Some(range), None)
|
||||||
.map(|event| event.unwrap())
|
.map(|event| event.unwrap())
|
||||||
.map(move |event| match event {
|
.map(move |event| match event {
|
||||||
|
// TODO: use byte slices directly
|
||||||
// convert byte offsets to char offset
|
// convert byte offsets to char offset
|
||||||
HighlightEvent::Source { start, end } => {
|
HighlightEvent::Source { start, end } => {
|
||||||
let start =
|
let start =
|
||||||
|
@ -317,6 +318,8 @@ impl EditorView {
|
||||||
theme: &Theme,
|
theme: &Theme,
|
||||||
highlights: H,
|
highlights: H,
|
||||||
) {
|
) {
|
||||||
|
// It's slightly more efficient to produce a full RopeSlice from the Rope, then slice that a bunch
|
||||||
|
// of times than it is to always call Rope::slice/get_slice (it will internally always hit RSEnum::Light).
|
||||||
let text = doc.text().slice(..);
|
let text = doc.text().slice(..);
|
||||||
|
|
||||||
let mut spans = Vec::new();
|
let mut spans = Vec::new();
|
||||||
|
@ -327,10 +330,6 @@ impl EditorView {
|
||||||
|
|
||||||
let text_style = theme.get("ui.text");
|
let text_style = theme.get("ui.text");
|
||||||
|
|
||||||
// It's slightly more efficient to produce a full RopeSlice from the Rope, then slice that a bunch
|
|
||||||
// of times than it is to always call Rope::slice/get_slice (it will internally always hit RSEnum::Light).
|
|
||||||
let text = text.slice(..);
|
|
||||||
|
|
||||||
'outer: for event in highlights {
|
'outer: for event in highlights {
|
||||||
match event {
|
match event {
|
||||||
HighlightEvent::HighlightStart(span) => {
|
HighlightEvent::HighlightStart(span) => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue