Skip to content

Commit c8ce7c9

Browse files
committed
config: add touch_on_select
this makes an entry bump to the newest slot when it is selected via `clipmenu`.
1 parent 3982971 commit c8ce7c9

7 files changed

Lines changed: 55 additions & 2 deletions

File tree

man/clipmenu.conf.5

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ include rofi's dmenu mode or a custom command. Default: "dmenu".
4747
When enabled, extra command-line arguments passed to clipmenu are forwarded to
4848
the launcher. Default: 1.
4949
.TP
50+
.B touch_on_select
51+
When an entry is selected via
52+
.BR clipmenu (1)
53+
it will also be moved up to the newest slot.
54+
Default: 0.
55+
.TP
5056
.B cm_dir
5157
Overrides the default directory for the clip store. This is by default at a
5258
subdirectory inside XDG_RUNTIME_DIR, TMPDIR, or if both are unset, inside /tmp.

src/clipmenu.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,11 @@ static int _nonnull_ interact_with_dmenu(struct config *cfg, int *input_pipe,
149149
return EXIT_FAILURE;
150150
}
151151

152-
return WEXITSTATUS(dmenu_status);
152+
int dmenu_exit_code = WEXITSTATUS(dmenu_status);
153+
if (dmenu_exit_code == EXIT_SUCCESS && cfg->touch_on_select) {
154+
expect(cs_make_newest(&cs, *out_hash) == 0);
155+
}
156+
return dmenu_exit_code;
153157
}
154158

155159
/**

src/config.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ int config_setup_internal(FILE *file, struct config *cfg) {
287287
0},
288288
{"launcher_pass_dmenu_args", "CM_LAUNCHER_PASS_DMENU_ARGS",
289289
&cfg->launcher_pass_dmenu_args, convert_bool, "1", 0},
290+
{"touch_on_select", NULL, &cfg->touch_on_select, convert_bool, "0", 0},
290291
{"cm_dir", "CM_DIR", &cfg->runtime_dir, convert_cm_dir, NULL, 0}};
291292

292293
size_t entries_len = arrlen(entries);

src/config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ struct config {
5151
struct ignore_window ignore_window;
5252
struct launcher launcher;
5353
bool launcher_pass_dmenu_args;
54+
bool touch_on_select;
5455
};
5556
typedef int (*conversion_func_t)(const char *, void *);
5657
struct config_entry {

src/store.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,7 @@ int cs_content_get(struct clip_store *cs, uint64_t hash,
533533
* @cs: The clip store to operate on
534534
* @hash: The hash of the entry to move
535535
*/
536-
static int cs_make_newest(struct clip_store *cs, uint64_t hash) {
536+
int cs_make_newest(struct clip_store *cs, uint64_t hash) {
537537
_drop_(cs_unref) struct ref_guard guard = cs_ref(cs);
538538
if (guard.status < 0) {
539539
return guard.status;

src/store.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,8 @@ void drop_cs_content_unmap(struct cs_content *content);
166166
void drop_cs_destroy(struct clip_store *cs);
167167
int _must_use_ _nonnull_ cs_content_get(struct clip_store *cs, uint64_t hash,
168168
struct cs_content *content);
169+
int _must_use_ _nonnull_n_(1)
170+
cs_make_newest(struct clip_store *cs, uint64_t hash);
169171
int _must_use_ _nonnull_n_(1)
170172
cs_add(struct clip_store *cs, const char *content, uint64_t *out_hash,
171173
enum cs_dupe_policy dupe_policy);

tests/test_store.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,44 @@ static bool test__cs_add__dupe_keep_last_with_multiple_entries(void) {
649649
return true;
650650
}
651651

652+
static bool check_order(struct clip_store *cs, uint64_t *order, size_t len) {
653+
_drop_(cs_unref) struct ref_guard guard = cs_ref(cs);
654+
struct cs_snip *snip = NULL;
655+
for (size_t i = 0; i < len; ++i) {
656+
bool iter_ret = cs_snip_iter(&guard, CS_ITER_NEWEST_FIRST, &snip);
657+
t_assert(iter_ret == true);
658+
t_assert(snip->hash == order[i]);
659+
}
660+
return 0;
661+
}
662+
663+
/* After calling cs_make_newest make sure the entry is at the newest slot while
664+
* other entries remain in order. */
665+
static bool test__cs_make_newest(void) {
666+
_drop_(teardown_test) struct clip_store cs = setup_test();
667+
668+
uint64_t hash_a, hash_b, hash_c;
669+
int ret = cs_add(&cs, "A", &hash_a, CS_DUPE_KEEP_ALL);
670+
t_assert(ret == 0);
671+
ret = cs_add(&cs, "B", &hash_b, CS_DUPE_KEEP_ALL);
672+
t_assert(ret == 0);
673+
ret = cs_add(&cs, "C", &hash_c, CS_DUPE_KEEP_ALL);
674+
t_assert(ret == 0);
675+
t_assert(cs.header->nr_snips == 3);
676+
677+
uint64_t order_before[3] = { hash_c, hash_b, hash_a };
678+
ret = check_order(&cs, order_before, 3);
679+
t_assert(ret == 0);
680+
/* Now the order should change to ["A", "C", "B"] */
681+
ret = cs_make_newest(&cs, hash_a);
682+
t_assert(ret == 0);
683+
uint64_t order_after[3] = { hash_a, hash_c, hash_b };
684+
ret = check_order(&cs, order_after, 3);
685+
t_assert(ret == 0);
686+
687+
return true;
688+
}
689+
652690
int main(void) {
653691
t_run(test__cs_init);
654692
t_run(test__cs_init__bad_size);
@@ -676,6 +714,7 @@ int main(void) {
676714
t_run(test__cs_add__dupe_keep_all);
677715
t_run(test__cs_add__dupe_keep_last);
678716
t_run(test__cs_add__dupe_keep_last_with_multiple_entries);
717+
t_run(test__cs_make_newest);
679718

680719
return 0;
681720
}

0 commit comments

Comments
 (0)