[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] master b753952 01/12: Add function and binding to clear template
From: |
Dmitry Gutov |
Subject: |
[elpa] master b753952 01/12: Add function and binding to clear template field and move to next (#660) |
Date: |
Sat, 15 Jul 2017 13:36:43 -0400 (EDT) |
branch: master
commit b753952d5a0ee288b6c49b2d8dfa9a223ff59715
Author: Peter Vasil <address@hidden>
Commit: Dmitry Gutov <address@hidden>
Add function and binding to clear template field and move to next (#660)
Add company-template-field-map and a binding that clears the field
Resolves #657
---
NEWS.md | 5 ++++
company-template.el | 67 +++++++++++++++++++++++++++++++++++++++++---------
test/template-tests.el | 51 ++++++++++++++++++++++++++++++++++++++
3 files changed, 112 insertions(+), 11 deletions(-)
diff --git a/NEWS.md b/NEWS.md
index 7d8ae3e..08b0b33 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,5 +1,10 @@
# History of user-visible changes
+## Next
+
+* `company-template` has a new shortcut (`C-d`) for deleting an unmodified
+ template field while cursor is on it.
+
## 2017-03-29 (0.9.3)
* New variable `company-echo-truncate-lines`.
diff --git a/company-template.el b/company-template.el
index 053429d..f77f365 100644
--- a/company-template.el
+++ b/company-template.el
@@ -1,6 +1,6 @@
;;; company-template.el --- utility library for template expansion
-;; Copyright (C) 2009, 2010, 2014-2016 Free Software Foundation, Inc.
+;; Copyright (C) 2009, 2010, 2014-2017 Free Software Foundation, Inc.
;; Author: Nikolaj Schumacher
@@ -35,6 +35,11 @@
(define-key keymap (kbd "TAB") 'company-template-forward-field)
keymap))
+(defvar company-template-field-map
+ (let ((keymap (make-sparse-keymap)))
+ (define-key keymap (kbd "C-d") 'company-template-clear-field)
+ keymap))
+
(defvar-local company-template--buffer-templates nil)
;; interactive
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -55,19 +60,52 @@
(defun company-template-forward-field ()
(interactive)
+ (let ((start (point))
+ (next-field-start (company-template-find-next-field)))
+ (push-mark)
+ (goto-char next-field-start)
+ (company-template-remove-field (company-template-field-at start))))
+
+(defun company-template-clear-field ()
+ "Clear the field at point."
+ (interactive)
+ (let ((ovl (company-template-field-at (point))))
+ (when ovl
+ (company-template-remove-field ovl t)
+ (let ((after-clear-fn
+ (overlay-get ovl 'company-template-after-clear)))
+ (when (functionp after-clear-fn)
+ (funcall after-clear-fn))))))
+
+(defun company-template--after-clear-c-like-field ()
+ "Function that can be called after deleting a field of a c-like template.
+For c-like templates it is set as `after-post-fn' property on fields in
+`company-template-add-field'. If there is a next field, delete everything
+from point to it. If there is no field after point, remove preceding comma
+if present."
+ (let* ((pos (point))
+ (next-field-start (company-template-find-next-field))
+ (last-field-p (not (company-template-field-at next-field-start))))
+ (cond ((and (not last-field-p)
+ (< pos next-field-start)
+ (string-match "^[ ]*,+[ ]*$" (buffer-substring-no-properties
+ pos next-field-start)))
+ (delete-region pos next-field-start))
+ ((and last-field-p
+ (looking-back ",+[ ]*" (line-beginning-position)))
+ (delete-region (match-beginning 0) pos)))))
+
+(defun company-template-find-next-field ()
(let* ((start (point))
- (templates (company-template-templates-at (point)))
+ (templates (company-template-templates-at start))
(minimum (apply 'max (mapcar 'overlay-end templates)))
(fields (cl-loop for templ in templates
append (overlay-get templ
'company-template-fields))))
- (dolist (pos (mapcar 'overlay-start fields))
+ (dolist (pos (mapcar 'overlay-start fields) minimum)
(and pos
- (> pos (point))
+ (> pos start)
(< pos minimum)
- (setq minimum pos)))
- (push-mark)
- (goto-char minimum)
- (company-template-remove-field (company-template-field-at start))))
+ (setq minimum pos)))))
(defun company-template-field-at (&optional point)
(cl-loop for ovl in (overlays-at (or point (point)))
@@ -93,10 +131,12 @@
(delq templ company-template--buffer-templates))
(delete-overlay templ))
-(defun company-template-add-field (templ beg end &optional display)
+(defun company-template-add-field (templ beg end &optional display
after-clear-fn)
"Add new field to template TEMPL spanning from BEG to END.
When DISPLAY is non-nil, set the respective property on the overlay.
-Leave point at the end of the field."
+Leave point at the end of the field.
+AFTER-CLEAR-FN is a function that can be used to apply custom behavior
+after deleting a field in `company-template-remove-field'."
(cl-assert templ)
(when (> end (overlay-end templ))
(move-overlay templ (overlay-start templ) end))
@@ -109,6 +149,10 @@ Leave point at the end of the field."
(overlay-put ov 'display display))
(overlay-put ov 'company-template-parent templ)
(overlay-put ov 'insert-in-front-hooks '(company-template-insert-hook))
+ (when after-clear-fn
+ (overlay-put ov 'company-template-after-clear after-clear-fn))
+ (overlay-put ov 'keymap company-template-field-map)
+ (overlay-put ov 'priority 101)
(push ov siblings)
(overlay-put templ 'company-template-fields siblings)))
@@ -179,7 +223,8 @@ Leave point at the end of the field."
(let ((last-pos (point)))
(while (re-search-forward "\\([^,]+\\),?" end 'move)
(when (zerop (car (parse-partial-sexp last-pos (point))))
- (company-template-add-field templ last-pos (match-end 1))
+ (company-template-add-field templ last-pos (match-end 1) nil
+
#'company-template--after-clear-c-like-field)
(skip-chars-forward " ")
(setq last-pos (point))))))
diff --git a/test/template-tests.el b/test/template-tests.el
index da746bd..bcca8a8 100644
--- a/test/template-tests.el
+++ b/test/template-tests.el
@@ -117,3 +117,54 @@
(company-template-objc-templatify text)
(should (equal (buffer-string) text))
(company-template-field-assert-text "(NSString)"))))
+
+(ert-deftest company-template-clear-field-c-like-first-arg ()
+ (with-temp-buffer
+ (let ((text "foo(int a, short b)"))
+ (insert text)
+ (company-template-c-like-templatify text)
+ (company-template-clear-field)
+ (should (equal "foo(short b)" (buffer-string))))))
+
+(ert-deftest company-template-clear-field-c-like-last-arg ()
+ (with-temp-buffer
+ (let ((text "foo(int a, short b)"))
+ (insert text)
+ (company-template-c-like-templatify text)
+ (insert "42")
+ (company-template-forward-field)
+ (company-template-clear-field)
+ (should (equal "foo(42)" (buffer-string))))))
+
+(ert-deftest company-template-clear-field-c-like-generic-1 ()
+ (with-temp-buffer
+ (let ((text "foo<TValue>(int a, short b)"))
+ (insert text)
+ (company-template-c-like-templatify text)
+ (company-template-clear-field)
+ (should (equal "foo<>(int a, short b)" (buffer-string))))))
+
+(ert-deftest company-template-clear-field-c-like-generic-2 ()
+ (with-temp-buffer
+ (let ((text "foo<TKey, TValue>(int a, short b)"))
+ (insert text)
+ (company-template-c-like-templatify text)
+ (company-template-clear-field)
+ (should (equal "foo<TValue>(int a, short b)" (buffer-string))))))
+
+(ert-deftest company-template-clear-field-objc-first-arg ()
+ (with-temp-buffer
+ (let ((text "createBookWithTitle:andAuthor:"))
+ (insert text)
+ (company-template-objc-templatify text)
+ (company-template-clear-field)
+ (should (equal "createBookWithTitle: andAuthor:arg1" (buffer-string))))))
+
+(ert-deftest company-template-insert-hook-c-like-field ()
+ (with-temp-buffer
+ (let ((text "foo(int a, short b)"))
+ (insert text)
+ (company-template-c-like-templatify text)
+ (let ((ovl (company-template-field-at (point))))
+ (company-template-insert-hook ovl nil)
+ (should (equal "foo(, short b)" (buffer-string)))))))
- [elpa] master updated (e9faca6 -> 89bd25a), Dmitry Gutov, 2017/07/15
- [elpa] master 950c547 04/12: Be more accurate about when to return `stop', Dmitry Gutov, 2017/07/15
- [elpa] master 1fe2634 02/12: Fix #665 quick and dirty, Dmitry Gutov, 2017/07/15
- [elpa] master a5289c5 03/12: Fix backspacing into a "bad" prefix, Dmitry Gutov, 2017/07/15
- [elpa] master 9dbabd1 08/12: company-diag: Output major mode as well, Dmitry Gutov, 2017/07/15
- [elpa] master 4184494 10/12: Update NEWS, Dmitry Gutov, 2017/07/15
- [elpa] master a557460 05/12: Set company-template-nav-map as parent of company-template-field-map, Dmitry Gutov, 2017/07/15
- [elpa] master 6d80e9f 09/12: company--col-row: Disable native line numbers temporarily, Dmitry Gutov, 2017/07/15
- [elpa] master a43f944 06/12: Merge pull request #674 from ptrv/fix-company-template-field-keymap, Dmitry Gutov, 2017/07/15
- [elpa] master 6d05ca5 07/12: Remove dead code, Dmitry Gutov, 2017/07/15
- [elpa] master b753952 01/12: Add function and binding to clear template field and move to next (#660),
Dmitry Gutov <=
- [elpa] master 89bd25a 12/12: Merge commit 'a197b072dc93dbad238f1dc70da01e3775ebfb56' from company, Dmitry Gutov, 2017/07/15
- [elpa] master a197b07 11/12: Release 0.9.4, Dmitry Gutov, 2017/07/15