Commit graph

197 commits

Author SHA1 Message Date
raf
ce98b6db09
Merge pull request #67 from NotAShelf/notashelf/push-otlvvpomrtom
meta: bump deps & MSRV; allow disabling multicall bins
2026-02-26 09:38:49 +03:00
4d58cae50d
nix: add platforms to meta; allow overriding symlink behaviour
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: Ib6e44abd86bd0e58f290b456680a97236a6a6964
2026-02-26 09:12:27 +03:00
2e3c73957a
meta: allow disabling symlinks in build script via env vars
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I07f5d565d26ca527d413edf69857539e6a6a6964
2026-02-26 09:12:26 +03:00
d367728b39
chore: set MSRV to 1.91.0
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: Iadde6dfe7e79a365edf4d664b941c0776a6a6964
2026-02-26 09:12:25 +03:00
2edecf4c17
chore: format with taplo
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I942883a08eccc5decd38a6865b3451496a6a6964
2026-02-26 09:12:24 +03:00
134da06fd0
chore: bump dependencies
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I53a5279d1c3e74ae54e2f32a800f83766a6a6964
2026-02-26 09:12:06 +03:00
2227ef7e89
chore: format Cargo manifest with Taplo; v0.3.5 v0.3.5
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: Id35b12bba16b0e181bb4536154259b5a6a6a6964
2026-02-01 18:12:53 +03:00
2e086800d0
chore: format TOML with Taplo
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I2ecc8923946ace5288a1c45ca202cb956a6a6964
2026-02-01 18:12:52 +03:00
cff9f7bbba
chore: bump dependencies
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: Ib0445df9b8e5f0d4aabfcd4ff1bc27f16a6a6964
2026-02-01 18:12:51 +03:00
raf
23bb89e3ea
Merge pull request #61 from NotAShelf/notashelf/push-wompwwqskzwu
mime: refactor mime detection to separate module; streamline
2026-02-01 16:45:41 +03:00
9afbe9ceca
watch: deprioritize text/html in MIME negotiation
Firefox and Electron apps offer `text/html` first when copying images,
which causes stash to store the HTML wrapper (`<img src="...">`) instead
of the actual image data, which is what we want. We handicap, i.e.,
deprioritize `text/html` in the "any" preference mode and prefer
`image/*` types first, then any non-html type. 

This sounds a little illogical, but in user will almost always prefer
the image itself rather than the text representation. So it's intuitive.

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I6bd5969344893e15226c27071442475f6a6a6964
2026-02-01 14:55:31 +03:00
3fd48896c1
watch: respect source MIME type order in clipboard polling
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I3da2e187276611579f3686acb20aacf36a6a6964
2026-02-01 11:55:18 +03:00
b4dd704961
db: add an in-memory test helper
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I22cc10df47265fa4d08d5c03cadbe9c56a6a6964
2026-02-01 11:55:17 +03:00
bb8e882565
mime: expand test coverage
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I3f17b98ad68f17ebcf9554e5e88f62676a6a6964
2026-02-01 11:55:02 +03:00
5c8591b2e5
docs: mention MIME preference usage in README
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I3bda3397f0350f27523b419bd079f8756a6a6964
2026-01-23 23:13:02 +03:00
ff2f272055
mime: refactor mime detection to separate module; streamline
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I489054d2537a4c0de32d79f793478c206a6a6964
2026-01-23 23:13:01 +03:00
raf
ded38723d4
Merge pull request #60 from NotAShelf/notashelf/push-wvyzsrrzyrum
add auto-expiry mechanism to `stash watch`
2026-01-23 21:10:41 +03:00
e185ecd32a
docs: document entry expiry features for stash watch & db cmds
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I60fe5afdb6e903b96023ca420bb7902d6a6a6964
2026-01-22 19:40:41 +03:00
b00e9b5f3a
watch: clear clipboard when expired entry content matches current clipboard
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I4bede5db16cea993ed8e8591e8d198d56a6a6964
2026-01-22 18:27:24 +03:00
5731fb08a5
cli: add db subcommand
Adds a `db` subcommand with `DbAction` for three new database
operations: wipe, vacuum and stats. We can extend this database later,
but this is a very good start for now and plays nicely with the
`--expired` flag. This soft-deprecates `stash wipe` in favor of a `stash
db wipe` with the addition of a new `--expired` flag that wipes the
expired entries only. 

