(setq res nil))))
res))
+(defun completion-at-point-function-with-frecency-sorting
+ (capf &optional num-ts)
+ (let ((cache (make-hash-table :test #'equal))
+ (num-ts (or num-ts 64)))
+ (lambda ()
+ (let ((res (ignore-errors (funcall capf))))
+ (and (consp res)
+ (not (functionp res))
+ (seq-let (beg end table &rest plist) res
+ (let* ((pred (plist-get plist :predicate))
+ (completion-extra-properties plist)
+ (md (completion-metadata (buffer-substring beg end) table pred))
+ (sf (completion-metadata-get md 'sort-function)))
+ `( ,beg ,end
+ ,(completion-table-with-metadata
+ table
+ `((sort-function
+ . ,(lambda (completions)
+ (sort (if sf (funcall sf completions) completions)
+ :key (let ((now (float-time)))
+ (lambda (c)
+ (if-let ((ts (gethash c cache)))
+ (- (log (- now (car ts))) (length ts))
+ 1.0e+INF)))
+ :in-place t)))))
+ ,@(plist-put
+ (copy-sequence plist)
+ :exit-function
+ (lambda (str _sts)
+ (let* ((str (substring-no-properties str))
+ (ts (gethash str cache)))
+ (setf (gethash str cache)
+ (cons (float-time) (take num-ts ts))))))))))))))
+
(defun completion-at-point ()
"Perform completion on the text around point.
The completion method is determined by `completion-at-point-functions'."
(setq-local project-vc-external-roots-function #'elisp-load-path-roots)
(setq-local syntax-propertize-function #'elisp-mode-syntax-propertize)
(add-hook 'completion-at-point-functions
- #'elisp-completion-at-point nil 'local)
+ #'elisp-capf nil 'local)
(add-hook 'flymake-diagnostic-functions #'elisp-flymake-checkdoc nil t)
(add-hook 'flymake-diagnostic-functions
#'elisp-flymake-byte-compile nil t)
(defun elisp--shorthand-aware-boundp (sym)
(boundp (intern-soft (symbol-name sym))))
+(defun elisp--sort-completions (completions)
+ (sort completions
+ (lambda (l r)
+ (let ((li (string-match "--" l))
+ (ri (string-match "--" r)))
+ (if li
+ (and ri
+ (or (< (length l) (length r))
+ (and (= (length l) (length r))
+ (string< l r))))
+ (or ri
+ (< (length l) (length r))
+ (and (= (length l) (length r))
+ (string< l r))))))))
+
(defun elisp-completion-at-point ()
(with-syntax-table emacs-lisp-mode-syntax-table
(when-let ((pos (point))
(beg-end (bounds-of-thing-at-point 'symbol))
(beg (car beg-end))
(end (cdr beg-end)))
- (list beg end (elisp--completion-local-symbols) :predicate predicate :exclusive 'no))))
+ (list beg end (elisp--completion-local-symbols)
+ :predicate predicate :exclusive 'no
+ :sort-function #'elisp--sort-completions))))
+
+(defalias 'elisp-capf
+ (completion-at-point-function-with-frecency-sorting
+ #'elisp-completion-at-point))
(defun elisp--company-kind (str)
(let ((sym (intern-soft str)))