Conversation
| if !cx.tab().preview.same_url(&hovered.url) { | ||
| cx.tab_mut().preview.skip = folder.map(|f| f.0).unwrap_or_default(); | ||
| // set matched line on the top of preview window | ||
| cx.tab_mut().preview.skip = folder.map(|f| f.0).unwrap_or_else(|| hovered.url.as_url().line().map_or(0, |l| l.saturating_sub(1))); |
There was a problem hiding this comment.
This should be handled in the seek() method of code.lua: when the URL contains line numbers, the unit for seek() should be 1, meaning it should jump between matching lines, then, peek() should get the N-th line number by skip.
| succ!(); | ||
| } | ||
|
|
||
| fn reveal_search(cx: &mut Ctx, opt: RevealOpt) -> Result<Data> { |
There was a problem hiding this comment.
If we use a search URL to create a File in rg.rs, to_search() ends up zeroing out the URN and URI, which results in the placeholder file issue in the reveal scenario. We’re using search URLs in the first place because regular URLs don't have a domain field.
let Some((fp, l, c)) = parse_rg_line_column(&line) else { continue };
let url = cwd.try_join(fp)
.ok()
.and_then(|u| u.to_search(&format!("{}#{}:{}", subject, l, c)).ok()); // URI set to 0 causing the placeholder file issue
let Some(url) = url else { continue };
if let Ok(file) = File::new(url).await {
tx.send(file).ok();
}| Ok(yazi_config::THEME.icon.matches(me).map(Icon::from)) | ||
| }); | ||
|
|
||
| $methods.add_method("line", |_, me, ()| { |
There was a problem hiding this comment.
This should be handled in the peek() method of code.lua
| Some('d') | Some('D') => self.visit_dirname(it, buf), | ||
| Some('t') | Some('T') => self.visit_tab(it, buf), | ||
| Some('y') | Some('Y') => self.visit_yanked(it, buf), | ||
| Some('l') | Some('L') => self.visit_line_number(it, buf), |
| function Entity:highlights() | ||
| local name, p = self._file.name, ui.printable | ||
|
|
||
| local ok, line = pcall(function() return self._file:line() end) |
There was a problem hiding this comment.
What if the file has multiple lines matched?
There was a problem hiding this comment.
This implementation is designed to achieve a #1095 like rg search experience, where each match in the same file is treated as an individual entry.
So 1 match = 1 "file"
There was a problem hiding this comment.
Why do you want to show the same file as multiple entries? Is there any advantage to this compared to showing it as a single entry?
There was a problem hiding this comment.
Well... It feels natural to me (that's how nvim + telescope handles it as seen in #1095 ). I haven't dug into the project too much yet, but would the line and column information be accessible in the context for opening files in the Openers? And I understand if you think it's bit complex or disruptive to the module design.
There was a problem hiding this comment.
That's possible, but it's better to discuss it in a separate issue on how to attach line numbers to the file path and keep this PR focused on preview matched lines
yazi-plugin/src/utils/preview.rs
Outdated
| let path = lock.url.as_url().unified_path(); | ||
| let inner = match Highlighter::new(path).highlight(lock.skip, area.size()).await { | ||
| Ok(text) => text, | ||
| Err(e @ PeekError::Exceed(max)) => return (e.to_string(), max).into_lua_multi(&lua), |
| #[inline] | ||
| pub fn domain<'s>(s: &'s str) -> PercentEncode<'s> { | ||
| const SET: &AsciiSet = &CONTROLS.add(b'/').add(b':'); | ||
| const SET: &AsciiSet = &CONTROLS.add(b'/').add(b':').add(b'#'); |
There was a problem hiding this comment.
This is not right - SET here is used to encode the entire domain, not just the keyword part in the domain, so .add(b'#') will not work if you intend to use it as the separator between the keyword and the line/col numbers
| pub fn line(self) -> Option<usize> { | ||
| let Self::Search { domain, .. } = self else { return None }; | ||
| let Some(hash_pos) = domain.find('#') else { | ||
| return None | ||
| }; | ||
|
|
||
| let frag = &domain[hash_pos + 1..]; | ||
| if let Some(colon_pos) = frag.find(':') { | ||
| frag[..colon_pos].parse::<usize>().ok() | ||
| } else { | ||
| frag.parse::<usize>().ok() | ||
| } | ||
| } | ||
|
|
||
| #[inline] | ||
| pub fn column(self) -> Option<usize> { | ||
| let Self::Search { domain, .. } = self else { return None }; | ||
| let Some(hash_pos) = domain.find('#') else { | ||
| return None | ||
| }; | ||
|
|
||
| let frag = &domain[hash_pos + 1..]; | ||
| if let Some(colon_pos) = frag.find(':') { | ||
| frag[colon_pos + 1..].parse::<usize>().ok() | ||
| } else { | ||
| None | ||
| } | ||
| } |
There was a problem hiding this comment.
This should be handled in the respective previewer so that different previewers can use different formats for different search metadata
Amazing tool! Try to improve the rg search experience.
Which issue does this PR resolve?
Resolves #3521
Rationale of this PR
See the issue for more details.
I changed the reveal logic to account for Search URL.