justinmk / vim-sneak

The missing motion for Vim :athletic_shoe:
http://www.vim.org/scripts/script.php?script_id=4809
MIT License
3.26k stars 88 forks source link

2-char labels #232

Closed ghost closed 4 years ago

ghost commented 6 years ago
let g:sneak#target_labels = "asdf"

I defined it like this because I want to go with left hand only, that makes me easier to move. But after defining this it shows something like that:

>ea

sn[a ]k
sn[s ]k
sn[d ]k
sn[f ]k
sneak

So I can't reach the last one. In easymotion its like this:

ea

sn[aa]k
sn[as]k
sn[ad]k
sn[af]k
sn[ss]k

And so on. That means I can do 4! = 24 labels while sneak is 4. If you have 6 letters, that means 6! = 720 labels (a lot) while sneak is 6. 720 labels at the same time should be easier for movement. Maybe add it as option because i dont want to spam spaces :smile:

justinmk commented 6 years ago

Current alternative is to use <Tab> to label the next batch (or <BS> or <S-Tab> to go in the other direction).

The current behavior was an intentional design choice so that adjacent labels are always separated, e.g.:

[a ][s ][d ][f ]

vs:

[aa][as][ad][af]

Also with your proposed labeling system, user always must hit 2-char labels, even if there are only a few matches (which is the common case).

ghost commented 6 years ago
lol this is a text
with some more text
lol this is a text
with some more text
ghost commented 6 years ago

Let's say i have a long content

lol this is a text
with some more text
lol this is a text
with some more text
lol this is a text
with some more text
lol this is a text
with some more text
lol this is a text
with some more text
lol this is a text
with some more text

I want to search lo. And my lo is at the end of content. Pressing Tab a lot or just pressing two keys? My usage case is this.

ghost commented 6 years ago

Or you can do this too:

If there is 5 matches and 5 g:target_labels charatchers, use the normal one, if there is more, use 2 char.

ghost commented 6 years ago

Like this:

[a ]llo [s ]llo [d ]llo [f ]llo [g ]llo

But if there is more

[aa]llo [as]llo [ad]llo [af]llo [ag]llo
[sa]llo [ss]llo [sd]llo [sf]llo [sg]llo

And so on.

justinmk commented 6 years ago

I understand the use case. If you only start with 4 label chars then it's very common to run out of labels. If you start with 15+ labels then its very uncommon to run out of labels, thus hitting <Tab> isn't a high cost.

So this double-char labeling is mostly useful if you restrict the label set.

ghost commented 6 years ago

Also, you can implement it in python easily, using itertools.combinations

def combinations(iterable, r):
    # combinations('ABCD', 2) --> AB AC AD BC BD CD
    # combinations(range(4), 3) --> 012 013 023 123
    pool = tuple(iterable)
    n = len(pool)
    if r > n:
        return
    indices = range(r)
    yield tuple(pool[i] for i in indices)
    while True:
        for i in reversed(range(r)):
            if indices[i] != i + n - r:
                break
        else:
            return
        indices[i] += 1
        for j in range(i+1, r):
            indices[j] = indices[j-1] + 1
        yield tuple(pool[i] for i in indices)

You can turn it into VimL. It works like

combinations('ABCD', 2) #--> AB AC AD BC BD CD
ghost commented 6 years ago

I'm not sure if laziness in VimL exists, because this yields an infinite amount of (while True:) combinations, and it generates when needed.

justinmk commented 6 years ago

Yeah, it's not difficult, it's just hours of my time that are not a high priority. If you send a PR with some tests, I'll merge it.

VimL doesn't have generators , but a generator isn't needed anyways.

ghost commented 6 years ago

Actually, I don't know vimL that good. Also creating plugins.