;;; -*- lexical-binding: t -*- ;; ;; ----------------------------------------------------------------------------- ;; https://dataswamp.org/~incal/emacs-init/ll/meta.el ;; ----------------------------------------------------------------------------- (require 'cl-lib) (defun meta--count-list (l) (cl-loop with res with done for e in l do (unless (member e done) (push (list (cl-count e l :test #'equal) e) res) (push e done)) finally return (cl-sort res #'>= :key #'car))) (defun meta--result-list (l) (cl-loop with biggest = (length (number-to-string (caar l))) with num-len = (length (number-to-string (length l))) with longest = (apply #'max (cl-mapcar (lambda (e) (length (cadr e))) l)) for (j lib) in l for i from 1 for str = (concat str (format (concat (format "%%%dd. " num-len) (format "%%-%ds " longest) (format "%%%dd" biggest) "\n") i lib j)) finally (insert "\n" str))) (defun meta--funs (&optional n pred label) (or n (setq n 20)) (or pred (setq pred #'functionp)) (or label (setq label (symbol-name pred))) (let ((num 0) (libs) (str) (dash) (par)) (mapatoms (lambda (e) (when (funcall pred e) (setq str (symbol-name e)) (setq dash (string-match "-" str)) (setq par (string-match "(" str)) (unless par (cl-incf num) (when dash (push (substring str 0 dash) libs)))))) (let ((buf (get-buffer-create "*emeta*"))) (with-current-buffer buf (insert (format "%s%s: %d\n" (if (= (point-min) (point-max)) "" "\n") label num)) (let* ((clst (meta--count-list libs)) (len (length clst))) (meta--result-list (cl-subseq clst 0 (min n (1- len))))) (pop-to-buffer buf) (if noninteractive (message (buffer-substring-no-properties (point-min) (point-max)) buf)))))) (defun meta-report (&optional n) (let ((n (or n 16))) (meta--funs n nil "functions") (meta--funs n #'boundp "variables") (meta--funs n #'facep "faces")) (pop-to-buffer "*emeta*")) ;; (meta-report) (provide 'meta)