The `list` subcommand has also been refactored to allow for a similar
`--expired` flag that lists only expired entries.

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I34107880185d231d207b0dab7782d5d96a6a6964
2026-01-22 16:56:44 +03:00
2e555ee043
commands/list: add include_expired parameter for filtering
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: Ia1ab13345cfa5e2cf9a92f8b32a6a9826a6a6964
2026-01-22 16:56:43 +03:00
b070d4d93d
watch: implement soft-delete behaviour for expired entries
The previous `--expire-after` flag behave more like *delete* after
rather than *expire*. This fixes that, and changes the behaviour to
excluding expired entries from list commands and already-marked expired
entries from expiration queue. Updates log messages accordingly.

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: Ib162dff3a76e23edcdfbd1af13b01b916a6a6964
2026-01-22 16:56:42 +03:00
d40b547c07
db: add is_expired column and implement vacuum/stats commands
Migrates schema to v5; `is_expired` column is added with partial index
and `include_expired` parameter to `list_entries()` and `list_json()`
methods. Also adds `vacuum()` and `stats()` methods for SQlite
"administration", and removes `next_sequence()` from trait and impl.

This has been a valuable addition to stash, as the database is now *less
abstract* in the sense that user is made aware of its presence (stash
wipe -> stash db wipe) and can modify it.

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: Icfab67753d7f18e3798c0a930b16d05e6a6a6964
2026-01-22 16:56:41 +03:00
f4936e56ff
cli: add --expire-after flag to watch and --expired flag to list
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I833e7bfaecb5e3254d2ea16f2b880e246a6a6964
2026-01-22 16:56:40 +03:00
dd7a55c760
watch: implement expiration queue w/ sub-second precision
This adds a Neg wrapper struct for min-heap behaviour on BinaryHeap
which has proven *really* valuable. Also modify `watch()` to take the
`expire_after` argument for various new features. See my previous commit
for what is actually new.

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I8705d404eae5d93ad48f738a24f698196a6a6964
2026-01-22 16:56:39 +03:00
71fc1ff40f
db: add `expires_at column and expiration management methods
Schema v4: add expires_at REAL column with partial index for NULL values

Other relevant methods that were added:

- `now()` for Unix timestamp with sub-second precision
- `cleanup_expired()` to remove all expired entries
- `get_expired_entries()` for for diagnostic output (`stash list --expired`)
- `get_next_expiration()` for heap initialization
- `set_expiration()` to update expiration timestamp

This feature has proven larger than I had anticipated (and hoped) but
that's the reality of dealing with databases. Some of the methods are
slightly redundant but it helps keep tracing the code manageable and
semantically correct. We'll probably not regret those later. Probably.

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: Ie9e5b0767673e74389b8e59c466afd946a6a6964
2026-01-22 16:56:38 +03:00
bb1c5dc50b
chore: release v0.3.4 v0.3.4
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: Ie637c425e0d13985e3025a2ebaac41916a6a6964
2026-01-22 14:04:20 +03:00
441334a250
chore: bump dependencies
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I8ef1f283622f50d93ba9d581699e272b6a6a6964
2026-01-22 14:04:19 +03:00
raf
4ab9ce4a71
Merge pull request #58 from NotAShelf/notashelf/push-oksprvxpxpxt
various: improve robustness of entry tracking in database
2026-01-22 13:53:50 +03:00
047445b143
db: distinguish HEIC from HEIF in mime type detection
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I1a25c6d30fde6b4cc33c2a1666b2e1606a6a6964
2026-01-22 13:48:30 +03:00
3d22a271bc
chore: add tempfile dependency for tests
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: Ibf7a842a2a26f83e8adaf1123386306b6a6a6964
2026-01-22 13:41:59 +03:00
c65073e0d1
db: rewrite migration with transactional schema versioning
This makes Stash's database handler a bit more robust. The changes
started as me trying to add an entry expiry, but I've realized that the
database system is a little fragile and it assumed the database does not
change, ever. Well that's not true, it does change and when it does
there's a chance that everything implodes.

We now wrap migrations in transaction for atomicity and track version
via PRAGMA user_version (0 -> 3). We also check column existence before
ALTER TABLE and use `last_insert_rowid()` instead of `next_sequence()`.

Last but not least, a bunch of regression tests have been added to the
database system because I'd rather not discover regressions in
production.

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: Ifeab42b0816a5161d736767cb82065346a6a6964
2026-01-22 13:41:58 +03:00
3165543580
commands: prevent usize underflow when navigating empty entry list
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I0432dcc88b22226772f6bb6e05cc64d36a6a6964
2026-01-22 13:41:57 +03:00
20b6a12461
stash: make db module public for test visibility
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I5f75e6515114e7479a3fe63771a4e7fe6a6a6964
2026-01-22 13:41:56 +03:00
dca7cca455
nix: add cargo-nextest to devshell
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I2266c2f3fccff23fa3950f8fac3365f36a6a6964
2026-01-22 13:41:55 +03:00
59423f9ae4
list: add content_hash and last_accessed tracking with de-duplication
Adds a `content_hash` column and index for deduplication, and a
`last_accessed` column & index for time tracking. We now de-duplicate on
copy by not copying if present, but instead bubbling up matching entry.

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: Icbcdbd6ac28bbb21324785cae30911f96a6a6964
2026-01-22 13:41:54 +03:00
raf
65a8eebd46
Merge pull request #57 from NotAShelf/notashelf/push-royltkszywmz
multicall: prevent newline corruption of binary data in wl-copy
2025-12-23 10:29:12 +03:00
f2274aa524
multicall: auto-select MIME type more intelligently when not specified
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: Idfd5ab25079161d694bda429e70500a16a6a6964
2025-12-23 10:11:28 +03:00
bbfe583423
multicall: prevent newline corruption of binary data in wl-copy
Previously we unconditionally appended a newline to all clipboard
contents, which ended up corrupting binary files like PNG images when
using shell redirection (e.g., `wl-paste > file.png`). Now we
intelligently (in quotes) detect content type via MIME type and only
append newlines to text-based content such as `text/*`,
`application/json` and so on. Binary data on another hand is written
exactly as it is. Falls back to UTF-8 validation when MIME type is
unavailable.

On paper this is also fully backwards compatible; text content still
gets newline by default *unless* the `--no-newline` flag is used.

Fixes #52

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I8b1e6f7013d081150be761820cafd1926a6a6964
2025-12-23 09:41:19 +03:00
raf
1f0312b2f6
Merge pull request #56 from NotAShelf/notashelf/push-umuwyuqntslp
various: bump dependencies
2025-12-22 17:14:53 +03:00
f6818c9e6f
chore: release v0.3.3
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I5d53159c67ea83260c213ea93114b3d96a6a6964
2025-12-22 16:59:13 +03:00
c2182d21dc
chore: bump dependencies; fix lifetime warnings for Rust 1.90+
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: If755ceefb970311c7660118cb2019c2c6a6a6964
2025-12-22 16:59:12 +03:00
8a25a03486
flake: bump nixpkgs
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I4572c7075e11282280d514ffde4361586a6a6964
2025-12-22 16:59:11 +03:00
raf
f838365314
Merge pull request #49 from NotAShelf/notashelf/push-vootvqpuytyv
multicall: go back to forking solution
2025-11-25 10:08:24 +03:00
raf
bb88c89a0f
Merge pull request #50 from NotAShelf/dependabot/github_actions/actions/checkout-6
build(deps): bump actions/checkout from 5 to 6
2025-11-21 21:03:35 +03:00
dependabot[bot]
c8ead9a308
build(deps): bump actions/checkout from 5 to 6
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-21 14:26:17 +00:00
a68946d54d
various: fix clippy lints
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I4bb649a5161460d8794dc5c93baa6cc46a6a6964
2025-11-13 00:05:52 +03:00
2d8ccf2a4f
multicall: go back to forking solution
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I2a24a3c7efc41fc45c675fd98e08782e6a6a6964
2025-11-13 00:05:48 +03:00
96089f364b
docs: fix typo
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I9b29db50afe2f2768bd4bc260bc5aaf96a6a6964
2025-10-28 13:03:00 +03:00
61ff65e9e8
stash: make log messages lowercase
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I45a9055b6bc3bfbf2179627470d0cedd6a6a6964
2025-10-28 13:02:59 +03:00