]> code.delx.au - gnu-emacs-elpa/commitdiff
company-template: Bring closer to yasnippet behavior
authorDmitry Gutov <dgutov@yandex.ru>
Fri, 22 Mar 2013 01:58:53 +0000 (05:58 +0400)
committerDmitry Gutov <dgutov@yandex.ru>
Fri, 22 Mar 2013 02:22:07 +0000 (06:22 +0400)
NEWS.md
company-clang.el
company-eclim.el
company-template.el

diff --git a/NEWS.md b/NEWS.md
index 57019cdcb57b8141e34f6a1afd76cbb30199ad94..f53a9fe43ac171fb4c575db91a7fb9bacb70f03b 100644 (file)
--- a/NEWS.md
+++ b/NEWS.md
@@ -2,12 +2,17 @@
 
 ## Next
 
-* `company-eclim` shows method overloads and inserts call templates with placeholders.
+* `company-template` has some breaking changes.  When point is at one of the
+  fields, it's displayed at the beginning, not right after it; `<tab>` jumps to
+  the next field, `forward-word` and `subword-forward` remappings are removed;
+  when you jump to the next field, if the current one hasn't been edited, the
+  overlay gets removed but the text remains.
+* `company-eclim` shows method overloads and inserts templates for calls.
 * `company-clang` ObjC arguments template insertion now requires explicit user action.
 * `company-clang-objc-templatify` does not insert spaces after colons anymore.
 * `company-clang` is now only initialized in supported buffers.
   So, no error messages if you don't have Clang until you open a C file.
-* `company-clang` recognizes Clang included with recent Xcode.
+* `company-clang` recognizes Clang included in recent Xcode.
 * New commands `company-select-previous-or-abort` and
   `company-select-next-or-abort`, bound to `<up>` and `<down>`.
 
