summaryrefslogtreecommitdiff
path: root/modules/custom-ordering.el
blob: 8e8a4da675d777fa5f216ddff1c26fae0ae3d80d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
;;; custom-ordering.el ---  -*- coding: utf-8; lexical-binding: t; -*-

;;; Commentary:

;; This module provides functions for converting text between different formats and sorting operations.
;; These utilities are useful for reformatting data structures and organizing text.

;; Functions include:

;; - converting lines to quoted comma-separated arrays (arrayify)
;; - converting arrays back to separate lines (unarrayify)
;; - alphabetically sorting words in a region
;; - splitting comma-separated text into individual lines

;; Bound to keymap prefix C-; o

;;; Code:

;; cj/custom-keymap defined in keybindings.el
(eval-when-compile (defvar cj/custom-keymap))
(defvar cj/ordering-map)

(defun cj/arrayify (start end quote)
  "Convert lines between START and END into quoted, comma-separated strings.
START and END identify the active region.
QUOTE specifies the quotation characters to surround each element."
  (interactive "r\nMQuotation character to use for array element: ")
  (let ((insertion
		 (mapconcat
		  (lambda (x) (format "%s%s%s" quote x quote))
		  (split-string (buffer-substring start end)) ", ")))
	(delete-region start end)
	(insert insertion)))

(defun cj/unarrayify (start end)
  "Convert quoted comma-separated strings between START and END to separate lines.
START and END identify the active region."
  (interactive "r")
  (let ((insertion
		 (mapconcat
		  (lambda (x) (replace-regexp-in-string "[\"']" "" x))
		  (split-string (buffer-substring start end) ", ") "\n")))
	(delete-region start end)
	(insert insertion)))

(defun cj/alphabetize-region ()
  "Alphabetize words in the active region and replace the original text.
Produce a comma-separated list as the result."
  (interactive)
  (unless (use-region-p)
	(user-error "No region selected"))
  (let ((start (region-beginning))
		(end (region-end))
		(string (buffer-substring-no-properties (region-beginning) (region-end))))
	(delete-region start end)
	(goto-char start)
	(insert
	 (mapconcat #'identity
				(sort (split-string string "[[:space:],]+" t)
					  #'string-lessp)
				", "))))

(defun cj/comma-separated-text-to-lines ()
  "Break up comma-separated text in active region so each item is on own line."
  (interactive)
  (if (not (region-active-p))
	  (error "No region selected"))

  (let ((beg (region-beginning))
		(end (region-end))
		(text (buffer-substring-no-properties (region-beginning) (region-end))))
	(with-temp-buffer
	  (insert text)
	  (goto-char (point-min))
	  (while (search-forward "," nil t)
		(replace-match "\n" nil t))
	  (delete-trailing-whitespace)
	  (setq text (buffer-string)))

	(delete-region beg end)
	(goto-char beg)
	(insert text)))



;; Ordering & sorting prefix and keymap
(define-prefix-command 'cj/ordering-map nil
                       "text ordering and sorting operations.")
(keymap-set cj/custom-keymap "o" #'cj/ordering-map)
(keymap-set cj/ordering-map "a" #'cj/arrayify)
(keymap-set cj/ordering-map "u" #'cj/unarrayify)
(keymap-set cj/ordering-map "A" #'cj/alphabetize-region)
(keymap-set cj/ordering-map "l" #'cj/comma-separated-text-to-lines)

(provide 'custom-ordering)
;;; custom-ordering.el ends here.