]> rtime.felk.cvut.cz Git - sojka/company-mode.git/blob - company-template.el
Added template insertion for ObjC selectors.
[sojka/company-mode.git] / company-template.el
1 (eval-when-compile (require 'cl))
2
3 (defface company-template-field
4   '((((background dark)) (:background "yellow" :foreground "black"))
5     (((background light)) (:background "orange" :foreground "black")))
6   "*Face used for editable text in template fields."
7   :group 'company)
8
9 (defvar company-template-nav-map
10   (let ((keymap (make-sparse-keymap)))
11     (define-key keymap [remap forward-word] 'company-template-forward-field)
12     (define-key keymap [remap subword-forward] 'company-template-forward-field)
13     ;; M-n
14     keymap))
15
16 ;; interactive ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17
18 (defsubst company-template-templates-at (pos)
19   (let (os)
20     (dolist (o (overlays-at pos))
21       (when (overlay-get o 'company-template-fields)
22         (push o os)))
23     os))
24
25 (defun company-template-move-to-first (templ)
26   (interactive)
27   (let ((fields (overlay-get templ 'company-template-fields)))
28     (push-mark)
29     (goto-char (apply 'min (mapcar 'overlay-start fields)))))
30
31 (defun company-template-forward-field ()
32   (interactive)
33   (let* ((templates (company-template-templates-at (point)))
34          (minimum (apply 'max (mapcar 'overlay-end templates)))
35          (fields (apply 'append
36                         (mapcar (lambda (templ)
37                                   (overlay-get templ 'company-template-fields))
38                                 templates))))
39     (dolist (pos (mapcar 'overlay-start fields))
40       (and pos
41            (> pos (point))
42            (< pos minimum)
43            (setq minimum pos)))
44     (push-mark)
45     (goto-char minimum)))
46
47 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
48
49 (defvar company-template--buffer-templates nil)
50 (make-variable-buffer-local 'company-template--buffer-templates)
51
52 (defun company-template-declare-template (beg end)
53   (let ((ov (make-overlay beg end)))
54     ;; (overlay-put ov 'face 'highlight)
55     (overlay-put ov 'keymap company-template-nav-map)
56     (overlay-put ov 'evaporate t)
57     (push ov company-template--buffer-templates)
58     (add-hook 'post-command-hook 'company-template-post-command nil t)
59     ov))
60
61 (defun company-template-remove-template (templ)
62   (mapc 'company-template-remove-field
63         (overlay-get templ 'company-template-fields))
64   (setq company-template--buffer-templates
65         (delq templ company-template--buffer-templates))
66   (delete-overlay templ))
67
68 (defun company-template-add-field (templ pos text)
69   (assert templ)
70   (save-excursion
71     ;; (goto-char pos)
72     (let ((ov (make-overlay pos pos))
73           (siblings (overlay-get templ 'company-template-fields))
74           (label (propertize text 'face 'company-template-field
75                              'company-template-parent templ)))
76       (overlay-put ov 'face 'highlight)
77       (add-text-properties 0 1 '(cursor t) label)
78       (overlay-put ov 'after-string label)
79       ;; (overlay-put ov 'evaporate t)
80       (overlay-put ov 'intangible t)
81       (overlay-put ov 'company-template-parent templ)
82       (overlay-put ov 'insert-in-front-hooks '(company-template-remove))
83       (push ov siblings)
84       (overlay-put templ 'company-template-fields siblings))))
85
86 (defun company-template-remove-field (field)
87   (when (overlayp field)
88     ;; (delete-region (overlay-start field) (overlay-end field))
89     (delete-overlay field))
90   ;; TODO: unlink
91   )
92
93 (defun company-template-clean-up (&optional pos)
94   "Clean up all templates that don't contain POS."
95   (unless pos (setq pos (point)))
96   (let ((local-ovs (overlays-in (- pos 2) pos)))
97     (dolist (templ company-template--buffer-templates)
98       (unless (memq templ local-ovs)
99         (company-template-remove-template templ)))))
100
101 ;; hooks ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
102
103 (defun company-template-remove (overlay after-p beg end &optional r)
104   "Called when a snippet input prompt is modified."
105   (when after-p
106     (delete-overlay overlay)))
107
108 (defun company-template-post-command ()
109   (company-template-clean-up)
110   (unless company-template--buffer-templates
111     (remove-hook 'post-command-hook 'company-template-post-command t)))
112
113 (provide 'company-template)
114 ;;; company-template.el ends here