index 6135f24d00400be3d787182052288ed1d581c59c..9dbd12d9241148d57c5090944a0e7e068fc40ab5 100644 (file)
@@ -198,14 +198,20 @@ Prefix files (-include ...) can be selected with
 (defun company-clang-objc-templatify (selector)
   (let* ((end (point))
          (beg (- (point) (length selector)))
-         (templ (company-template-declare-template beg end)))
+         (templ (company-template-declare-template beg end))
+         (cnt 0))
     (save-excursion
       (goto-char beg)
       (while (search-forward ":" end t)
-        (replace-match ": ")
-        (incf end)
-        (company-template-add-field templ (1- (match-end 0)) "<arg>"))
-      (delete-char -1))
+        (let* ((name (format "arg%d" cnt))
+               (len (length name)))
+          (incf end len)
+          (company-template-add-field templ (match-end 0) name)
+          (goto-char (+ (match-end 0) len))
+          (when (< (point) end)
+            (insert " ")
+            (incf end))
+          (incf cnt))))
     (company-template-move-to-first templ)))
 
 (defun company-clang (command &optional arg &rest ignored)
index 1637f3cab37859e1ade9ca5bad259153d6b620f2..cda300c12a343e16280018c61fa49f44f5193d83 100644 (file)
@@ -141,12 +141,11 @@ eclim can only complete correctly when the buffer has been saved."
          (templ (company-template-declare-template beg end)))
     (save-excursion
       (goto-char beg)
-      (while (re-search-forward "\\([(,] ?\\)\\(?:[^ ]+ \\)\\([^ ,)]*\\)" end t)
-        (let ((name (match-string 2)))
+      (while (re-search-forward "\\([(,] ?\\)\\([^ ]+ \\)\\([^ ,)]*\\)" end t)
+        (let ((name (match-string 3)))
           (replace-match "\\1" t)
-          (decf end (- (length (match-string 0))
-                       (length (match-string 1))))
-          (company-template-add-field templ (point) (format "<%s>" name)))))
+          (decf end (length (match-string 2)))
+          (company-template-add-field templ (point) name))))
     (company-template-move-to-first templ)))
 
 (defun company-eclim (command &optional arg &rest ignored)
index 69eac7c52b560ee5a9b8d5dc46e2229fe10d0310..05389acc7a51c093415fab69b9647b401c1027a6 100644 (file)
 
 (defvar company-template-nav-map
   (let ((keymap (make-sparse-keymap)))
-    (define-key keymap [remap forward-word] 'company-template-forward-field)
-    (define-key keymap [remap subword-forward] 'company-template-forward-field)
-    ;; M-n
+    (define-key keymap [tab] 'company-template-forward-field)
     keymap))
 
 ;; interactive ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
-(defsubst company-template-templates-at (pos)
+(defun company-template-templates-at (pos)
   (let (os)
     (dolist (o (overlays-at pos))
       (when (overlay-get o 'company-template-fields)
 
 (defun company-template-forward-field ()
   (interactive)
-  (let* ((templates (company-template-templates-at (point)))
+  (let* ((start (point))
+         (templates (company-template-templates-at (point)))
          (minimum (apply 'max (mapcar 'overlay-end templates)))
-         (fields (apply 'append
-                        (mapcar (lambda (templ)
-                                  (overlay-get templ 'company-template-fields))
-                                templates))))
+         (fields (loop for templ in templates
+                       append (overlay-get templ 'company-template-fields))))
     (dolist (pos (mapcar 'overlay-start fields))
       (and pos
            (> pos (point))
            (< pos minimum)
            (setq minimum pos)))
     (push-mark)
-    (goto-char minimum)))
+    (goto-char minimum)
+    (let ((field (loop for ovl in (overlays-at start)
+                       when (overlay-get ovl 'company-template-parent)
+                       return ovl)))
+      (company-template-remove-field field))))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
@@ -76,6 +77,7 @@
   (let ((ov (make-overlay beg end)))
     ;; (overlay-put ov 'face 'highlight)
     (overlay-put ov 'keymap company-template-nav-map)
+    (overlay-put ov 'priority 101)
     (overlay-put ov 'evaporate t)
     (push ov company-template--buffer-templates)
     (add-hook 'post-command-hook 'company-template-post-command nil t)
 (defun company-template-add-field (templ pos text)
   (assert templ)
   (save-excursion
-    ;; (goto-char pos)
-    (let ((ov (make-overlay pos pos))
-          (siblings (overlay-get templ 'company-template-fields))
-          (label (propertize text 'face 'company-template-field
-                             'company-template-parent templ)))
-      (overlay-put ov 'face 'highlight)
-      (add-text-properties 0 1 '(cursor t) label)
-      (overlay-put ov 'after-string label)
+    (save-excursion
+      (goto-char pos)
+      (insert text)
+      (when (> (point) (overlay-end templ))
+        (move-overlay templ (overlay-start templ) (point))))
+    (let ((ov (make-overlay pos (+ pos (length text))))
+          (siblings (overlay-get templ 'company-template-fields)))
       ;; (overlay-put ov 'evaporate t)
       (overlay-put ov 'intangible t)
+      (overlay-put ov 'face 'company-template-field)
       (overlay-put ov 'company-template-parent templ)
-      (overlay-put ov 'insert-in-front-hooks '(company-template-remove))
+      (overlay-put ov 'insert-in-front-hooks '(company-template-insert-hook))
       (push ov siblings)
       (overlay-put templ 'company-template-fields siblings))))
 
-(defun company-template-remove-field (field)
-  (when (overlayp field)
-    ;; (delete-region (overlay-start field) (overlay-end field))
-    (delete-overlay field))
-  ;; TODO: unlink
-  )
+(defun company-template-remove-field (ovl &optional clear)
+  (when (overlayp ovl)
+    (when (overlay-buffer ovl)
+      (when clear
+        (delete-region (overlay-start ovl) (overlay-end ovl)))
+      (delete-overlay ovl))
+    (let* ((templ (overlay-get ovl 'company-template-parent))
+           (siblings (overlay-get templ 'company-template-fields)))
+      (setq siblings (delq ovl siblings))
+      (overlay-put templ 'company-template-fields siblings))))
 
 (defun company-template-clean-up (&optional pos)
   "Clean up all templates that don't contain POS."
   (unless pos (setq pos (point)))
   (let ((local-ovs (overlays-in (- pos 2) pos)))
     (dolist (templ company-template--buffer-templates)
-      (unless (memq templ local-ovs)
+      (unless (and (memq templ local-ovs)
+                   (overlay-get templ 'company-template-fields))
         (company-template-remove-template templ)))))
 
 ;; hooks ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
-(defun company-template-remove (overlay after-p beg end &optional r)
+(defun company-template-insert-hook (ovl after-p &rest ignore)
   "Called when a snippet input prompt is modified."
-  (when after-p
-    (delete-overlay overlay)))
+  (unless after-p
+    (company-template-remove-field ovl t)))
 
 (defun company-template-post-command ()
   (company-template-clean-up)