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))))))
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))))))
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)))))
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!")))
And its definition is
Exchange the order of application of two closest outer forms, relative to current expression or region.
Top comments (3)
on Discord, I'm given this example:
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
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!