💾 Archived View for idiomdrottning.org › paredit captured on 2022-01-08 at 13:42:04. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2021-12-17)

➡️ Next capture (2022-07-16)

-=-=-=-=-=-=-

A paredit pro tip

I realized a few days ago that in Lisp, since most stuff is lower case, you can bind the uppercase letters to stuff, using paredit’s context predicates (like paredit-in-comment-p and paredit-in-string-p) so you can still type normal stuff in comments and strings. So far, I’ve only bound M, W. V and Z (remember that those four are next to each other on Dvorak). It has been so awesome and it’s now the main way I type parens. M when I want to insert a pair, and W when I want to wrap the next sexp. I often enough wanna wrap two or three so that’s V or Z.

Mnemonics: M for Make pair, W for Wrap, a V has two edges, a Z has three. And also the MWVZ 0123 physical location.

If I do need to insert those uppercase characters in a symbol or identifier, I can with C-q.

I was just about to continue the series with PYFGCRL (for Dvorak reasons: it’s also where I have numbers four through zero on Atreus Layer #1) but I realized that that I should hold off on that since I only more rarely wrap that many. (While wrap two is great.)

I hope you come up with something cool for your uppercase paredit stuff.♥

(defmacro define-paredit-wrap (letter number)
  `(defun ,(intern (apply 'concat (list "paredit-wrap-" letter)))
       ()
     (interactive)
     (if
     (or (paredit-in-string-p) (paredit-in-comment-p))
     (insert ,(upcase letter))
       (paredit-wrap-round ,number))))

(define-paredit-wrap "m" 0)
(define-paredit-wrap "w" 1)
(define-paredit-wrap "v" 2)
(define-paredit-wrap "z" 3)

(eval-after-load "paredit"
  '(progn
    (define-key paredit-mode-map (kbd "M") 'paredit-wrap-m)
    (define-key paredit-mode-map (kbd "W") 'paredit-wrap-w)
    (define-key paredit-mode-map (kbd "V") 'paredit-wrap-v)
    (define-key paredit-mode-map (kbd "Z") 'paredit-wrap-z)))

Update

First of all, I got so used to it that I was getting annoyed in other modes so I moved my normal open round to layer #1 M. Not quite the same immediacy of shift M but at least the same ballpark.

Second, I bound C-c m to toggle between markdown-mode and scheme-mode, since I often write markdown files that have Scheme code. (It also calls untabify on the whole buffer when I switch. Then I have to markdown-pre-region manually, which I have set to csp on god-mode. I think that’s the default. I usually do this last of all.) Even so, I’m sometimes sloppy and just write a line or two without switching, and I’ve been really rewarded by W, V and Z being so rare in my writing. M on the other hand...

So maybe it should get even better at recognizing context, or I should get better at switching modes or using C-q M, but it’s fine. I’m so much faster at programming now, I’m kinda embarrassing that physically typing parens was holding me back.

Update again

Since I’m doing so much Clojure, I added the equivalent for [] on HTNS and at first I added the equivalent of {} on GCRL, buuuut I really don’t want to mess with G since that’s already a thing in god mode so unaesthetically enough I used FCRL for the {} wrappers.

So now for those three brace types, I can wrap zero (i.e. insert an empty pair and put cursor there), one, two, or three.

If I want to wrap more, I still can. I need to hit, in the right order: hold layer switcher, hold ctrl, type the number I want to wrap, and then n.

Many paredit-users use (ewwww, these names “slurp”) and “barf” but I’m way more about the wrap and splice and raise workflow. Convolute is also great, as is split and join.

I do have a way to use “slurp” and “barf” on some Vulcan neckpinch four finger combo but it’s not something I use every day. When I was first getting used to all these shortcuts, I had a bunch of sticky notes over the monitor.

I also have kill-sexp set to M-d. Killing and yanking sexps are part of the basics of paredit, it should be easy.

Atreus Keyboard Review

Update again

Here is how the code looks now:

(defmacro define-paredit-wrap (letter number shape)
  `(defun ,(intern (apply 'concat (list "paredit-wrap-" letter)))
       ()
     (interactive)
     (if
         (or (paredit-in-string-p) (paredit-in-comment-p))
         (insert ,(upcase letter))
       (,(intern (apply 'concat (list "paredit-wrap-" shape))) ,number))))

(define-paredit-wrap "m" 0 "round")
(define-paredit-wrap "w" 1 "round")
(define-paredit-wrap "v" 2 "round")
(define-paredit-wrap "z" 1000 "round")
(define-paredit-wrap "f" 0 "curly")
(define-paredit-wrap "c" 1 "curly")
(define-paredit-wrap "r" 2 "curly")
(define-paredit-wrap "l" 1000 "curly")
(define-paredit-wrap "h" 0 "square")
(define-paredit-wrap "t" 1 "square")
(define-paredit-wrap "n" 2 "square")
(define-paredit-wrap "s" 1000 "square")

(eval-after-load "paredit"
  '(progn
     (define-key paredit-mode-map (kbd "M") 'paredit-wrap-m)
     (define-key paredit-mode-map (kbd "W") 'paredit-wrap-w)
     (define-key paredit-mode-map (kbd "V") 'paredit-wrap-v)
     (define-key paredit-mode-map (kbd "Z") 'paredit-wrap-z)
     (define-key paredit-mode-map (kbd "H") 'bracket-wrap-h)
     (define-key paredit-mode-map (kbd "T") 'bracket-wrap-t)
     (define-key paredit-mode-map (kbd "N") 'bracket-wrap-n)
     (define-key paredit-mode-map (kbd "S") 'bracket-wrap-s)
     (define-key paredit-mode-map (kbd "F") 'brace-wrap-f)
     (define-key paredit-mode-map (kbd "C") 'brace-wrap-c)
     (define-key paredit-mode-map (kbd "R") 'brace-wrap-r)
     (define-key paredit-mode-map (kbd "L") 'brace-wrap-l))

I changed to from three to thousand because that lets me to just wrap to the end of the current level.

For example, (foo (a b | c d e f g) bar) becomes (foo (a b (|c d e f g)) bar) which is often useful.