diff --git a/yazi-core/src/highlighter.rs b/yazi-core/src/highlighter.rs
index 99f2bd83..0082e4d9 100644
--- a/yazi-core/src/highlighter.rs
+++ b/yazi-core/src/highlighter.rs
@@ -1,20 +1,20 @@
-use std::{
- io::{BufRead, BufReader, Cursor, Seek},
- path::PathBuf,
- sync::OnceLock,
-};
-
use anyhow::{Result, anyhow, bail};
use ratatui::{
layout::Size,
text::{Line, Span, Text},
};
+use std::{
+ io::{BufRead, BufReader, Cursor, Seek},
+ path::PathBuf,
+ sync::OnceLock,
+};
use syntect::{
LoadingError, dumps,
easy::HighlightLines,
highlighting::{self, Theme, ThemeSet},
parsing::{SyntaxReference, SyntaxSet},
};
+use yazi_binding::elements::HighlightPosition;
use yazi_config::{THEME, YAZI};
use yazi_runner::previewer::PeekError;
use yazi_shared::{Id, Ids, replace_to_printable};
@@ -37,12 +37,17 @@ pub struct Highlighter {
}
impl Highlighter {
- pub async fn oneshot
(path: P, skip: usize, size: Size) -> Result, PeekError>
+ pub async fn oneshot(
+ path: P,
+ skip: usize,
+ size: Size,
+ position: Option,
+ ) -> Result, PeekError>
where
P: Into,
{
let path = path.into();
- tokio::task::spawn_blocking(move || Self::make(path, skip, size)?.highlight()).await?
+ tokio::task::spawn_blocking(move || Self::make(path, skip, size)?.highlight(position)).await?
}
fn make(path: P, skip: usize, size: Size) -> Result
@@ -75,7 +80,7 @@ impl Highlighter {
INCR.next();
}
- fn highlight(mut self) -> Result, PeekError> {
+ fn highlight(mut self, position: Option) -> Result, PeekError> {
self.load_syntax()?;
let mut plain = self.syntax.is_none();
@@ -84,7 +89,6 @@ impl Highlighter {
let mut lines = Vec::with_capacity(self.size.height as usize);
let mut inspected = 0u16;
while self.reader.read_until(b'\n', &mut buf).is_ok_and(|n| n > 0) {
- // tracing::debug!("{:?}", buf);
if Self::is_binary(&buf, &mut inspected) {
Err(anyhow!("Binary file"))?;
}
@@ -95,9 +99,9 @@ impl Highlighter {
}
self.ensure_not_cancelled()?;
- if plain && !self.process_plain(&buf, &mut i, &mut lines)? {
+ if plain && !self.process_plain(&buf, &mut i, &position, &mut lines)? {
break;
- } else if !plain && !self.process_hyper(&buf, &mut i, &mut lines)? {
+ } else if !plain && !self.process_hyper(&buf, &mut i, &position, &mut lines)? {
break;
}
buf.clear();
@@ -110,7 +114,13 @@ impl Highlighter {
Ok(Text::from(lines))
}
- fn process_plain(&mut self, buf: &[u8], i: &mut usize, lines: &mut Vec) -> Result {
+ fn process_plain(
+ &mut self,
+ buf: &[u8],
+ i: &mut usize,
+ position: &Option,
+ lines: &mut Vec,
+ ) -> Result {
let b = replace_to_printable(buf, true, YAZI.preview.tab_size, false);
let s = String::from_utf8_lossy(&b);
@@ -131,11 +141,18 @@ impl Highlighter {
Ok(true)
}
- fn process_hyper(&mut self, buf: &[u8], i: &mut usize, lines: &mut Vec) -> Result {
+ fn process_hyper(
+ &mut self,
+ buf: &[u8],
+ i: &mut usize,
+ position: &Option,
+ lines: &mut Vec,
+ ) -> Result {
let Some(syntax) = self.syntax else { bail!("No syntax") };
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);
diff --git a/yazi-core/src/tab/preview.rs b/yazi-core/src/tab/preview.rs
index d1f9f4fe..ce182153 100644
--- a/yazi-core/src/tab/preview.rs
+++ b/yazi-core/src/tab/preview.rs
@@ -45,8 +45,6 @@ impl Preview {
let job = PeekJob { previewer, file, mime, skip: self.skip, search_idx: self.search_idx };
- tracing::debug!("preview before to peek {:?}", self.search_idx);
-
self.handle = Some(tokio::spawn(async move {
let mut rx = RUNNER.peek(&job).await;
match rx.recv().await.unwrap_or(Err(PeekError::Cancelled)) {
diff --git a/yazi-plugin/preset/plugins/code.lua b/yazi-plugin/preset/plugins/code.lua
index 6ad206ee..d366718e 100644
--- a/yazi-plugin/preset/plugins/code.lua
+++ b/yazi-plugin/preset/plugins/code.lua
@@ -4,7 +4,8 @@ local function get_search_occurrences(url)
if not url.is_search then
return
end
- local occurrences = tostring(url):match("^search://(.-)//")
+ -- Shoud we encode ~ too?
+ local subject_len, occurrences = tostring(url):match("^search://([^~]+)~(.-)//")
local lines = {}
for occurrence in occurrences:gmatch("[^,]+") do
local line, col = occurrence:match("(%d+)-(%d+)")
@@ -15,7 +16,7 @@ local function get_search_occurrences(url)
return
end
- return lines
+ return tonumber(subject_len), lines
end
local function get_next_occurrence_idx(search_idx, direction, occurrences_len)
@@ -37,18 +38,19 @@ local function get_next_occurrence_idx(search_idx, direction, occurrences_len)
end
function M:peek(job)
- local search_occurrences = get_search_occurrences(job.file.url)
+ local subject_len, search_occurrences = get_search_occurrences(job.file.url)
local search_idx = job.search_idx
- ya.dbg("code.lua: search_occurrences:", search_occurrences)
-
local occurrence
if search_occurrences and search_idx then
occurrence = search_occurrences[search_idx]
+ job.position = {
+ line = occurrence[1],
+ col = occurrence[2],
+ length = subject_len,
+ }
end
- ya.dbg("code.lua: Occurrence:", occurrence)
- -- Todo: Pass the occurrence for highlighting
local err, bound = ya.preview_code(job)
if bound then
ya.emit("peek", { bound, only_if = job.file.url, upper_bound = true })
@@ -61,14 +63,13 @@ function M:seek(job)
local direction = job.units > 0 and "down" or "up"
local search_idx = cx.active.preview.search_idx
- ya.dbg("search index before to set it in seek", search_idx)
local h = cx.active.current.hovered
if not h or h.url ~= job.file.url then
return
end
- local search_occurrences = get_search_occurrences(job.file.url)
+ local _, search_occurrences = get_search_occurrences(job.file.url)
if search_occurrences then
local next_occurrence_idx = get_next_occurrence_idx(search_idx, direction, #search_occurrences)
local occurrence = search_occurrences[next_occurrence_idx]
diff --git a/yazi-plugin/src/utils/preview.rs b/yazi-plugin/src/utils/preview.rs
index 4cf50b2c..70a9ae19 100644
--- a/yazi-plugin/src/utils/preview.rs
+++ b/yazi-plugin/src/utils/preview.rs
@@ -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;
+use yazi_shared::url::{AsUrl, UrlLike};
use super::Utils;
@@ -20,16 +20,10 @@ impl Utils {
let area: Area = t.raw_get("area")?;
let position: Option = t.raw_get("position").ok();
- tracing::debug!("{:?}", position);
-
let mut lock = PreviewLock::try_from(t)?;
let path = lock.url.as_url().unified_path();
- let search_subject = lock.url.as_url().scheme().domain();
-
- tracing::debug!("search subject{:?}", search_subject);
-
- let inner = match Highlighter::oneshot(path, lock.skip, area.size()).await {
+ let inner = match Highlighter::oneshot(path, lock.skip, area.size(), position).await {
Ok(text) => {
// tracing::debug!("{:?}", text);
text