hpdeifel / hledger-iadd

A terminal UI as drop-in replacement for hledger add.
BSD 3-Clause "New" or "Revised" License
84 stars 8 forks source link

Fuzzy Matching #2

Closed trishume closed 7 years ago

trishume commented 8 years ago

This adds fuzzy matching capability to the filtering, which activates when matching against something with a : in it.

I find this makes it way easier to quickly select an account in a way that is easy to think about.

For example previously if I wanted to select Liabilities:Credit but also had an Assets:Credit:Library then searching li cr wouldn’t work and I had to type lia cr. Now I can type lc and it finds it uniquely.

Basically it matches prefixes of the segments of an account in order. This is backwards compatible except for queries that are infixes of a part of an account like iab no longer matching Liabilities which I think is actually good.

Examples:

@hpdeifel

hpdeifel commented 8 years ago

Seems to work pretty well on first testing.

I usually don't like fuzzy matching, because I find it to be a little too unpredictable. But I need to try it out a bit longer to see if it works for me in this case. If it doesn't, I'll merge it anyways and make it optional as a config option.

Two thoughts:

  1. Fuzzy matching tends to be puzzling to people who don't expect it. For example trying to match Expenses:Transport:Eel with the string eel might also match Expenses:Electrons:Free, which might be puzzling. Even if you do know about fuzzy matching, some matches can be quite unexpected.
  2. I actually do use infix matches if the prefix has hard to type characters. E.g the german word for baker is "Bäcker". Since the prefix contains an umlaut that is hard to type on my keyboard, I got into the habit of typing "cker" to match it. But I guess that's just an artifact of my workflow.

I wonder if the following would be a good idea: Words match the beginnings of parts of accounts in order. E.g "foo bar" would match Food:Barium but not Friends:Oocytes:Barney and also not Barber:Foot.

trishume commented 8 years ago

Personally I like the way this fuzzy matching works without needing spaces. For some reason I find I type contiguous strings of letters faster than I type many short strings separated by spaces, although that might be purely the extra time of the space bar and any extra delay is my imagination.

hpdeifel commented 7 years ago

Sorry this took so long. Fuzzy matching is now available via the config option completion-engine = fuzzy.

Also, you were right: Adding a new config option and threading it to the leaf functions is painful

simonmichael commented 7 years ago

I look forward to trying this. Related, one reason I've delayed trying hledger-iadd seriously is the imagined effort I'll have to put in to get past my confusion around the (ever-evolving) matching behaviour. I should probably have just started using it, but there's this expectation of being confused and losing time in figuring it out, so I just stick with my current tools.

When I look at the examples above, the feeling is only confirmed; I see "asc matches Assets:Wallet:Cash" and I don't understand exactly how the matching works. Really clear explanation of the matching process (in readme, on-screen help, and/or live visual feedback) is not so easy but I think very worthwhile for attracting new users.

trishume commented 7 years ago

Thanks @hpdeifel. I'm totally on board with the decision to make it not the default, it only hurts you if you don't know what it is, as @simonmichael mentions.

Sublime Text has a phenomenally good fuzzy matching algorithm that has the right level of weighting on starts of words, substrings and spaces so that it doesn't confuse beginners and almost always gets the right result as fast as possible. However, I have no idea what that algorithm is, and I'm sure it would take a lot of work to clone even if I did know.

hpdeifel commented 7 years ago

@simonmichael That's why I didn't make fuzzy matching the default. Also, I think better on-screen help/feedback would be great! It already gives live results on the date and amount parsing for this reason. There are a couple of other things I can think of:

simonmichael commented 7 years ago

Love it.. yeah eg highlighting each letter typed ("asc") where it is found in the match ("Assets:Wallet:Cash" ?) would probably help a lot.