From ec19fb5f78036a5fe5f36eab713d79164f087a5a Mon Sep 17 00:00:00 2001 From: Case Duckworth Date: Sat, 22 May 2021 16:40:18 -0500 Subject: Add `sort-sexps' from unpackaged.el --- lisp/acdw.el | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/lisp/acdw.el b/lisp/acdw.el index 8b87dd5..f607695 100644 --- a/lisp/acdw.el +++ b/lisp/acdw.el @@ -195,6 +195,55 @@ With a prefix argument N, (un)comment that many sexps." (dotimes (_ (or n 1)) (comment-sexp--raw)))) + +;;; Sort sexps +;; from https://github.com/alphapapa/unpackaged.el#sort-sexps + +(defun sort-sexps (beg end) + "Sort sexps in region. +Comments stay with the code below." + (interactive "r") + (cl-flet ((skip-whitespace () (while (looking-at (rx (1+ (or space "\n")))) + (goto-char (match-end 0)))) + (skip-both () (while (cond ((or (nth 4 (syntax-ppss)) + (ignore-errors + (save-excursion + (forward-char 1) + (nth 4 (syntax-ppss))))) + (forward-line 1)) + ((looking-at (rx (1+ (or space "\n")))) + (goto-char (match-end 0))))))) + (save-excursion + (save-restriction + (narrow-to-region beg end) + (goto-char beg) + (skip-both) + (cl-destructuring-bind (sexps markers) + (cl-loop do (skip-whitespace) + for start = (point-marker) + for sexp = (ignore-errors + (read (current-buffer))) + for end = (point-marker) + while sexp + ;; Collect the real string, then one used for sorting. + collect (cons (buffer-substring (marker-position start) (marker-position end)) + (save-excursion + (goto-char (marker-position start)) + (skip-both) + (buffer-substring (point) (marker-position end)))) + into sexps + collect (cons start end) + into markers + finally return (list sexps markers)) + (setq sexps (sort sexps (lambda (a b) + (string< (cdr a) (cdr b))))) + (cl-loop for (real . sort) in sexps + for (start . end) in markers + do (progn + (goto-char (marker-position start)) + (insert-before-markers real) + (delete-region (point) (marker-position end))))))))) + ;;; Emacs configuration functions -- cgit 1.4.1-21-gabe81