sxyazi / yazi

💥 Blazing fast terminal file manager written in Rust, based on async I/O.
https://yazi-rs.github.io
MIT License
14.65k stars 332 forks source link

When grepping (`search rg`), preview could highlight the first match #1095

Open mikavilpas opened 3 months ago

mikavilpas commented 3 months ago

Please describe the problem you're trying to solve

When I search using S (search rg), and preview a file that matched my search, the file preview could

Would you be willing to contribute this feature?

Describe the solution you'd like

This is the neovim + telescope implementation

image

The matched files are displayed on the left, and the preview on the right.

Can it be done the same way? I think it's enough to just display each file once, even if it had multiple matches.

Additional context

Not sure what the performance implications might be.

mikavilpas commented 3 months ago

Btw, this is not urgent for me. I was able to add a feature to yazi.nvim where I can read the last cd DDS event and run telescope inside neovim, limiting the search to the directory. The experience is quite good.

https://github.com/sxyazi/yazi/assets/300791/b8a0123f-51ce-42a2-b381-a51a5cbc70bd

sxyazi commented 3 months ago

I'd like to know more about the implementation details:

mikavilpas commented 3 months ago

Currently, there's no saved information about the matching line numbers. Where do you plan to store them? Will it be in the file's own attributes or a separate variable?

Here is a sample match from rg using the --json flag to get machine readable output (it seems to provide line numbers already):

// $ rg "window" --files-with-matches --json
{
  "type": "match",
  "data": {
    "path": { "text": "lua/yazi/utils.lua" },
    "lines": { "text": "---@param window YaziFloatingWindow\n" },
    "line_number": 195,
    "absolute_offset": 5224,
    "submatches": [{ "match": { "text": "window" }, "start": 10, "end": 16 }],
  },
}

One possibility would store it as a new struct, composing the existing File with additional information:

pub struct RgSearchMatch {
    pub file:        File,
    pub line_number: u32,
}

We need to consider the worst-case scenario: if the offset is large, for example, if the first match is the last line of a 10,000-line file, highlighting will take a long time. How will we handle this?

I don't know what would be the best way to handle this. I can think of a few approaches:

Should we implement this as a unified feature, or distribute it among the Lua code for each previewer

To tell you the truth, I would personally be very happy with a super basic implementation in yazi that showed some context around the match. I would give previewer plugins the possibility of doing opt-in fancy things.

For example, a plugin could be written that applies a tree-sitter parser (I believe this is the implementation in https://github.com/nvim-telescope/telescope.nvim).

mikavilpas commented 3 months ago

Looks like rg also provides a rudimentary integration with delta: https://github.com/BurntSushi/ripgrep?tab=readme-ov-file#related-tools

I tried this out and it worked.. but some files were not highlighted correctly. Also, this requires a bit of tinkering to set up, so I don't really think it's that good.

DreamMaoMao commented 2 months ago

This task is want to make like fg.yazi to a built-in feature?

mikavilpas commented 2 months ago

Hmm, conceptually they are very similar, but here are some differences: