Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple sets of patterns #124

Open
casey opened this issue Aug 4, 2021 · 9 comments
Open

Multiple sets of patterns #124

casey opened this issue Aug 4, 2021 · 9 comments

Comments

@casey
Copy link

casey commented Aug 4, 2021

Thanks for the great plugin!

I mostly program in Rust, and adding Cargo.toml to g:rooter_patterns usually works to find the correct project root when working in rust projects.

However, Rust supports workspaces with directories with Cargo.toml files. In this case, sometimes vim-rooter will stop at a Cargo.toml file in a subdirectory.

In such cases, I'd rather vim-rooter use the location of the .git directory to find the project root.

I was thinking about how vim-rooter might support this, and one possibility is to to allow setting g:rooter_patterns to multiple sets of patterns, which would be checked in order.

In my this case, I would use the following configuration:

let g:rooter_patterns = [['.git/'], ['Cargo.toml']]

vim-rooter would first search for a .git directory, and only if that failed search for a Cargo.toml file.

I think this would be a pretty simple change. A new configuration option, g:rooter_pattern_groups. If it was unset, it would default to [g:rooter_patterns], for backwards compatibility. And the implementation would be an additional for loop around the main for loop in plugin/rooter.vim.

@airblade
Copy link
Owner

airblade commented Aug 4, 2021

What does the directory structure of a workspace(s) look like?

@casey
Copy link
Author

casey commented Aug 4, 2021

It's pretty flexible, but a few layouts might be:

Cargo.toml
crate-a/Cargo.toml
crate-b/Cargo.toml

Or:

Cargo.toml
crates/a/Cargo.toml
crates/b/Cargo.toml

@airblade
Copy link
Owner

airblade commented Aug 4, 2021

I've never used Rust. Do those layouts show the project root directory with the crates being workspaces? Or Is each example a workspace? If the latter, please could you show where workspaces sit in relation to the project root.

Presumably you can't just use .git because the workspaces have their own .git directories?

@casey
Copy link
Author

casey commented Aug 4, 2021

Each example is a workspace, with the top Cargo.toml being the crate root, and a and b being sub-crates in the workspace.

Usually workspaces have .git directories, but sometimes they don't.

@airblade
Copy link
Owner

airblade commented Aug 4, 2021

Hmm, so is a workspace the root of a project? Or does the root of a project contain workspaces?

@casey
Copy link
Author

casey commented Aug 4, 2021

A workspaces is usually at the root of a project, and it contains one or more crates.

A real-world example is here. The repo is a workspace, and the root Cargo.toml is here. There are also sub-crates with their own Cargo.tomls, like this one or this one.

@airblade
Copy link
Owner

airblade commented Aug 5, 2021

Thanks for explaining further.

Would you expect to see a Cargo.lock at the top level only?

If not, these patterns work for me:

let g:rooter_patterns = ['!../Cargo.toml', '!../../Cargo.toml', 'Cargo.toml']

Your suggestion of an extra loop changes the algorithm from breadth-first to depth-first. If I'm going to do that I'd prefer an explicit option and to keep the patterns as a simple list.

@casey
Copy link
Author

casey commented Aug 6, 2021

Would you expect to see a Cargo.lock at the top level only?

You would expect to see a Cargo.lcok at the top level, but a Cargo.lock file doesn't exist when a project is initialized, only when it's first built. Also, library crates don't check the Cargo.lock file into version control, so it will be missing upon first check-out.

let g:rooter_patterns = ['!../Cargo.toml', '!../../Cargo.toml', 'Cargo.toml']

That's a good idea, I'll do that.

Your suggestion of an extra loop changes the algorithm from breadth-first to depth-first. If I'm going to do that I'd prefer an explicit option and to keep the patterns as a simple list.

I understand the reluctance to do so, although the advantage of a list of lists is that it has extra flexibility in that it combines breadth first and depth first searches. And if it's possible to check if an item is a list or a list of lists, it could still retain the existing behavior by default when it's just a list of strings.

@Freed-Wu
Copy link

Freed-Wu commented Sep 6, 2023

In my this case, I would use the following configuration:

let g:rooter_patterns = [['.git/'], ['Cargo.toml']]

vim-rooter would first search for a .git directory, and only if that failed search for a Cargo.toml file.

I met similar situation. Android use repo to manage code, I hope it search .repo firstly, only when .repo doesn't exist, search .git. Looks like your

let g:rooter_patterns = [['.repo'], ['.git']]

intelfx added a commit to intelfx/dotfiles that referenced this issue Oct 16, 2024
Disable specific project root patterns (Makefile, package.json) that are
liable to appear below toplevel and confuse vim-rooter, until we gain
the ability to choose between BFS and DFS semantics.
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

No branches or pull requests

3 participants