diff options
| author | salmonik <raisersoft@proton.me> | 2026-06-06 19:50:57 +0300 |
|---|---|---|
| committer | salmonik <raisersoft@proton.me> | 2026-06-06 19:50:57 +0300 |
| commit | 74de13fa18ea7ea5ea95326265f1a598b1ccfb4e (patch) | |
| tree | 2107a8ffcc9e7f237e74723d36ae7737db9b12b5 | |
| parent | correctly working auto completion for db (diff) | |
| download | rsplayer-74de13fa18ea7ea5ea95326265f1a598b1ccfb4e.tar.gz rsplayer-74de13fa18ea7ea5ea95326265f1a598b1ccfb4e.zip | |
delete not needed md file
| -rw-r--r-- | PLAN.md | 135 |
1 files changed, 0 insertions, 135 deletions
diff --git a/PLAN.md b/PLAN.md deleted file mode 100644 index baff505..0000000 --- a/PLAN.md +++ /dev/null | |||
| @@ -1,135 +0,0 @@ | |||
| 1 | # Dynamic Shell Autocompletion for Artists/Albums/Tracks | ||
| 2 | |||
| 3 | ## Problem | ||
| 4 | |||
| 5 | `rsp play <query>` and `rsp queue <query>` accept freeform strings. No tab-completion for artists, albums, or tracks from the SQLite library DB. User must type full path or query blindly. | ||
| 6 | |||
| 7 | ## Approach: Direct DB read (no daemon dependency) | ||
| 8 | |||
| 9 | Hidden CLI subcommand `rsp complete <entity> [prefix]` that: | ||
| 10 | 1. Opens DB directly (same as `rsp scan` at cli.rs:204-205) | ||
| 11 | 2. Queries with prefix match | ||
| 12 | 3. Prints newline-separated results to stdout | ||
| 13 | 4. Returns empty on error (never crash completion) | ||
| 14 | |||
| 15 | Works with or without daemon running. SQLite prefix query is ~1ms. | ||
| 16 | |||
| 17 | ## Steps | ||
| 18 | |||
| 19 | ### 1. Add completion query methods to `Database` (`src/database.rs`) | ||
| 20 | |||
| 21 | ``` | ||
| 22 | pub fn complete_artists(&self, prefix: &str) -> SqlResult<Vec<String>> | ||
| 23 | pub fn complete_albums(&self, prefix: &str) -> SqlResult<Vec<String>> | ||
| 24 | pub fn complete_tracks(&self, prefix: &str) -> SqlResult<Vec<String>> | ||
| 25 | ``` | ||
| 26 | |||
| 27 | SQL: | ||
| 28 | - artists: `SELECT name FROM artists WHERE name LIKE ? ORDER BY name` | ||
| 29 | - albums: `SELECT title FROM albums WHERE title LIKE ? ORDER BY title` | ||
| 30 | - tracks: `SELECT title FROM tracks WHERE title LIKE ? ORDER BY title` | ||
| 31 | |||
| 32 | Prefix `"a"` → `LIKE 'a%'`. Limit results (e.g. 25). | ||
| 33 | |||
| 34 | ### 2. Add hidden `DbComplete` subcommand (`src/cli.rs`) | ||
| 35 | |||
| 36 | ``` | ||
| 37 | #[clap(hide = true)] | ||
| 38 | DbComplete { | ||
| 39 | entity: String, // "artists", "albums", "tracks" | ||
| 40 | prefix: Option<String>, | ||
| 41 | } | ||
| 42 | ``` | ||
| 43 | |||
| 44 | Dispatch in `Cli::run()`: | ||
| 45 | ``` | ||
| 46 | Commands::DbComplete { entity, prefix } => { | ||
| 47 | let config = Config::load()?; | ||
| 48 | let db = Database::open(&config)?; | ||
| 49 | let results = match entity.as_str() { ... }; | ||
| 50 | for r in results { println!("{r}"); } | ||
| 51 | } | ||
| 52 | ``` | ||
| 53 | |||
| 54 | Errors → silent empty (stderr) so completion never breaks. | ||
| 55 | |||
| 56 | ### 3. Filter `DbComplete` out of generated completions (like `Completions`) | ||
| 57 | |||
| 58 | In `Completions` generation (cli.rs:238-253): filter `s.get_name() != "db-complete"`. | ||
| 59 | |||
| 60 | ### 4. Dynamic zsh completion function | ||
| 61 | |||
| 62 | Replace `/usr/share/zsh/site-functions/_rsp` with a wrapper that: | ||
| 63 | |||
| 64 | ```zsh | ||
| 65 | #compdef rsp | ||
| 66 | # Static part (generated by clap) | ||
| 67 | _rsp_command() { ... } # clap-generated | ||
| 68 | |||
| 69 | # Dynamic overrides | ||
| 70 | _rsp() { | ||
| 71 | case $line[1] in | ||
| 72 | play|queue) | ||
| 73 | if compset -P 1; then | ||
| 74 | # Subcommand → complete tracks/artists/albums | ||
| 75 | local -a suggestions | ||
| 76 | suggestions=(${(f)"$(rsp complete tracks "$words[CURRENT]")"}) | ||
| 77 | suggestions+=(${(f)"$(rsp complete artists "$words[CURRENT]")"}) | ||
| 78 | suggestions+=(${(f)"$(rsp complete albums "$words[CURRENT]")"}) | ||
| 79 | compadd -a suggestions | ||
| 80 | else | ||
| 81 | _rsp_command | ||
| 82 | fi | ||
| 83 | ;; | ||
| 84 | *) | ||
| 85 | _rsp_command | ||
| 86 | ;; | ||
| 87 | esac | ||
| 88 | } | ||
| 89 | ``` | ||
| 90 | |||
| 91 | For `play <query>`, complete artists + albums + tracks. | ||
| 92 | Where artists have the biggest priority, then comes albums and at the end tracks. | ||
| 93 | Additionally, when we have autocompleted an artist, put a '/' after the name. Next autocompletions will autocomplete albums/tracks, do the same for albums. | ||
| 94 | |||
| 95 | ### 5. Update `Completions` generation to produce the wrapper | ||
| 96 | |||
| 97 | In `cli.rs`, after `generate()` for zsh, append the dynamic wrapper code. The generated file becomes: `clap-generated-code` + `_rsp() { ... dynamic ... }`. | ||
| 98 | |||
| 99 | Or simpler: write the wrapper as `completions/_rsp.dynamic` and concatenate in install.sh. | ||
| 100 | |||
| 101 | ### 6. Update `install.sh` | ||
| 102 | |||
| 103 | Replace `rsp completions zsh | sudo tee ...` with: | ||
| 104 | ```bash | ||
| 105 | (rsp completions zsh; echo; cat completions/_rsp) | sudo tee "$dest" | ||
| 106 | ``` | ||
| 107 | |||
| 108 | ### 7. Update `TODO.md` | ||
| 109 | |||
| 110 | Mark "[x] Dynamic autocompletion of artists, albums and tracks" | ||
| 111 | |||
| 112 | ### 8. Tests | ||
| 113 | |||
| 114 | Add tests in `tests/database.rs`: | ||
| 115 | - `test_complete_artists_prefix` | ||
| 116 | - `test_complete_albums_prefix` | ||
| 117 | - `test_complete_tracks_prefix` | ||
| 118 | - `test_complete_empty_db` | ||
| 119 | - `test_complete_no_match` | ||
| 120 | |||
| 121 | Need a test helper that creates a temp DB with known data, runs queries, checks results. | ||
| 122 | |||
| 123 | ## Files changed | ||
| 124 | |||
| 125 | | File | Change | | ||
| 126 | |------|--------| | ||
| 127 | | `src/database.rs` | +3 pub methods (complete_artists/albums/tracks) | | ||
| 128 | | `src/cli.rs` | +DbComplete variant, +dispatch, +filter in Completions | | ||
| 129 | | `completions/_rsp.dynamic` (new) | zsh dynamic completion wrapper | | ||
| 130 | | `install.sh` | concatenate static + dynamic | | ||
| 131 | | `tests/database.rs` | +completion query tests | | ||
| 132 | |||
| 133 | ## Future: fish/bash | ||
| 134 | |||
| 135 | Same pattern. Fish uses `complete -c rsp -n '__fish_seen_subcommand_from play' -a '(rsp complete tracks (commandline -ct))'`. Bash uses `COMPREPLY=($(compgen -W "$(rsp complete tracks "$cur")" -- "$cur"))`. Start with zsh only (user's shell). | ||
