ambevar-dotfiles/.emacs.d/lisp/package-cl-inspect-mode.el

63 lines
2.6 KiB
EmacsLisp

;;; package-cl-inspect-mode.el --- -*- lexical-binding: t -*-
;; TODO: Name? cl-inspect? clinspect? clidget? eclidget?
;; Actually, make it independent of CL.
;; TODO: Better table abstraction?
;; Maybe https://github.com/kiwanami/emacs-ctable?
;; TODO: Add filters.
;; Can we add filters that ask for a column and a range depending on the type of data?
(require 'cl-lib)
(defvar clinspect-column-max-width 40)
(defun clinspect--tabulated-list-sorter (entry index)
"Return a sorter that smarter than `tabulated-list' default.
If ENTRY element at INDEX is a number, sort by number, otherwise sort by string."
(if (numberp (nth index entry))
(lambda (a b)
(< (string-to-number (aref (cadr a) index))
(string-to-number (aref (cadr b) index))))
t))
(defun clinspect--tabulated-list-format (header entries)
(apply #'vector (mapcar (lambda (index)
(let ((column (nth index header)))
(list column
(min clinspect-column-max-width
(max (length column)
(apply #'max (mapcar
(lambda (entry)
(length (prin1-to-string
(nth index entry))))
entries))))
(clinspect--tabulated-list-sorter (car entries) index))))
(number-sequence 0 (1- (length header))))))
(define-derived-mode clinspect-mode tabulated-list-mode "Clinspect"
"Mode to inspect Common Lisp sequences."
(add-hook 'tabulated-list-revert-hook 'tabulated-list-init-header nil t))
(defvar clinspect-buffer-name "clinspector")
(defun clinspect (header data &optional name)
"Inspect DATA.
DATA is a list of things.
HEADER is a list of strings, the column names."
(switch-to-buffer
(generate-new-buffer (format "*%s%s*" clinspect-buffer-name
(if name
(format "<%s>" name)
""))))
(clinspect-mode)
(setq tabulated-list-entries
(cl-loop for line in data
for index from 1 upto (length header)
collect (list index (apply #'vector (mapcar #'prin1-to-string line)))))
(setq tabulated-list-format (clinspect--tabulated-list-format header data))
(tabulated-list-revert))
(provide 'clinspect)