| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
| |
The F10 playlist docked as a right-side column when the frame was wide enough, splitting the frame three ways. That's annoying and often unexpected, so the frame's shape no longer decides where the playlist goes.
I deleted the chooser (cj/--music-playlist-side) and the right-dock width knobs rather than leaving them wired to nothing, and a test asserts they're gone. cj/preferred-dock-direction stays, since ai-term and eat still dock by frame shape.
The old side-chooser test is replaced by one that stubs cj/side-window-display and asserts what the toggle asks for, so it runs headless.
|
| |
|
|
|
|
| |
The two radio search commands were reachable only as n/t inside the playlist buffer, and R jumped straight into the manual name+URL entry. r is now a radio prefix with the same letters the playlist's Radio row uses: n searches by name, t by tag, m is the manual entry.
The rest of the menu's uppercase keys moved to lowercase homes: v shows the playlist (was M), u shuffles (was Z), and repeat-playlist moved from r to l to free the radio prefix. In the playlist buffer, save moved from w to v.
|
| |
|
|
|
|
|
|
| |
The radio-browser lookup and the manual station creator no longer write .m3u files at pick time. Picks become url tracks in the queue, carrying the station name, uuid, and favicon as track properties, and play immediately. The display and cover-art layers read the properties first and fall back to the on-disk metadata, so existing station files keep working.
Saving is the normal playlist save, now on w. The radio feature's S=stop rebind had silently shadowed the old S=save binding. An all-stream queue saves into the MPD playlist dir, and the station name pre-fills the prompt with no -Radio suffix. A custom emitter writes the station metadata back out as .m3u comment lines, since the stock EMMS writer emits bare URLs and would lose names and cover art on reload.
I removed the write-at-pick machinery (station-m3u, write-stations, disambiguate-name, the -Radio filename suffix) and the orphaned safe-filename helper. An empty name at the save prompt now signals an error instead of writing a hidden .m3u.
|
| |
|
|
|
|
|
|
|
|
| |
Phase 3 is the fancy visual layer from the prototype. In a graphical frame with cj/music-fancy-ui on, the player draws a now-playing hero (cover image, a serif amber title, a subtitle, and a progress bar) with thumbnailed serif rows below it. A TTY frame, or the toggle off, falls back to phase 1's plain text.
The progress bar had a rendering but no data source. I added cj/music--mpv-get-property, which does an IPC round-trip that reads mpv's reply, so a file's bar fills from percent-pos. The old cj/music--mpv-command only sent commands and threw the reply away. A stream has no duration, so it shows "on air". The bar redraws on a ~1s timer that runs only across a playing span and skips when the buffer isn't visible.
I split cj/music--header-text into shared playlist and controls pieces with a text-versus-fancy dispatcher, so the two render paths build from one place and can't drift. The hero replaces the Current line when a track plays. Rows gain a cover thumbnail and a serif name. Cover art comes from phase 2's non-blocking cj/music-art--for-track. A separate idle-timer pre-warm fetches the real art off the render path, so a slow favicon host never freezes playback start.
The serif family defaults to the nov reading view's, and the amber comes from the themed warning face so the dupre theme owns it. The block-bar renderer has Normal, Boundary, and Error tests. The images, faces, and the bar advancing are a live check. The full suite is green.
|
| |
|
|
|
|
|
|
|
|
| |
Phase 2 gives each track a local cover-image path so phase 3's GUI has art to draw. A radio station uses its logo, a local file a sibling cover image, and anything without either falls back to a shipped vinyl placeholder.
I consolidated the .m3u parse into one richer cj/music--m3u-entries that reads :name, :uuid, and :favicon per station. Phase 1's cj/music--m3u-labels is now a thin projection of it, so names and art share a single cached disk read. New stations capture their favicon into a #RADIOBROWSERFAVICON line at creation, so most need no lookup later. A legacy station with only a UUID resolves its favicon through a byuuid call.
The render path never touches the network. cj/music-art--for-track reads only the cache and returns the placeholder until art exists. cj/music-art--ensure does the blocking fetch off that path. A fetched response is validated as an actual image before it's cached, so an HTML error page or an empty body becomes the placeholder, not a poisoned cache entry. Only http and https URLs are fetched, so an external favicon field can't reach a file:// resource. Art lands under data/music-art/, keyed by UUID or a file hash. cj/music-clear-art-cache empties it, with no automatic expiry.
The pure helpers carry the tests: the parser, the cache key, the favicon URL, and the image validation, each with Normal, Boundary, and Error cases. The fetch, the byuuid lookup, and the placeholder fallback are verified live against a real station. Local files use a sibling cover image for now. Embedded-tag extraction is deferred. The full suite is green.
|
| |
|
|
|
|
|
|
|
|
| |
The EMMS playlist showed the raw stream URL for every radio track, so the buffer read like a debug log. This is phase 1 of the fancy player: real names, still plain text. It ships on its own and becomes the fallback for the image and GUI phases.
I split the old cj/music--track-description into a pure, name-only cj/music--display-name that the header's Current line and the row renderer both call, so the two never drift. A url track resolves to its #EXTINF label (read once from all the playlist .m3u files into a cached map) or a tidied host. A file shows Artist - Title or its filename. The row renderer adds a dim nerd-icon glyph and the duration as right-aligned meta with an :align-to space, so it survives a window resize. The header line stays clean: just the name plus an on-air or duration suffix.
The pure helpers carry the tests: display-name, tidy-host, m3u-labels, bar-fill, format-meta, Normal/Boundary/Error each (32 tests across four files). The glyph, the aligned meta, and the disk-backed name map are the thin composition, verified live against 44 real stations.
The progress bar's visual and its live elapsed source come in phase 3. The bar-fill helper is the tested pure core it will feed. The full suite is green.
|
| |
|
|
|
|
|
|
| |
I turned the radio-browser lookup into a Radio row in the playlist buffer: n searches by station name, t searches by tag/genre, m enters a station by hand. Tag search is new (it was a vNext item), and both name and tag hit radio-browser's search endpoint with a name= or tag= field.
Freeing n and t moved two keys: single mode goes from t to s, and stop goes from s to S. The header gains a Radio row and the Mode row now reads [s] single. Created station files carry a -Radio suffix (Adroit_Jazz_Underground-Radio.m3u).
The pure pieces and the search-URL field are unit-tested (20). Name and tag searches are live-verified. The picker and playback stay a manual check.
|
| |
|
|
|
|
| |
I wired up the interactive side of the radio-browser lookup: cj/music-radio-search, bound to S in the EMMS playlist buffer (s stays emms-stop). It searches, lists the matches annotated with codec, bitrate, country, votes, and tags, and lets you pick several one at a time. Selection is a completing-read loop with a "[done]" sentinel that removes each pick from the pool, so a station name with a comma can't be mis-split. Each pick is written into the save directory (no-URL stations skipped and named, colliding filenames disambiguated by UUID), then the selection plays through mpv, interrupting whatever was on.
The dedup and write-collect logic are unit-tested. The picker and playback are left to a manual check.
|
| |
|
|
|
|
|
|
| |
I built the first phase of the radio-browser lookup: the pure pieces and the network client behind the search command, with no UI yet. It lives in modules/music-config.el, alongside the existing radio-station creator.
The client is url.el plus json-parse-string, trying a pinned host and falling back to one from /json/servers. The pure layer parses a response into station plists, and a non-JSON body signals a clear user-error rather than a stack trace. It picks a station's stream URL (url_resolved, then url), emits the .m3u in the existing radio format with the radio-browser UUID, formats the completion annotation (codec, bitrate, country, votes, tags), and disambiguates a colliding filename by UUID. Names are newline-stripped so an odd one can't inject extra m3u lines.
The pure pieces are unit-tested (14). The network client is smoke-tested against the live API.
|
| |
|
|
|
|
|
|
| |
The MPD radio-stream playlists moved into version control at ~/.local/share/mpd/playlists/, while the 24 local-library playlists stay at ~/music/. MPD has a single playlist_directory and its load only sees that one, so the union has to happen at the Emacs layer.
I added cj/music-m3u-roots, a precedence-ordered list of directories the reading path unions (get-m3u-files, basenames, select, load). Missing directories are skipped. On a basename collision the earlier root wins, so a local playlist shadows a same-named radio one. Saving and radio-station creation still target the single cj/music-m3u-root. Radio .m3u hold stream URLs, which the track reader and the mpv subprocess already handle, so nothing else changed to play them.
The two tests that pinned the old single-directory contract now bind the list. Their "missing directory signals an error" cases became "missing directory is skipped" to match the new behavior.
|
| |
|
|
|
|
|
|
|
|
| |
Eight completing-read pickers listed bare file basenames, so marginalia had no directory to resolve and couldn't annotate them. Add cj/completion-file-annotator to system-lib — an annotation-function factory that takes a candidate->path resolver and yields a size + modification-date suffix (or "dir" for directories, nil for missing files). Wire each picker through cj/completion-table-annotated with a per-site category and resolver: timer sounds, drill flashcards, Info files, the test-runner focus add/remove, vc clone dirs, hugo drafts, and agenda projects (the project's todo.org mtime). music-config's existing completion table gains the category and annotator inline, keeping its sort metadata.
The candidate strings and every return value are unchanged — this only adds completion metadata — so all downstream logic is untouched. The six modules that didn't already pull in system-lib now require it.
Tests: cj/completion-file-annotator gets Normal/Boundary/Error coverage (file, directory, nil path, missing file). Full suite green at 5394.
Claude-Session: https://claude.ai/code/session_014fyKMTTqLrZpL3rDF3dYc3
|
| |
|
|
| |
The route-colors pass dropped the literal cj/music-* face definitions but left the playlist header referencing them, so every header render spammed "Invalid face reference". I restored the five as deffaces that inherit themed base faces, so the theme still owns their colors. A test asserts each referenced face is defined.
|
| |
|
|
| |
22 module headers carried long user-manual commentaries (quick-starts, keybinding matrices, setup walkthroughs) that belong in user docs, not source. Each now states the purpose, load contract, and entry points tersely. ai-term also drops its stale F9 keybinding references (the scheme is C-; a plus M-SPC now) and a header line claiming a vertical-split that's really host-aware.
|
| |
|
|
| |
The subprocess player I just switched to dropped in-track seek. I re-added it without the startup fragility that made the IPC player unreliable. mpv still plays the track as a direct argument, so the reliable start is untouched, and --input-ipc-server opens a control socket that only carries seek commands to the already-playing process. f and b seek by cj/music-seek-seconds (default 5). The socket send is a no-op when nothing is playing, so it never errors.
|
| |
|
|
| |
EMMS drove mpv over an IPC socket, starting it idle and sending loadfile across the socket. That handshake left mpv loaded but never streaming, so playback silently failed and the playing flag never set. I replaced it with a subprocess player that runs mpv with the track as a direct argument, the invocation that plays every time. Pause works in place through process signals, SIGSTOP and SIGCONT. In-track seek is gone, the deliberate trade for reliability. --no-config isolates this mpv from the interactive video setup so the two cannot interfere, and it follows the system default audio sink.
|
| |
|
|
| |
Remove every hardcoded color from the config so nothing assigns a non-themeable value. Stripped: the org-faces defface defaults (28 hex foregrounds, which the theme overrides at runtime anyway), the hl-todo keyword colors, the eshell prompt gray/white, the org-noter and music active-window #1d1b19 bg tint (face-remap is now a no-op), the pdf-view midnight palette, and the calibredb/nov epub sepia. The config now renders with default/theme faces, which surfaces where theming support is missing. Those gaps are tracked in todo.org as the next phase. 0 hex colors remain; validate-modules clean and the org-faces/build-theme/face-diagnostic tests pass.
|
| |
|
|
|
|
| |
Move own-command bindings out of use-package :bind to keymap-global-set / with-eval-after-load (C-c C-a org-appear-toggle, R music radio-station, C-c n r/t roam recipe/topic) — same keys, verified live. Pull music-config helper defuns out of :config/with-eval-after-load to top level (their proper home; emms referenced only at call time via declare-function). Swap obsolete org-show-all for org-fold-show-all (9.6). Plus declare-function/defvar for lazy symbols. No behavior change; full suite + launch smoke green.
Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
|
| |
|
|
|
|
| |
Byte-compile flagged three let-bindings of package vars as unused lexical variables — under lexical-binding they compiled to dead locals the package never saw, so the intended behavior silently never happened. Declare each var special so the binding is dynamic: music-config now actually suppresses the emms overwrite prompt on playlist save (emms-source-playlist-ask-before-overwrite) and turns off orderless smart-case for the music picker; org-roam copy-todo-to-today now actually applies its custom dailies capture template. Same class as the coverage-core json fix.
Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
|
| |
|
|
|
|
| |
The F9 agent always docked as a right-side column on a landscape frame. On this 138-column frame that left ~68-column panes, too cramped to read code and the agent side by side. The F12 terminal and F10 playlist hardcoded a bottom split with no width-aware path.
I added cj/preferred-dock-direction and the cj/window-dock-min-columns defcustom (default 80) to the window-geometry lib: dock side-by-side only when the narrower pane keeps at least the minimum width, otherwise stack below. All three toggles now route through it. F9 drops its pixel-aspect rule. F12 and F10 gain a right-column width default and become adaptive. F10 keeps width and height size memory in separate vars so a resize on one axis doesn't leak to the other.
|
| |
|
|
| |
Strip per-module face configuration so the active theme is the single source of face styling. Removed the dired text-greying set-face-attribute calls (kept the buffer-local face-remap), the org appearance set-face-attribute calls, the highlight-indent-guides colors, the rainbow-delimiters depth colors (which were overriding the theme's blue with red), and the cj/music-* defface forms plus the emms-playlist custom-set-faces. Left nerd-icons' set-face-foreground alone, since it's runtime tint logic rather than static config. Each touched file is backed up beside it as <name>.el.faces.bak (untracked). The cj/music-* faces now come from the theme instead of the module, so until the theme provides them music rendering falls back to the default face.
|
| |
|
|
|
|
|
|
|
|
| |
Lock screen: slock is X11-only and never grabbed the Wayland session, so C-; ! l silently did nothing. On Wayland the locker now runs loginctl lock-session, which logind turns into a Lock signal that hypridle handles by running hyprlock, the same path idle and before-sleep locking already use. X11 keeps slock. system-commands.el now also requires host-environment, which it used at load time but never declared.
Confirmation tier: the global (fset 'yes-or-no-p 'y-or-n-p) plus use-short-answers t both flattened yes-or-no-p to a single keystroke, so the deliberate strong-confirm tier for irreversible actions was dead. A stray space could power off the machine or destroy files. I added cj/confirm-strong, which binds use-short-answers nil for one call to force a typed "yes", and routed the six irreversible sites through it (shutdown/reboot, permanent file destruction, file overwrites). I dropped the redundant fset and kept use-short-answers t so ordinary prompts stay single-key.
Mail folders: the cmail context set no trash folder, so D fell back to a nonexistent /trash, and no context set a refile folder, so r targeted a nonexistent /archive everywhere. Accepting mu4e's offer to create the maildir stranded mail where mbsync never syncs it. cmail now trashes to /cmail/Trash. Refile is computed per message rather than per context, because mu4e context :vars are sticky and a per-context refile would leak one account's archive folder into another. cmail archives to /cmail/Archive. The Gmail-backed accounts have no synced archive maildir, so they signal rather than move mail into an unsynced folder.
Lock and confirm-tier need a daemon restart to fully take effect. The mail changes apply on next mu4e open.
|
| |
|
|
|
|
|
|
|
|
| |
The F10 music playlist opened at a fixed fraction every time, so any manual resize was lost the moment it was toggled closed. Now the toggle captures the window's size on close and reopens at that height, for the rest of the session.
The mechanism is generic, not music-specific. cj/window-size-fraction (geometry-lib) is the pure kernel: a clamped window/frame ratio. cj/side-window-capture-size and cj/side-window-display (toggle-lib) wrap it for any display-buffer-in-side-window consumer — height for top/bottom, width for left/right — storing the remembered fraction in a caller-supplied state var. It mirrors the direction-split toggle pattern the vterm dispatchers already use, but for atomic side windows that can't be split.
music-config wires F10 to it: cj/music-playlist-window-height is the default, cj/--music-playlist-height holds the remembered value (in-memory, resets each session).
12 new tests across the two libs, Normal/Boundary/Error each covered.
|
| |
|
|
|
|
| |
Migrated all 31 cj/custom-keymap registration sites across 24 modules from direct (keymap-set cj/custom-keymap ...) calls to cj/register-prefix-map and cj/register-command. Consumers no longer reference cj/custom-keymap directly, so keybindings.el is the sole owner of the C-; prefix and modules reach it only through the API (each already requires keybindings from Phase 2).
Behavior-preserving: I dumped every C-; binding before and after the migration and they're identical: 279 bindings, each resolving to the same command. The which-key label blocks are untouched, since they use string key descriptions and never assumed the keymap existed. I byte-compiled all 24 files (no new free-variable warnings, because the cj/custom-keymap references are gone), and make test, validate-modules, and an init load all pass.
|
| |
|
|
|
|
| |
Final classification batch: the last 19 modules — linear-config, local-repository, lorem-optimum, mail-config, markdown-config, music-config, pdf-config, quick-video-capture, reconcile-open-repos, restclient-config, slack-config, system-commands, telega-config, tramp-config, transcription-config, video-audio-recording, vterm-config, weather-config, wrap-up. I annotated each header, added a Batch 9 table to the inventory, and extended the validation allowlist. 101 of 102 modules are now classified; only elfeed-config remains, deferred on its test fix.
Two more hidden dependencies turned up. video-audio-recording uses the boundp shim for its C-; r binding, and mail-config registers C-; e directly without requiring keybindings, so it errors standalone rather than degrading. Both recorded for Phase 2.
|
| |
|
|
|
|
|
|
| |
`make validate-modules` had 19 module-load failures, all the same shape: a module references a symbol or feature owned by another module without saying so. Production was fine because init.el orders requires correctly. The batch target loads each module in isolation, though, and surfaces the gap.
I added explicit `(require 'keybindings)` or `(require 'user-constants)` to each affected module. The requires are idempotent at runtime, so production load order is unchanged. For three optional packages (elpa-mirror, mu4e, org-contacts), I switched to `(require 'X nil t)` so the modules load cleanly when those packages aren't installed. The activation calls become no-ops in that case.
`make validate-modules` now reports 0 failures.
|
| |
|
|
|
|
|
|
|
|
| |
Music: random mode now respected by next/previous keys. Previous navigates
a 50-track play history ring buffer. Fixed playlist replacement bug.
24 new tests.
Calendar-sync: consolidated duplicate parse functions, extracted timezone
localization helper, unified expand-daily/monthly/yearly into parameterized
function, removed dead code. 33 new characterization tests. -90 lines.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Add 47 new unit tests across 7 test files covering playlist-modified-p,
assert-valid-playlist-file, playlist-tracks, create-radio-station,
ensure-playlist-buffer, after-playlist-clear, and header-text.
Extract three helpers to reduce duplication: assert-m3u-files-exist (dedupes
2 identical guards), sync-playlist-file (dedupes 3 state-sync patterns),
and select-m3u-file (reusable M3U selection with cancel). Simplify
append-track-to-playlist nesting from 6 to 4 levels. Delete unused
cj/music-keymap-prefix variable.
|
| | |
|
| |
|
|
|
| |
Bind orderless-smart-case to nil in cj/music-fuzzy-select-and-add
so typing uppercase characters doesn't switch to case-sensitive matching.
|
| |
|
|
|
|
|
|
|
|
|
| |
Replace raw file paths with clean track descriptions (Artist - Title [M:SS]),
add multi-line header overlay showing playlist info, now-playing, mode
indicators with gold/muted toggle states, and keybinding hints. Style
non-playing tracks in Dupre steel, playing track in Dupre gold. Playlist
window now opens from the bottom at 50% height with subtle background
highlight on focus.
Unit tests for format-duration (13 tests) and track-description (16 tests).
|
| |
|
|
|
|
| |
Document playlist-mode keybindings with ncmpcpp default alignment
status (83% match). Note intentional divergences (SPC/p swap,
x=consume vs crossfade) and EMMS-only features.
|
| |
|
|
|
|
|
|
|
|
| |
Reconcile playlist-mode bindings with ncmpcpp defaults: add ncmpcpp-
compatible aliases (>/<, +, S-up/S-down, c), new toggles (r repeat,
t repeat-track, z random, x consume), info keys (i, o), and relocate
radio (r→R), reload (R→g), shuffle (x→Z). Add consume mode that
removes tracks from playlist after playback via emms-player-finished-
hook. Fix buffer-local bug where emms-playlist-selected-marker was
checked outside with-current-buffer. 13 ERT tests.
|
| |
|
|
| |
Bind + to cj/music-add-dired-selection in dirvish-mode-map.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- Fix dwim-shell-commands-menu keybinding in dirvish/dired
- Remove :after (dired dirvish) which prevented package loading
- Add :demand t to load package immediately at startup
- Move keybindings inside :config block after menu function definition
- M-D now works immediately in dirvish without manual trigger
- Enhance extract-audio-from-video function
- Fix :extensions parameter (was regex string, now proper list)
- Change from copy to AAC re-encoding for codec compatibility
- Add interactive bitrate selection (64k/96k/128k/192k)
- Fixes Opus codec compatibility issues with M4A containers
- Remove conflicting keybindings
- Remove music-config p binding in dirvish (was overriding path copy)
- Clean up extraneous requires/hooks from troubleshooting
- Add TODO for dwim-shell-command status dashboard [#D priority]
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Major improvements to music player configuration:
Backend Changes:
- Switch from emms-player-mpd to emms-player-mpv
- Remove MPD daemon dependency (no service management required)
- Configure MPV with --quiet, --no-video, --audio-display flags
- Support both local files and streaming URLs (http/https/mms)
Keybinding Enhancements:
- Add C-; m n → next track
- Add C-; m p → previous track
- Add C-; m g → go to playlist
- In playlist: n/P for next/prev, f/b for seek forward/backward
- Update which-key descriptions
Code Quality:
- Use music-dir constant from user-constants.el (not hardcoded path)
- Add (require 'user-constants) for proper dependency
- Update commentary to reflect MPV backend
Test Fixes:
- Fix 8 failing append-track tests
- Update test mock data to use cj/music-root for portability
- All 104 music-config tests now passing
Benefits:
- No daemon to start/stop/manage
- Simpler architecture (one process vs MPD+EMMS)
- Streaming radio URLs work out of the box
- Better path consistency across codebase
|
| |
|
|
|
|
|
|
| |
Changed cj/music--append-track-to-m3u-file to convert absolute paths
to relative paths from cj/music-root before writing to M3U files.
This fixes playlist loading in Mopidy, which expects relative paths
in M3U files based on the configured base_dir.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
todo.org updates:
- Added 2 new inbox items about printing keybindings
- Reordered Method 1 tasks by priority
- Removed blank lines (linter formatting)
music-config.el improvements:
- Added validation checks to cj/music--valid-file-p and cj/music--valid-directory-p
- Fixed regex escaping in cj/music--m3u-file-tracks
- Added new cj/music--append-track-to-m3u-file function for testing
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Enhance which-key integration by providing detailed descriptions for
new key bindings across multiple modules. This improves the
usability of custom keymaps by clarifying the purpose of each
keybinding, making it easier for users to navigate and understand
different menus and options available within the configuration.
This update ensures that all custom keymaps now display a
descriptive label in the which-key popup to explain their
functionality, aiding users in identifying keymap purposes promptly.
|
| |
|
|
|
|
|
|
|
|
| |
Refactor the keymap definitions across multiple modules by replacing
`define-prefix-command` with `defvar-keymap`. This simplifies the
keymap setup and integrates better with the `which-key` package for
enhanced documentation and usability. Updated modules include
custom-ordering, custom-text-enclose, custom-whitespace,
mail-config, music-config, org-drill-config, test-runner, and
vc-config.
|
| |
|
|
|
|
|
|
|
| |
Deleted eradio-config.el file as it is no longer needed. Refactored
music-config.el to improve readability and maintainability by
removing unused autoload directives, unnecessary eval-when-compile
blocks, adjusting indentation, and enhancing the setup function for
EMMS. Additionally, removed duplicate code and ensured playlist
handling is more robust.
|
| |
|
|
|
|
|
|
| |
Optimized key binding configurations across modules for consistency
and reduced redundancy. Improved conditional requiring to handle
errors gracefully in `music-config.el`, ensuring robustness across
different machine environments. Eliminated comments clutter and
adjusted function definitions to adhere to revised standards.
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
|
| |
Simplified EMMS configuration:
- restructured helper functions
- standardized error handling
- removed redundant wrappers
- ensured buffer state synchronization
- improved Dired/Dirvish integration for playlist management
|
| | |
|
| | |
|
| | |
|
| |
|