Releases: Mjoyufull/fsel
[3.1.0-kiwicrab]
[3.1.0-kiwicrab] Latest
Breaking changes
- Image previews no longer use chafa
- Clipboard image previews are now rendered inside the TUI via ratatui-image. The
chafabinary is no longer used or required. - If you relied on chafa for cclip image previews, uninstall it; 3.1.0 uses built-in Kitty/Sixel/Halfblocks support only.
- Clipboard image previews are now rendered inside the TUI via ratatui-image. The
- Dependencies
- Removed
base64crate (was only used for manual Kitty protocol encoding). No migration; existing config and data unchanged.
- Removed
Added
- Native TUI image previews in cclip mode (from pr #24)
- Inline image preview in the content panel when an image clipboard entry is selected.
- Fullscreen image preview (Alt+i); exit with Esc or q.
- Automatic terminal protocol detection (Kitty, Sixel, Halfblocks) via ratatui-image; no external image viewer.
- New
ImageManagerinui/graphics.rs: centralized load/render, LRU cache (50 entries), async load with 5s timeout, decode offloaded withspawn_blocking. - Display states: Empty, Image, Loading, Failed; preview header and status reflect current state.
- Clipboard copy
- Wayland: single
cclip copy <rowid>(no morecclip get | wl-copypipeline). - Mouse-click copy uses the same path as Enter/Ctrl+Y:
CclipItem::from_lineandcopy_to_clipboard(); parse errors shown in the UI.
- Wayland: single
- Cclip UX and robustness
reload_and_restorehelper for delete/tag/untag; selection and scroll restored by rowid; scroll_offset clamped so the selected item stays visible.failed_rowidsset to avoid endless retry on repeated load failures.- Fullscreen preview loop: bounded tolerance for consecutive input errors so the UI cannot hang on persistent
input.next()failures. - Navigation uses shared
max_visibleto avoid u16 underflow on very small terminals.
Changed
- Graphics and detection
GraphicsAdapter::detect()uses Picker-based protocol when available (Kitty, Sixel, Halfblocks, iTerm2); env fallback only when Picker is not used.- Dmenu mode: removed
Picker::from_query_stdio()on startup; usesGraphicsAdapter::detect(None)env fallback only (no image rendering in dmenu).
- Cclip parsing and UI
- Image detection uses
is_cclip_image_item(mime type) instead ofget_cclip_rowid(which applied to all entries), so text entries are no longer treated as images. get_cclip_rowid,get_image_info, and related parsing indmenu_ui.rsusesplitnconsistently; duplicateget_cclip_rowidremoved.DisplayState: simplified toImage(String)(unusedRectremoved); laterDisplayStatemadestd::sync::Mutexwith poison recovery (unwrap_or_else(|e| e.into_inner())) for consistency.
- Image detection uses
- Dependencies / build
- Added:
ratatui-image10.0 (crossterm, tokio),image0.25 (png, jpeg, gif, bmp, webp; noimage-defaults). - Removed:
base64. - Ratatui 0.30 constraints API:
.as_ref()removal for compatibility.
- Added:
Fixed
-
Fullscreen image preview loop could hang when
input.next()repeatedly returned errors; now exits after bounded consecutive failures. -
Stale image state when
load_cclip_imagefailed; state is cleared and UI shows failure instead of previous image. -
Navigation in cclip could panic in debug on very small terminals due to unchecked u16 subtraction; layout now uses shared
max_visibleand safe bounds. -
Scroll position after reload (delete/tag/untag) could leave the selected item off-screen;
scroll_offsetis clamped so the selected item remains visible. -
Parse errors on clipboard copy (Enter and mouse) were dropped; they are now shown via the UI temp message.
-
Mutex poisoning in
DISPLAY_STATEcould drop updates; all lock sites now use poison recovery so state stays consistent after a panic. -
In modes/cclip/run.rs fixed maintain selection index after item deletion (from pr #27)
Technical details -
ImageManager (
src/ui/graphics.rs):load_cclip_image(rowid)runscclip get <rowid>viatokio::process::Commandwith 5s timeout; stdout is decoded intokio::task::spawn_blockingand stored asStatefulProtocolin an LRU cache;render()draws viaStatefulImageand propagateslast_encoding_result(). -
DisplayState: global
DISPLAY_STATE(std sync Mutex) holdsEmpty | Image(rowid) | Loading(rowid) | Failed(msg); updated from ImageManager and cclip run loop; used byinfo_with_image_supportfor status text. -
Cclip run loop: ImageManager created with Picker (or halfblocks fallback); graphics adapter cached once per run; background task loads images and updates DISPLAY_STATE/failed_rowids; fullscreen modal reuses same ImageManager and clears or restores state on exit.
Documentation
- PROJECT_STANDARDS.md (v1.3.0, from pr #26): Release and hotfix rules; main updated only via release or hotfix branches; release branches for version bumps and docs only; hotfix process and main --> dev sync; tag = version number only; GitHub release title
[version-codename]; release body template and section rules. - README, USAGE, CONTRIBUTING: Chafa removed from requirements; note that pre-3.1.0 still uses chafa, 3.1.0+ uses built-in ratatui-image.
- config.toml: Comment for image preview updated (Kitty/Sixel/Halfblocks, no chafa).
- fsel.1: Version 3.1.0-kiwicrab, date 2026-02-23; app launcher lock path corrected to
~/.local/share/fsel/fsel-fsel.lock;--cclipand Alt-i description updated;[cclip]example includeshide_inline_image_message.
Notes
- SemVer: MINOR (3.0.0 --> 3.1.0). New feature (native image previews), no breaking config or database format; only removal of chafa requirement and of the base64 dependency.
- This release ships the ratatui-image–based cclip preview (pr #24) and the updated project standards (pr #26), plus docs and manpage fixes for 3.1.0, and the fix for item deletion (pr #27)
Contributors
- @Mjoyufull
- Code review and suggestions: @coderabbitai (which lowkey sucked and didn't understand the codebase so i switched to ) -->, @cubic-dev-ai
Compatibility
- Language/runtime: Rust 1.89+ (unchanged).
- Platforms: GNU/Linux and *BSD (unchanged).
- Config / database: Compatible; no migration.
[cclip]options unchanged. - dev,note: PRE 3.1.0 STILL USES CHAFA I CANNOT GO BACK IN TIME
[3.0.0-kiwicrab]
Breaking changes
- Database and cache format
- Serialization changed from bincode to postcard. Existing history, cache, and pinned apps are not migrated. On first run after upgrading, history and cache will be reset/rebuilt. Re-pin apps and reconfigure as needed.
Added
from pr #23
-
TTY mode
-t, --ttyflag andterminal_launcher = "tty"config option for launching terminal apps in the current terminal.- In TTY mode fsel replaces itself with the target application using
exec, so the launched app takes over the session (e.g. htop, vim). - History and frecency are recorded before process replacement; uwsm/systemd prefixes are bypassed in TTY mode.
-
Clipboard entry deletion (cclip)
Alt+Deletekeybind to delete the selected clipboard item (callscclip delete <ID>).- Selection and scroll position preserved after deletion (next item becomes selected at the same index).
- Deletion failures reported in the UI; active tag filter maintained when reloading after delete.
-
Environment overrides
FSEL_*environment variables override config for layout, dmenu, cclip, and app_launcher options (e.g.FSEL_TERMINAL_LAUNCHER,FSEL_CCLIP_IMAGE_PREVIEW).
-
Version bump to 3.0.0-kiwicrab (new codename: kiwicrab).
Changed
-
App launcher launch flow
- Target executable is validated and resolved (PATH search, executable bit) before opening the write transaction and updating history/frecency.
- Failed execs are no longer recorded as successful launches; resolved path used for exec.
-
Dependencies and serialization
- Replaced
bincodewithpostcard1.1 for all database and cache serialization. - Replaced
chronowithtime0.3 for debug logging. - Replaced
configcrate with direct TOML parsing and env handling. - Replaced
regexwithstrip-ansi-escapesfor ANSI stripping. - Replaced
dirswithdirectoriescrate equivalents. - Ratatui updated to 0.30 with
layout-cachefeature for faster layout calculations and UI rendering. - Tokio 1.49 with slimmer feature set; nucleo-matcher 0.3.1, unicode-width 0.2.2, directories 6.0.
- Replaced
-
CLI
- Duplicate
prefix_depthfield removed;-tshorthand for--ttyparsing fixed. - When TTY mode is detected,
terminal_launcherconfig is normalized to empty string to prevent misuse.
- Duplicate
-
Build and binary
- Dependency count reduced (e.g. from ~317 to ~229); release binary size reduced (e.g. ~4.5MB to ~2.7MB).
- Resolved
atomic-polyfillaudit by disabling unusedheaplessfeatures in postcard.
Fixed
- cclip deletion error handling: failures from
cclip deleteare reported to the user; tag filter persists when reloading history after deletion. - Selection jump after cclip delete: selection index and scroll offset preserved so the list does not jump to the top.
Breaking changes
- Database and cache format
- Serialization changed from bincode to postcard. Existing history, cache, and pinned apps are not migrated. On first run after upgrading, history and cache will be reset/rebuilt. Re-pin apps and reconfigure as needed.
Technical details
- TTY mode: Uses
CommandExt::execto replace the fsel process with the target; launch logic records history/frecency before exec and skips environment-specific prefixes in TTY mode. - cclip delete: New
cclip_deletekeybind (default Alt+Delete), configurable in keybinds.toml;delete_itemhelper invokescclip delete <ID>; UI preserves selection and scroll after reload. - Config: Direct TOML parsing with
tomlcrate; env overrides applied per-option for general, layout, dmenu, cclip, and app_launcher sections. - Persistence: redb still used for database; postcard for serialization of history, frecency, pinned apps, cache entries, and tag metadata.
Documentation
- README: version references 3.0.0-kiwicrab; install and usage updated.
- USAGE.md: TTY mode, cclip deletion (Alt+Delete), env overrides; Field Reference includes
prefix_depthandterminal_launcher = "tty"; debug example date updated. - Man page (fsel.1): version 3.0.0-kiwicrab;
-t, --tty; Alt+Delete for cclip delete; config example comment forterminal_launcher = "tty". - config.toml: comment for
terminal_launcher"tty" option. - CONTRIBUTING.md / PROJECT_STANDARDS.md: release examples and codename policy updated for 3.x (kiwicrab).
Notes
This is a MAJOR release under Semantic Versioning 2.0.0:
- Breaking change: database/cache format (bincode → postcard). Existing data is reset on first run.
- New features (TTY mode, cclip deletion, env overrides) are additive.
- Config file structure and CLI flags remain compatible except for the persistence format change.
Rationale: TTY mode enables seamless terminal app launching from TTY login; cclip deletion improves clipboard workflow; dependency modernization reduces binary size, dependency count, and addresses maintenance/security (e.g. unmaintained bincode, audit findings) preparing for sum big type shi.
Contributors
- @Mjoyufull
- Co-authored-by: @coderabbitai (review and follow-up suggestions)
Compatibility
- Rust: 1.89+ stable (unchanged).
- Platforms: GNU/Linux and *BSD (unchanged).
- Config: config.toml structure and options remain compatible; no new required keys.
- Breaking: History, cache, and pinned apps use the new postcard format. First run after upgrade will reset/rebuild them. Back up or re-pin if needed.
[2.5.0-seedclay]
Added
from pr #22
- Advanced search ranking system
- 12-tier prioritization system with sophisticated scoring algorithm
- Prioritizes pinned apps, exact matches (app name and executable), prefix matches, and word-start matches
- Metadata matching on keywords and categories with configurable scoring
- Configurable prefix depth for fine-tuning when prefix matches take priority over fuzzy matches
- Frecency boost (additive) combined with fuzzy matcher scores for intelligent ranking
- Ensures the most relevant apps surface first, making it easy to find what you're looking for
from pr #21
-
Improved error handling for stale lock file cleanup (cclip mode)
- Better handling of corrupted or invalid PID values in lock files
- Graceful error recovery when lock file cleanup fails (non-blocking warnings)
- Prevents startup failures due to stale lock files from crashed processes
-
Version bump to 2.5.0-seedclay
Changed
-
Search ranking algorithm
- Replaced simple scoring with sophisticated 12-tier bucket system
- Pinned apps now have distinct priority tiers (120M-20M score range)
- Normal apps have separate tiers (90M-0 score range)
- Exact matches (app name and executable) prioritized over prefix matches
- Prefix matches prioritized over word-start matches within configurable depth
- Word-start matches prioritized over fuzzy matches
- Metadata matches (keywords, categories) receive dedicated scoring tiers
- Frecency boost applied additively after bucket scoring for fine-grained ranking
-
Search behavior
- Within prefix depth, prefix and word-start matches take priority over fuzzy matches
- Executable name matches receive 2x weight in fuzzy scoring
- Fuzzy matcher scores multiplied by 100 and added to bucket scores
- Frecency scores multiplied by 10 and added to final score for time-based prioritization
Fixed
- cclip mode lock file handling
- Stale lock files from crashed processes no longer block startup
- Corrupted lock files (invalid PID format) are automatically cleaned up
- Lock file cleanup errors are logged as warnings instead of fatal errors
- Better error messages when lock file operations fail
Technical Details
-
Search ranking implementation
- 12 distinct scoring tiers based on match type and pin status:
- Pinned App Name Exact: 120,000,000
- Pinned Exec Name Exact: 115,000,000
- Pinned App Name Prefix: 110,000,000
- Pinned Exec Name Prefix: 105,000,000
- Pinned App Name Word-Start: 100,000,000
- Pinned Exec Name Word-Start: 95,000,000
- Normal App Name Exact: 90,000,000
- Normal Exec Name Exact: 85,000,000
- Normal App Name Prefix: 80,000,000
- Normal Exec Name Prefix: 75,000,000
- Normal App Name Word-Start: 70,000,000
- Normal Exec Name Word-Start: 65,000,000
- Pinned Metadata Match: 40,000,000
- Normal Metadata Match: 30,000,000
- Pinned Fuzzy Match: 20,000,000
- Normal Fuzzy Match: 0 (base)
- Fuzzy matcher scores (from nucleo-matcher) multiplied by 100 and added to bucket score
- Frecency scores (from zoxide-style algorithm) multiplied by 10 and added to final score
- Prefix depth configuration (default: 3) determines when prefix/word-start matches take priority
- Word-start detection uses regex to find word boundaries in app names and executables
- 12 distinct scoring tiers based on match type and pin status:
-
Lock file cleanup
- Process existence check before attempting cleanup
- Graceful error handling with warning messages instead of fatal errors
- Non-interactive commands (tag clear, tag list, tag wipe) skip lock file checks entirely
- Lock file removal errors are logged but don't prevent startup
Documentation
-
README
- Added prominent feature description for advanced search ranking system
- Updated version references to 2.5.0-seedclay
-
Man page (fsel.1)
- Version updated to 2.5.0-seedclay
- Date updated to 2026-01-06
Notes
-
This is a MINOR release under SemVer:
- New features added in a backward-compatible manner (advanced search ranking, improved error handling)
- No breaking changes to config format or database schema
- Existing search behavior enhanced but remains compatible
-
Rationale:
- Advanced search ranking ensures users find the apps they're looking for faster
- 12-tier system provides clear prioritization hierarchy
- Improved lock file handling prevents frustrating startup failures
- Frecency integration maintains context-aware ranking while respecting explicit match quality
Contributors
Compatibility
- Rust 1.89+ (unchanged)
- GNU/Linux and *BSD (unchanged)
- Config and database formats remain compatible; no destructive schema changes
- Existing pinned apps and frecency data preserved
[2.4.0-seedclay]
Added
from pr #19
-
Async core & TEA-inspired UI
- Migrate main loop to tokio + ratatui using a state/message/update pattern inspired by The Elm Architecture.
- Enables non-blocking event handling and clearer state flow for future features.
-
Frecency ranking (Zoxide-style)
- Time-bucketed scoring combining recency and frequency for more contextually relevant results.
- Recently used apps (within 1 hour) get 4x boost; within 1 day get 2x; older entries are deprioritized.
- Automatic aging when total scores exceed threshold to prevent unbounded growth.
-
Parallel app scanning with jwalk + rayon
- Directory walking now uses jwalk for parallel filesystem traversal.
- Desktop file parsing parallelized with rayon for faster startup on systems with many apps.
- File list caching: subsequent launches skip directory walking entirely when no changes detected.
-
config-rs based configuration
- Replaced manual TOML parsing with config-rs for more robust config handling.
- Supports environment variable overrides with FSEL_ prefix.
-
Fullscreen image viewer input lock (cclip mode)
- Alt+i now enters a focused viewing mode where all input is ignored except Esc/q/Ctrl+C.
- Prevents accidental navigation or selection while examining clipboard images.
-
Version bump to 2.4.0-seedclay
Changed
-
Startup & loading
- Preserve synchronous, instant-visible startup while using async event loop internally.
- All apps loaded upfront before first render for instant display.
- App detection now caches the file list with directory mtime tracking; cache invalidates automatically when apps are added/removed.
-
UI parity & input behavior
- Restored legacy scroll physics and mouse-selection behavior to match v2.2.0 exactly.
- Input handling realigned so existing keybinds and selection UX remain consistent.
-
Ranking
- Frecency scoring replaces simple launch-count history for smarter app ordering.
- Pinned apps still take priority over frecency.
-
Dependencies & build
- Add tokio, ratatui, config-rs, jwalk, rayon (and small supporting crates). Expect a modestly larger binary.
Fixed
-
Parity regressions introduced during refactor
- Reinstated legacy scroll momentum and mouse selection semantics.
- Fixed rendering/input desyncs introduced during early async experiments.
-
Startup race conditions and graceful shutdown
- Deterministic drawing order and proper process cleanup on exit.
-
Config parsing robustness
- Legacy config keys handled with backward-compatible defaults and clearer error messages.
Technical Details
-
Runtime & UI
- Tokio is the async runtime; the app uses
block_on()to bridge async event handling with synchronous operations. - TEA-inspired pattern: State (model), Message (events), update() (state transitions), render() (view).
- Tokio is the async runtime; the app uses
-
App discovery
- jwalk provides parallel directory traversal (replaces walkdir for performance).
- rayon parallelizes desktop file parsing across CPU cores.
- File list cached in redb with directory mtimes; invalidates when directories change.
-
Frecency algorithm
- Zoxide-style time-bucketed scoring:
- Within 1 hour: score × 4
- Within 1 day: score × 2
- Within 1 week: score × 0.5
- Older: score × 0.25
- Automatic aging when total scores exceed 10,000 to prevent unbounded growth.
- Zoxide-style time-bucketed scoring:
-
Configuration
- config-rs loads defaults then merges user config → environment values.
- Existing config keys remain supported; no breaking changes to config format.
-
Persistence
- Frecency data stored in redb database alongside history and pinned apps.
- Existing history preserved; timestamps migrated seamlessly.
-
Safety
#![deny(unsafe_code)]at crate root; limited#[allow(unsafe_code)]only for necessary libc calls (process management).
Documentation
-
README / USAGE
- Updated with frecency ranking notes and current feature set.
-
Man page (fsel.1)
- Version updated to 2.4.0-seedclay.
- Added frecency description, --tag wipe option, improved examples.
Notes
-
This is a MINOR release under SemVer:
- New features added in a backward-compatible manner (async internals, frecency, parallel scanning).
- No breaking user-facing config keys removed; legacy parity prioritized.
-
Rationale:
- Async event loop enables responsive UI and lays groundwork for future background features.
- Frecency ranking surfaces relevant apps without manual pinning.
- Parallel scanning with jwalk/rayon significantly improves cold-start performance on large app collections.
Contributors
- @Mjoyufull
- Acknowledgements to @Marbowls for prior groundwork and testing.
Compatibility
- Rust 1.89+ (unchanged)
- GNU/Linux and *BSD (unchanged)
- Config and database formats remain compatible; no destructive schema changes.
[2.3.0-seedclay]
Added
- Clean fullscreen image preview in cclip (Alt+I)
- Kitty: clear screen, center image, position cursor at (0,0) for a clean background.
- Foot/Sixel: true fullscreen (full terminal size) with explicit pre-clear and top-left origin.
- Config error UX: duplicate key/table detection with actionable guidance
- Clear message when the same key/table appears more than once.
- Explains correct placement (root vs [dmenu] vs [cclip]) and avoiding repeated sections.
Changed
- Foot/Sixel clearing and redraw strategy
- On text↔image or “image changed” transitions, perform pre-draw terminal.clear(), then Clear all panels inside the draw to re-sync ratatui’s buffer and prevent missing glyphs.
- Keeps clearing targeted to panels; avoids full-screen flicker in normal navigation.
- Tag-mode image handling in cclip
- Entering tag edit/create clears the current image and suspends inline preview for the duration of tag mode; automatically resumes on exit.
- Kitty: use graphics protocol hide. Foot/Sixel: terminal.clear() + panel Clear to sync buffer.
- Rendering pipeline robustness
- Layout and wrapping calculations moved inside terminal.draw() so compute and render use identical dimensions.
- Removed post-draw clearing; now use Clear inside the draw pass for correct diffing.
- Process management API (Option A, non-breaking)
- Added kill_process_sigterm_result(pid) -> io::Result<()>, kept kill_process_sigterm(pid) wrapper.
- Lockfile semantics: only remove lock on Ok or ESRCH; preserve on EPERM/other errors.
- Version bumped to 2.3.0-seedclay (MINOR, backward-compatible).
Fixed
- Missing/disappearing characters in Foot due to out-of-sync screen clears.
- Fullscreen preview not truly fullscreen/centered across terminals.
- Lingering text artifacts at panel edges (panel Clear in-draw).
- Clippy warning (collapsed consecutive replace calls in content sanitizer).
Technical Details
- Terminal/graphics
- Kitty: use Clear widgets on panels for text, Kitty graphics protocol for image hide.
- Foot/Sixel: pre-draw terminal.clear() on image transitions; inside draw, Clear content/items/input panels so ratatui repaints all cells atomically.
- Synchronized updates (DECSET 2026) used around draw where appropriate to avoid mid-frame tearing.
- UI pipeline
- Wrapping and width measurement aligned with actual render area (computed inside draw).
- Inline image preview is suspended while in tag modes to prevent redraws during workflows.
- Config parsing
- read_with_enhanced_errors detects duplicate keys/tables and emits a professional, actionable message.
Documentation
- README: install/version references updated to 2.3.0-seedclay.
- Man page (fsel.1): version updated and key sections clarified.
- Usage notes: reflect clean fullscreen behavior and improved config error message.
Notes
- This is a MINOR release under SemVer:
- Backward-compatible features and UX improvements.
- No breaking API changes.
- Patch reset to 0.
Contributors
- Special thanks to @Marbowls for the original pr #17 and substantial groundwork:
- Introduced the fallible kill helper and improved lockfile semantics.
- Helped drive the Foot/Sixel clearing discussion and stability work.
- Follow-up integration, terminal-specific refinements, config error UX, and release prep by me.
Compatibility
- Rust 1.89+ (unchanged).
- GNU/Linux and *BSD (unchanged).
- Config and database formats remain compatible; no schema changes.
[2.2.3-seedclay]
[2.2.3-seedclay] - 2025-10-29
Fixed
- Completed selection reset refactor - removed leftover old logic in
app_ui.rsthat was causing inconsistent selection behavior when filtering (PR #16, continuation of #11) - Selection now properly resets to first item whenever filter query changes, matching behavior across entire codebase
Notes
PATCH version bump per Semantic Versioning 2.0.0 - backward compatible bug fix only.
Credits
- @walldmtd for catching the leftover logic and providing the fix
[2.2.2-seedclay]
Hotfix Release - UX improvement for tag operations.
Fixed
- Cursor Position: Cursor now stays on current item after tag operations
- Previously jumped to top of list after creating/editing/removing tags
- Now preserves both selection and scroll offset
- Applies to Ctrl+T (tag creation) and Alt+T (tag removal)
Changed
- Documentation: Clarified
--tag clearbehavior- Now explicitly states it only clears fsel's tag metadata (colors, emojis)
- Added notes about clearing cclip tags separately with
cclip tag -d <ID> - Updated in README.md, USAGE.md, fsel.1, and CLI help
Technical Details
- Scroll offset now preserved when reloading items after tag operations
- Selection restoration uses
old_scroll_offset.min(pos)to ensure visibility - Both tag creation and tag removal handlers updated
Compatibility
- Rust 1.89+ stable required (unchanged)
- GNU/Linux and *BSD support (unchanged)
- Config files fully compatible with 2.2.1
- No database schema changes
- All CLI flags backward compatible
[2.2.1-seedclay]
Hotfix Release - Critical bug fixes for cclip mode.
Fixed
- Lock File Issue: Non-interactive commands (
--tag clear,--tag list) no longer blocked by lock file check- Users can now run tag management commands while cclip TUI is open
- Lock file only created for interactive TUI mode
- UTF-8 Crash: Fixed panic when scrolling through clipboard items with multi-byte UTF-8 characters at 5000-byte boundary
- Content truncation now respects UTF-8 char boundaries
- No more crashes on Unicode characters like
─,│, emoji, etc.
- Invalid Command: Removed non-existent
cclip clear-tagscommand call--tag clearnow only clears fsel's tag metadata- Provides helpful instructions for manual cclip tag clearing
Technical Details
- Lock file check now skips for
cclip_clear_tagsandcclip_tag_listflags - Content truncation uses
is_char_boundary()to find valid UTF-8 boundary - Tag clear command updated with user-friendly guidance
Compatibility
- Rust 1.89+ stable required (unchanged)
- GNU/Linux and *BSD support (unchanged)
- Config files fully compatible with 2.2.0
- No database schema changes
- All CLI flags backward compatible
[2.2.0-seedclay]
Added
- Complete Tag System for Clipboard Items: Full-featured tagging system for organizing clipboard history
- Interactive Tag Creation (Ctrl+T in cclip mode):
- Multi-step wizard for creating tags with name, emoji, and color
- Browse and select from existing tags
- Edit existing tag metadata (emoji/color)
- Tag metadata stored in fsel's database
- Tag Removal (Alt+T in cclip mode):
- Remove individual tags from items
- Remove all tags at once (blank input)
- Interactive selection from item's tags
- Tag Filtering:
--tag <name>- Filter clipboard items by tag--tag list- List all available tags--tag list <name>- List items with specific tag (use-vvfor details)
- Tag Management:
--tag clear- Clear all tags and metadata from database--cclip-show-tag-color-names- Show color names in tag display (e.g.,[tag(blue)])
- Tag Display:
- Tags shown as
[tagname]prefix in clipboard list - Optional emoji prefixes (e.g.,
[📌 important]) - Color-coded tags with customizable colors
- Tag metadata (emoji, color) persists across sessions
- Tags shown as
- Tag Metadata Storage:
- Stored in fsel's redb database (separate from cclip)
- Supports hex colors, RGB, named colors, and 8-bit colors
- Emoji support for visual tag identification
- Interactive Tag Creation (Ctrl+T in cclip mode):
- Config Option:
show_tag_color_namesin[cclip]section for persistent color name display - Keybinds: Configurable tag keybind (default: Ctrl+T) in keybinds.toml
Changed
- Major Codebase Refactor: Reorganized flat module structure into hierarchical organization
src/common/- Shared item structures and utilitiessrc/core/- Cache and database operationssrc/desktop/- Desktop file handlingsrc/modes/- Mode-specific implementations (app_launcher, dmenu, cclip)src/ui/- UI components, graphics, input handling, keybinds
- Selection Reset Behavior: Selection and scroll offset now reset on filter changes (contributed by @walldmtd in #11)
- Matches rofi behavior for more intuitive filtering
- Selection no longer stays on stale positions when results change
- Improves UX when typing or using backspace in dmenu/filter mode
- Graphics Module: Moved from
src/graphics.rstosrc/ui/graphics.rs - Keybinds: Updated module path references from
crate::keybindstocrate::ui::keybinds - Sixel Image Clearing: Improved logic to prevent text corruption in Sixel terminals
Fixed
- Tag color names now display correctly in clipboard history UI when enabled
to_list_item()function now preserves formatted tag strings fromdisplay_text- Sixel terminal image clearing no longer wipes ratatui-drawn text
- Graphics state management race conditions further refined
Technical Details
- Module Organization: Better separation of concerns with clear module boundaries
- Code Maintainability: Improved code organization for easier navigation and maintenance
- Display State: Made
DisplayStatepublicly exported from graphics module - Tag System Architecture:
TagModeenum insrc/ui/dmenu_ui.rsfor tag UI state managementTagMetadatastruct insrc/modes/cclip/mod.rsfor tag dataTagMetadataFormatterfor consistent tag display formattingCclipItemstruct extended withtags: Vec<String>field- Tag metadata stored in redb
TAG_METADATA_TABLE - Integration with cclip's tag commands (tag, untag, clear-tags, list-tags)
- Tag Formatting: Fixed tag display pipeline to respect
include_color_namesparameter - Tag Keybinds: Added
matches_tag()method to Keybinds struct for configurable tag shortcuts
Documentation
- Updated README.md with:
- Tag system feature description
- Tag management CLI examples
- Tag keybind documentation (Ctrl+T, Alt+T)
- Updated USAGE.md with:
- Complete tag management section
- Interactive tag creation workflow
- Tag filtering examples
- Tag removal examples
- Updated man page (fsel.1) with:
- All tag-related CLI flags
- Tag keybind reference
- Tag usage examples
- Updated config.toml with:
show_tag_color_namesoption in[cclip]section- Tag-related comments and examples
- Updated keybinds.toml with:
- Tag keybind configuration (Ctrl+T)
- Untag keybind documentation (Alt+T, hardcoded)
- Tag workflow instructions
Notes
This is a MINOR version bump (2.1.1 → 2.2.0) per Semantic Versioning 2.0.0:
- New features added in backward compatible manner
- No breaking changes to existing functionality
- Internal refactoring does not affect public API
The codebase refactor improves maintainability without changing user-facing behavior. All existing features continue to work as before.
Contributors
Special thanks to:
Compatibility
- Rust 1.89+ stable required (unchanged)
- GNU/Linux and *BSD support (unchanged)
- Config files fully compatible
- No database schema changes
- All CLI flags backward compatible
[2.1.1-seedclay]
Fixed
- Restore full detach semantics so
--uwsm/--systemd-runlaunches no longer leak terminal control when invoked from otter-launcher, matching the 2.0.x behavior (src/helpers.rs). - Include the
--separator inuwsm app -- …invocations to ensure commands reach the intended target (src/helpers.rs).
Changed
- Bump release metadata to
2.1.1-seedclayacross Cargo.toml, Cargo.lock, flake.nix, and installation instructions in README.md.
Removed
unbind_proc = truefrom otter-launcher examples in USAGE.md; added guidance to leave it disabled for TUIs to avoid raw-input corruption.