helm-apropos
is indeed pretty slow. I think it comes from joining 5
very large lists:
helm-apropos-function-list
;; =>
;; (helm-def-source--emacs-commands
;; helm-def-source--emacs-functions
;; helm-def-source--eieio-classes
;; helm-def-source--eieio-generic
;; helm-def-source--emacs-variables
;; helm-def-source--emacs-faces
;; helm-def-source--helm-attributes)
You can speed it up by generating one huge list right off the bat:
(defun helm-fast-apropos ()
(interactive)
(helm :sources
'((name . "apropos: ")
(candidates .
(lambda ()
(all-completions "" obarray
(lambda (x)
(or
;; commands
(commandp x)
;; functions
(fboundp x)
;; EIEIO class
(class-p x)
;; EIEIO generic
(generic-p x)
;; variable
(and (boundp x) (not (keywordp x))))))))
(action . (lambda (x)
(setq x (intern x))
(cond ((boundp x)
(describe-variable x))
((fboundp x)
(describe-function x))))))))
I also just had a quick look at the ivy equivalent of the above,
I think it's around 0.2s faster:
(defun ivy-apropos ()
(interactive)
(ivy-read "apropos: "
(all-completions "" obarray
(lambda (x)
(or
;; commands
(commandp x)
;; functions
(fboundp x)
;; EIEIO class
(class-p x)
;; EIEIO generic
(generic-p x)
;; variable
(and (boundp x) (not (keywordp x))))))
:keymap counsel-describe-map
:preselect (counsel-symbol-at-point)
:action (lambda (x)
(setq x (intern x))
(cond ((boundp x)
(describe-variable x))
((fboundp x)
(describe-function x))))))
Edit: typical approach for caching
Very simple: store the whole collection into a variable, and hope that it doesn't need to be recomputed;
recompute manually when needed (usually, when new packages are loaded):
(defvar helm-fast-apropos-cache nil)
(defun helm-update-apropos-cache ()
(interactive)
(setq helm-fast-apropos-cache
(all-completions "" obarray
(lambda (x)
(or
;; commands
(commandp x)
;; functions
(fboundp x)
;; EIEIO class
(class-p x)
;; EIEIO generic
(generic-p x)
;; variable
(and (boundp x) (not (keywordp x))))))))
(defun helm-fast-apropos ()
(interactive)
(helm :sources
(quote ((name . "apropos: ")
(candidates .
(lambda ()
(or helm-fast-apropos-cache
(helm-update-apropos-cache))))
(action . (lambda (x)
(setq x (intern x))
(cond ((boundp x)
(describe-variable x))
((fboundp x)
(describe-function x)))))))))
This approach saves only fraction of a second in this case, so it might not be worth it.