Skip to content

Conversation

@SPFabGerman
Copy link
Contributor

The current implementations of the searchmethod / filtermethod options is slightly inconsistent. text and regex both require a substring match of a filename, while glob requires a full match of the entire filename. (See also https://pkg.go.dev/path/filepath#Match and https://pkg.go.dev/regexp#MatchString) Neither behaviour is documented in lf so far.

This PR attempts to improve on this inconsistency by allowing the user to explicitly specify wether they want full or just substring matches. For this I added the two options glob-full and regex-full, that require a full filename match. The original options text, glob and regex now all require just a partial or substring match.
(I haven't implemented a text-full option, as this can at most only ever match a single file and is functionally equivalent to just using the select command with the desired filename.)

In my opinion this provides more consistent and expected behaviour, especially when switching the searchmethod / filtermethod options. In particular, any regular string (without special characters, so like foobar) now provides identical behaviour for the text, glob and regex options.
And arguably only providing a partial match is more useful and intuitive for the user. If I am searching or filtering files, it's likely that I don't yet know the exact filename I'm looking for, making specifications of full filename matches more cumbersome.

This change technically doesn't add any new features to lf, as glob patterns can easily be made into substring matches, by surrounding them with *. Similarly, regex patterns can easily be made full matches by using ^ and $. Both can be easily implemented with push mappings. But I still think the consistent behaviour provided by this PR is worth it's inclusion.

Unfortunately neither Go Package provides functions already implementing this behaviour, so I had to rely on changing the patterns as described above. However, Go's implementation of glob patterns is quite simple and does not provide any conditionals (beside arguably character classes), so surrounding the patterns with * suffices and should never result in any unwanted or unexpected behaviour. Regexs can simply be surrounded by brackets to avoid any issues with conditionals.

I should also mention that while regex and regex-full are equally powerful (as the user can simply create regexs like ^.*PATTER.*$ to restore substring matches even with regex-full), glob is actually weaker than glob-full as there is no way to force a full match after surrounding a pattern with *.

As this PR changes the behaviour of the glob option, this is a breaking change. But as the old behaviour can be easily restored by replacing glob with glob-full, I doubt this will cause any real trouble.

As I mentioned above, I personally find the full filename matches of the options glob-full and regex-full a bit useless. So we might even consider removing them and only changing the behaviour of the glob option. But this is technically a regressions as the glob option is weakened through this PR. (See above.) But I don't have any strong opinions here either way.

I haven't yet added anything to the documentation, in case anyone would like any further changes.

@CatsDeservePets
Copy link
Collaborator

CatsDeservePets commented Dec 30, 2025

At least to me, the glob behaviour works exactly as I expect it to work.
For example when I want list all .go files, I use ls *.go not ls go.
With this change, you are basically converting the configuration of all the users with searchmethod/filtermethod glob to text.
What are your actual use cases for wanting to match a substring without the need to specify * around it while still being able to use other glob features? Why not use text instead and provide multiple filters to further specify the result?

@CatsDeservePets CatsDeservePets added breaking Pull requests that introduce breaking changes enhancement labels Dec 30, 2025
@CatsDeservePets
Copy link
Collaborator

Also, if your main goal is to avoid having to type * for substring matches, how about wring a simple custom command like this?

cmd myfilter :filter; push **<left>

@CatsDeservePets CatsDeservePets added new Pull requests that add new behavior and removed enhancement labels Jan 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking Pull requests that introduce breaking changes new Pull requests that add new behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants