Created
December 15, 2019 17:59
-
-
Save lawlist/af7b837436688d84124784a372bde5d4 to your computer and use it in GitHub Desktop.
Are the symbols in the current buffer defined?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(require 'cl) | |
;; (global-set-key [f1] 'is-it-defined) | |
(defun is-it-defined () | |
(interactive) | |
(save-excursion | |
(goto-char (point-min)) | |
(let ((output-buffer (get-buffer-create "*IS-IT-DEFINED*")) | |
(cleanup (lambda () | |
(recenter 1) | |
(unless (get-buffer-window output-buffer) | |
(display-buffer output-buffer t))))) | |
(message "is-it-defined: Scanning ...") | |
(with-current-buffer output-buffer | |
(unless truncate-lines | |
(setq truncate-lines t)) | |
(erase-buffer)) | |
(goto-char (point-min)) | |
(while (re-search-forward "[^;\s]+\(\\(defmacro\\|defun\\|defsubst\\|defvar\\|defcustom\\|defconst\\) \\([a-zA-Z]+\\)" nil t) | |
(let ((pt (match-beginning 2)) | |
(type (match-string-no-properties 1))) | |
(goto-char pt) | |
(cond | |
((member type '("defmacro" "defun" "defsubst")) | |
(let ((sym (function-called-at-point))) | |
(if | |
(and | |
(not (memq sym '(defun defmacro defsubst))) | |
(not (null sym))) | |
(with-current-buffer output-buffer | |
(insert type ": " (propertize (format "%s" sym) 'face '(:foreground "orangered")) "\n")) | |
(let ((what (what-is-at-point))) | |
(funcall cleanup) | |
(with-current-buffer output-buffer | |
(insert (format "%s: %s has %s been defined!\n" | |
what | |
(propertize "FUNCTION" 'face '(:foreground "chartreuse")) | |
(propertize "NOT" 'face '(:foreground "orangered"))))))))) | |
((member type '("defvar" "defcustom" "defconst")) | |
(let ((sym (variable-at-point))) | |
(if | |
(and | |
(not (memq sym '(defvar defcustom defconst))) | |
(not (null sym)) | |
(not (and (integerp sym) (= sym 0)))) | |
(with-current-buffer output-buffer | |
(insert type ": " (propertize (format "%s" sym) 'face '(:foreground "darkgreen")) "\n")) | |
(let ((what (what-is-at-point))) | |
(funcall cleanup) | |
(with-current-buffer output-buffer | |
(insert (format "%s: %s has %s been defined!\n" | |
what | |
(propertize "VARIABLE" 'face '(:foreground "chartreuse")) | |
(propertize "NOT" 'face '(:foreground "orangered"))))))))) | |
(t | |
(funcall cleanup) | |
(message "Cannot find anything else: %s" type))))) | |
(funcall cleanup) | |
(message "is-it-defined: Scanning ... done!")))) | |
(defun what-is-at-point () | |
"Return a function around point or else called by the list containing point. | |
If that doesn't give a function, return nil." | |
(let (found) | |
(with-syntax-table emacs-lisp-mode-syntax-table | |
(or (condition-case () | |
(save-excursion | |
(or (not (zerop (skip-syntax-backward "_w"))) | |
(eq (char-syntax (following-char)) ?w) | |
(eq (char-syntax (following-char)) ?_) | |
(forward-sexp -1)) | |
(skip-chars-forward "'") | |
(let ((obj (read (current-buffer)))) | |
(push obj found) | |
(and (symbolp obj) (fboundp obj) obj))) | |
(error nil)) | |
(condition-case () | |
(save-excursion | |
(save-restriction | |
(narrow-to-region (max (point-min) | |
(- (point) 1000)) (point-max)) | |
(if (looking-at "[ \t]") | |
(error "Probably not a Lisp function call")) | |
(let ((obj (read (current-buffer)))) | |
(push obj found) | |
(and (symbolp obj) (fboundp obj) obj)))) | |
(error nil)) | |
(let* ((str (find-tag-default)) | |
(sym (if str (intern-soft str)))) | |
(push sym found) | |
(if (and sym (fboundp sym)) | |
sym | |
(save-match-data | |
(when (and str (string-match "\\`\\W*\\(.*?\\)\\W*\\'" str)) | |
(setq sym (intern-soft (match-string 1 str))) | |
(and (fboundp sym) sym))))) | |
(let ((result (remove-duplicates found :test 'eq :from-end t))) | |
(if (= (length result) 1) | |
(car result) | |
result)))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment