Skip to content

Conversation

@carlosedp
Copy link
Contributor

@carlosedp carlosedp commented Oct 20, 2025

This pull request introduces a file exclude system to the file manager, adding support for custom ignore patterns per path. It enables users to control which files and directories are hidden from view. The changes span configuration, core logic, and integration with the actor and file management systems. The PR also contemplates the API to support rules from Lua plugins which can be used to provide exclusions like gitignores.

Configuration and Integration

New [files] configuration to include excludes settings, allowing users to specify custom ignore patterns.

Sample configuration:

[files]
excludes = [
  # SFTP temporary files
  { urn = "*.tmp", in = "sftp://**" },
  # Python cache in search results
  { urn = "/root/**/*.pyc", in = "search://**" },
  # Multiple patterns for /code directory (supports arrays)
  { urn = [".git", ".DS_Store", "__pycache__"], in = "/code/**" },
  # Negation: show target/ even if previously ignored
  { urn = "!target/", in = "*" },
  # Ignore debug/ only inside target/ directories
  { urn = "debug", in = "/target/**" },
  #Fallback rule for all contexts
  { urn = ".DS_Store", in = "*" }
]

These changes collectively add robust and flexible ignore filtering, enhancing the file manager's ability to hide unwanted files and directories according to user preferences and project standards as explained in #3257 (comment).

There are companion PRs and repos to this PR:

@carlosedp
Copy link
Contributor Author

The companion documentation PR has been updated at yazi-rs/yazi-rs.github.io#294

@carlosedp carlosedp force-pushed the ignores branch 2 times, most recently from 671e952 to 6107a47 Compare October 22, 2025 13:57
@carlosedp
Copy link
Contributor Author

Hi @sxyazi ... any news on this? :)
Also I've been building the latest versions and it doesn't work with the Dracula flavor I'm using on the release version. Is this expected?

show_hidden = false
show_symlink = true
scrolloff = 5
mouse_events = [ "click", "scroll" ]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please keep the file the original style

@@ -1,44 +1,46 @@
[package]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please keep the file the original style

@@ -1,58 +1,86 @@
[workspace]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please keep the file the original style

pub fn from_dir(
dir: impl AsRef<Path>,
exclude_patterns: &[String],
use_git: bool,
Copy link
Owner

@sxyazi sxyazi Oct 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove use_git - as said in #3257 (comment), there are no plans to build gitignore support in, to reduce complexity and maintenance costs, instead, provide a command or Lua API to allow users to load any external ignore rules at runtime, possibly as a fetcher.

Comment on lines 17 to 18
#[serde(rename = "in")]
pub context: String,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#[serde(rename = "in")]
pub context: String,
pub r#in: String,

Please use a raw identifier instead

@and-rs
Copy link

and-rs commented Oct 27, 2025

Hi guys, I was trying out the branch on the current state and it works well. I was wondering; if this option is removed

[files]
gitignores = true

Then the objective would be to delegate the .gitignore responsibility to a plugin? Honestly, I think the way it's currently implemented is the right move, because from a user perspective, that was the only thing that I thought that yazi lacked, hiding git ignore files. I just want to advocate to refine the PR as requested by @sxyazi but keep the git ignore feature builtin. I know it is maintenance cost and I don't want to sound entitled, but I think it's a really useful feature when using yazi on Helix or Neovim, for example. I'd involve myself in the process but I simply lack the Rust skills to do so at the moment. Thanks btw

@carlosedp
Copy link
Contributor Author

I agree with @and-rs and think the addition of gitignore only bring gains and ease the burden of big part of the user base with almost no effort.
I'd love to keep this feature. Will clean up the rest when this is settled as I'm currently out of the computer now.

@sxyazi
Copy link
Owner

sxyazi commented Oct 27, 2025

Yes, I plan to implement it as a plugin.

I don't really see the problem with implementing it as a plugin, because from the user's perspective, you just need to install it and simply enable it to start using it, just like the existing git.yazi plugin. There's no need to understand the plugin API, since that part is handled by the plugin author.

If installing plugins is a challenge, we can also bundle it in, distributing it to users as a preset plugin just like all other Yazi preset plugins, the user would just need to enable it, and the experience would be no different from having it implemented in Rust. However, it's best to maintain it in a separate repository at first, so it isn't tied to Yazi's release cycle and can get bug fixes more promptly - in Yazi, plugins are first-class citizens, and most features are provided through plugins from the inside out.

Technically, loading and parsing gitignore files involves IO operations, so it should be implemented as a fetcher in an asynchronous way to avoid blocking the main thread (the current implementation is synchronous). In Yazi, all IO operations are and should be asynchronous, and fetchers exist for exactly this purpose: they load external information and transform sync into async, but fetchers are built around Lua and can only exist as plugins - there is no equivalent infrastructure available in Rust.

It could also be maintained as a community fork if "implemented in Rust" is a concern here - not all features need to be upstreamed, and I encourage users to maintain their forks to fit their own needs, and I can link these forks in the documentation so others interested in the future can use or help maintain them.

- Introduced `Ignore` actor to manage ignore patterns based on gitignore and user-defined overrides.
- Implemented `IgnoreFilter` to handle ignored paths and patterns.
- Updated `Files` struct to include an ignore filter, allowing files to be filtered based on ignore rules.
- Modified existing actors and managers to apply ignore filters during file operations.
- Updated  `Cargo.toml` and `Cargo.lock` to include new dependencies related to ignore functionality.
@carlosedp
Copy link
Contributor Author

I'm looking into reverting the gitignore config. Which tool is used for toml formatting as taplo automatically formats it as now.

@sxyazi
Copy link
Owner

sxyazi commented Oct 28, 2025 via email

@carlosedp
Copy link
Contributor Author

Just pushed the changes.

@sxyazi sxyazi changed the title Add file excludes config based on granular rules and optional git ignores feat: folder-specific file exclusion rules Oct 30, 2025
@carlosedp
Copy link
Contributor Author

Hold the review a bit. I'll push a commit later today which adds API to allow the use of exclusion by plugins and also the lua plugin to load gitignore files from repos.

@carlosedp
Copy link
Contributor Author

The latest commit adds the API allowing Lua plugins to add exclude patterns to the processing. Patterns from [[files.excludes]] have higher priority than the ones added by plugins so the user can override and/or negate any pattern added by a plugin like gitignores or similar.

As a companion, I've created the gitignore.yazi plugin which is at https://github.com/carlosedp/gitignore.yazi.

@carlosedp
Copy link
Contributor Author

Btw @and-rs ... if you can test this out with the plugin I'd love to get some feedback... :)

@and-rs
Copy link

and-rs commented Oct 30, 2025

Hi honestly, thanks for working on it so quickly. This is my feedback
My config for reference:

  • .config/yazi/yazi.toml
[mgr]
ratio = [2,2,0]
sort_by = "natural"
show_hidden = true

[files]
excludes = [
  { urn = ".git", in = "*" },
  { urn = "!.env", in = "*" },
]

[[plugin.prepend_fetchers]]
id   = "gitignore"
url = "*"
run  = "gitignore"

[[plugin.prepend_fetchers]]
id   = "git"
name = "*"
run  = "git"

[[plugin.prepend_fetchers]]
id   = "git"
name = "*/"
run  = "git"
image

In this first image, when I open a directory that's after the main .gitignore file, the first panel doesn't hide the corresponding files to the config and .gitignore of that dir (basically what's in orange should be hidden but because I didn't open the yazi instance in that directory, it isn't)

This next image is the same instance after I hit "h" to go back one dir.
image

Then the behavior seems to be a bit inconsistent. We can see node_modules not hidden when it should be hidden. Although that doesn't always happen. Sometimes it gets hidden properly, so that's a bit weird.

Also, there's a brief window when I enter a yazi instance or switch directories that I can catch the ignored entries being removed. I don't know if it's my setup or environment or if it is a performance limitation introduced by lua but hiding the files is not truly instant or done before the first render, there is a very brief delay. I might sound a bit nitpicky, but perhaps it's meaningful feedback, thanks again

@carlosedp
Copy link
Contributor Author

carlosedp commented Oct 31, 2025

I'm already looking into this... Facing a problem when e browsing a git repo subdir and going back... Something about yazi caching the repo and not calling the fetcher to update the files.

This brief "flashing" you see is normal since the fetcher is async and when opening a dir the file is shown until the plugin returns and yazi hides it.

Tips @sxyazi ?

@sxyazi
Copy link
Owner

sxyazi commented Oct 31, 2025 via email

@carlosedp
Copy link
Contributor Author

Fixed the caching issue and updated the plugin as well since it had a pattern matching problem.

Can you test this out @and-rs? It needs to pull and build this new commit and update the plugin from it's repo.
Thanks for the feedback and help on this.

@and-rs
Copy link

and-rs commented Nov 3, 2025

I found one bug. There is a mismatch between what's highlighted on the first panel and the current path. It changes back to the correct entry after the first keypress.
image

Apart from that, it's hiding on the first panel correctly, and it's more consistent and faster. There's still a noticeable delay sometimes, but I'm guessing that's just part of the overhead introduced.

Also, I have a question: I am using another plugin, git.yazi, it doesn't work with this current build of yazi, could this be a bug or is it related to something else?

Edit: I was using yazi from neovim in the screenshot, but the bug is reproducible with the same config I provided in my previous comment outside neovim

@carlosedp
Copy link
Contributor Author

@and-rs I override my config with yours and here it's working fine:

Untitled.video.-.Made.with.Clipchamp.2.mp4

I have git.yazi too and it's not working with the upstream main branch (not related to my changes)... I've noticed many other issues with nightly like some flavors (Dracula). Yatline plugin is broken too. Maybe @sxyazi can chime in about this and if there's a guide on deprecations so plugin owners fix them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants