|
54 | 54 | (modify-syntax-entry ?& "w" table) |
55 | 55 | (modify-syntax-entry ?$ "w" table) |
56 | 56 | (modify-syntax-entry ?! "w" table) |
| 57 | + (modify-syntax-entry ?\\ "w" table) |
| 58 | + (modify-syntax-entry ?\[ "w" table) |
| 59 | + (modify-syntax-entry ?\] "w" table) |
57 | 60 | table) |
58 | 61 | "Syntax table for `kanata-kbd-mode`.") |
59 | 62 |
|
60 | | -(defun kanata-kbd-indent-line () |
61 | | - "Indent current line for kanata-kbd-mode." |
62 | | - (let ((indent 0)) |
63 | | - (save-excursion |
64 | | - (beginning-of-line) |
65 | | - (let ((paren-depth 0)) |
66 | | - (save-excursion |
67 | | - (goto-char (point-min)) |
68 | | - (while (< (point) (line-beginning-position)) |
69 | | - (cond |
70 | | - ((looking-at "(") (setq paren-depth (1+ paren-depth))) |
71 | | - ((looking-at ")") (setq paren-depth (1- paren-depth)))) |
72 | | - (forward-char))) |
73 | | - (setq indent (* paren-depth 2)))) |
74 | | - (indent-line-to indent))) |
75 | | - |
76 | | -(defun kanata-kbd-comment-dwim (arg) |
77 | | - "Comment or uncomment region or line intelligently." |
78 | | - (interactive "*P") |
79 | | - (if (use-region-p) |
80 | | - (comment-or-uncomment-region (region-beginning) (region-end)) |
81 | | - (comment-or-uncomment-region (line-beginning-position) (line-end-position)))) |
82 | | - |
83 | | -(defun kanata-kbd-align-deflayer () |
84 | | - "Align the keys within a deflayer block." |
85 | | - (interactive) |
86 | | - (save-excursion |
87 | | - (let (start end) |
88 | | - (unless (re-search-backward "(deflayer" nil t) |
89 | | - (user-error "Not in a deflayer block")) |
90 | | - (setq start (match-beginning 0)) |
91 | | - (goto-char start) |
92 | | - (with-syntax-table kanata-kbd-mode-syntax-table |
93 | | - (let ((end-pos (scan-sexps (point) 1))) |
94 | | - (unless end-pos |
95 | | - (user-error "Could not find end of deflayer block.")) |
96 | | - (setq end end-pos))) |
97 | | - |
98 | | - (let* ((block-text (buffer-substring-no-properties start end)) |
99 | | - (lines (split-string block-text "\n" t)) |
100 | | - (first-line (car lines)) |
101 | | - (layer-name (and (string-match "(deflayer\\s-+\\([a-zA-Z0-9_-]+\\)" first-line) |
102 | | - (match-string 1 first-line))) |
103 | | - (body-lines (butlast (cdr lines) 1)) |
104 | | - (parsed-lines (cl-loop for line in body-lines |
105 | | - for trimmed = (string-trim line) |
106 | | - collect |
107 | | - (if (or (string-empty-p trimmed) |
108 | | - (string-prefix-p ";;" trimmed)) |
109 | | - line |
110 | | - (split-string trimmed "[ \t]+")))) |
111 | | - (key-rows (cl-remove-if-not #'listp parsed-lines)) |
112 | | - (num-columns (if key-rows (apply #'max (mapcar #'length key-rows)) 0)) |
113 | | - (max-widths (make-list num-columns 0))) |
114 | | - (dolist (row key-rows) |
115 | | - (dotimes (i (length row)) |
116 | | - (setf (nth i max-widths) |
117 | | - (max (nth i max-widths) (length (nth i row)))))) |
118 | | - (let* ((formatted-lines |
119 | | - (cl-loop for line-data in parsed-lines |
120 | | - collect |
121 | | - (if (listp line-data) |
122 | | - (concat " " |
123 | | - (string-join |
124 | | - (cl-loop for item in line-data |
125 | | - for i from 0 |
126 | | - collect |
127 | | - (let ((width (nth i max-widths))) |
128 | | - (format (concat "%-" (number-to-string width) "s") item))) |
129 | | - " ")) |
130 | | - line-data))) |
131 | | - (new-text |
132 | | - (concat "(deflayer " (or layer-name "") "\n" |
133 | | - (string-join formatted-lines "\n") |
134 | | - "\n)"))) |
135 | | - (delete-region start end) |
136 | | - (insert new-text)))))) |
137 | | - |
138 | | - |
139 | 63 | (defconst kanata-kbd-top-level-directives |
140 | 64 | '("defcfg" "defsrc" "deflayer" "deflayermap" "defalias" "defvar" |
141 | 65 | "defvirtualkeys" "deffakekeys" "defseq" "defoverrides" "defchords" "defchordsv2" |
|
261 | 185 | (2 font-lock-constant-face)) |
262 | 186 |
|
263 | 187 | ;; Strings and numbers |
264 | | - ("\"\\(?:\\\\.\\S-*\\|[^\"]\\)*\"" . font-lock-string-face) |
| 188 | + ("\"\\(?:\\\\.\\|[^\"]\\)*\"" . font-lock-string-face) |
265 | 189 | ("\\b[0-9]+\\b" . font-lock-string-face)) |
266 | 190 | "Font lock keywords for `kanata-kbd-mode`.") |
267 | 191 |
|
| 192 | +(defun kanata-kbd-indent-line () |
| 193 | + "Indent current line for kanata-kbd-mode." |
| 194 | + (let ((indent 0)) |
| 195 | + (save-excursion |
| 196 | + (beginning-of-line) |
| 197 | + (let ((paren-depth 0)) |
| 198 | + (save-excursion |
| 199 | + (goto-char (point-min)) |
| 200 | + (while (< (point) (line-beginning-position)) |
| 201 | + (cond |
| 202 | + ((looking-at "(") (setq paren-depth (1+ paren-depth))) |
| 203 | + ((looking-at ")") (setq paren-depth (1- paren-depth)))) |
| 204 | + (forward-char))) |
| 205 | + (setq indent (* paren-depth 2)))) |
| 206 | + (indent-line-to indent))) |
| 207 | + |
| 208 | +(defun kanata-kbd-comment-dwim (arg) |
| 209 | + "Comment or uncomment region or line intelligently." |
| 210 | + (interactive "*P") |
| 211 | + (if (use-region-p) |
| 212 | + (comment-or-uncomment-region (region-beginning) (region-end)) |
| 213 | + (comment-or-uncomment-region (line-beginning-position) (line-end-position)))) |
| 214 | + |
| 215 | +(defun kanata-kbd-align-deflayer () |
| 216 | + "Align the keys within a deflayer block." |
| 217 | + (interactive) |
| 218 | + (save-excursion |
| 219 | + (let (start end) |
| 220 | + (unless (re-search-backward "(deflayer" nil t) |
| 221 | + (user-error "Not in a deflayer block")) |
| 222 | + (setq start (match-beginning 0)) |
| 223 | + (goto-char start) |
| 224 | + (with-syntax-table kanata-kbd-mode-syntax-table |
| 225 | + (let ((end-pos (scan-sexps (point) 1))) |
| 226 | + (unless end-pos |
| 227 | + (user-error "Could not find end of deflayer block.")) |
| 228 | + (setq end end-pos))) |
| 229 | + |
| 230 | + (let* ((block-text (buffer-substring-no-properties start end)) |
| 231 | + (lines (split-string block-text "\n" t)) |
| 232 | + (first-line (car lines)) |
| 233 | + (layer-name (and (string-match "(deflayer\\s-+\\([a-zA-Z0-9_-]+\\)" first-line) |
| 234 | + (match-string 1 first-line))) |
| 235 | + (body-lines (butlast (cdr lines) 1)) |
| 236 | + (parsed-lines (cl-loop for line in body-lines |
| 237 | + for trimmed = (string-trim line) |
| 238 | + collect |
| 239 | + (if (or (string-empty-p trimmed) |
| 240 | + (string-prefix-p ";;" trimmed)) |
| 241 | + line |
| 242 | + (split-string trimmed "[ \t]+")))) |
| 243 | + (key-rows (cl-remove-if-not #'listp parsed-lines)) |
| 244 | + (num-columns (if key-rows (apply #'max (mapcar #'length key-rows)) 0)) |
| 245 | + (max-widths (make-list num-columns 0))) |
| 246 | + (dolist (row key-rows) |
| 247 | + (dotimes (i (length row)) |
| 248 | + (setf (nth i max-widths) |
| 249 | + (max (nth i max-widths) (length (nth i row)))))) |
| 250 | + (let* ((formatted-lines |
| 251 | + (cl-loop for line-data in parsed-lines |
| 252 | + collect |
| 253 | + (if (listp line-data) |
| 254 | + (concat " " |
| 255 | + (string-join |
| 256 | + (cl-loop for item in line-data |
| 257 | + for i from 0 |
| 258 | + collect |
| 259 | + (let ((width (nth i max-widths))) |
| 260 | + (format (concat "%-" (number-to-string width) "s") item))) |
| 261 | + " ")) |
| 262 | + line-data))) |
| 263 | + (new-text |
| 264 | + (concat "(deflayer " (or layer-name "") "\n" |
| 265 | + (string-join formatted-lines "\n") |
| 266 | + "\n)"))) |
| 267 | + (delete-region start end) |
| 268 | + (insert new-text)))))) |
| 269 | + |
268 | 270 | ;;;###autoload |
269 | 271 | (define-derived-mode kanata-kbd-mode prog-mode "KanataKBD" |
270 | 272 | "Major mode for editing Kanata .kbd configuration files." |
|
0 commit comments