Skip to content

Commit cd734ee

Browse files
word wrapping feature refactor
1 parent 0cff3ce commit cd734ee

File tree

1 file changed

+64
-40
lines changed

1 file changed

+64
-40
lines changed

yazi-plugin/src/external/highlighter.rs

Lines changed: 64 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ impl Highlighter {
7676
}
7777

7878
if plain {
79+
if !wrap {
80+
let indent = " ".repeat(PREVIEW.tab_size as usize);
81+
return Ok(Text::from(after.join("").replace('\t', &indent)));
82+
}
7983
Ok(Text::from(after.join("")))
8084
} else {
8185
Self::highlight_with(before, after, syntax.unwrap()).await
@@ -105,39 +109,33 @@ impl Highlighter {
105109
buf.clear()
106110
}
107111

108-
let mut i = 0;
112+
let mut lines_handled = 0;
109113
for mut long_line in long_lines {
110-
if long_line.is_empty() || i > skip + area.height as usize {
114+
if long_line.is_empty() || lines_handled > skip + area.height as usize {
111115
break;
112116
}
113117
Self::replace_tabs_with_spaces(&mut long_line, PREVIEW.tab_size as usize);
114118
for line in Self::chunk_by_width(long_line, area.width as usize) {
115119
let mut line = line.to_vec();
116-
i += 1;
117-
if line.is_empty() || i > skip + area.height as usize {
120+
lines_handled += 1;
121+
let must_break = Self::handle_single_line(
122+
lines_handled,
123+
skip,
124+
*plain,
125+
area.height as usize,
126+
&mut line,
127+
&mut before,
128+
&mut after,
129+
);
130+
if must_break {
118131
break;
119132
}
120-
121-
if line.ends_with(b"\r\n") {
122-
line.pop();
123-
line.pop();
124-
line.push(b'\n');
125-
} else if !line.ends_with(b"\n") {
126-
line.push(b'\n')
127-
}
128-
129-
let text = String::from_utf8_lossy(&line).into_owned();
130-
if i > skip {
131-
after.push(text);
132-
} else if !*plain {
133-
before.push(text);
134-
}
135133
}
136134
}
137135

138-
let no_more_scroll = i < skip + area.height as usize;
136+
let no_more_scroll = lines_handled < skip + area.height as usize;
139137
if skip > 0 && no_more_scroll {
140-
return Err(PeekError::Exceed(i.saturating_sub(area.height as usize)));
138+
return Err(PeekError::Exceed(lines_handled.saturating_sub(area.height as usize)));
141139
}
142140

143141
Ok((before, after))
@@ -152,41 +150,67 @@ impl Highlighter {
152150
let mut before = Vec::with_capacity(if *plain { 0 } else { skip });
153151
let mut after = Vec::with_capacity(area.height as usize);
154152

155-
let mut i = 0;
153+
let mut lines_handled = 0;
156154
let mut buf = vec![];
157155
while reader.read_until(b'\n', &mut buf).await.is_ok() {
158-
i += 1;
159-
if buf.is_empty() || i > skip + area.height as usize {
160-
break;
161-
}
162-
156+
lines_handled += 1;
163157
if !*plain && buf.len() > 6000 {
164158
*plain = true;
165159
drop(mem::take(&mut before));
166160
}
167-
168-
if buf.ends_with(b"\r\n") {
169-
buf.pop();
170-
buf.pop();
171-
buf.push(b'\n');
172-
}
173-
174-
if i > skip {
175-
after.push(String::from_utf8_lossy(&buf).into_owned());
176-
} else if !*plain {
177-
before.push(String::from_utf8_lossy(&buf).into_owned());
161+
let must_break = Self::handle_single_line(
162+
lines_handled,
163+
skip,
164+
*plain,
165+
area.height as usize,
166+
&mut buf,
167+
&mut before,
168+
&mut after,
169+
);
170+
if must_break {
171+
break;
178172
}
179173
buf.clear();
180174
}
181175

182-
let no_more_scroll = i < skip + area.height as usize;
176+
let no_more_scroll = lines_handled < skip + area.height as usize;
183177
if skip > 0 && no_more_scroll {
184-
return Err(PeekError::Exceed(i.saturating_sub(area.height as usize)));
178+
return Err(PeekError::Exceed(lines_handled.saturating_sub(area.height as usize)));
185179
}
186180

187181
Ok((before, after))
188182
}
189183

184+
fn handle_single_line(
185+
lines_handled: usize,
186+
skip: usize,
187+
plain: bool,
188+
limit: usize,
189+
line: &mut Vec<u8>,
190+
before: &mut Vec<String>,
191+
after: &mut Vec<String>,
192+
) -> bool {
193+
if line.is_empty() || lines_handled > skip + limit {
194+
return true;
195+
}
196+
197+
if line.ends_with(b"\r\n") {
198+
line.pop();
199+
line.pop();
200+
line.push(b'\n');
201+
} else if !line.ends_with(b"\n") {
202+
line.push(b'\n')
203+
}
204+
205+
let text = String::from_utf8_lossy(&line).into_owned();
206+
if lines_handled > skip {
207+
after.push(text);
208+
} else if !plain {
209+
before.push(text);
210+
}
211+
false
212+
}
213+
190214
fn chunk_by_width(line: Vec<u8>, width: usize) -> Vec<Vec<u8>> {
191215
let mut res = vec![];
192216
let mut buf = vec![];

0 commit comments

Comments
 (0)