all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: PJ Weisberg <pj@irregularexpressions.net>
To: Sean McAfee <eefacm@gmail.com>
Cc: help-gnu-emacs@gnu.org
Subject: Re: Lisp refactoring puzzle
Date: Thu, 29 Mar 2012 18:51:14 -0700	[thread overview]
Message-ID: <CAJsNXTkKZSFbomN0xVG3oGqsCMs++zNWH1eL_iL+JT6N-ghqRg@mail.gmail.com> (raw)
In-Reply-To: <bp8r564d0do.fsf@usca1uw-JZWWPM1.sanmateo.corp.akamai.com>

On Tue, Jul 5, 2011 at 11:54 AM, Sean McAfee <eefacm@gmail.com> wrote:
> I use EMMS (Emacs Multi Media System) a lot, and I have the following
> key mappings set up to easily skip around inside large MP3s:
>
> (global-set-key [(super left)]
>                (lambda () (interactive) (emms-seek -7)))
> (global-set-key [(super meta left)]
>                (lambda () (interactive) (emms-seek -60)))
> (global-set-key [(super meta control left)]
>                (lambda () (interactive) (emms-seek -360)))
>
> ...and likewise for the right arrow key, with positive arguments to
> emms-seek.
>
> These mappings are of course repetitive, and so a while back I wrote
> some code to set them up.  As I became more familiar with the loop
> macro, I refined the code several times, until I got what I have today:
>
> (defconst skip-intervals '((7 . super) (60 . meta) (360 . control)))
>
> (loop for (magnitude . modifier) in skip-intervals
>      collecting modifier into modifiers
>      do (loop for key in '(right left)
>               and delta = magnitude then (- magnitude)
>               do (global-set-key
>                    (vector (append modifiers (list key)))
>                    `(lambda () (interactive) (emms-seek ,delta)))))
>
> This is fairly elegant, but I'm disappointed that it doesn't really save
> me any lines of code over just writing out the mappings by hand.
>
> Can anyone suggest a more compact/elegant way to establish these
> mappings?

You're trying to outsmart yourself.  Refactoring isn't about trying to
fit all your logic into as few bytes of code as possible.  Your first
set of three calls to `global-set-key' make it obvious exactly what
the code is doing.  I had to stare at that loop for a minute before I
realized what the "collecting" part was trying to accomplish.

On the other hand, my brain won't ever let me leave a "how do you do
X?" question alone, so I went ahead anyway and wrote what I think is a
clearer way of doing what you're doing above.

(let ((skip-intervals '((7 . "s") (60 . "s-M") (360 . "s-M-C")))
      (directions '(("left" . -1) ("right" . 1))))

  (loop for (magnitude . modifier) in skip-intervals do
        (loop for (direction . sign) in directions do
              (global-set-key (read-kbd-macro (format "%s-<%s>"
modifier direction))
                              (lambda () (interactive) (emms-seek (*
sign magnitude)))))))


-PJ

Gehm's Corollary to Clark's Law: Any technology distinguishable from
magic is insufficiently advanced.



           reply	other threads:[~2012-03-30  1:51 UTC|newest]

Thread overview: expand[flat|nested]  mbox.gz  Atom feed
 [parent not found: <bp8r564d0do.fsf@usca1uw-JZWWPM1.sanmateo.corp.akamai.com>]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAJsNXTkKZSFbomN0xVG3oGqsCMs++zNWH1eL_iL+JT6N-ghqRg@mail.gmail.com \
    --to=pj@irregularexpressions.net \
    --cc=eefacm@gmail.com \
    --cc=help-gnu-emacs@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.