From 6b1050575ceaac57976caddf0663d6ce62e855ef Mon Sep 17 00:00:00 2001 From: Dylan Araps Date: Sat, 14 Mar 2026 09:57:57 +0200 Subject: 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. --- config_key.h.in | 3 +++ dfm.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) 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; diff --git a/dfm.c b/dfm.c index 79664a2..9c21a7d 100644 --- a/dfm.c +++ b/dfm.c @@ -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 {{{ -- cgit v1.2.3