DEV Community

vindarel
vindarel

Posted on • Edited on

Emacs' lispy-mode: Convolute real-world example!

It took me years to find a real-world use case for lispy-mode's convolute key, bound to C! Here it is :)

My original code. There's a loop and error handling inside. I want to move the error handling before the loop.

;; ORIGINAL
(defun post-products (products &rest keys)
  "Call the API, at most 500 products by POST."
  (let ((batches (batches products 500)))
    (loop for batch in batches
          for i = 1 then (incf i)
          with nb-batches = (length batches)
          do
             (format t "POST request ~a/~a… " i nb-batches)
             (handler-case
                 (prog1
                     (apply #'post/public/offers/v1/products/ean :verbose t :location (location) :products batch keys)
                   (format t "~&POST batch products ~a/~a done.~&" i nb-batches))
               ;; TODO: stop loop earlier.
               (error (c)
                 (format *error-output* "~&POST products error: ~a~&" c))))))
Enter fullscreen mode Exit fullscreen mode

Put the cursor here on the prog1:

(defun post-products (products &rest keys)
  "Call the API, at most 500 products by POST."
  (let ((batches (batches products 500)))
    (loop for batch in batches
          for i = 1 then (incf i)
          with nb-batches = (length batches)
          do
             (format t "POST request ~a/~a… " i nb-batches)
             (handler-case
 cursor ------> |(prog1
                     (apply #'post/public/offers/v1/products/ean :verbose t :location (location) :products batch keys)
                   (format t "~&POST batch products ~a/~a done.~&" i nb-batches))
               ;; TODO: stop loop earlier.
               (error (c)
                 (format *error-output* "~&POST products error: ~a~&" c))))))
Enter fullscreen mode Exit fullscreen mode

If you didn't, either activate Alt-x lispy-mode and press capital C or call Alt-x lispy-convolute (with the mode active or inactive), and TADA!

;; We want to move the HANDLER-CASE before the loop.
;;
;; With lispy-mode => C (convolute)
;;
(defun post-products (products &rest keys)
  "Call the API, at most 500 products by POST."
  (let ((batches (batches products 500)))
    (handler-case
        (loop for batch in batches
              for i = 1 then (incf i)
              with nb-batches = (length batches)
              do
                 (format t "POST request ~a/~a… " i nb-batches)
                 (prog1
                     (apply #'post/public/offers/v1/products/ean :verbose t :location (location) :products batch keys)
                   (format t "~&POST batch products ~a/~a done.~&" i nb-batches)))
      ;; TODO: stop loop earlier.
      (error (c)
        (format *error-output* "~&POST products error: ~a~&" c)))))
Enter fullscreen mode Exit fullscreen mode

The official example is this one:

(if (= (weight person) standard-duck-weight)
    (unless (sinks-in-water person)
--->  |(message "Burn her!")))

=>

(unless (sinks-in-water person)
  (if (= (weight person) standard-duck-weight)
      (message "Burn her!")))
Enter fullscreen mode Exit fullscreen mode

And its definition is

Exchange the order of application of two closest outer forms, relative to current expression or region.

Top comments (3)

Collapse
 
vindarel profile image
vindarel

on Discord, I'm given this example:

(f (let ... (g))) 

=>

 (let ... (f (g)))
Enter fullscreen mode Exit fullscreen mode
Collapse
 
taqmuraz profile image
Taqmuraz

Is emacs is really overcomplicated or it's me not getting it right?

I've tried to start with emacs multiple times, and each time I was confused with doing most simple things like copy-pasting text, search/replace entry, jump to line by number.
I don't remember exactly, but it was like 3 or 4 keys I should press to use such simple feature.

At the same time very complex features were very easy to use by mistake by just pressing single key.

So, features I would use constantly, felt like passing memory exam each time, while features I would likely never use were just annoying me

Collapse
 
vindarel profile image
vindarel

Hello o/ Emacs is… different, and not very user friendly out of the box. You know, it's carrying history, and maintainers don't easily break things that work and have worked like this to follow a new trend… so it's more on Emacs than on you. Now proceed in order and in no haste. To copy-paste, you can look at the menu entries and learn the keybindings like that. You'll notice they are the keybindings used in GNU software everywhere: in the terminal, in Mac apps, etc. By looking at the menu you'll notice you can enable CUA-mode aka "just give me C-c and C-v" to copy and paste.

You can also use the excellent evil-mode for vim keybindings. That's what I do, they are shorter and better for my wrists.

Take the time to be comfortable. Follow blogs, watch videos…

Then you'll stay for all the features. For the malleability. For the stability. And for SLIME and the REPL!