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, 2016
My current Razer E-Blue mouse had this issue since I've got it - Mouse-2 /
BTN_MIDDLE / middle-click (useful mostly as "open new tab" in browsers and
"paste" in X) sometimes produces two click events (in rapid succession) instead
It was more rare before, but lately it feels like it's harder to make it click
once than twice.
Seem to be either hardware problem with debouncing circuitry or logic in the
controller, or maybe a button itself not mashing switch contacts against each
other hard enough... or soft enough (i.e. non-elastic), actually, given that
they shouldn't "bounce" against each other.
Since there's no need to double-click that wheel-button ever, it looks rather
easy to debounce the click on Xorg input level, by ignoring repeated button
up/down events after producing the first full "click".
Easiest solution of that kind that I've found was to use guile (scheme) script
with xbindkeys tool to keep that click-state data and perform clicks
selectively, using xdotool:
(define razer-delay-min 0.2)
(define razer-wait-max 0.5)
(define razer-ts-start #f)
(define razer-ts-done #f)
(define razer-debug #f)
"Return monotonic timestamp in seconds as real."
(+ 0.0 (/ (get-internal-real-time) internal-time-units-per-second)))
(xbindkey-function '("b:8") (lambda ()
(let ((ts (mono-time)))
;; Enforce min ts diff between "done" and "start" of the next one
(or (not razer-ts-done) (>= (- ts razer-ts-done) razer-delay-min))
(set! razer-ts-start ts)))))
(xbindkey-function '(Release "b:8") (lambda ()
(let ((ts (mono-time)))
(format #t "razer: ~a/~a delay=~a[~a] wait=~a[~a]\n"
(and razer-ts-done (- ts razer-ts-done)) razer-delay-min
(and razer-ts-start (- ts razer-ts-start)) razer-wait-max))
;; Enforce min ts diff between previous "done" and this one
(or (not razer-ts-done) (>= (- ts razer-ts-done) razer-delay-min))
;; Enforce max "click" wait time
(and razer-ts-start (<= (- ts razer-ts-start) razer-wait-max)))
(set! razer-ts-done ts)
(when razer-debug (format #t "razer: --- click!\n"))
(run-command "xdotool click 2")))))
Note that xbindkeys actually grabs "b:8" here, which is a "mouse button 8", as
if it was "b:2", then "xdotool click 2" command will recurse into same code, so
wheel-clicker should be bound to button 8 in X for that to work.
Rebinding buttons in X is trivial to do on-the-fly, using standard "xinput" tool
- e.g. xinput set-button-map "My Mouse" 1 8 3 (xinitrc.input script can
be used as an extended example).
Running "xdotool" to do actual clicks at the end seem a bit wasteful, as
xbindkeys already hooks into similar functionality, but unfortunately there's no
"send input event" calls exported to guile scripts (as of 1.8.6, at least).
Still, works well enough as it is, fixing that rather annoying issue.
[xbindkeysrc.scm on github]
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.
Dec 09, 2010
It's been a while since I augmented libnotify / notification-daemon stack to better
suit my (maybe not-so-) humble needs, and it certainly was an improvement, but
there's no limit to perfection and since then I felt the urge to upgrade it
every now and then.
One early fix was to let messages with priority=critical through without
delays and aggregation. I've learned it the hard way when my laptop shut down
because of drained battery without me registering any notification about it.
Other good candidates for high priority seem to be real-time messages like
track updates and network
connectivity loss events which either too important to ignore or just don't
make much sense after delay. Implementation here is straightforward - just
check urgency level and pass these unhindered to notification-daemon.
Another important feature which seem to be missing in reference daemon is the
ability to just cleanup the screen of notifications. Sometimes you just need
to dismiss them to see the content beneath, or you just read them and don't
want them drawing any more attention.
The only available interface for that seem to be CloseNotification method,
which can only close notification message using it's id, hence only useful
from the application that created the note. Kinda makes sense to avoid apps
stepping on each others toes, but since id's in question are sequential, it
won't be much of a problem to an app to abuse this mechanism anyway.
Proxy script, sitting in the middle of dbus communication as it is, don't have
to guess these ids, as can just keep track of them.
So, to clean up the occasional notification-mess I extended the
CloseNotification method to accept 0 as a "special" id, closing all the
Binding it to a key is just a matter of (a bit inelegant, but powerful)
dbus-send tool invocation:
% dbus-send --type=method_call\
Expanding the idea of occasional distraction-free needs, I found the idea of
the ability to "plug" the notification system - collecting the notifications
into the same digest behind the scenes (yet passing urgent ones, if this
behavior is enabled) - when necessary quite appealing, so I just added a flag
akin to "fullscreen" check, forcing notification aggregation regardless of
rate when it's set.
Of course, some means of control over this flag was necessary, so another
extension of the interface was to add "Set" method to control
notification-proxy options. Method was also useful to occasionally toggle
special "urgent" messages treatment, so I empowered it to do so as well by
making it accept a key-value array of parameters to apply.
And since now there is a plug, I also found handy to have a complimentary
"Flush" method to dump last digested notifications.
Same handy dbus-send tool comes to rescue again, when these need to be toggled
or set via cli:
% dbus-send --type=method_call\
In contrast to cleanup, I occasionally found myself monitoring low-traffic IRC
conversations entirely through notification boxes - no point switching the
apps if you can read the whole lines right there, but there was a catch of
course - you have to immediately switch attention from whatever you're doing
to a notification box to be able to read it before it times out and
disappears, which of course is a quite inconvenient.
Easy solution is to just override "timeout" value in notification boxes to
make them stay as long as you need to, so one more flag for the "Set" method
to handle plus one-liner check and there it is.
Now it's possible to read them with minimum distraction from the current
activity and dismiss via mentioned above extended CloseNotification method.
As if the above was not enough, sometimes I found myself willing to read and
react to the stuff from one set of sources, while temporarily ignoring the
traffic from the others, like when you're working at some hack, discussing it
(and the current implications / situation) in parallel over jabber or irc,
while heated discussion (but interesting none the less) starts in another
Shutting down the offending channel in ERC
, leaving BNC
to monitor the
conversation or just supress notifications with some ERC command would
probably be the right way to handle that, yet it's not always that simple,
especially since every notification-enabled app then would have to implement
some way of doing that, which of course is not the case at all.
Remedy is in the customizable filters for notifications, which can be a simple
set of regex'es, dumped into some specific dot-file, but even as I started to
implement the idea, I could think of several different validation scenarios
like "match summary against several regexes", "match message body", "match
simple regex with a list of exceptions" or even some counting and more complex
logic for them.
Idea of inventing yet another perlish (poorly-designed, minimal, ambiguous,
write-only) DSL for filtering rules didn't struck me as an exactly bright one,
so I thought for looking for some lib implementation of clearly-defined and
thought-through syntax for such needs, yet found nothing designed purely for
such filtering task (could be one of the reasons why every tool and daemon
hard-codes it's own DSL for that *sigh*).
On that note I thought of some generic yet easily extensible syntax for such
rules, and came to realization that simple SICP-like subset of scheme/lisp
with regex support would be exactly what I need.
Luckily, there are plenty implementations of such embedded languages in
python, and since I needed a really simple and customizabe one, I've decided
to stick with extended 90-line "lis.py
described by Peter Norvig here
. Out goes unnecessary file-handling,
plus regexes and some minor fixes and the result is "make it into whatever you
Just added a stat and mtime check on a dotfile, reading and compiling the
matcher-function from it on any change. Contents may look like this:
(define-macro define-matcher (lambda
(name comp last rev-args)
`(define ,name (lambda args
(if (= (length args) 1) ,last
(let ((atom (car args)) (args (cdr args)))
(~ ,@(if rev-args '((car args) atom) '(atom (car args))))
(apply ,name (cons atom (cdr args))))))))))
(define-matcher ~all and #t #f)
(define-matcher all~ and #t #t)
(define-matcher ~any or #f #f)
(define-matcher any~ or #f #t)
(lambda (summary body)
(~ "^erc: #\S+" summary)
(~ "^\*\*\* #\S+ (was created on|modes:) " body))
(all~ summary "^erc: #pulseaudio$" "^mail:")))
Which kinda shows what can you do with it, making your own syntax as you go
along (note that stuff like "and" is also a macro, just defined on a higher
Even with weird macros I find it much more comprehensible than rsync filters,
apache/lighttpd rewrite magic or pretty much any pseudo-simple magic set of
string-matching rules I had to work with.
I considered using python itself to the same end, but found that it's syntax
is both more verbose and less flexible/extensible for such goal, plus it
allows to do far too much for a simple filtering script which can potentially
be evaluated by process with elevated privileges, hence would need some sort
of sandboxing anyway.
In my case all this stuff is bound to convenient key shortcuts via fluxbox wm
# Notification-proxy control
Print :Exec dbus-send --type=method_call\
Shift Print :Exec dbus-send --type=method_call\
Pause :Exec dbus-send --type=method_call\
Shift Pause :Exec dbus-send --type=method_call\
Pretty sure there's more room for improvement in this aspect, so I'd have to
extend the system once again, which is fun all by itself.
Resulting (and maybe further extended) script is here, now linked against a
bit revised lis.py scheme implementation.