diff options
| author | Dylan Araps <dylan.araps@gmail.com> | 2026-03-14 09:57:57 +0200 |
|---|---|---|
| committer | Dylan Araps <dylan.araps@gmail.com> | 2026-03-14 09:57:57 +0200 |
| commit | 6b1050575ceaac57976caddf0663d6ce62e855ef (patch) | |
| tree | 20fda7562cefda0abeaeb416f82a974a6ece7544 | |
| parent | 624a19678d5716a38bc8759b23e9de6887db5092 (diff) | |
dfm: Add range marking
Normal marking works like Ctrl+click in Windows Explorer.
This new act works like Shift+click.
It is bound to Alt+Space and also 'V' by default.
| -rw-r--r-- | config_key.h.in | 3 | ||||
| -rw-r--r-- | dfm.c | 33 |
2 files changed, 36 insertions, 0 deletions
diff --git a/config_key.h.in b/config_key.h.in index 4c087bf..5fcfdb8 100644 --- a/config_key.h.in +++ b/config_key.h.in @@ -102,6 +102,9 @@ static inline void (*fm_key(u32 cp))(struct fm *) case 'M': return act_cd_mark_directory; case ' ': return act_mark_toggle; + case K(MOD_ALT, ' '): return act_mark_range; + case 'v': return act_mark_toggle; + case 'V': return act_mark_range; case K(MOD_CTRL, 'a'): return act_mark_toggle_all; case 'I': return act_mark_invert; case 'C': return act_mark_clear; @@ -3355,6 +3355,39 @@ act_mark_invert(struct fm *p) p->f |= FM_REDRAW_DIR|FM_REDRAW_NAV; } +static inline void +act_mark_range(struct fm *p) +{ + if (p->c == SIZE_MAX) return; + if (!(p->f & FM_MARK_PWD)) + fm_mark_init(p); + usize ml = SIZE_MAX; + usize nw = BITSET_W(p->dl); + for (usize b = 0; b < nw; b++) { + u64 w = p->vm[b] & p->v[b]; + while (w) { + usize i = (b << 6) + u64_ctz(w); + w &= w - 1; + if (i >= p->dl) break; + ml = i; + } + } + if (ml == SIZE_MAX) { + fm_mark_toggle_idx(p, p->c); + p->f |= FM_REDRAW_DIR | FM_REDRAW_NAV; + return; + } + usize lo = MIN(ml, p->c); + usize hi = MAX(ml, p->c); + for (usize i = lo; i <= hi; i++) { + if (!ent_v_geto(p, i, VIS)) continue; + if (!ent_v_geto(p, i, MARK)) + fm_mark_toggle_idx(p, i); + } + fm_mark_invalidate(p); + p->f |= FM_REDRAW_DIR|FM_REDRAW_NAV; +} + // }}} // Input {{{ |