mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-22 23:31:05 +00:00
feat: pass highlight position from code.lua to highlight.rs module
This commit is contained in:
parent
d95d323a89
commit
04501c6aa9
4 changed files with 43 additions and 33 deletions
|
|
@ -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<P>(path: P, skip: usize, size: Size) -> Result<Text<'static>, PeekError>
|
||||
pub async fn oneshot<P>(
|
||||
path: P,
|
||||
skip: usize,
|
||||
size: Size,
|
||||
position: Option<HighlightPosition>,
|
||||
) -> Result<Text<'static>, PeekError>
|
||||
where
|
||||
P: Into<PathBuf>,
|
||||
{
|
||||
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<P>(path: P, skip: usize, size: Size) -> Result<Self>
|
||||
|
|
@ -75,7 +80,7 @@ impl Highlighter {
|
|||
INCR.next();
|
||||
}
|
||||
|
||||
fn highlight(mut self) -> Result<Text<'static>, PeekError> {
|
||||
fn highlight(mut self, position: Option<HighlightPosition>) -> Result<Text<'static>, 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<Line>) -> Result<bool> {
|
||||
fn process_plain(
|
||||
&mut self,
|
||||
buf: &[u8],
|
||||
i: &mut usize,
|
||||
position: &Option<HighlightPosition>,
|
||||
lines: &mut Vec<Line>,
|
||||
) -> Result<bool> {
|
||||
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<Line>) -> Result<bool> {
|
||||
fn process_hyper(
|
||||
&mut self,
|
||||
buf: &[u8],
|
||||
i: &mut usize,
|
||||
position: &Option<HighlightPosition>,
|
||||
lines: &mut Vec<Line>,
|
||||
) -> Result<bool> {
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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)) {
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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<HighlightPosition> = 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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue