-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathocodo-custom-bindings-to-markdown.el
182 lines (162 loc) · 7.01 KB
/
ocodo-custom-bindings-to-markdown.el
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
;;; ocodo-custom-bindings.el -*- lexical-binding: t; -*-
(defvar ocodo-key-binding-groups '(("Markdown Soma" 1 "Markdown soma")
("Smart Parens" 1 "Sp ")
("Text Transforms" 0 "C-c t t")
("Auto Snippet" 1 "Aya ")
("Ruby" 1 "Ruby ")
("Swiper" 1 "Swiper ")
("Git" 0 "C-x v ")
("Color" 1 "Color ")
("Dired" 1 "Dired ")
("ERT Testing" 1 "Ert ")
("Debugging" 1 "Debug ")
("Windows" 1 "Window "))
"Key binding group filters.")
(defvar ocodo-key-bindings-lisp-files
(-concat
`(,(expand-file-name "~/.doom.d/key-bindings.el"))
(f-entries "~/.doom.d/use/"
(lambda (file)
(let1 text
(f-read file 'utf-8)
(s-contains? "bind-key" text)))))
"List of emacs-lisp files which have personalised key bindings.")
(defvar ocodo-key-bindings-heading
"Ocodo's Emacs Key Bindings."
"Key bindings page heading.")
(defvar ocodo-key-bindings-table-heading (concat
"| Key(s) | Command | keymap |\n"
"|:--------|:--------|--------:|")
"Markdown table heading for key binding documentation.")
(defun ocodo-make-key-binding-table-row (binding)
"Make a markdown table row from BINDING."
(cl-destructuring-bind
(keys command keymap)
binding
(format "| <kbd>%s</kbd> | %s | %s |" keys command keymap)))
(defun ocodo-filter-key-bindings (filter index bindings)
"Filter BINDINGS by FILTER on INDEX."
(-filter (lambda (it)
(let ((fn-name (when (and (nth index it) (symbolp (nth index it)))
(symbol-name (nth index it)))))
(when fn-name
(s-matches-p filter fn-name))))
bindings))
(defun ocodo-ungrouped-key-bindings (bindings title groups)
"Collect BINDINGS and TITLE into GROUPS."
(let ((predicates (mapcar
(lambda (group)
(cl-destructuring-bind (_ index filter) group
`(lambda (bind)
(when (stringp bind) (s-matches-p ,filter (nth ,index bind))))))
groups)))
(list title
(sort
(-filter (lambda (b)
(--map (funcall it b) predicates))
bindings)
(lambda (a b)
(string> (prin1-to-string a) (prin1-to-string b)))))))
(defun ocodo-make-key-binding-groups (bindings headings groups)
"Collect BINDINGS and HEADINGS into GROUPS."
(--map
(cl-destructuring-bind (title index filter) it
(list title
(sort
(ocodo-filter-key-bindings
filter index
bindings)
#'string>)))
groups))
(defun ocodo-arrow-key-bindings-use-unicode-arrows (key-binding &optional white-arrows)
"KEY-BINDING string directions to unicode arrows.
<up> <down> <left> <right> replaced with ↑ ↓ ← →.
<return> replaced with ⮐.
Setting WHITE-ARROWS to t, gives these replacements: ⇧ ⇩ ⇦ ⇨ and ⏎."
(let* ((key-to-arrow '(("<return>" ("⏎" . "⮐"))
("<up>" ("⇧" . "↑"))
("<down>" ("⇩" . "↓"))
("<left>" ("⇦" . "←"))
("<right>" ("⇨" . "→"))))
(fn (or (and white-arrows 'cdar) 'cddr))
(keys (mapcar (lambda (it) (car it)) key-to-arrow)))
(if (member key-binding keys)
(cl-reduce (lambda (text it)
(s-replace (car it) (funcall fn it) text))
key-binding)
key-binding)))
(defun ocodo-key-bindings-for-documentation ()
"Cleaned list of key bindings for documentation."
(ocodo-clean-key-bindings-for-documentation
(ocodo-collate-key-bindings-for-documentation)))
(defun ocodo-clean-key-bindings-for-documentation (bindings)
"Prepare collated binding-list for documentation."
(mapcar (lambda (it)
(let* ((key-chord (if (car it)
(ocodo-arrow-key-bindings-use-unicode-arrows (car it))
""))
(command-fn (nth 1 it))
(command-name (if command-fn
(s-capitalized-words (s-replace "#'" "" (prin1-to-string command-fn)))
""))
(key-map (if (and (nth 2 it) (symbolp (nth 2 it))
(s-capitalized-words (format "%s" (symbol-name (nth 2 it)))))
"Global")))
(list key-chord (s-replace "#'" "" (format "%s" command-name)) key-map)))
(delq nil bindings)))
(defun ocodo-collate-key-bindings-for-documentation ()
"Collate all key bindings found in ocodo-key-bindings-lisp-files."
(eval
(car
(read-from-string
(format "'(%s)"
(s-join
"\n"
(--map
(format
"( %s )"
(nth 1 (s-match
"[[:space:]]*?(bind-key\\(.*?\\))+$"
it)))
(--filter (s-contains-p "(bind-key " it)
(-flatten
(--map (s-split "\n" (f-read it 'utf-8))
ocodo-key-bindings-lisp-files))))))))))
(defun ocodo-key-binding-groups-to-markdown (binding-groups headings)
"Convert BINDING-GROUPS to string of markdown tables with HEADINGS."
(concat
(format-multiline "|# %s
|
|%s
|"
ocodo-key-bindings-heading
(lm-commentary "~/.doom.d/key-bindings.el"))
(s-join "\n"
(--map
(cl-destructuring-bind (title bindings) it
(format-multiline "|
|### %s
|
|%s
|%s"
title
headings
(s-join "\n"
(--map
(ocodo-make-key-binding-table-row it)
bindings))))
(push
(ocodo-ungrouped-key-bindings (ocodo-key-bindings-for-documentation)
"General" ocodo-key-binding-groups)
binding-groups)))))
(defun ocodo-custom-key-bindings-markdown (file)
"Generate markdown FILE with table of custom bindings."
(interactive "f[Cusom Bindings] Save to markdown file: ")
(let* ((table-heading ocodo-key-bindings-table-heading)
(binding-list (ocodo-key-bindings-for-documentation))
(custom-key-bindings-markdown (ocodo-key-binding-groups-to-markdown
(ocodo-make-key-binding-groups binding-list table-heading ocodo-key-binding-groups)
table-heading)))
(f-write custom-key-bindings-markdown 'utf-8 file)
(message ": %s" file)
(when (y-or-n-p (format "Generated %s, open it?" file)) (find-file file))))