]> code.delx.au - gnu-emacs-elpa/blob - company-template.el
Added template insertion for ObjC selectors.
[gnu-emacs-elpa] / 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