Apr 16, 2018
EMMS is the best music player out there (at least if you use emacs),
as it allows full power and convenience of proper $EDITOR for music playlists and such.
All mpv backends for it that I'm aware of were restarting player binary for
every track though, which is simple, good compatibility-wise,
but also suboptimal in many ways.
For one thing, stuff like audio visualization is pita if it's in a constantly
created/destroyed transient window, it adds significant gaps between played tracks
(gapless+crossfade? forget it!), and - more due to why player starts/exit
(know when playback ends) - feedback/control over it are very limited,
since clearly no good APIs are used there, if wrapper relies on process exit
as "playback ended" event.
Rewritten emms-player-mpv.el (also in "mpv-json-ipc" branch of emms git
atm) fixes all that.
What's curious is that I didn't see almost all of these interesting use-cases,
which using the tool in the sane way allows for, and only wrote new wrapper to
get nice "playback position" feedback and out of petty pedantry over how lazy
simple implementation seem to be.
Having separate persistent player window allows OSD config or lua to display any
kind of metadata or infographics (with full power of lua + mpv + ffmpeg)
about current tracks or playlist stuff there (esp. for online streams),
enables subs/lyrics display, and getting stream of metadata update events from
mpv allows to update any "now playing" meta stuff in emacs/emms too.
What seemed like a petty and almost pointless project to have fun with lisp,
turned out to be actually useful, which seem to often be the case once you take
a deep-dive into things, and not just blindly assume stuff about them
(fire hot, water wet, etc).
Hopefully might get merged upstream after EMMS 5.0 and get a few more features
and interesting uses like that along the way.
(though I'd suggest not waiting and just adding anything that comes to mind in
~/.emacs via emms-mpv-event-connect-hook, emms-mpv-event-functions and
emms-mpv-ipc-req-send - should be really easy now)
May 15, 2017
Mostly use unorthodox variable-width font for coding, but do need monospace
sometimes, e.g. for jagged YAML files or .rst.
Had weird issue with my emacs for a while, where switching to monospace font
will slow window/frame rendering significantly, to a noticeable degree, having
stuff blink and lag, making e.g. holding key to move cursor impossible, etc.
Usual profiling showed that it's an actual rendering via C code, so kinda hoped
that it'd go away in one of minor releases, but nope - turned out to be the
dumbest thing in ~/.emacs:
(set-face-font 'fixed-pitch "DejaVu Sans Mono-7.5")
That one line is what slows stuff down to a crawl in monospace ("fixed-pitch")
configuration, just due to non-integer font size, apparently.
Probably not emacs' fault either, just xft or some other lower-level rendering
lib, and a surprising little quirk that can affect high-level app experience a lot.
Changing font size there to 8 or 9 gets rid of the issue. Oh well...
Dec 09, 2015
Following-up on my gpg replacement endeavor, also needed to add transparent
decryption for buffers loaded from *.ghg files, and encryption when writing
stuff back to these.
git filters (defined via gitattributes file) do same thing when interacting
with the repo.
Such thing is already done by a few exising elisp modules, such as jka-compr.el
for auto-compression-mode (opening/saving .gz and similar files as if they were
plaintext), and epa.el for transparent gpg encryption.
While these modules do this The Right Way by adding "file-name-handler-alist"
entry, googling for a small ad-hoc boilerplate, found quite a few examples that
do it via hooks, which seem rather unreliable and with esp. bad failure modes
wrt transparent encryption.
So, in the interest of providing right-er boilerplate for the task (and because
I tend to like elisp) - here's fg_sec.el example (from mk-fg/emacs-setup)
of how it can be implemented cleaner, in similar fashion to epa and jka-compr.
Code calls ghg -do when visiting/reading files (with contents piped to
stdin) and ghg -eo (with stdin/stdout buffers) when writing stuff back.
Entry-point/hook there is "file-name-handler-alist", where regexp to match
*.ghg gets added to call "ghg-io-handler" for every i/o operation (including
path ops like "expand-file-name" or "file-exists-p" btw), with only
"insert-file-contents" (read) and "write-region" (write) being overidden.
Unlike jka-compr though, no temporary files are used in this implementation,
only temp buffers, and "insert-file-contents" doesn't put unauthenticated data
into target buffer as it arrives, patiently waiting for subprocess to exit with
success code first.
Fairly sure that this bit of elisp can be used for any kind of processing, by
replacing "ghg" binary with anything else that can work as a pipe (stdin ->
processing -> stdout), which opens quite a lot of possibilities.
For example, all JSON files can be edited as a pretty YAML version, without
strict syntax and all the brackets of JSON, or the need to process/convert them
purely in elisp's json-mode or something - just plug python -m pyaml and
python -m json commands for these two i/o ops and it should work.
Suspect there's gotta be something that'd make such filters easier in MELPA
already, but haven't been able to spot anything right away, maybe should put up
a package there myself.
[fg_sec.el code link]
Dec 23, 2014
I've been using emacs for a while now, and always on a lookout for a features
that'd be nice to have there.
Accumulated quite a number of these in my emacs-setup repo as a result.
Most of these features start from ideas in other editors or tools (e.g. music
players, irc clients, etc - emacs seem to be best for a lot of stuff), or a
simplistic proof-of-concept implementation of something similar.
I usually add these to my emacs due to sheer fun of coding in lisps, compared
to pretty much any other lang family I know of.
Recently added two of these, and wanted to share/log the ideas here, in case
someone else might find these useful.
"Remote" based on emacsclient tool
As I use laptop and desktop machines for coding and procrastination
interchangeably, can have e.g. irc client (ERC - seriously the best irc client
I've seen by far) running on either of these.
But even with ZNC bouncer setup (and easy log-reading tools for it), it's
still a lot of hassle to connect to same irc from another machiine and catch-up
on chan history there.
Or sometimes there are unsaved buffer changes, or whatever other stuff
happening, or just stuff you want to do in a remote emacs instance, which would
be easy if you could just go turn on the monitor, shrug-off screen blanking,
sometimes disable screen-lock, then switch to emacs and press a few hotkeys
there... yeah, it doesn't look that easy even when I'm at home and close to the
emacs has "emacsclient" thing, that allows you to eval whatever elisp code on a
remote emacs instance, but it's impossible to use for such simple tasks without
some convenient wrappers.
And these remote invocation wrappers is what this idea is all about.
Consider terminal dump below, running in an ssh or over tcp to remote emacs
server (and I'd strongly suggest having (server-start) right in ~/.emacs,
though maybe not on tcp socket for security reasons):
% ece b
% ece b remote
*ERROR*: Failed to uniquely match buffer by `remote', matches:
--- whoops... lemme try again
% ece b fg_rem
...(contents of the buffer, matched by unique name part)...
% ece erc
--- Showing last (unchecked) irc activity, same as erc-track-mode does (but nicer)
% ece erc twitter | t
[13:36:45]<fijall> hint - you can use gc.garbage in Python to store any sort of ...
[14:57:59]<veorq> Going shopping downtown. Pray for me.
[15:48:59]<mitsuhiko> I like how if you google for "London Bridge" you get ...
[17:15:15]<simonw> TIL the Devonshire word "frawsy" (or is it "frawzy"?) - a ...
[17:17:04] *** -------------------- ***
[17:24:01]<veorq> RT @collinrm: Any opinions on VeraCrypt?
[17:33:31]<veorq> insightful comment by @jmgosney about the Ars Technica hack ...
[17:35:36]<veorq> .@jmgosney as you must know "iterating" a hash is in theory ...
[17:51:50]<veorq> woops #31c3 via @joernchen ...
--- "t" above is an alias for "tail" that I use in all shells, lines snipped jic
% ece h
buffer (aliases: b, buff)
help (aliases: h, rtfm, wat)
% ece h erc-mark
Put /mark to a specified ERC chan and reset its activity track.
--- Whole "help" thing is auto-generated, see "fg-remote-help" in fg_remote.el
And so on - anything is trivial to implement as elisp few-liner.
For instance, missing "buffer-save" command will be:
(defun fg-remote-buffer-save (pattern)
"Saves specified bufffer, matched via `fg-get-useful-buffer'."
(with-current-buffer (fg-get-useful-buffer pattern) (save-buffer)))
(defalias 'fg-remote-bs 'fg-remote-buffer-save)
Both "bufffer-save" command and its "bs" alias will instantly appear in "help"
and be available for calling via emacs client.
Hell, you can "implement" this stuff from terminal and eval on a remote emacs
(i.e. just pass code above to emacsclient -e), extending its API in an
ad-hoc fashion right there.
"ece" script above is a thin wrapper around "emacsclient" to avoid typing that
long binary name and "-e" flag with a set of parentheses every time, can be
found in the root of emacs-setup repo.
So it's easier to procrastinate in bed whole morning with a laptop than ever.
Yup, that's the real point of the whole thing.
Unique per-file buffer colors
Stumbled upon this idea in a deliberate-software blog entry recently.
There, author suggests making static per-code-project colors, but I thought -
why not have slight (and automatic) per-file-path color alterations for buffer
Doing that makes file buffers (or any non-file ones too) recognizable, i.e. you
don't need to look at the path or code inside anymore to instantly know that
it's that exact file you want (or don't want) to edit - eye/brain picks it up
emacs' color.el already has all the cool stuff for colors - tools for conversion
to/from L*a*b* colorspace (humane "perceptual" numbers), CIEDE2000 color
diffs (JUST LOOK AT THIS THING), and so on - easy to use these for the
Result is "fg-color-tweak" function that I now use for slight changes to buffer
bg, based on md5 hash of the file path and reliably-contrast irc nicknames
(based also on the hash, used way worse and unreliable "simple" thing for this
in the past):
(fg-color-tweak COLOR &optional SEED MIN-SHIFT MAX-SHIFT (CLAMP-RGB-AFTER 20)
Adjust COLOR based on (md5 of-) SEED and MIN-SHIFT / MAX-SHIFT lists.
COLOR can be provided as a three-value (0-1 float)
R G B list, or a string suitable for `color-name-to-rgb'.
MIN-SHIFT / MAX-SHIFT can be:
* three-value list (numbers) of min/max offset on L*a*b* in either direction
* one number - min/max cie-de2000 distance
* four-value list of offsets and distance, combining both options above
* nil for no-limit
SEED can be number, string or nil.
Empty string or nil passed as SEED will return the original color.
CLAMP-RGB-AFTER defines how many attempts to make in picking
L*a*b* color with random offset that translates to non-imaginary sRGB color.
When that number is reached, last color will be `color-clamp'ed to fit into sRGB.
Returns color plus/minus offset as a hex string.
Resulting color offset should be uniformly distributed between min/max shift limits.
It's a bit complicated under the hood, parsing all the options and limits,
making sure resulting color is not "imaginary" L*a*b* one and converts to RGB
without clamping (if possible), while maintaining requested min/max distances,
doing several hashing rounds if necessary, with fallbacks... etc.
Actual end-result is simple though - deterministic and instantly-recognizable
color-coding for anything you can think of - just pass the attribute to base
coding on and desired min/max contrast levels, get back the hex color to use,
Should you use something like that, I highly suggest taking a moment to look
at L*a*b* and HSL color spaces, to understand how colors can be easily tweaked
along certain parameters.
For example, passing '(0 a b) as min/max-shift to the function above will
produce color variants with the same "lightness", which is super-useful to
control, making sure you won't ever get out-of-whack colors for
e.g. light/dark backgrounds.
Coding lispy stuff is super-fun, just for the sake of it ;)
Actually, speaking of fun, I can't recommend installing magnars' s.el
dash.el right now
highly enough, unless you have these already.
They make coding elisp stuff so much more fun and trivial, to a degree that'd
be hard to describe, so please at least try coding somethig with these.
All the stuff mentioned above is in (also linked here already) emacs-setup repo.