branch: externals/cape
commit 809076d88a4bc99f46266362e9efa3a3d673be3a
Author: Daniel Mendler <m...@daniel-mendler.de>
Commit: Daniel Mendler <m...@daniel-mendler.de>

    Move some of the heavier, rarely used Capfs to separate files
---
 cape-char.el    | 138 ++++++++++++++++++++
 cape-keyword.el | 306 ++++++++++++++++++++++++++++++++++++++++++++
 cape.el         | 387 --------------------------------------------------------
 3 files changed, 444 insertions(+), 387 deletions(-)

diff --git a/cape-char.el b/cape-char.el
new file mode 100644
index 0000000000..4eb65fa401
--- /dev/null
+++ b/cape-char.el
@@ -0,0 +1,138 @@
+;;; cape-char.el --- Character completion functions -*- lexical-binding: t -*-
+
+;; Copyright (C) 2021, 2022  Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; This program is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This package provides the `cape-tex', `cape-sgml' and `cape-rfc1345'
+;; completion functions.
+
+;;; Code:
+
+(require 'cape)
+
+;; Declare as pure function which is evaluated at compile time. We don't use a
+;; macro for this computation since packages like `helpful' will
+;; `macroexpand-all' the expensive `cape-char--define' macro calls.
+(eval-when-compile
+  (defun cape-char--translation (method regexp)
+    "Return character translation hash for METHOD.
+REGEXP is the regular expression matching the names."
+    (declare (pure t))
+    (save-window-excursion
+      (describe-input-method method)
+      (with-current-buffer "*Help*"
+        (let ((lines
+               (split-string
+                (replace-regexp-in-string
+                 "\n\n\\(\n\\|.\\)*" ""
+                 (replace-regexp-in-string
+                  "\\`\\(\n\\|.\\)*?----\n" ""
+                  (replace-regexp-in-string
+                   "\\`\\(\n\\|.\\)*?KEY SEQUENCE\n-+\n" ""
+                   (buffer-string))))
+                "\n"))
+              (hash (make-hash-table :test #'equal)))
+          (dolist (line lines)
+            (let ((beg 0) (len (length line)))
+              (while (< beg len)
+                (let* ((ename (next-single-property-change beg 'face line len))
+                       (echar (next-single-property-change ename 'face line 
len)))
+                  (when (and (get-text-property beg 'face line) (< ename len) 
(<= echar len))
+                    (let ((name (string-trim (substring-no-properties line beg 
ename)))
+                          (char (string-trim (substring-no-properties line 
ename echar))))
+                      (when (and (string-match-p regexp name) (= (length char) 
1))
+                        (puthash name (aref char 0) hash))))
+                  (setq beg echar)))))
+          (kill-buffer)
+          hash)))))
+
+(defmacro cape-char--define (name method &rest prefix)
+  "Define character translation capf.
+NAME is the name of the capf.
+METHOD is the input method.
+PREFIX are the prefix characters."
+  (let ((capf (intern (format "cape-%s" name)))
+        (prefix-required (intern (format "cape-%s-prefix-required" name)))
+        (hash (intern (format "cape--%s-hash" name)))
+        (ann (intern (format "cape--%s-annotation" name)))
+        (docsig (intern (format "cape--%s-docsig" name)))
+        (exit (intern (format "cape--%s-exit" name)))
+        (properties (intern (format "cape--%s-properties" name))))
+    `(progn
+       (defvar ,hash (cape-char--translation
+                      ,method
+                      ,(concat "\\`" (regexp-opt (mapcar #'char-to-string 
prefix)))))
+       (defcustom ,prefix-required t
+         ,(format "Initial prefix is required for `%s' to trigger." capf)
+         :type 'boolean
+         :group 'cape)
+       (defun ,ann (name)
+         (when-let (char (gethash name ,hash))
+           (format " %c" char)))
+       (defun ,docsig (name)
+         (when-let (char (gethash name ,hash))
+           (format "%s (%s)"
+                   (get-char-code-property char 'name)
+                   (char-code-property-description
+                    'general-category
+                    (get-char-code-property char 'general-category)))))
+       (defun ,exit (name status)
+         (unless (eq status 'exact)
+           (when-let (char (gethash name ,hash))
+             (delete-region (max (point-min) (- (point) (length name))) 
(point))
+             (insert (char-to-string char)))))
+       (defvar ,properties
+         (list :annotation-function #',ann
+               :company-docsig #',docsig
+               :exit-function #',exit
+               :company-kind (lambda (_) 'text))
+         ,(format "Completion extra properties for `%s'." name))
+       (defun ,capf (&optional interactive)
+         ,(format "Complete unicode character at point.
+Uses the same input format as the %s input method,
+see (describe-input-method %S). If INTERACTIVE
+is nil the function acts like a capf." method method)
+         (interactive (list t))
+         (if interactive
+             ;; NOTE: Disable cycling since replacement breaks it.
+             (let (completion-cycle-threshold ,prefix-required)
+               (when (memq last-input-event ',prefix)
+                 (self-insert-command 1 last-input-event))
+               (cape--interactive #',capf))
+           (when-let (bounds
+                      (cond
+                       ((thing-at-point-looking-at
+                         ,(concat (regexp-opt (mapcar #'char-to-string 
prefix)) "[^ \n\t]*" ))
+                        (cons (match-beginning 0) (match-end 0)))
+                       ((not ,prefix-required) (cons (point) (point)))))
+             (append
+              (list (car bounds) (cdr bounds)
+                    (cape--table-with-properties ,hash :category ',capf)
+                    :exclusive 'no)
+              ,properties)))))))
+
+;;;###autoload (autoload 'cape-tex "cape-char" nil t)
+;;;###autoload (autoload 'cape-sgml "cape-char" nil t)
+;;;###autoload (autoload 'cape-rfc1345 "cape-char" nil t)
+(cape-char--define tex "TeX" ?\\ ?^ ?_)
+(cape-char--define sgml "sgml" ?&)
+(cape-char--define rfc1345 "rfc1345" ?&)
+
+(provide 'cape-char)
+;;; cape-char.el ends here
diff --git a/cape-keyword.el b/cape-keyword.el
new file mode 100644
index 0000000000..75e8b57fea
--- /dev/null
+++ b/cape-keyword.el
@@ -0,0 +1,306 @@
+;;; cape-keyword.el --- Keyword completion function -*- lexical-binding: t -*-
+
+;; Copyright (C) 2021, 2022  Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; This program is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This package provides the `cape-keyword' completion function.
+
+;;; Code:
+
+(require 'cape)
+
+(defcustom cape-keyword-list
+  ;; This variable was taken from company-keywords.el.
+  ;; Please contribute corrections or additions to both Cape and Company.
+  '((c++-mode ;; https://en.cppreference.com/w/cpp/keyword
+     "alignas" "alignof" "and" "and_eq" "asm" "atomic_cancel" "atomic_commit"
+     "atomic_noexcept" "auto" "bitand" "bitor" "bool" "break" "case" "catch"
+     "char" "char16_t" "char32_t" "char8_t" "class" "co_await" "co_return"
+     "co_yield" "compl" "concept" "const" "const_cast" "consteval" "constexpr"
+     "constinit" "continue" "decltype" "default" "delete" "do" "double"
+     "dynamic_cast" "else" "enum" "explicit" "export" "extern" "false" "final"
+     "float" "for" "friend" "goto" "if" "import" "inline" "int" "long" "module"
+     "mutable" "namespace" "new" "noexcept" "not" "not_eq" "nullptr" "operator"
+     "or" "or_eq" "override" "private" "protected" "public" "reflexpr" 
"register"
+     "reinterpret_cast" "requires" "return" "short" "signed" "sizeof" "static"
+     "static_assert" "static_cast" "struct" "switch" "synchronized" "template"
+     "this" "thread_local" "throw" "true" "try" "typedef" "typeid" "typename"
+     "union" "unsigned" "using" "virtual" "void" "volatile" "wchar_t" "while"
+     "xor" "xor_eq")
+    (c-mode ;; https://en.cppreference.com/w/c/keyword
+     "_Alignas" "_Alignof" "_Atomic" "_Bool" "_Complex" "_Generic" "_Imaginary"
+     "_Noreturn" "_Static_assert" "_Thread_local"
+     "auto" "break" "case" "char" "const" "continue" "default" "do"
+     "double" "else" "enum" "extern" "float" "for" "goto" "if" "inline"
+     "int" "long" "register" "restrict" "return" "short" "signed" "sizeof"
+     "static" "struct" "switch" "typedef" "union" "unsigned" "void" "volatile"
+     "while")
+    (csharp-mode
+     "abstract" "add" "alias" "as" "base" "bool" "break" "byte" "case"
+     "catch" "char" "checked" "class" "const" "continue" "decimal" "default"
+     "delegate" "do" "double" "else" "enum" "event" "explicit" "extern"
+     "false" "finally" "fixed" "float" "for" "foreach" "get" "global" "goto"
+     "if" "implicit" "in" "int" "interface" "internal" "is" "lock" "long"
+     "namespace" "new" "null" "object" "operator" "out" "override" "params"
+     "partial" "private" "protected" "public" "readonly" "ref" "remove"
+     "return" "sbyte" "sealed" "set" "short" "sizeof" "stackalloc" "static"
+     "string" "struct" "switch" "this" "throw" "true" "try" "typeof" "uint"
+     "ulong" "unchecked" "unsafe" "ushort" "using" "value" "var" "virtual"
+     "void" "volatile" "where" "while" "yield")
+    (d-mode ;; http://www.digitalmars.com/d/2.0/lex.html
+     "abstract" "alias" "align" "asm"
+     "assert" "auto" "body" "bool" "break" "byte" "case" "cast" "catch"
+     "cdouble" "cent" "cfloat" "char" "class" "const" "continue" "creal"
+     "dchar" "debug" "default" "delegate" "delete" "deprecated" "do"
+     "double" "else" "enum" "export" "extern" "false" "final" "finally"
+     "float" "for" "foreach" "foreach_reverse" "function" "goto" "idouble"
+     "if" "ifloat" "import" "in" "inout" "int" "interface" "invariant"
+     "ireal" "is" "lazy" "long" "macro" "mixin" "module" "new" "nothrow"
+     "null" "out" "override" "package" "pragma" "private" "protected"
+     "public" "pure" "real" "ref" "return" "scope" "short" "static" "struct"
+     "super" "switch" "synchronized" "template" "this" "throw" "true" "try"
+     "typedef" "typeid" "typeof" "ubyte" "ucent" "uint" "ulong" "union"
+     "unittest" "ushort" "version" "void" "volatile" "wchar" "while" "with")
+    (f90-mode ;; f90.el
+     "abs" "abstract" "achar" "acos" "adjustl" "adjustr" "aimag" "aint"
+     "align" "all" "all_prefix" "all_scatter" "all_suffix" "allocatable"
+     "allocate" "allocated" "and" "anint" "any" "any_prefix" "any_scatter"
+     "any_suffix" "asin" "assign" "assignment" "associate" "associated"
+     "asynchronous" "atan" "atan2" "backspace" "bind" "bit_size" "block"
+     "btest" "c_alert" "c_associated" "c_backspace" "c_bool"
+     "c_carriage_return" "c_char" "c_double" "c_double_complex" "c_f_pointer"
+     "c_f_procpointer" "c_float" "c_float_complex" "c_form_feed" "c_funloc"
+     "c_funptr" "c_horizontal_tab" "c_int" "c_int16_t" "c_int32_t" "c_int64_t"
+     "c_int8_t" "c_int_fast16_t" "c_int_fast32_t" "c_int_fast64_t"
+     "c_int_fast8_t" "c_int_least16_t" "c_int_least32_t" "c_int_least64_t"
+     "c_int_least8_t" "c_intmax_t" "c_intptr_t" "c_loc" "c_long"
+     "c_long_double" "c_long_double_complex" "c_long_long" "c_new_line"
+     "c_null_char" "c_null_funptr" "c_null_ptr" "c_ptr" "c_short"
+     "c_signed_char" "c_size_t" "c_vertical_tab" "call" "case" "ceiling"
+     "char" "character" "character_storage_size" "class" "close" "cmplx"
+     "command_argument_count" "common" "complex" "conjg" "contains" "continue"
+     "copy_prefix" "copy_scatter" "copy_suffix" "cos" "cosh" "count"
+     "count_prefix" "count_scatter" "count_suffix" "cpu_time" "cshift"
+     "cycle" "cyclic" "data" "date_and_time" "dble" "deallocate" "deferred"
+     "digits" "dim" "dimension" "distribute" "do" "dot_product" "double"
+     "dprod" "dynamic" "elemental" "else" "elseif" "elsewhere" "end" "enddo"
+     "endfile" "endif" "entry" "enum" "enumerator" "eoshift" "epsilon" "eq"
+     "equivalence" "eqv" "error_unit" "exit" "exp" "exponent" "extends"
+     "extends_type_of" "external" "extrinsic" "false" "file_storage_size"
+     "final" "floor" "flush" "forall" "format" "fraction" "function" "ge"
+     "generic" "get_command" "get_command_argument" "get_environment_variable"
+     "goto" "grade_down" "grade_up" "gt" "hpf_alignment" "hpf_distribution"
+     "hpf_template" "huge" "iachar" "iall" "iall_prefix" "iall_scatter"
+     "iall_suffix" "iand" "iany" "iany_prefix" "iany_scatter" "iany_suffix"
+     "ibclr" "ibits" "ibset" "ichar" "ieee_arithmetic" "ieee_exceptions"
+     "ieee_features" "ieee_get_underflow_mode" "ieee_set_underflow_mode"
+     "ieee_support_underflow_control" "ieor" "if" "ilen" "implicit"
+     "import" "include" "independent" "index" "inherit" "input_unit"
+     "inquire" "int" "integer" "intent" "interface" "intrinsic" "ior"
+     "iostat_end" "iostat_eor" "iparity" "iparity_prefix" "iparity_scatter"
+     "iparity_suffix" "ishft" "ishftc" "iso_c_binding" "iso_fortran_env"
+     "kind" "lbound" "le" "leadz" "len" "len_trim" "lge" "lgt" "lle" "llt"
+     "log" "log10" "logical" "lt" "matmul" "max" "maxexponent" "maxloc"
+     "maxval" "maxval_prefix" "maxval_scatter" "maxval_suffix" "merge"
+     "min" "minexponent" "minloc" "minval" "minval_prefix" "minval_scatter"
+     "minval_suffix" "mod" "module" "modulo" "move_alloc" "mvbits" "namelist"
+     "ne" "nearest" "neqv" "new" "new_line" "nint" "non_intrinsic"
+     "non_overridable" "none" "nopass" "not" "null" "nullify"
+     "number_of_processors" "numeric_storage_size" "only" "onto" "open"
+     "operator" "optional" "or" "output_unit" "pack" "parameter" "parity"
+     "parity_prefix" "parity_scatter" "parity_suffix" "pass" "pause"
+     "pointer" "popcnt" "poppar" "precision" "present" "print" "private"
+     "procedure" "processors" "processors_shape" "product" "product_prefix"
+     "product_scatter" "product_suffix" "program" "protected" "public"
+     "pure" "radix" "random_number" "random_seed" "range" "read" "real"
+     "realign" "recursive" "redistribute" "repeat" "reshape" "result"
+     "return" "rewind" "rrspacing" "same_type_as" "save" "scale" "scan"
+     "select" "selected_char_kind" "selected_int_kind" "selected_real_kind"
+     "sequence" "set_exponent" "shape" "sign" "sin" "sinh" "size" "spacing"
+     "spread" "sqrt" "stop" "subroutine" "sum" "sum_prefix" "sum_scatter"
+     "sum_suffix" "system_clock" "tan" "tanh" "target" "template" "then"
+     "tiny" "transfer" "transpose" "trim" "true" "type" "ubound" "unpack"
+     "use" "value" "verify" "volatile" "wait" "where" "while" "with" "write")
+    (go-mode ;; https://golang.org/ref/spec#Keywords, 
https://golang.org/pkg/builtin/
+     "append" "bool" "break" "byte" "cap" "case" "chan" "close" "complex" 
"complex128"
+     "complex64" "const" "continue" "copy" "default" "defer" "delete" "else" 
"error"
+     "fallthrough" "false" "float32" "float64" "for" "func" "go" "goto" "if" 
"imag"
+     "import" "int" "int16" "int32" "int64" "int8" "interface" "len" "make"
+     "map" "new" "nil" "package" "panic" "print" "println" "range" "real" 
"recover"
+     "return" "rune" "select" "string" "struct" "switch" "true" "type" "uint" 
"uint16"
+     "uint32" "uint64" "uint8" "uintptr" "var")
+    (java-mode
+     "abstract" "assert" "boolean" "break" "byte" "case" "catch" "char" "class"
+     "continue" "default" "do" "double" "else" "enum" "extends" "final"
+     "finally" "float" "for" "if" "implements" "import" "instanceof" "int"
+     "interface" "long" "native" "new" "package" "private" "protected" "public"
+     "return" "short" "static" "strictfp" "super" "switch" "synchronized"
+     "this" "throw" "throws" "transient" "try" "void" "volatile" "while")
+    (javascript-mode ;; https://tc39.github.io/ecma262/
+     "async" "await" "break" "case" "catch" "class" "const" "continue"
+     "debugger" "default" "delete" "do" "else" "enum" "export" "extends" 
"false"
+     "finally" "for" "function" "if" "import" "in" "instanceof" "let" "new"
+     "null" "return" "static" "super" "switch" "this" "throw" "true" "try"
+     "typeof" "undefined" "var" "void" "while" "with" "yield")
+    (kotlin-mode
+     "abstract" "annotation" "as" "break" "by" "catch" "class" "companion"
+     "const" "constructor" "continue" "data" "do" "else" "enum" "false" "final"
+     "finally" "for" "fun" "if" "import" "in" "init" "inner" "interface"
+     "internal" "is" "lateinit" "nested" "null" "object" "open" "out" 
"override"
+     "package" "private" "protected" "public" "return" "super" "this" "throw"
+     "trait" "true" "try" "typealias" "val" "var" "when" "while")
+    (lua-mode ;; https://www.lua.org/manual/5.3/manual.html
+     "and" "break" "do" "else" "elseif" "end" "false" "for" "function" "goto" 
"if"
+     "in" "local" "nil" "not" "or" "repeat" "return" "then" "true" "until" 
"while")
+    (objc-mode
+     "@catch" "@class" "@encode" "@end" "@finally" "@implementation"
+     "@interface" "@private" "@protected" "@protocol" "@public"
+     "@selector" "@synchronized" "@throw" "@try" "alloc" "autorelease"
+     "bycopy" "byref" "in" "inout" "oneway" "out" "release" "retain")
+    (perl-mode ;; cperl.el
+     "AUTOLOAD" "BEGIN" "CHECK" "CORE" "DESTROY" "END" "INIT" "__END__"
+     "__FILE__" "__LINE__" "abs" "accept" "alarm" "and" "atan2" "bind"
+     "binmode" "bless" "caller" "chdir" "chmod" "chomp" "chop" "chown" "chr"
+     "chroot" "close" "closedir" "cmp" "connect" "continue" "cos"
+     "crypt" "dbmclose" "dbmopen" "defined" "delete" "die" "do" "dump" "each"
+     "else" "elsif" "endgrent" "endhostent" "endnetent" "endprotoent"
+     "endpwent" "endservent" "eof" "eq" "eval" "exec" "exists" "exit" "exp"
+     "fcntl" "fileno" "flock" "for" "foreach" "fork" "format" "formline"
+     "ge" "getc" "getgrent" "getgrgid" "getgrnam" "gethostbyaddr"
+     "gethostbyname" "gethostent" "getlogin" "getnetbyaddr" "getnetbyname"
+     "getnetent" "getpeername" "getpgrp" "getppid" "getpriority"
+     "getprotobyname" "getprotobynumber" "getprotoent" "getpwent" "getpwnam"
+     "getpwuid" "getservbyname" "getservbyport" "getservent" "getsockname"
+     "getsockopt" "glob" "gmtime" "goto" "grep" "gt" "hex" "if" "index" "int"
+     "ioctl" "join" "keys" "kill" "last" "lc" "lcfirst" "le" "length"
+     "link" "listen" "local" "localtime" "lock" "log" "lstat" "lt" "map"
+     "mkdir" "msgctl" "msgget" "msgrcv" "msgsnd" "my" "ne" "next" "no"
+     "not" "oct" "open" "opendir" "or" "ord" "our" "pack" "package" "pipe"
+     "pop" "pos" "print" "printf" "push" "q" "qq" "quotemeta" "qw" "qx"
+     "rand" "read" "readdir" "readline" "readlink" "readpipe" "recv" "redo"
+     "ref" "rename" "require" "reset" "return" "reverse" "rewinddir" "rindex"
+     "rmdir" "scalar" "seek" "seekdir" "select" "semctl" "semget" "semop"
+     "send" "setgrent" "sethostent" "setnetent" "setpgrp" "setpriority"
+     "setprotoent" "setpwent" "setservent" "setsockopt" "shift" "shmctl"
+     "shmget" "shmread" "shmwrite" "shutdown" "sin" "sleep" "socket"
+     "socketpair" "sort" "splice" "split" "sprintf" "sqrt" "srand" "stat"
+     "study" "sub" "substr" "symlink" "syscall" "sysopen" "sysread" "system"
+     "syswrite" "tell" "telldir" "tie" "time" "times" "tr" "truncate" "uc"
+     "ucfirst" "umask" "undef" "unless" "unlink" "unpack" "unshift" "untie"
+     "until" "use" "utime" "values" "vec" "wait" "waitpid"
+     "wantarray" "warn" "while" "write" "x" "xor" "y")
+    (php-mode ;; https://www.php.net/manual/reserved.php
+     "Closure" "Error" "Exception" "Generator" "Throwable" "__CLASS__" 
"__DIR__"
+     "__FILE__" "__FUNCTION__" "__LINE__" "__METHOD__" "__NAMESPACE__"
+     "__TRAIT__" "abstract" "and" "array" "as" "bool" "break" "callable" "case"
+     "catch" "class" "clone" "const" "continue" "declare" "default" "die" "do"
+     "echo" "else" "elseif" "empty" "enddeclare" "endfor" "endforeach" "endif"
+     "endswitch" "endwhile" "enum" "eval" "exit" "extends" "false" "final"
+     "finally" "float" "fn" "for" "foreach" "function" "global" "goto" "if"
+     "implements" "include" "include_once" "instanceof" "insteadof" "interface"
+     "isset" "iterable" "list" "match" "namespace" "new" "null" "object" "or"
+     "print" "private" "protected" "public" "readonly" "require" "require_once"
+     "return" "self" "static" "string" "switch" "this" "throw" "trait" "true"
+     "try" "unset" "use" "var" "void" "while" "xor" "yield" "yield from")
+    (python-mode ;; 
https://docs.python.org/3/reference/lexical_analysis.html#keywords
+     "False" "None" "True" "and" "as" "assert" "break" "class" "continue" "def"
+     "del" "elif" "else" "except" "exec" "finally" "for" "from" "global" "if"
+     "import" "in" "is" "lambda" "nonlocal" "not" "or" "pass" "print" "raise"
+     "return" "try" "while" "with" "yield")
+    (ruby-mode
+     "BEGIN" "END" "alias" "and"  "begin" "break" "case" "class" "def" 
"defined?"
+     "do" "else" "elsif"  "end" "ensure" "false" "for" "if" "in" "module"
+     "next" "nil" "not" "or" "redo" "rescue" "retry" "return" "self" "super"
+     "then" "true" "undef" "unless" "until" "when" "while" "yield")
+    (rust-mode ;; https://doc.rust-lang.org/grammar.html#keywords
+     "Self" "as" "box" "break" "const" "continue" "crate" "else" "enum" 
"extern"
+     "false" "fn" "for" "if" "impl" "in" "let" "loop" "macro" "match" "mod"
+     "move" "mut" "pub" "ref" "return" "self" "static" "struct" "super"
+     "trait" "true" "type" "unsafe" "use" "where" "while")
+    (scala-mode
+     "abstract" "case" "catch" "class" "def" "do" "else" "extends" "false"
+     "final" "finally" "for" "forSome" "if" "implicit" "import" "lazy" "match"
+     "new" "null" "object" "override" "package" "private" "protected"
+     "return" "sealed" "super" "this" "throw" "trait" "true" "try" "type" "val"
+     "var" "while" "with" "yield")
+    (swift-mode
+     "Protocol" "Self" "Type" "and" "as" "assignment" "associatedtype"
+     "associativity" "available" "break" "case" "catch" "class" "column" 
"continue"
+     "convenience" "default" "defer" "deinit" "didSet" "do" "dynamic" 
"dynamicType"
+     "else" "elseif" "endif" "enum" "extension" "fallthrough" "false" "file"
+     "fileprivate" "final" "for" "func" "function" "get" "guard" "higherThan" 
"if"
+     "import" "in" "indirect" "infix" "init" "inout" "internal" "is" "lazy" 
"left"
+     "let" "line" "lowerThan" "mutating" "nil" "none" "nonmutating" "open"
+     "operator" "optional" "override" "postfix" "precedence" "precedencegroup"
+     "prefix" "private" "protocol" "public" "repeat" "required" "rethrows" 
"return"
+     "right" "selector" "self" "set" "static" "struct" "subscript" "super" 
"switch"
+     "throw" "throws" "true" "try" "typealias" "unowned" "var" "weak" "where"
+     "while" "willSet")
+    (julia-mode
+     "abstract" "break" "case" "catch" "const" "continue" "do" "else" "elseif"
+     "end" "eval" "export" "false" "finally" "for" "function" "global" "if"
+     "ifelse" "immutable" "import" "importall" "in" "let" "macro" "module"
+     "otherwise" "quote" "return" "switch" "throw" "true" "try" "type"
+     "typealias" "using" "while")
+    (thrift-mode ;; 
https://github.com/apache/thrift/blob/master/contrib/thrift.el
+     "binary" "bool" "byte" "const" "double" "enum" "exception" "extends"
+     "i16" "i32" "i64" "include" "list" "map" "oneway" "optional" "required"
+     "service" "set" "string" "struct" "throws" "typedef" "void")
+    ;; Aliases
+    (js2-mode javascript-mode)
+    (js2-jsx-mode javascript-mode)
+    (espresso-mode javascript-mode)
+    (js-mode javascript-mode)
+    (js-jsx-mode javascript-mode)
+    (rjsx-mode javascript-mode)
+    (cperl-mode perl-mode)
+    (jde-mode java-mode)
+    (ess-julia-mode julia-mode)
+    (phps-mode php-mode)
+    (enh-ruby-mode ruby-mode))
+  "Alist of major modes and keywords."
+  :type 'alist
+  :group 'cape)
+
+(defun cape--keyword-list ()
+  "Return keywords for current major mode."
+  (when-let (kw (alist-get major-mode cape-keyword-list))
+    (if (symbolp (cadr kw)) (alist-get (cadr kw) cape-keyword-list) kw)))
+
+(defvar cape--keyword-properties
+  (list :annotation-function (lambda (_) " Keyword")
+        :company-kind (lambda (_) 'keyword))
+  "Completion extra properties for `cape-keyword'.")
+
+;;;###autoload
+(defun cape-keyword (&optional interactive)
+  "Complete programming language keyword at point.
+See the variable `cape-keyword-list'.
+If INTERACTIVE is nil the function acts like a capf."
+  (interactive (list t))
+  (if interactive
+      (cape--interactive #'cape-keyword)
+    (when-let (keywords (cape--keyword-list))
+      (let ((bounds (cape--bounds 'symbol)))
+        `(,(car bounds) ,(cdr bounds)
+          ,(cape--table-with-properties keywords :category 'cape-keyword)
+          :exclusive no ,@cape--keyword-properties)))))
+
+(provide 'cape-keyword)
+;;; cape-keyword.el ends here
diff --git a/cape.el b/cape.el
index 941bb5bad3..e3af53ddba 100644
--- a/cape.el
+++ b/cape.el
@@ -89,258 +89,6 @@ The buffers are scanned for completion candidates by 
`cape-line'."
                  (const :tag "Buffers with same major mode" 
cape--buffers-major-mode)
                  (function :tag "Custom function")))
 
-(defcustom cape-keywords
-  ;; This variable was taken from company-keywords.el.
-  ;; Please contribute corrections or additions to both Cape and Company.
-  '((c++-mode ;; https://en.cppreference.com/w/cpp/keyword
-     "alignas" "alignof" "and" "and_eq" "asm" "atomic_cancel" "atomic_commit"
-     "atomic_noexcept" "auto" "bitand" "bitor" "bool" "break" "case" "catch"
-     "char" "char16_t" "char32_t" "char8_t" "class" "co_await" "co_return"
-     "co_yield" "compl" "concept" "const" "const_cast" "consteval" "constexpr"
-     "constinit" "continue" "decltype" "default" "delete" "do" "double"
-     "dynamic_cast" "else" "enum" "explicit" "export" "extern" "false" "final"
-     "float" "for" "friend" "goto" "if" "import" "inline" "int" "long" "module"
-     "mutable" "namespace" "new" "noexcept" "not" "not_eq" "nullptr" "operator"
-     "or" "or_eq" "override" "private" "protected" "public" "reflexpr" 
"register"
-     "reinterpret_cast" "requires" "return" "short" "signed" "sizeof" "static"
-     "static_assert" "static_cast" "struct" "switch" "synchronized" "template"
-     "this" "thread_local" "throw" "true" "try" "typedef" "typeid" "typename"
-     "union" "unsigned" "using" "virtual" "void" "volatile" "wchar_t" "while"
-     "xor" "xor_eq")
-    (c-mode ;; https://en.cppreference.com/w/c/keyword
-     "_Alignas" "_Alignof" "_Atomic" "_Bool" "_Complex" "_Generic" "_Imaginary"
-     "_Noreturn" "_Static_assert" "_Thread_local"
-     "auto" "break" "case" "char" "const" "continue" "default" "do"
-     "double" "else" "enum" "extern" "float" "for" "goto" "if" "inline"
-     "int" "long" "register" "restrict" "return" "short" "signed" "sizeof"
-     "static" "struct" "switch" "typedef" "union" "unsigned" "void" "volatile"
-     "while")
-    (csharp-mode
-     "abstract" "add" "alias" "as" "base" "bool" "break" "byte" "case"
-     "catch" "char" "checked" "class" "const" "continue" "decimal" "default"
-     "delegate" "do" "double" "else" "enum" "event" "explicit" "extern"
-     "false" "finally" "fixed" "float" "for" "foreach" "get" "global" "goto"
-     "if" "implicit" "in" "int" "interface" "internal" "is" "lock" "long"
-     "namespace" "new" "null" "object" "operator" "out" "override" "params"
-     "partial" "private" "protected" "public" "readonly" "ref" "remove"
-     "return" "sbyte" "sealed" "set" "short" "sizeof" "stackalloc" "static"
-     "string" "struct" "switch" "this" "throw" "true" "try" "typeof" "uint"
-     "ulong" "unchecked" "unsafe" "ushort" "using" "value" "var" "virtual"
-     "void" "volatile" "where" "while" "yield")
-    (d-mode ;; http://www.digitalmars.com/d/2.0/lex.html
-     "abstract" "alias" "align" "asm"
-     "assert" "auto" "body" "bool" "break" "byte" "case" "cast" "catch"
-     "cdouble" "cent" "cfloat" "char" "class" "const" "continue" "creal"
-     "dchar" "debug" "default" "delegate" "delete" "deprecated" "do"
-     "double" "else" "enum" "export" "extern" "false" "final" "finally"
-     "float" "for" "foreach" "foreach_reverse" "function" "goto" "idouble"
-     "if" "ifloat" "import" "in" "inout" "int" "interface" "invariant"
-     "ireal" "is" "lazy" "long" "macro" "mixin" "module" "new" "nothrow"
-     "null" "out" "override" "package" "pragma" "private" "protected"
-     "public" "pure" "real" "ref" "return" "scope" "short" "static" "struct"
-     "super" "switch" "synchronized" "template" "this" "throw" "true" "try"
-     "typedef" "typeid" "typeof" "ubyte" "ucent" "uint" "ulong" "union"
-     "unittest" "ushort" "version" "void" "volatile" "wchar" "while" "with")
-    (f90-mode ;; f90.el
-     "abs" "abstract" "achar" "acos" "adjustl" "adjustr" "aimag" "aint"
-     "align" "all" "all_prefix" "all_scatter" "all_suffix" "allocatable"
-     "allocate" "allocated" "and" "anint" "any" "any_prefix" "any_scatter"
-     "any_suffix" "asin" "assign" "assignment" "associate" "associated"
-     "asynchronous" "atan" "atan2" "backspace" "bind" "bit_size" "block"
-     "btest" "c_alert" "c_associated" "c_backspace" "c_bool"
-     "c_carriage_return" "c_char" "c_double" "c_double_complex" "c_f_pointer"
-     "c_f_procpointer" "c_float" "c_float_complex" "c_form_feed" "c_funloc"
-     "c_funptr" "c_horizontal_tab" "c_int" "c_int16_t" "c_int32_t" "c_int64_t"
-     "c_int8_t" "c_int_fast16_t" "c_int_fast32_t" "c_int_fast64_t"
-     "c_int_fast8_t" "c_int_least16_t" "c_int_least32_t" "c_int_least64_t"
-     "c_int_least8_t" "c_intmax_t" "c_intptr_t" "c_loc" "c_long"
-     "c_long_double" "c_long_double_complex" "c_long_long" "c_new_line"
-     "c_null_char" "c_null_funptr" "c_null_ptr" "c_ptr" "c_short"
-     "c_signed_char" "c_size_t" "c_vertical_tab" "call" "case" "ceiling"
-     "char" "character" "character_storage_size" "class" "close" "cmplx"
-     "command_argument_count" "common" "complex" "conjg" "contains" "continue"
-     "copy_prefix" "copy_scatter" "copy_suffix" "cos" "cosh" "count"
-     "count_prefix" "count_scatter" "count_suffix" "cpu_time" "cshift"
-     "cycle" "cyclic" "data" "date_and_time" "dble" "deallocate" "deferred"
-     "digits" "dim" "dimension" "distribute" "do" "dot_product" "double"
-     "dprod" "dynamic" "elemental" "else" "elseif" "elsewhere" "end" "enddo"
-     "endfile" "endif" "entry" "enum" "enumerator" "eoshift" "epsilon" "eq"
-     "equivalence" "eqv" "error_unit" "exit" "exp" "exponent" "extends"
-     "extends_type_of" "external" "extrinsic" "false" "file_storage_size"
-     "final" "floor" "flush" "forall" "format" "fraction" "function" "ge"
-     "generic" "get_command" "get_command_argument" "get_environment_variable"
-     "goto" "grade_down" "grade_up" "gt" "hpf_alignment" "hpf_distribution"
-     "hpf_template" "huge" "iachar" "iall" "iall_prefix" "iall_scatter"
-     "iall_suffix" "iand" "iany" "iany_prefix" "iany_scatter" "iany_suffix"
-     "ibclr" "ibits" "ibset" "ichar" "ieee_arithmetic" "ieee_exceptions"
-     "ieee_features" "ieee_get_underflow_mode" "ieee_set_underflow_mode"
-     "ieee_support_underflow_control" "ieor" "if" "ilen" "implicit"
-     "import" "include" "independent" "index" "inherit" "input_unit"
-     "inquire" "int" "integer" "intent" "interface" "intrinsic" "ior"
-     "iostat_end" "iostat_eor" "iparity" "iparity_prefix" "iparity_scatter"
-     "iparity_suffix" "ishft" "ishftc" "iso_c_binding" "iso_fortran_env"
-     "kind" "lbound" "le" "leadz" "len" "len_trim" "lge" "lgt" "lle" "llt"
-     "log" "log10" "logical" "lt" "matmul" "max" "maxexponent" "maxloc"
-     "maxval" "maxval_prefix" "maxval_scatter" "maxval_suffix" "merge"
-     "min" "minexponent" "minloc" "minval" "minval_prefix" "minval_scatter"
-     "minval_suffix" "mod" "module" "modulo" "move_alloc" "mvbits" "namelist"
-     "ne" "nearest" "neqv" "new" "new_line" "nint" "non_intrinsic"
-     "non_overridable" "none" "nopass" "not" "null" "nullify"
-     "number_of_processors" "numeric_storage_size" "only" "onto" "open"
-     "operator" "optional" "or" "output_unit" "pack" "parameter" "parity"
-     "parity_prefix" "parity_scatter" "parity_suffix" "pass" "pause"
-     "pointer" "popcnt" "poppar" "precision" "present" "print" "private"
-     "procedure" "processors" "processors_shape" "product" "product_prefix"
-     "product_scatter" "product_suffix" "program" "protected" "public"
-     "pure" "radix" "random_number" "random_seed" "range" "read" "real"
-     "realign" "recursive" "redistribute" "repeat" "reshape" "result"
-     "return" "rewind" "rrspacing" "same_type_as" "save" "scale" "scan"
-     "select" "selected_char_kind" "selected_int_kind" "selected_real_kind"
-     "sequence" "set_exponent" "shape" "sign" "sin" "sinh" "size" "spacing"
-     "spread" "sqrt" "stop" "subroutine" "sum" "sum_prefix" "sum_scatter"
-     "sum_suffix" "system_clock" "tan" "tanh" "target" "template" "then"
-     "tiny" "transfer" "transpose" "trim" "true" "type" "ubound" "unpack"
-     "use" "value" "verify" "volatile" "wait" "where" "while" "with" "write")
-    (go-mode ;; https://golang.org/ref/spec#Keywords, 
https://golang.org/pkg/builtin/
-     "append" "bool" "break" "byte" "cap" "case" "chan" "close" "complex" 
"complex128"
-     "complex64" "const" "continue" "copy" "default" "defer" "delete" "else" 
"error"
-     "fallthrough" "false" "float32" "float64" "for" "func" "go" "goto" "if" 
"imag"
-     "import" "int" "int16" "int32" "int64" "int8" "interface" "len" "make"
-     "map" "new" "nil" "package" "panic" "print" "println" "range" "real" 
"recover"
-     "return" "rune" "select" "string" "struct" "switch" "true" "type" "uint" 
"uint16"
-     "uint32" "uint64" "uint8" "uintptr" "var")
-    (java-mode
-     "abstract" "assert" "boolean" "break" "byte" "case" "catch" "char" "class"
-     "continue" "default" "do" "double" "else" "enum" "extends" "final"
-     "finally" "float" "for" "if" "implements" "import" "instanceof" "int"
-     "interface" "long" "native" "new" "package" "private" "protected" "public"
-     "return" "short" "static" "strictfp" "super" "switch" "synchronized"
-     "this" "throw" "throws" "transient" "try" "void" "volatile" "while")
-    (javascript-mode ;; https://tc39.github.io/ecma262/
-     "async" "await" "break" "case" "catch" "class" "const" "continue"
-     "debugger" "default" "delete" "do" "else" "enum" "export" "extends" 
"false"
-     "finally" "for" "function" "if" "import" "in" "instanceof" "let" "new"
-     "null" "return" "static" "super" "switch" "this" "throw" "true" "try"
-     "typeof" "undefined" "var" "void" "while" "with" "yield")
-    (kotlin-mode
-     "abstract" "annotation" "as" "break" "by" "catch" "class" "companion"
-     "const" "constructor" "continue" "data" "do" "else" "enum" "false" "final"
-     "finally" "for" "fun" "if" "import" "in" "init" "inner" "interface"
-     "internal" "is" "lateinit" "nested" "null" "object" "open" "out" 
"override"
-     "package" "private" "protected" "public" "return" "super" "this" "throw"
-     "trait" "true" "try" "typealias" "val" "var" "when" "while")
-    (lua-mode ;; https://www.lua.org/manual/5.3/manual.html
-     "and" "break" "do" "else" "elseif" "end" "false" "for" "function" "goto" 
"if"
-     "in" "local" "nil" "not" "or" "repeat" "return" "then" "true" "until" 
"while")
-    (objc-mode
-     "@catch" "@class" "@encode" "@end" "@finally" "@implementation"
-     "@interface" "@private" "@protected" "@protocol" "@public"
-     "@selector" "@synchronized" "@throw" "@try" "alloc" "autorelease"
-     "bycopy" "byref" "in" "inout" "oneway" "out" "release" "retain")
-    (perl-mode ;; cperl.el
-     "AUTOLOAD" "BEGIN" "CHECK" "CORE" "DESTROY" "END" "INIT" "__END__"
-     "__FILE__" "__LINE__" "abs" "accept" "alarm" "and" "atan2" "bind"
-     "binmode" "bless" "caller" "chdir" "chmod" "chomp" "chop" "chown" "chr"
-     "chroot" "close" "closedir" "cmp" "connect" "continue" "cos"
-     "crypt" "dbmclose" "dbmopen" "defined" "delete" "die" "do" "dump" "each"
-     "else" "elsif" "endgrent" "endhostent" "endnetent" "endprotoent"
-     "endpwent" "endservent" "eof" "eq" "eval" "exec" "exists" "exit" "exp"
-     "fcntl" "fileno" "flock" "for" "foreach" "fork" "format" "formline"
-     "ge" "getc" "getgrent" "getgrgid" "getgrnam" "gethostbyaddr"
-     "gethostbyname" "gethostent" "getlogin" "getnetbyaddr" "getnetbyname"
-     "getnetent" "getpeername" "getpgrp" "getppid" "getpriority"
-     "getprotobyname" "getprotobynumber" "getprotoent" "getpwent" "getpwnam"
-     "getpwuid" "getservbyname" "getservbyport" "getservent" "getsockname"
-     "getsockopt" "glob" "gmtime" "goto" "grep" "gt" "hex" "if" "index" "int"
-     "ioctl" "join" "keys" "kill" "last" "lc" "lcfirst" "le" "length"
-     "link" "listen" "local" "localtime" "lock" "log" "lstat" "lt" "map"
-     "mkdir" "msgctl" "msgget" "msgrcv" "msgsnd" "my" "ne" "next" "no"
-     "not" "oct" "open" "opendir" "or" "ord" "our" "pack" "package" "pipe"
-     "pop" "pos" "print" "printf" "push" "q" "qq" "quotemeta" "qw" "qx"
-     "rand" "read" "readdir" "readline" "readlink" "readpipe" "recv" "redo"
-     "ref" "rename" "require" "reset" "return" "reverse" "rewinddir" "rindex"
-     "rmdir" "scalar" "seek" "seekdir" "select" "semctl" "semget" "semop"
-     "send" "setgrent" "sethostent" "setnetent" "setpgrp" "setpriority"
-     "setprotoent" "setpwent" "setservent" "setsockopt" "shift" "shmctl"
-     "shmget" "shmread" "shmwrite" "shutdown" "sin" "sleep" "socket"
-     "socketpair" "sort" "splice" "split" "sprintf" "sqrt" "srand" "stat"
-     "study" "sub" "substr" "symlink" "syscall" "sysopen" "sysread" "system"
-     "syswrite" "tell" "telldir" "tie" "time" "times" "tr" "truncate" "uc"
-     "ucfirst" "umask" "undef" "unless" "unlink" "unpack" "unshift" "untie"
-     "until" "use" "utime" "values" "vec" "wait" "waitpid"
-     "wantarray" "warn" "while" "write" "x" "xor" "y")
-    (php-mode ;; https://www.php.net/manual/reserved.php
-     "Closure" "Error" "Exception" "Generator" "Throwable" "__CLASS__" 
"__DIR__"
-     "__FILE__" "__FUNCTION__" "__LINE__" "__METHOD__" "__NAMESPACE__"
-     "__TRAIT__" "abstract" "and" "array" "as" "bool" "break" "callable" "case"
-     "catch" "class" "clone" "const" "continue" "declare" "default" "die" "do"
-     "echo" "else" "elseif" "empty" "enddeclare" "endfor" "endforeach" "endif"
-     "endswitch" "endwhile" "enum" "eval" "exit" "extends" "false" "final"
-     "finally" "float" "fn" "for" "foreach" "function" "global" "goto" "if"
-     "implements" "include" "include_once" "instanceof" "insteadof" "interface"
-     "isset" "iterable" "list" "match" "namespace" "new" "null" "object" "or"
-     "print" "private" "protected" "public" "readonly" "require" "require_once"
-     "return" "self" "static" "string" "switch" "this" "throw" "trait" "true"
-     "try" "unset" "use" "var" "void" "while" "xor" "yield" "yield from")
-    (python-mode ;; 
https://docs.python.org/3/reference/lexical_analysis.html#keywords
-     "False" "None" "True" "and" "as" "assert" "break" "class" "continue" "def"
-     "del" "elif" "else" "except" "exec" "finally" "for" "from" "global" "if"
-     "import" "in" "is" "lambda" "nonlocal" "not" "or" "pass" "print" "raise"
-     "return" "try" "while" "with" "yield")
-    (ruby-mode
-     "BEGIN" "END" "alias" "and"  "begin" "break" "case" "class" "def" 
"defined?"
-     "do" "else" "elsif"  "end" "ensure" "false" "for" "if" "in" "module"
-     "next" "nil" "not" "or" "redo" "rescue" "retry" "return" "self" "super"
-     "then" "true" "undef" "unless" "until" "when" "while" "yield")
-    (rust-mode ;; https://doc.rust-lang.org/grammar.html#keywords
-     "Self" "as" "box" "break" "const" "continue" "crate" "else" "enum" 
"extern"
-     "false" "fn" "for" "if" "impl" "in" "let" "loop" "macro" "match" "mod"
-     "move" "mut" "pub" "ref" "return" "self" "static" "struct" "super"
-     "trait" "true" "type" "unsafe" "use" "where" "while")
-    (scala-mode
-     "abstract" "case" "catch" "class" "def" "do" "else" "extends" "false"
-     "final" "finally" "for" "forSome" "if" "implicit" "import" "lazy" "match"
-     "new" "null" "object" "override" "package" "private" "protected"
-     "return" "sealed" "super" "this" "throw" "trait" "true" "try" "type" "val"
-     "var" "while" "with" "yield")
-    (swift-mode
-     "Protocol" "Self" "Type" "and" "as" "assignment" "associatedtype"
-     "associativity" "available" "break" "case" "catch" "class" "column" 
"continue"
-     "convenience" "default" "defer" "deinit" "didSet" "do" "dynamic" 
"dynamicType"
-     "else" "elseif" "endif" "enum" "extension" "fallthrough" "false" "file"
-     "fileprivate" "final" "for" "func" "function" "get" "guard" "higherThan" 
"if"
-     "import" "in" "indirect" "infix" "init" "inout" "internal" "is" "lazy" 
"left"
-     "let" "line" "lowerThan" "mutating" "nil" "none" "nonmutating" "open"
-     "operator" "optional" "override" "postfix" "precedence" "precedencegroup"
-     "prefix" "private" "protocol" "public" "repeat" "required" "rethrows" 
"return"
-     "right" "selector" "self" "set" "static" "struct" "subscript" "super" 
"switch"
-     "throw" "throws" "true" "try" "typealias" "unowned" "var" "weak" "where"
-     "while" "willSet")
-    (julia-mode
-     "abstract" "break" "case" "catch" "const" "continue" "do" "else" "elseif"
-     "end" "eval" "export" "false" "finally" "for" "function" "global" "if"
-     "ifelse" "immutable" "import" "importall" "in" "let" "macro" "module"
-     "otherwise" "quote" "return" "switch" "throw" "true" "try" "type"
-     "typealias" "using" "while")
-    (thrift-mode ;; 
https://github.com/apache/thrift/blob/master/contrib/thrift.el
-     "binary" "bool" "byte" "const" "double" "enum" "exception" "extends"
-     "i16" "i32" "i64" "include" "list" "map" "oneway" "optional" "required"
-     "service" "set" "string" "struct" "throws" "typedef" "void")
-    ;; Aliases
-    (js2-mode javascript-mode)
-    (js2-jsx-mode javascript-mode)
-    (espresso-mode javascript-mode)
-    (js-mode javascript-mode)
-    (js-jsx-mode javascript-mode)
-    (rjsx-mode javascript-mode)
-    (cperl-mode perl-mode)
-    (jde-mode java-mode)
-    (ess-julia-mode julia-mode)
-    (phps-mode php-mode)
-    (enh-ruby-mode ruby-mode))
-  "Alist of major modes and keywords."
-  :type 'alist)
-
 ;;;; Helpers
 
 (defmacro cape--silent (&rest body)
@@ -608,115 +356,6 @@ 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, cape-sgml, cape-rfc1345
-
-;; Declare as pure function which is evaluated at compile time. We don't use a
-;; macro for this computation since packages like `helpful' will
-;; `macroexpand-all' the expensive `cape--define-char' macro calls.
-(eval-when-compile
-  (defun cape--char-translation (method regexp)
-    "Return character translation hash for METHOD.
-REGEXP is the regular expression matching the names."
-    (declare (pure t))
-    (save-window-excursion
-      (describe-input-method method)
-      (with-current-buffer "*Help*"
-        (let ((lines
-               (split-string
-                (replace-regexp-in-string
-                 "\n\n\\(\n\\|.\\)*" ""
-                 (replace-regexp-in-string
-                  "\\`\\(\n\\|.\\)*?----\n" ""
-                  (replace-regexp-in-string
-                   "\\`\\(\n\\|.\\)*?KEY SEQUENCE\n-+\n" ""
-                   (buffer-string))))
-                "\n"))
-              (hash (make-hash-table :test #'equal)))
-          (dolist (line lines)
-            (let ((beg 0) (len (length line)))
-              (while (< beg len)
-                (let* ((ename (next-single-property-change beg 'face line len))
-                       (echar (next-single-property-change ename 'face line 
len)))
-                  (when (and (get-text-property beg 'face line) (< ename len) 
(<= echar len))
-                    (let ((name (string-trim (substring-no-properties line beg 
ename)))
-                          (char (string-trim (substring-no-properties line 
ename echar))))
-                      (when (and (string-match-p regexp name) (= (length char) 
1))
-                        (puthash name (aref char 0) hash))))
-                  (setq beg echar)))))
-          (kill-buffer)
-          hash)))))
-
-(defmacro cape--char-define (name method &rest prefix)
-  "Define character translation capf.
-NAME is the name of the capf.
-METHOD is the input method.
-PREFIX are the prefix characters."
-  (let ((capf (intern (format "cape-%s" name)))
-        (prefix-required (intern (format "cape-%s-prefix-required" name)))
-        (hash (intern (format "cape--%s-hash" name)))
-        (ann (intern (format "cape--%s-annotation" name)))
-        (docsig (intern (format "cape--%s-docsig" name)))
-        (exit (intern (format "cape--%s-exit" name)))
-        (properties (intern (format "cape--%s-properties" name))))
-    `(progn
-       (defvar ,hash (cape--char-translation
-                      ,method
-                      ,(concat "\\`" (regexp-opt (mapcar #'char-to-string 
prefix)))))
-       (defcustom ,prefix-required t
-         ,(format "Initial prefix is required for `%s' to trigger." capf)
-         :type 'boolean)
-       (defun ,ann (name)
-         (when-let (char (gethash name ,hash))
-           (format " %c" char)))
-       (defun ,docsig (name)
-         (when-let (char (gethash name ,hash))
-           (format "%s (%s)"
-                   (get-char-code-property char 'name)
-                   (char-code-property-description
-                    'general-category
-                    (get-char-code-property char 'general-category)))))
-       (defun ,exit (name status)
-         (unless (eq status 'exact)
-           (when-let (char (gethash name ,hash))
-             (delete-region (max (point-min) (- (point) (length name))) 
(point))
-             (insert (char-to-string char)))))
-       (defvar ,properties
-         (list :annotation-function #',ann
-               :company-docsig #',docsig
-               :exit-function #',exit
-               :company-kind (lambda (_) 'text))
-         ,(format "Completion extra properties for `%s'." name))
-       (defun ,capf (&optional interactive)
-         ,(format "Complete unicode character at point.
-Uses the same input format as the %s input method,
-see (describe-input-method %S). If INTERACTIVE
-is nil the function acts like a capf." method method)
-         (interactive (list t))
-         (if interactive
-             ;; NOTE: Disable cycling since replacement breaks it.
-             (let (completion-cycle-threshold ,prefix-required)
-               (when (memq last-input-event ',prefix)
-                 (self-insert-command 1 last-input-event))
-               (cape--interactive #',capf))
-           (when-let (bounds
-                      (cond
-                       ((thing-at-point-looking-at
-                         ,(concat (regexp-opt (mapcar #'char-to-string 
prefix)) "[^ \n\t]*" ))
-                        (cons (match-beginning 0) (match-end 0)))
-                       ((not ,prefix-required) (cons (point) (point)))))
-             (append
-              (list (car bounds) (cdr bounds)
-                    (cape--table-with-properties ,hash :category ',capf)
-                    :exclusive 'no)
-              ,properties)))))))
-
-;;;###autoload (autoload 'cape-tex "cape" nil t)
-;;;###autoload (autoload 'cape-sgml "cape" nil t)
-;;;###autoload (autoload 'cape-rfc1345 "cape" nil t)
-(cape--char-define tex "TeX" ?\\ ?^ ?_)
-(cape--char-define sgml "sgml" ?&)
-(cape--char-define rfc1345 "rfc1345" ?&)
-
 ;;;;; cape-abbrev
 
 (defun cape--abbrev-tables ()
@@ -768,32 +407,6 @@ If INTERACTIVE is nil the function acts like a capf."
           ,(cape--table-with-properties abbrevs :category 'cape-abbrev)
           :exclusive no ,@cape--abbrev-properties)))))
 
-;;;;; cape-keyword
-
-(defun cape--keyword-list ()
-  "Return keywords for current major mode."
-  (when-let (kw (alist-get major-mode cape-keywords))
-    (if (symbolp (cadr kw)) (alist-get (cadr kw) cape-keywords) kw)))
-
-(defvar cape--keyword-properties
-  (list :annotation-function (lambda (_) " Keyword")
-        :company-kind (lambda (_) 'keyword))
-  "Completion extra properties for `cape-keyword'.")
-
-;;;###autoload
-(defun cape-keyword (&optional interactive)
-  "Complete programming language keyword at point.
-See the variable `cape-keywords'.
-If INTERACTIVE is nil the function acts like a capf."
-  (interactive (list t))
-  (if interactive
-      (cape--interactive #'cape-keyword)
-    (when-let (keywords (cape--keyword-list))
-      (let ((bounds (cape--bounds 'symbol)))
-        `(,(car bounds) ,(cdr bounds)
-          ,(cape--table-with-properties keywords :category 'cape-keyword)
-          :exclusive no ,@cape--keyword-properties)))))
-
 ;;;;; cape-line
 
 (defvar cape--line-properties nil

Reply via email to