]> code.delx.au - gnu-emacs-elpa/blob - packages/gnome-c-style/gnome-c-snippet.el
Merge commit 'd827bb511203a64da3ae5cc6910b87b7c99d233b'
[gnu-emacs-elpa] / packages / gnome-c-style / gnome-c-snippet.el
1 ;;; gnome-c-snippet.el --- GNOME-style code generation -*- lexical-binding: t; -*-
2 ;; Copyright (C) 2016 Free Software Foundation, Inc.
3
4 ;; Author: Daiki Ueno <ueno@gnu.org>
5 ;; Keywords: GNOME, C, coding style
6
7 ;; This file is part of GNU Emacs.
8
9 ;; GNU Emacs is free software: you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation, either version 3 of the License, or
12 ;; (at your option) any later version.
13
14 ;; GNU Emacs is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
21
22 ;;; Commentary:
23
24 ;; FIXME: The snippets defined here could be rewritten in yasnippet
25
26 ;;; Code:
27
28 (require 'gnome-c-align)
29 (require 'subword)
30
31 (defvar gnome-c-snippet-package nil)
32 (make-variable-buffer-local 'gnome-c-snippet-package)
33
34 (defvar gnome-c-snippet-class nil)
35 (make-variable-buffer-local 'gnome-c-snippet-class)
36
37 (defvar gnome-c-snippet-parent-package nil)
38 (make-variable-buffer-local 'gnome-c-snippet-parent-package)
39
40 (defvar gnome-c-snippet-parent-class nil)
41 (make-variable-buffer-local 'gnome-c-snippet-parent-class)
42
43 (defconst gnome-c-snippet-guess-name-functions
44 '(gnome-c-snippet--guess-name-from-header-buffer
45 gnome-c-snippet--guess-name-from-declaration
46 gnome-c-snippet--guess-name-from-file-name))
47
48 (defcustom gnome-c-snippet-align-arglist t
49 "Whether to align argument list of the inserted snippet"
50 :type 'boolean
51 :group 'gnome-c-style)
52
53 (make-variable-buffer-local 'gnome-c-snippet-align-arglist)
54
55 (defun gnome-c-snippet--find-declaration ()
56 (save-excursion
57 (let (beg end)
58 (goto-char (point-min))
59 (when (re-search-forward
60 "^G_DECLARE_\\(?:FINAL\\|DERIVABLE\\)_TYPE\\s-*("
61 nil t)
62 (setq beg (match-beginning 0))
63 (goto-char (match-end 0))
64 (backward-char)
65 (condition-case nil
66 (progn
67 (c-forward-sexp)
68 (setq end (point)))
69 (error)))
70 (when (and beg end)
71 (list beg end)))))
72
73 (defun gnome-c-snippet--extract-names-from-declaration (beg end)
74 (save-excursion
75 (narrow-to-region beg end)
76 (goto-char (point-min))
77 (search-forward "(")
78 (c-forward-syntactic-ws)
79 (let ((capitalized-package-class
80 (buffer-substring-no-properties (point)
81 (progn
82 (c-forward-token-2)
83 (c-backward-syntactic-ws)
84 (point))))
85 uppercased-package uppercased-class
86 capitalized-package capitalized-class capitalized-parent)
87 (c-forward-syntactic-ws)
88 (c-forward-token-2 3)
89 (setq uppercased-package (split-string
90 (buffer-substring (point)
91 (progn
92 (c-forward-token-2)
93 (c-backward-syntactic-ws)
94 (point)))
95 "_"))
96 (c-forward-syntactic-ws)
97 (c-forward-token-2)
98 (setq uppercased-class (split-string
99 (buffer-substring (point)
100 (progn
101 (c-forward-token-2)
102 (c-backward-syntactic-ws)
103 (point)))
104 "_"))
105 (c-forward-syntactic-ws)
106 (c-forward-token-2)
107 (setq capitalized-parent (gnome-c-snippet--parse-name
108 (buffer-substring (point)
109 (progn
110 (c-forward-token-2)
111 (c-backward-syntactic-ws)
112 (point)))))
113 (catch 'error
114 (let ((index 0))
115 (dolist (uppercased uppercased-package)
116 (let* ((length (length uppercased))
117 (capitalized
118 (substring capitalized-package-class
119 index (+ index length))))
120 (unless (equal (upcase capitalized) uppercased)
121 (throw 'error nil))
122 (push capitalized capitalized-package)
123 (setq index (+ index length))))
124 (dolist (uppercased uppercased-class)
125 (let* ((length (length uppercased))
126 (capitalized
127 (substring capitalized-package-class
128 index (+ index length))))
129 (unless (equal (upcase capitalized) uppercased)
130 (throw 'error nil))
131 (push capitalized capitalized-class)
132 (setq index (+ index length))))))
133 (list (nreverse capitalized-package)
134 (nreverse capitalized-class)
135 capitalized-parent))))
136
137 (defun gnome-c-snippet--find-header-buffer ()
138 (pcase (file-name-extension buffer-file-name)
139 ("h"
140 (current-buffer))
141 ("c"
142 (let ((header-file-name
143 (concat (file-name-sans-extension buffer-file-name) ".h")))
144 (cl-find-if
145 (lambda (buffer)
146 (with-current-buffer buffer
147 (equal buffer-file-name header-file-name)))
148 (buffer-list))))))
149
150 (defun gnome-c-snippet--guess-name-from-header-buffer (symbol)
151 (let ((header-buffer (gnome-c-snippet--find-header-buffer)))
152 (when header-buffer
153 (with-current-buffer header-buffer
154 (symbol-value (intern (format "gnome-c-snippet-%S" symbol)))))))
155
156 (defun gnome-c-snippet--guess-name-from-declaration (symbol)
157 (when (memq symbol '(package class parent-package parent-class))
158 (let ((header-buffer (gnome-c-snippet--find-header-buffer)))
159 (when header-buffer
160 (with-current-buffer header-buffer
161 (let ((region (gnome-c-snippet--find-declaration))
162 names)
163 (when region
164 (setq names
165 (apply #'gnome-c-snippet--extract-names-from-declaration
166 region))
167 (when names
168 (pcase symbol
169 (`package (car names))
170 (`class (nth 1 names))
171 (`parent-package (list (car (nth 2 names))))
172 (`parent-class (cdr (nth 2 names))))))))))))
173
174 (defun gnome-c-snippet--guess-name-from-file-name (symbol)
175 (when (memq symbol '(package class))
176 (let ((filename (file-name-sans-extension
177 (file-name-nondirectory buffer-file-name))))
178 (when (string-match-p "-" filename)
179 (let ((names (split-string filename "-")))
180 (pcase symbol
181 (`package (list (upcase-initials (car names))))
182 (`class (mapcar #'upcase-initials (cdr names)))))))))
183
184 (defun gnome-c-snippet--parse-name (name)
185 (with-temp-buffer
186 (let (words)
187 (insert (upcase-initials name))
188 (goto-char (point-min))
189 (while (not (eobp))
190 ;; Skip characters not recognized by subword-mode.
191 (if (looking-at "[^[:lower:][:upper:][:digit:]]+")
192 (goto-char (match-end 0)))
193 (push (buffer-substring (point) (progn (subword-forward 1)
194 (point)))
195 words))
196 (nreverse words))))
197
198 (defun gnome-c-snippet--read-name (prompt symbol &optional default)
199 (when (or current-prefix-arg
200 (not (symbol-value symbol)))
201 (set symbol
202 (gnome-c-snippet--parse-name
203 (read-string prompt
204 (or (if (symbol-value symbol)
205 (gnome-c-snippet--format-Package
206 (symbol-value symbol)))
207 default)))))
208 (symbol-value symbol))
209
210 (defun gnome-c-snippet--read-package-and-class (parent)
211 (append (list (gnome-c-snippet--read-name
212 "Package (CamelCase): "
213 'gnome-c-snippet-package
214 (gnome-c-snippet--format-Package
215 (run-hook-with-args-until-success
216 'gnome-c-snippet-guess-name-functions
217 'package)))
218 (gnome-c-snippet--read-name
219 "Class (CamelCase): "
220 'gnome-c-snippet-class
221 (gnome-c-snippet--format-Class
222 (run-hook-with-args-until-success
223 'gnome-c-snippet-guess-name-functions
224 'class))))
225 (when parent
226 (list (gnome-c-snippet--read-name
227 "Parent package (CamelCase): "
228 'gnome-c-snippet-parent-package
229 (gnome-c-snippet--format-Package
230 (run-hook-with-args-until-success
231 'gnome-c-snippet-guess-name-functions
232 'parent-package)))
233 (gnome-c-snippet--read-name
234 "Parent class (CamelCase): "
235 'gnome-c-snippet-parent-class
236 (gnome-c-snippet--format-Class
237 (run-hook-with-args-until-success
238 'gnome-c-snippet-guess-name-functions
239 'parent-class)))))))
240
241 (defun gnome-c-snippet--read-package-and-interface (parent)
242 (list (gnome-c-snippet--read-name
243 "Package (CamelCase): "
244 'gnome-c-snippet-package
245 (gnome-c-snippet--format-Package
246 (run-hook-with-args-until-success
247 'gnome-c-snippet-guess-name-functions
248 'package)))
249 (gnome-c-snippet--read-name
250 "Interface (CamelCase): "
251 'gnome-c-snippet-class
252 (gnome-c-snippet--format-Class
253 (run-hook-with-args-until-success
254 'gnome-c-snippet-guess-name-functions
255 'class)))
256 (when parent
257 (list (gnome-c-snippet--read-name
258 "Parent package (CamelCase): "
259 'gnome-c-snippet-parent-package
260 (gnome-c-snippet--format-Package
261 (run-hook-with-args-until-success
262 'gnome-c-snippet-guess-name-functions
263 'parent-package)))
264 (gnome-c-snippet--read-name
265 "Parent class (CamelCase): "
266 'gnome-c-snippet-parent-class
267 (gnome-c-snippet--format-Class
268 (run-hook-with-args-until-success
269 'gnome-c-snippet-guess-name-functions
270 'parent-class)))))))
271
272 (defun gnome-c-snippet--format-PACKAGE (package)
273 (mapconcat #'upcase package "_"))
274 (defalias 'gnome-c-snippet--format-CLASS 'gnome-c-snippet--format-PACKAGE)
275
276 (defun gnome-c-snippet--format-PACKAGE_CLASS (package class)
277 (concat (gnome-c-snippet--format-PACKAGE package)
278 "_"
279 (gnome-c-snippet--format-CLASS class)))
280
281 (defun gnome-c-snippet--format-package (package)
282 (mapconcat #'downcase package "_"))
283 (defalias 'gnome-c-snippet--format-class 'gnome-c-snippet--format-package)
284
285 (defun gnome-c-snippet--format-package_class (package class)
286 (concat (gnome-c-snippet--format-package package)
287 "_"
288 (gnome-c-snippet--format-class class)))
289
290 (defun gnome-c-snippet--format-Package (package)
291 (mapconcat #'identity package ""))
292 (defalias 'gnome-c-snippet--format-Class 'gnome-c-snippet--format-Package)
293
294 (defun gnome-c-snippet--format-PackageClass (package class)
295 (concat (gnome-c-snippet--format-Package package)
296 (gnome-c-snippet--format-Class class)))
297
298 ;;;###autoload
299 (defun gnome-c-snippet-insert-package_class (package class)
300 "Insert the class name before the current point."
301 (interactive (gnome-c-snippet--read-package-and-class nil))
302 (insert (gnome-c-snippet--format-package_class package class)))
303
304 ;;;###autoload
305 (defun gnome-c-snippet-insert-PACKAGE_CLASS (package class)
306 "Insert the class name before the current point."
307 (interactive (gnome-c-snippet--read-package-and-class nil))
308 (insert (gnome-c-snippet--format-PACKAGE_CLASS package class)))
309
310 ;;;###autoload
311 (defun gnome-c-snippet-insert-PackageClass (package class)
312 "Insert the class name (in CamelCase) before the current point."
313 (interactive (gnome-c-snippet--read-package-and-class nil))
314 (insert (gnome-c-snippet--format-PackageClass package class)))
315
316 (defun gnome-c-snippet-insert-interface-declaration (package iface
317 parent-package parent-class)
318 "Insert interface declaration for PACKAGE and IFACE"
319 (interactive (gnome-c-snippet--read-package-and-interface t))
320 (insert "\
321 #define " (gnome-c-snippet--format-PACKAGE package) "_TYPE_" (gnome-c-snippet--format-CLASS iface) " (" (gnome-c-snippet--format-package package) "_" (gnome-c-snippet--format-class iface) "_get_type ())
322 G_DECLARE_INTERFACE (" (gnome-c-snippet--format-PackageClass package iface) ", "
323 (gnome-c-snippet--format-package_class package iface) ", " (gnome-c-snippet--format-PACKAGE package) ", " (gnome-c-snippet--format-CLASS iface) ", " (gnome-c-snippet--format-PackageClass parent-package parent-class) ")
324 "))
325
326 (defun gnome-c-snippet--insert-class-declaration (package
327 class
328 parent-package
329 parent-class
330 derivable)
331 (insert "\
332 #define " (gnome-c-snippet--format-PACKAGE package) "_TYPE_" (gnome-c-snippet--format-CLASS class) " (" (gnome-c-snippet--format-package_class package class) "_get_type ())
333 G_DECLARE_" (if derivable "DERIVABLE" "FINAL") "_TYPE (" (gnome-c-snippet--format-PackageClass package class) ", "
334 (gnome-c-snippet--format-package_class package class) ", " (gnome-c-snippet--format-PACKAGE package) ", " (gnome-c-snippet--format-CLASS class) ", " (gnome-c-snippet--format-PackageClass parent-package parent-class) ")
335 "))
336
337 (defun gnome-c-snippet-insert-final-class-declaration (package
338 class
339 parent-package
340 parent-class)
341 "Insert final class declaration for PACKAGE and CLASS."
342 (interactive (gnome-c-snippet--read-package-and-class t))
343 (gnome-c-snippet--insert-class-declaration package
344 class
345 parent-package
346 parent-class
347 nil))
348
349 (defun gnome-c-snippet-insert-derivable-class-declaration (package
350 class
351 parent-package
352 parent-class)
353 "Insert derivable class declaration for PACKAGE and CLASS."
354 (interactive (gnome-c-snippet--read-package-and-class t))
355 (gnome-c-snippet--insert-class-declaration package
356 class
357 parent-package
358 parent-class
359 t))
360
361 (defun gnome-c-snippet-insert-interface-definition (package
362 iface
363 parent-package
364 parent-class)
365 "Insert class definition for PACKAGE and CLASS."
366 (interactive (gnome-c-snippet--read-package-and-interface t))
367 (insert "\
368 static void
369 " (gnome-c-snippet--format-package_class package iface) "_default_init (" (gnome-c-snippet--format-PackageClass package iface) "Interface *iface) {
370 }
371
372 G_DEFINE_INTERFACE (" (gnome-c-snippet--format-PackageClass package iface) ", "
373 (gnome-c-snippet--format-package_class package iface) ", " (gnome-c-snippet--format-PACKAGE parent-package) "_TYPE_" (gnome-c-snippet--format-CLASS parent-class) ")
374 "))
375
376 (defun gnome-c-snippet--insert-class-definition (package
377 class
378 parent-package
379 parent-class
380 abstract
381 code)
382 (insert "\
383 G_DEFINE_" (if abstract "ABSTRACT_" "") "TYPE" (if code "WITH_CODE" "") " (" (gnome-c-snippet--format-PackageClass package class) ", "
384 (gnome-c-snippet--format-package_class package class) ", " (gnome-c-snippet--format-PACKAGE parent-package) "_TYPE_" (gnome-c-snippet--format-CLASS parent-class) (if code ", " "") ")"))
385
386 (defun gnome-c-snippet-insert-G_DEFINE_TYPE (package
387 class
388 parent-package
389 parent-class)
390 "Insert G_DEFINE_TYPE for PACKAGE and CLASS."
391 (interactive (gnome-c-snippet--read-package-and-class t))
392 (gnome-c-snippet--insert-class-definition package
393 class
394 parent-package
395 parent-class
396 nil
397 nil))
398
399 (defun gnome-c-snippet-insert-G_DEFINE_TYPE_WITH_CODE (package
400 class
401 parent-package
402 parent-class)
403 "Insert G_DEFINE_TYPE_WITH_CODE for PACKAGE and CLASS."
404 (interactive (gnome-c-snippet--read-package-and-class t))
405 (gnome-c-snippet--insert-class-definition package
406 class
407 parent-package
408 parent-class
409 nil
410 t))
411
412 (defun gnome-c-snippet-insert-G_DEFINE_ABSTRACT_TYPE (package
413 class
414 parent-package
415 parent-class)
416 "Insert G_DEFINE_ABSTRACT_TYPE for PACKAGE and CLASS."
417 (interactive (gnome-c-snippet--read-package-and-class t))
418 (gnome-c-snippet--insert-class-definition package
419 class
420 parent-package
421 parent-class
422 t
423 nil))
424
425 (defun gnome-c-snippet-insert-G_DEFINE_ABSTRACT_TYPE_WITH_CODE (package
426 class
427 parent-package
428 parent-class)
429 "Insert G_DEFINE_ABSTRACT_TYPE_WITH_CODE for PACKAGE and CLASS."
430 (interactive (gnome-c-snippet--read-package-and-class t))
431 (gnome-c-snippet--insert-class-definition package
432 class
433 parent-package
434 parent-class
435 t
436 t))
437
438 (defun gnome-c-snippet-insert-constructor (package class)
439 "Insert 'constructor' vfunc of GObjectClass for PACKAGE and CLASS."
440 (interactive (gnome-c-snippet--read-package-and-class nil))
441 (let (arglist-start body-start)
442 (insert "\
443 static GObject *
444 " (gnome-c-snippet--format-package_class package class) "_constructor (")
445 (setq arglist-start (point-marker))
446 (insert "GType *object,
447 guint n_construct_properties,
448 GObjectConstructParam *construct_properties)\n")
449 (setq body-start (point-marker))
450 (if gnome-c-snippet-align-arglist
451 (progn
452 (goto-char arglist-start)
453 (gnome-c-align-arglist-at-point))
454 (indent-region arglist-start (point)))
455 (goto-char body-start)
456 (insert "{
457 " (gnome-c-snippet--format-PackageClass package class) " *self = "
458 (gnome-c-snippet--format-PACKAGE_CLASS package class) " (object);
459
460 G_OBJECT_CLASS (" (gnome-c-snippet--format-package_class package class) "_parent_class)->constructor (type, n_construct_properties, construct_properties);
461 }
462 ")
463 (indent-region body-start (point))))
464
465 (defun gnome-c-snippet-insert-set_property (package class)
466 "Insert 'set_property' vfunc of GObjectClass for PACKAGE and CLASS."
467 (interactive (gnome-c-snippet--read-package-and-class nil))
468 (let (arglist-start body-start)
469 (insert "\
470 static void
471 " (gnome-c-snippet--format-package_class package class) "_set_property (")
472 (setq arglist-start (point-marker))
473 (insert "GObject *object,
474 guint prop_id,
475 const GValue *value,
476 GParamSpec *pspec)\n")
477 (setq body-start (point-marker))
478 (if gnome-c-snippet-align-arglist
479 (progn
480 (goto-char arglist-start)
481 (gnome-c-align-arglist-at-point))
482 (indent-region arglist-start (point)))
483 (goto-char body-start)
484 (insert "{
485 " (gnome-c-snippet--format-PackageClass package class) " *self = "
486 (gnome-c-snippet--format-PACKAGE_CLASS package class) " (object);
487
488 switch (prop_id)
489 {
490 default:
491 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
492 break;
493 }
494 }
495 ")
496 (indent-region body-start (point))))
497
498 (defun gnome-c-snippet-insert-get_property (package class)
499 "Insert 'get_property' vfunc of GObjectClass for PACKAGE and CLASS."
500 (interactive (gnome-c-snippet--read-package-and-class nil))
501 (let (arglist-start body-start)
502 (insert "\
503 static void
504 " (gnome-c-snippet--format-package_class package class) "_get_property (")
505 (setq arglist-start (point-marker))
506 (insert "GObject *object,
507 guint prop_id,
508 GValue *value,
509 GParamSpec *pspec)\n")
510 (setq body-start (point-marker))
511 (if gnome-c-snippet-align-arglist
512 (progn
513 (goto-char arglist-start)
514 (gnome-c-align-arglist-at-point))
515 (indent-region arglist-start (point)))
516 (goto-char body-start)
517 (insert "{
518 " (gnome-c-snippet--format-PackageClass package class) " *self = "
519 (gnome-c-snippet--format-PACKAGE_CLASS package class) " (object);
520
521 switch (prop_id)
522 {
523 default:
524 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
525 break;
526 }
527 }
528 ")
529 (indent-region body-start (point))))
530
531 (defun gnome-c-snippet-insert-dispose (package class)
532 "Insert 'dispose' vfunc of GObjectClass for PACKAGE and CLASS."
533 (interactive (gnome-c-snippet--read-package-and-class nil))
534 (let (body-start)
535 (insert "\
536 static void
537 " (gnome-c-snippet--format-package_class package class) "_dispose (GObject *object)\n")
538 (setq body-start (point-marker))
539 (insert "{
540 " (gnome-c-snippet--format-PackageClass package class) " *self = "
541 (gnome-c-snippet--format-PACKAGE_CLASS package class) " (object);
542
543 G_OBJECT_CLASS (" (gnome-c-snippet--format-package_class package class) "_parent_class)->dispose (object);
544 }
545 ")
546 (indent-region body-start (point))))
547
548 (defun gnome-c-snippet-insert-finalize (package class)
549 "Insert 'finalize' vfunc of GObjectClass for PACKAGE and CLASS."
550 (interactive (gnome-c-snippet--read-package-and-class nil))
551 (let (body-start)
552 (insert "\
553 static void
554 " (gnome-c-snippet--format-package_class package class) "_finalize (GObject *object)\n")
555 (setq body-start (point-marker))
556 (insert "{
557 " (gnome-c-snippet--format-PackageClass package class) " *self = "
558 (gnome-c-snippet--format-PACKAGE_CLASS package class) " (object);
559
560 G_OBJECT_CLASS (" (gnome-c-snippet--format-package_class package class) "_parent_class)->finalize (object);
561 }
562 ")
563 (indent-region body-start (point))))
564
565 (defun gnome-c-snippet-insert-dispatch_properties_changed (package class)
566 "Insert 'dispatch_properties_changed vfunc of GObjectClass for
567 PACKAGE and CLASS."
568 (interactive (gnome-c-snippet--read-package-and-class nil))
569 (let (arglist-start body-start)
570 (insert "\
571 static void
572 " (gnome-c-snippet--format-package_class package class) "_dispatch_properties_changed (")
573 (setq arglist-start (point-marker))
574 (insert "GObject *object,
575 guint n_pspecs,
576 GParamSpec **pspecs)\n")
577 (setq body-start (point-marker))
578 (if gnome-c-snippet-align-arglist
579 (progn
580 (goto-char arglist-start)
581 (gnome-c-align-arglist-at-point))
582 (indent-region arglist-start (point)))
583 (goto-char body-start)
584 (insert "{
585 " (gnome-c-snippet--format-PackageClass package class) " *self = "
586 (gnome-c-snippet--format-PACKAGE_CLASS package class) " (object);
587
588 G_OBJECT_CLASS (" (gnome-c-snippet--format-package_class package class) "_parent_class)->dispatch_properties_changed (object, n_pspecs, pspecs);
589 }
590 ")
591 (indent-region body-start (point))))
592
593 (defun gnome-c-snippet-insert-notify (package class)
594 "Insert 'notify' vfunc of GObjectClass for PACKAGE and CLASS."
595 (interactive (gnome-c-snippet--read-package-and-class nil))
596 (let (arglist-start body-start)
597 (insert "\
598 static void
599 " (gnome-c-snippet--format-package_class package class) "_notify (")
600 (setq arglist-start (point-marker))
601 (insert "GObject *object,
602 GParamSpec *pspec)\n")
603 (setq body-start (point-marker))
604 (if gnome-c-snippet-align-arglist
605 (progn
606 (goto-char arglist-start)
607 (gnome-c-align-arglist-at-point))
608 (indent-region arglist-start (point)))
609 (insert "{
610 " (gnome-c-snippet--format-PackageClass package class) " *self = "
611 (gnome-c-snippet--format-PACKAGE_CLASS package class) " (object);
612
613 G_OBJECT_CLASS (" (gnome-c-snippet--format-package_class package class) "_parent_class)->notify (object, pspec);
614 }
615 ")
616 (indent-region body-start (point))))
617
618 (defun gnome-c-snippet-insert-constructed (package class)
619 "Insert 'constructed' vfunc of GObjectClass for PACKAGE and CLASS."
620 (interactive (gnome-c-snippet--read-package-and-class nil))
621 (let (body-start)
622 (insert "\
623 static void
624 " (gnome-c-snippet--format-package_class package class) "_constructed (GObject *object)\n")
625 (setq body-start (point-marker))
626 (insert "{
627 " (gnome-c-snippet--format-PackageClass package class) " *self = "
628 (gnome-c-snippet--format-PACKAGE_CLASS package class) " (object);
629
630 G_OBJECT_CLASS (" (gnome-c-snippet--format-package_class package class) "_parent_class)->constructed (object);
631 }
632 ")
633 (indent-region body-start (point))))
634
635 (defun gnome-c-snippet-insert-class-init (package class)
636 "Insert '_class_init' function for PACKAGE and CLASS."
637 (interactive (gnome-c-snippet--read-package-and-class nil))
638 (insert "\
639 static void
640 " (gnome-c-snippet--format-package_class package class) "_class_init (" (gnome-c-snippet--format-PackageClass package class) "Class *klass)\n")
641 (insert "{
642 }
643 "))
644
645 (defun gnome-c-snippet-insert-init (package class)
646 "Insert '_init' function for PACKAGE and CLASS."
647 (interactive (gnome-c-snippet--read-package-and-class nil))
648 (insert "\
649 static void
650 " (gnome-c-snippet--format-package_class package class) "_init (" (gnome-c-snippet--format-PackageClass package class) " *self)\n")
651 (insert "{
652 }
653 "))
654
655 (defvar gnome-c-snippet-snippet-commands
656 '(("G_DECLARE_INTERFACE" . gnome-c-snippet-insert-interface-declaration)
657 ("G_DECLARE_FINAL_TYPE" . gnome-c-snippet-insert-final-class-declaration)
658 ("G_DECLARE_DERIVABLE_TYPE" .
659 gnome-c-snippet-insert-derivable-class-declaration)
660 ("G_DEFINE_INTERFACE" . gnome-c-snippet-insert-interface-definition)
661 ("G_DEFINE_TYPE" . gnome-c-snippet-insert-G_DEFINE_TYPE)
662 ("G_DEFINE_TYPE_WITH_CODE" . gnome-c-snippet-insert-G_DEFINE_TYPE_WITH_CODE)
663 ("G_DEFINE_ABSTRACT_TYPE" .
664 gnome-c-snippet-insert-G_DEFINE_ABSTRACT_TYPE)
665 ("G_DEFINE_ABSTRACT_TYPE_WITH_CODE" .
666 gnome-c-snippet-insert-G_DEFINE_ABSTRACT_TYPE_WITH_CODE)
667 ("GObjectClass.constructor" . gnome-c-snippet-insert-constructor)
668 ("GObjectClass.set_property" . gnome-c-snippet-insert-set_property)
669 ("GObjectClass.get_property" . gnome-c-snippet-insert-get_property)
670 ("GObjectClass.dispose" . gnome-c-snippet-insert-dispose)
671 ("GObjectClass.finalize" . gnome-c-snippet-insert-finalize)
672 ("GObjectClass.dispatch_properties_changed" .
673 gnome-c-snippet-insert-dispatch_properties_changed)
674 ("GObjectClass.notify" . gnome-c-snippet-insert-notify)
675 ("GObjectClass.constructed" . gnome-c-snippet-insert-constructed)
676 ;; Will be overridden by `gnome-c-snippet-insert'.
677 ("_class_init" . gnome-c-snippet-insert-class-init)
678 ;; Will be overridden by `gnome-c-snippet-insert'.
679 ("_init" . gnome-c-snippet-insert-init)))
680
681 ;;;###autoload
682 (defun gnome-c-snippet-insert (command)
683 (interactive
684 (let ((commands (copy-tree gnome-c-snippet-snippet-commands)))
685 (when (and gnome-c-snippet-package gnome-c-snippet-class)
686 (setcar (assoc "_class_init" commands)
687 (concat (gnome-c-snippet--format-package_class
688 gnome-c-snippet-package gnome-c-snippet-class)
689 "_class_init"))
690 (setcar (assoc "_init" commands)
691 (concat (gnome-c-snippet--format-package_class
692 gnome-c-snippet-package gnome-c-snippet-class)
693 "_init")))
694 (let* ((name (completing-read "Snippet: " commands nil t))
695 (entry (assoc name commands)))
696 (unless entry
697 (error "Unknown snippet: %s" name))
698 (list (cdr entry)))))
699 (call-interactively command))
700
701 (provide 'gnome-c-snippet)
702
703 ;;; gnome-c-snippet.el ends here