emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/cape aae065830c 115/146: Add cape-sgml and cape-tex


From: ELPA Syncer
Subject: [elpa] externals/cape aae065830c 115/146: Add cape-sgml and cape-tex
Date: Sun, 9 Jan 2022 20:57:47 -0500 (EST)

branch: externals/cape
commit aae065830c26cbd9e21ac7205dff0dfec423392b
Author: Daniel Mendler <mail@daniel-mendler.de>
Commit: Daniel Mendler <mail@daniel-mendler.de>

    Add cape-sgml and cape-tex
---
 README.org | 19 +++++++++++++++-
 cape.el    | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 92 insertions(+), 3 deletions(-)

diff --git a/README.org b/README.org
index 9aee1a9df8..1866b23bdb 100644
--- a/README.org
+++ b/README.org
@@ -31,6 +31,19 @@ packages or configurations, since it completes elisp symbols 
anywere.
 On the more experimental side, Cape has the super power to transform Company
 backends into Capfs and merge multiple Capfs into a Super-Capf!
 
+* Available Capfs
+
+* ~cape-dabbrev~: Complete word from current buffers
+* ~cape-file~: Complete file name
+* ~cape-keyword~: Complete programming language keyword
+* ~cape-symbol~: Complete Elisp symbol
+* ~cape-abbrev~: Complete abbreviation (~add-global-abbrev~, ~add-mode-abbrev~)
+* ~cape-ispell~: Complete word from Ispell dictionary
+* ~cape-dict~: Complete word from dictionary file
+* ~cape-line~: Complete entire line from file
+* ~cape-tex~: Complete unicode char from TeX command, e.g. ~\hbar~,
+* ~cape-sgml~: Complete unicode char from Sgml entity, e.g., ~&alpha~.
+
 * Configuration
 
 Cape is available from MELPA. In the long term some of the Capfs provided by
@@ -55,12 +68,16 @@ this package should be upstreamed into Emacs itself.
            ("C-c p a" . cape-abbrev)
            ("C-c p i" . cape-ispell)
            ("C-c p l" . cape-line)
-           ("C-c p w" . cape-dict))
+           ("C-c p w" . cape-dict)
+           ("C-c p \\" . cape-tex)
+           ("C-c p &" . cape-sgml))
     :init
     ;; Add `completion-at-point-functions', used by `completion-at-point'.
     (add-to-list 'completion-at-point-functions #'cape-file)
+    (add-to-list 'completion-at-point-functions #'cape-tex)
     (add-to-list 'completion-at-point-functions #'cape-dabbrev)
     (add-to-list 'completion-at-point-functions #'cape-keyword)
+    ;;(add-to-list 'completion-at-point-functions #'cape-sgml)
     ;;(add-to-list 'completion-at-point-functions #'cape-abbrev)
     ;;(add-to-list 'completion-at-point-functions #'cape-ispell)
     ;;(add-to-list 'completion-at-point-functions #'cape-dict)
diff --git a/cape.el b/cape.el
index 2cc00bd594..67e6fefcc5 100644
--- a/cape.el
+++ b/cape.el
@@ -567,6 +567,71 @@ If INTERACTIVE is nil the function acts like a capf."
         ,(cape--table-with-properties (cape--dict-words) :category 'cape-dict)
         :exclusive no ,@cape--dict-properties))))
 
+;;;;; cape-tex and cape-sgml
+
+(defmacro cape--quail-define (name method prefix)
+  "Define quail translation variable with NAME.
+METHOD is the input method.
+PREFIX is the prefix regular expression."
+  (describe-input-method method)
+  (let ((capf (intern (format "cape-%s" name)))
+        (list (intern (format "cape--%s-list" name)))
+        (ann (intern (format "cape--%s-annotation" name)))
+        (exit (intern (format "cape--%s-exit" name)))
+        (properties (intern (format "cape--%s-properties" name)))
+        (translation
+         (with-current-buffer "*Help*"
+           (let ((str (replace-regexp-in-string
+                       "\n\n\\(\n\\|.\\)*" ""
+                       (replace-regexp-in-string
+                        "\\`\\(\n\\|.\\)*?----\n" ""
+                        (replace-regexp-in-string
+                         "\\`\\(\n\\|.\\)*?KEY SEQUENCE\n-+\n" ""
+                         (buffer-substring-no-properties (point-min) 
(point-max))))))
+                 (pos 0)
+                 (list nil)
+                 (regexp (format "\\(%s[^ \t\n]+\\)[ \t\n]+\\([^ \t\n]+\\)" 
prefix)))
+             (while (string-match regexp str pos)
+               (let ((char (match-string 2 str))
+                     (name (if (equal method "sgml")
+                               (string-remove-suffix ";" (match-string 1 str))
+                             (match-string 1 str))))
+                 (push (cons name char) list)
+                 (setq pos (match-end 0))))
+             (kill-buffer-and-window)
+             (sort list (lambda (x y) (string< (car x) (car y))))))))
+    `(progn
+       (defvar ,list ',translation)
+       (defun ,ann (name)
+         (concat " " (cdr (assoc name ,list))))
+       (defun ,exit (name status)
+         (unless (eq status 'exact)
+           (when-let (str (cdr (assoc name ,list)))
+             (delete-region (- (point) (length name)) (point))
+             (insert str))))
+       (defvar ,properties
+         (list :annotation-function #',ann
+               :exit-function #',exit
+               :company-kind (lambda (_) 'text)))
+       (defun ,capf (&optional interactive)
+         (interactive (list t))
+         (if interactive
+             ;; NOTE: Disable cycling since replacement breaks it.
+             (let (completion-cycle-threshold)
+               (cape--interactive #',capf))
+           (require 'thingatpt)
+           (let ((bounds (if (thing-at-point-looking-at ,(format "%s[^ \n\t]*" 
prefix))
+                             (cons (match-beginning 0) (match-end 0))
+                           (cons (point) (point)))))
+             (append
+              (list (car bounds) (cdr bounds)
+                    (cape--table-with-properties ,list :category ',capf)
+                    :exclusive 'no)
+              ,properties)))))))
+
+(cape--quail-define tex "TeX" "[\\\\^_]")
+(cape--quail-define sgml "sgml" "&")
+
 ;;;;; cape-abbrev
 
 (defun cape--abbrev-list ()
@@ -583,9 +648,14 @@ If INTERACTIVE is nil the function acts like a capf."
                 (abbrev--symbol abbrev global-abbrev-table)))
            30 0 nil t)))
 
+(defun cape--abbrev-exit (_str status)
+  "Expand expansion if STATUS is not exact."
+   (unless (eq status 'exact)
+     (expand-abbrev)))
+
 (defvar cape--abbrev-properties
   (list :annotation-function #'cape--abbrev-annotation
-        :exit-function (lambda (&rest _) (expand-abbrev))
+        :exit-function #'cape--abbrev-exit
         :company-kind (lambda (_) 'snippet))
   "Completion extra properties for `cape-abbrev'.")
 
@@ -595,7 +665,9 @@ If INTERACTIVE is nil the function acts like a capf."
 If INTERACTIVE is nil the function acts like a capf."
   (interactive (list t))
   (if interactive
-      (cape--interactive #'cape-abbrev)
+      ;; NOTE: Disable cycling since abbreviation replacement breaks it.
+      (let (completion-cycle-threshold)
+        (cape--interactive #'cape-abbrev))
     (when-let (abbrevs (cape--abbrev-list))
       (let ((bounds (cape--bounds 'symbol)))
         `(,(car bounds) ,(cdr bounds)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]