mirror of
https://github.com/sxyazi/yazi.git
synced 2026-06-28 10:21:53 +00:00
feat: Improve line highlighting for search
This commit is contained in:
parent
a53d404aa4
commit
2bb1c8fb8f
6 changed files with 41 additions and 64 deletions
|
|
@ -61,8 +61,6 @@ impl Highlighter {
|
|||
let path = path.into();
|
||||
let (theme, syntaxes) = CACHE.get_or_init(Self::load);
|
||||
|
||||
// tracing::debug!("{:?}", theme);
|
||||
|
||||
Ok(Self {
|
||||
reader: BufReader::new(std::fs::File::open(&path)?),
|
||||
path,
|
||||
|
|
@ -112,7 +110,6 @@ impl Highlighter {
|
|||
if self.skip > 0 && i < self.skip + self.size.height as usize {
|
||||
return Err(PeekError::Exceeded(i.saturating_sub(self.size.height as _)));
|
||||
}
|
||||
|
||||
Ok(Text::from(lines))
|
||||
}
|
||||
|
||||
|
|
@ -136,7 +133,13 @@ impl Highlighter {
|
|||
if *i > self.skip + self.size.height as usize {
|
||||
return Ok(false);
|
||||
} else if *i > self.skip {
|
||||
lines.push(spans.into_static_line());
|
||||
let mut static_line = spans.into_static_line();
|
||||
if let Some(pos) = position
|
||||
&& pos.line == *i
|
||||
{
|
||||
static_line.style = Style::new().bg(style::Color::Red);
|
||||
}
|
||||
lines.push(static_line);
|
||||
}
|
||||
self.ensure_not_cancelled()?;
|
||||
}
|
||||
|
|
@ -154,7 +157,6 @@ impl Highlighter {
|
|||
let h = self.inner.get_or_insert_with(|| HighlightLines::new(syntax, self.theme));
|
||||
let s = String::from_utf8_lossy(buf);
|
||||
|
||||
// tracing::debug!("s {:?}", s);
|
||||
let line = [Self::to_line_widget(h.highlight_line(&s, self.syntaxes)?)];
|
||||
let mut it = LineIter::parsed(&line, YAZI.preview.tab_size);
|
||||
if let Some(wrap) = YAZI.preview.wrap.into() {
|
||||
|
|
@ -167,16 +169,16 @@ impl Highlighter {
|
|||
return Ok(false);
|
||||
} else if *i > self.skip {
|
||||
let mut static_line = spans.into_static_line();
|
||||
if let Some(pos) = position {
|
||||
if pos.line == *i {
|
||||
tracing::debug!("Position: {:?}, line: {}", pos, i);
|
||||
static_line.style = Style::new().bg(style::Color::Red);
|
||||
}
|
||||
if let Some(pos) = position
|
||||
&& pos.line == *i
|
||||
{
|
||||
static_line.style = Style::new().bg(style::Color::Red);
|
||||
}
|
||||
lines.push(static_line);
|
||||
}
|
||||
self.ensure_not_cancelled()?;
|
||||
}
|
||||
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,11 +43,12 @@ impl MgrProxy {
|
|||
pub fn update_peeked_error(job: PeekJob, error: String) {
|
||||
let area = LAYOUT.get().preview;
|
||||
Self::update_peeked(PreviewLock {
|
||||
url: job.file.url,
|
||||
cha: job.file.cha,
|
||||
url: job.file.url,
|
||||
cha: job.file.cha,
|
||||
mime: job.mime,
|
||||
|
||||
skip: job.skip,
|
||||
search_idx: job.search_idx,
|
||||
area: area.into(),
|
||||
data: vec![
|
||||
Renderable::Clear(yazi_binding::elements::Clear { area: area.into() }),
|
||||
|
|
|
|||
|
|
@ -115,7 +115,8 @@ impl Preview {
|
|||
}
|
||||
|
||||
pub fn same_lock(&self, file: &File, mime: &str) -> bool {
|
||||
self.same_file(file, mime) && matches!(&self.lock, Some(l) if l.skip == self.skip)
|
||||
self.same_file(file, mime)
|
||||
&& matches!(&self.lock, Some(l) if l.skip == self.skip && l.search_idx == self.search_idx)
|
||||
}
|
||||
|
||||
pub fn same_folder(&self, url: &UrlBuf) -> bool {
|
||||
|
|
|
|||
|
|
@ -1,14 +1,18 @@
|
|||
use mlua::Table;
|
||||
use yazi_binding::{FileRef, elements::{Rect, Renderable}};
|
||||
use yazi_binding::{
|
||||
FileRef,
|
||||
elements::{Rect, Renderable},
|
||||
};
|
||||
use yazi_shared::pool::{InternStr, Symbol};
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct PreviewLock {
|
||||
pub url: yazi_shared::url::UrlBuf,
|
||||
pub cha: yazi_fs::cha::Cha,
|
||||
pub url: yazi_shared::url::UrlBuf,
|
||||
pub cha: yazi_fs::cha::Cha,
|
||||
pub mime: Symbol<str>,
|
||||
|
||||
pub skip: usize,
|
||||
pub search_idx: Option<usize>,
|
||||
pub area: Rect,
|
||||
pub data: Vec<Renderable>,
|
||||
}
|
||||
|
|
@ -19,11 +23,12 @@ impl TryFrom<Table> for PreviewLock {
|
|||
fn try_from(t: Table) -> Result<Self, Self::Error> {
|
||||
let file: FileRef = t.raw_get("file")?;
|
||||
Ok(Self {
|
||||
url: file.url_owned(),
|
||||
cha: file.cha,
|
||||
url: file.url_owned(),
|
||||
cha: file.cha,
|
||||
mime: t.raw_get::<mlua::String>("mime")?.to_str()?.intern(),
|
||||
|
||||
skip: t.raw_get("skip")?,
|
||||
search_idx: t.raw_get("search_idx")?,
|
||||
area: t.raw_get("area")?,
|
||||
data: Default::default(),
|
||||
})
|
||||
|
|
|
|||
|
|
@ -41,6 +41,17 @@ function M:peek(job)
|
|||
local subject_len, search_occurrences = get_search_occurrences(job.file.url)
|
||||
local search_idx = job.search_idx
|
||||
|
||||
if search_idx == nil and search_occurrences then
|
||||
local occurrence = search_occurrences[1]
|
||||
local line = occurrence[1]
|
||||
ya.emit("peek", {
|
||||
math.max(0, line - 1),
|
||||
only_if = job.file.url,
|
||||
search_idx = 1,
|
||||
})
|
||||
return
|
||||
end
|
||||
|
||||
local occurrence
|
||||
if search_occurrences and search_idx then
|
||||
occurrence = search_occurrences[search_idx]
|
||||
|
|
@ -53,7 +64,7 @@ function M:peek(job)
|
|||
|
||||
local err, bound = ya.preview_code(job)
|
||||
if bound then
|
||||
ya.emit("peek", { bound, only_if = job.file.url, upper_bound = true })
|
||||
ya.emit("peek", { bound, only_if = job.file.url, upper_bound = true, search_idx = search_idx })
|
||||
elseif err and not err:find("cancelled", 1, true) then
|
||||
require("empty").msg(job, err)
|
||||
end
|
||||
|
|
@ -61,7 +72,6 @@ end
|
|||
|
||||
function M:seek(job)
|
||||
local direction = job.units > 0 and "down" or "up"
|
||||
|
||||
local search_idx = cx.active.preview.search_idx
|
||||
|
||||
local h = cx.active.current.hovered
|
||||
|
|
@ -74,14 +84,11 @@ function M:seek(job)
|
|||
local next_occurrence_idx = get_next_occurrence_idx(search_idx, direction, #search_occurrences)
|
||||
local occurrence = search_occurrences[next_occurrence_idx]
|
||||
local line = occurrence[1]
|
||||
-- local col = occurrence[2]
|
||||
|
||||
ya.emit("peek", { math.max(0, line - 1), only_if = job.file.url, search_idx = next_occurrence_idx })
|
||||
return
|
||||
end
|
||||
|
||||
-- ya.emit("peek", { math.max(0, line - 1), only_if = job.file.url })
|
||||
|
||||
local step = math.floor(job.units * job.area.h / 10)
|
||||
step = step == 0 and ya.clamp(-1, job.units, 1) or step
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use yazi_binding::{
|
|||
use yazi_core::{Highlighter, MgrProxy, tab::PreviewLock};
|
||||
use yazi_fs::FsUrl;
|
||||
use yazi_runner::previewer::PeekError;
|
||||
use yazi_shared::url::{AsUrl, UrlLike};
|
||||
use yazi_shared::url::AsUrl;
|
||||
|
||||
use super::Utils;
|
||||
|
||||
|
|
@ -24,18 +24,13 @@ impl Utils {
|
|||
let path = lock.url.as_url().unified_path();
|
||||
|
||||
let inner = match Highlighter::oneshot(path, lock.skip, area.size(), position).await {
|
||||
Ok(text) => {
|
||||
// tracing::debug!("{:?}", text);
|
||||
text
|
||||
}
|
||||
Ok(text) => text,
|
||||
Err(e @ PeekError::Exceeded(max)) => return (e, max).into_lua_multi(&lua),
|
||||
Err(e) => {
|
||||
return e.into_lua_multi(&lua);
|
||||
}
|
||||
};
|
||||
|
||||
// tracing::debug!("Inner: {inner}");
|
||||
|
||||
lock.data = vec![Renderable::Text(Text { area, inner, ..Default::default() })];
|
||||
|
||||
MgrProxy::update_peeked(lock);
|
||||
|
|
@ -72,37 +67,3 @@ impl Utils {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
// fn apply_highlight(text: &mut Text, column: usize, length: usize) {
|
||||
// use ratatui::text::Span;
|
||||
// if length == 0 {
|
||||
// return;
|
||||
// }
|
||||
// let Some(line) = text.inner.lines.first_mut() else { return };
|
||||
// let mut new_spans = Vec::new();
|
||||
// let mut char_pos = 0usize;
|
||||
// for span in std::mem::take(&mut line.spans) {
|
||||
// let n = span.content.chars().count();
|
||||
// let range = char_pos..char_pos + n;
|
||||
// if range.end <= column || range.start >= column + length || n == 0 {
|
||||
// new_spans.push(span);
|
||||
// } else {
|
||||
// let chars: Vec<char> = span.content.chars().collect();
|
||||
// let hl_start = column.saturating_sub(char_pos).min(n);
|
||||
// let hl_end = (column + length).saturating_sub(char_pos).min(n);
|
||||
// if hl_start > 0 {
|
||||
// new_spans.push(Span { content: chars[..hl_start].iter().collect(), style: span.style });
|
||||
// }
|
||||
// {
|
||||
// let mut hl_style = span.style;
|
||||
// hl_style.bg = hl_style.bg.or(Some(Color::Yellow));
|
||||
// new_spans.push(Span { content: chars[hl_start..hl_end].iter().collect(), style: hl_style });
|
||||
// }
|
||||
// if hl_end < n {
|
||||
// new_spans.push(Span { content: chars[hl_end..].iter().collect(), style: span.style });
|
||||
// }
|
||||
// }
|
||||
// char_pos = range.end;
|
||||
// }
|
||||
// line.spans = new_spans;
|
||||
// }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue