Skip to content

Url enhancement: support line and column addressing for more precise rg searches #3521

@Cachey4467

Description

@Cachey4467

yazi --debug output

Yazi
    Version: 26.1.4 (3c39a326 2026-01-06)
    Debug  : true
    Triple : x86_64-pc-windows-msvc (windows-x86_64)
    Rustc  : 1.92.0 (ded5c06c 2025-12-08)

Ya
    Version: 26.1.4 (3c39a326 2026-01-06)

Emulator
    TERM                : None
    TERM_PROGRAM        : Some("vscode")
    TERM_PROGRAM_VERSION: Some("1.107.1")
    Brand.from_env      : Some(VSCode)
    Emulator.detect     : Emulator { kind: Left(VSCode), version: "", light: false, csi_16t: (0, 0), force_16t: false }

Adapter
    Adapter.matches    : Iip
    Dimension.available: Dimension { rows: 31, columns: 150, width: 0, height: 0 }

Desktop
    XDG_SESSION_TYPE           : None
    WAYLAND_DISPLAY            : None
    DISPLAY                    : None
    SWAYSOCK                   : None
    HYPRLAND_INSTANCE_SIGNATURE: None
    WAYFIRE_SOCKET             : None

SSH
    shared.in_ssh_connection: false

WSL
    WSL: false

Variables
    SHELL              : None
    EDITOR             : None
    VISUAL             : None
    YAZI_FILE_ONE      : None
    YAZI_CONFIG_HOME   : None
    YAZI_ZOXIDE_OPTS   : None
    FZF_DEFAULT_OPTS   : None
    FZF_DEFAULT_COMMAND: None

Text Opener
    default     : Some(OpenerRule { run: "code -g \"%s:%l\"", block: true, orphan: false, desc: "Edit with default editor", for: None, spread: true })
    block-create: Some(OpenerRule { run: "code -g \"%s:%l\"", block: true, orphan: false, desc: "Edit with default editor", for: None, spread: true })
    block-rename: Some(OpenerRule { run: "code -g \"%s:%l\"", block: true, orphan: false, desc: "Edit with default editor", for: None, spread: true })

Multiplexers
    TMUX               : false
    tmux version       : program not found
    tmux build flags   : enable-sixel=Unknown
    ZELLIJ_SESSION_NAME: None
    Zellij version     : program not found

Dependencies
    file          : 5.45
    ueberzugpp    : program not found
    ffmpeg/ffprobe: 8.0.1 / 8.0.1
    pdftoppm      : 25.07.0
    magick        : 7.1.2-11
    fzf           : 0.67.0
    fd/fdfind     : 10.3.0 / program not found
    rg            : 15.1.0
    chafa         : program not found
    zoxide        : 0.9.8
    7zz/7z        : program not found / program not found
    resvg         : program not found
    jq            : 1.8.1

Clipboard
    wl-copy/paste: program not found / program not found
    xclip        : program not found
    xsel         : program not found

Routine
    `file -bL --mime-type`: text/plain

Please describe the problem you're trying to solve

Intention

I think Yazi's content searching experience is not quite ideal compared to VS Code currently.
I looked at the attempts of #3346 and #1095. and I summarized our needs as follows:

  • Show the matched line in the preview so you can tell if it’s the file you want
  • Place the cursor on the matched line (or the words) when opening the file in the default editor so you can start editing right away
    And I find it impossible to solve this purely with a plugin, so we should tackle it step by step.

Would you be willing to contribute this feature?

  • Yes, I'll give it a shot

Describe the solution you'd like

Solution

I’d break the solution down like this:

  1. Yazi will transmit line information to the previewer and the opener while in search mode (transparent to user, purely a system design detail).
  2. The previewers will be responsible for highlighting logic.
  3. The openers will accept those parameters and behave accordingly.

With that in mind, it makes sense to extend Url to support steps 1 and 3. I suggest adding line and column fields to Url.

pub enum UrlBuf {
	Regular(LocBuf),
	Search { loc: LocBuf, domain: Symbol<str>, line: Option<usize>, column: Option<usize> },
	Archive { loc: LocBuf, domain: Symbol<str> },
	Sftp { loc: LocBuf<typed_path::UnixPathBuf>, domain: Symbol<str> },
}

// same as UrlCow and Url

My implementation focuses on extending the Url module so previewers can highlight precisely and openers can jump to the exact line/column.

Why this approach

  1. Including line and column in Url just feels natural.
  2. Url is a flexible part of Yazi; using it to carry search details to the previewer and opener keeps added system complexity minimal.
  3. Minimal impact on other modules: Copy/Move/Delete/Tab/Folder can simply ignore the extra attributes.

Notes / Open question

Should we implement this as a unified feature, or distribute it among the Lua code for each previewer? If it's the latter, it will allow us to expand support for other file types in the future (e.g., PDF, where it would be page numbers instead of line numbers). This would make it easier to #1084, which supports searching in file types other than just text files.

I’m still unsure about the best way to handle step 2. The previewer could receive an appropriately offset position in the peek function, but we might want a new method to tell the previewer which line to highlight. Or we might want a single built-in highlighting mechanism.

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?

This is a step 2 problem. I don't know if it is critical XD

I use --no-heading in rg.rs, so it shows matches inline instead of grouped by file.

Additional context

2026-01-07.02-26-12.mp4

WIP
Still buggy. Path display is kinda broken, and a few larger bugs that cause other issues

Checklist

  • I have searched the existing issues/discussions
  • The latest nightly build doesn't already have this feature

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureNew feature request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions