Multiplicative is an mpv extension that adds a variety of useful features and improvements, with an emphasis on usability, consistency, and dynamism.
- Usability: All commands are invoked via a system of hierarchical mnemonic keybindings.
- Consistency: Commands have consistent, predictable names and aliases.
- Dynamism: Keybindings and command, function, and variable documentation is introspectable at runtime.
A major effort is made to keep the code clean, well-documented, and beautiful. For this reason, among others, Multiplicative is written in Fennel–a Lisp-like language that compiles to Lua–rather than Lua directly.
When writing keybindings, we sometimes use Emacs-style keybinding notation:
C-
- Ctrl+key.M-
- Meta+key. On Linux and Windows, Meta is theAlt
key, while on macOS, it’sCommand
.s-
- Super+key. On many keyboards, the Super key is printed with the Windows logo.
Examples:
C-f
- HoldCtrl
, tapf
, then releaseCtrl
.M-.
- HoldAlt
, tap.
, then releaseAlt
.C-h k
- HoldCtrl
, taph
, releaseCtrl
, then tapk
.C-1 M-x foobar RET
- HoldCtrl
, tap1
, releaseCtrl
, holdAlt
, tapx
, releaseAlt
, typefoobar
, then tapEnter
.
- Fennel REPL (
:
orM-:
). - “Frame” stepping for audio files (
.
and,
when an audio file is playing).
- Copy path/URL to clipboard, including timestamp if the media is being played from YouTube (
c
). - Directory jumping (
N
andP
to jump to the next/previous playlist item in a different directory). - Auto-copy screenshot path to clipboard when taking a screenshot (
s
, orS
to screenshot without subtitles). - Delete/trash current file (
D
, plus optionsdelete-command
,trash-command
, anddelete-by-trashing
). - Open the media’s directory contents in a new mpv instance (
v
). - Open the media in your browser (
B
, plus optionbrowser
). - Open the containing directory or URL of the media in your file manager or browser (
M-.
, plus optionfile-manager
). - Better xscreensaver prevention (only prevent screensaver if the media has audio (i.e. is not a gif) and is playing unmuted).
- Option to exit mpv 5 seconds after the end of the playlist (option
pre-exit-pause-time
). - Option to log the date/time, path/URL, and title of played media (options
record-history
,history-log-filename
, andhistory-exclusion-pattern
). - Lots of utility functions to make development easier.
- Convenience functions wrapping mpv’s Lua API.
See TODO.org for a list of ideas for features that could eventually be implemented.
To compile, install Fennel, and then run:
fennel --compile --metadata --require-as-include --globals '*' multiplicative.fnl >multiplicative.lua
Once compilation finishes, simply move multiplicative.lua
into your mpv scripts/
directory to complete the installation.
In the future, releases of Multiplicative will be available as pre-compiled Lua so you won’t need to do this yourself.
Contributions to Multiplicative are welcome, but if you’re contributing code, please ensure:
- The existing code style is followed.
- Commit messages properly describe the change and its rationale.
- New functions or commands have a docstring, which:
- Starts with a sentence that summarizes the command.
- Describes the arguments, with their names in UPPERCASE.
- Contains a “See also” line that references similar or related functions/commands/variables, if applicable.
- Links to other functions, commands, or variables by surrounding them with a backtick (
`
) and apostrophe ('
); example:`foo'
- Doesn’t go into implementation details that the user of the function doesn’t need to know about (put those in comments instead).
- Multiplicative’s wrappers for mpv functions are preferred unless they are ill-fitting due to speed, efficiency, or functionality concerns.
If you want to work on this code, your editor of choice likely has support for Fennel.
In general, though, Emacs is probably the best editor for Lisp-like languages, with the side benefit of also being the best editor full stop. If you’re writing Fennel in Emacs, you should use fennel-mode, preferably combined with LSP support such as that provided by Eglot, which is included with Emacs 28.1 and above. I also recommend adding the following configuration to your init.el:
(put 'cmd 'fennel-indent-function 'defun)