wting / autojump

A cd command that learns - easily navigate directories from the command line
Other
16.27k stars 705 forks source link

Option to disable fuzzy and anywhere match #359

Open quark-zju opened 9 years ago

quark-zju commented 9 years ago

Approximate match is pretty annoying if the user did not make typos. For example,

$ j venv
/home/quark/src/github/quark-zju/some-rails-project/vendor

$ j .venv
/home/quark/.rbenv

$ autojump -s | grep venv
...
14.1:   /home/quark/*/src/neutron/.venv/lib/python2.7

# I'd like to go to /home/quark/*/src/neutron/.venv

The old behavior that just exits with non-zero seems more appropriate. I see autojump does not use any config files and has currently hardcoded:

        chain(
            match_consecutive(needles, data, ignore_case)
            match_fuzzy(needles, data, ignore_case),
            match_anywhere(needles, data, ignore_case))

match_anywhere does not make sense to me, either. How about adding a config file to disable them?

lilydjwg commented 9 years ago

I'm sometimes annoyed when I didn't make a typo, but autojump doesn't have that path (I lost many paths in an incident described in #358 ), so it goes to a rather random place.

ToyKeeper commented 2 years ago

The forced fuzzy match is making autojump mostly useless for me. For example, it fails when I try to go to a known directory by using a unique match. And it's not even picking the match with the highest score...

~/> j -s | grep fox
26.5:   /home/selene/src/qmk/toykeeper/keyboards/input_club/whitefox/keymaps/toykeeper
~/> j fox
/tmp/foo
/tmp/foo/> j -s | grep whitef
26.5:   /home/selene/src/qmk/toykeeper/keyboards/input_club/whitefox/keymaps/toykeeper
/tmp/foo/> j whitef
/home/selene/daily/2021/09/03/site
~/daily/2021/09/03/site/> j -s | grep $(pwd)
17.3:   /home/selene/daily/2021/09/03/site

This makes no sense at all.

I'm using autojump 22.5.1-1 from Debian.

Commenting out the match_fuzzy() line helps, but it still picks directories I've only used once instead of directories I've used hundreds of times.

Upon further experimentation, though, I find it works much better if I simply re-order the chained calls. It also seems to help slightly if I add path length as one of the sorting keys. Here's a slightly modified snippet from find_matches() which seems to improve results immensely:

    #data = sorted(
    #    entries,
    #    key=attrgetter('weight', 'path'),
    #    reverse=True)

    foo = [(-e.weight, -len(e.path), e.path, e) for e in entries]
    foo.sort()
    data = [f[-1] for f in foo]

    return ifilter(
        lambda entry: not is_cwd(entry) and path_exists(entry),
        chain(
            match_anywhere(needles, data, ignore_case),
            match_consecutive(needles, data, ignore_case),
            match_fuzzy(needles, data, ignore_case)
            ))

This jumps to the highest weight. If there's a tie, it takes a longer directory over a shorter one... because if it's short it probably doesn't need a shortcut. And if exact matching fails, it falls back on fuzzy matching... but fuzzy matches no longer override exact matches.