diff --git a/Makefile b/Makefile index ad2d8c7..91a391c 100644 --- a/Makefile +++ b/Makefile @@ -22,6 +22,7 @@ ELFILES = \ purescript-string.el \ purescript-unicode-input-method.el \ purescript-utils.el \ + purescript-decl-scan.el \ purescript-yas.el ELCFILES = $(ELFILES:.el=.elc) diff --git a/purescript-decl-scan.el b/purescript-decl-scan.el index b3b61ed..7af65b7 100644 --- a/purescript-decl-scan.el +++ b/purescript-decl-scan.el @@ -104,6 +104,7 @@ (require 'syntax) (require 'cl-lib) (require 'imenu) +(require 'subr-x) (defgroup purescript-decl-scan nil "PureScript declaration scanning (`imenu' support)." @@ -453,6 +454,12 @@ positions and the type is one of the symbols \"variable\", \"datatype\", ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Declaration scanning via `imenu'. +(defmacro purescript-when-let (spec &rest body) + "A wrapper to silence `when-let' deprecation warning" + (if (fboundp 'when-let*) + (list 'when-let* spec (macroexp-progn body)) + (with-no-warnings (list 'when-let spec (macroexp-progn body))))) + ;;;###autoload (defun purescript-ds-create-imenu-index () "Function for finding `imenu' declarations in PureScript mode. @@ -462,11 +469,7 @@ datatypes) in a PureScript file for the `imenu' package." ;; These lists are nested using `(INDEX-TITLE . INDEX-ALIST)'. (let* ((bird-literate (purescript-ds-bird-p)) (index-alist '()) - (index-class-alist '()) ;; Classes - (index-var-alist '()) ;; Variables - (index-imp-alist '()) ;; Imports - (index-inst-alist '()) ;; Instances - (index-type-alist '()) ;; Datatypes + (imenu (make-hash-table :test 'equal)) ;; Variables for showing progress. (bufname (buffer-name)) (divisor-of-progress (max 1 (/ (buffer-size) 100))) @@ -486,40 +489,25 @@ datatypes) in a PureScript file for the `imenu' package." (name (car name-posns)) (posns (cdr name-posns)) (start-pos (car posns)) - (type (cdr result)) - ;; Place `(name . start-pos)' in the correct alist. - (sym (cdr (assq type - '((variable . index-var-alist) - (datatype . index-type-alist) - (class . index-class-alist) - (import . index-imp-alist) - (instance . index-inst-alist)))))) - (set sym (cons (cons name start-pos) (symbol-value sym)))))) + (type (cdr result))) + (puthash type + (cons (cons name start-pos) (gethash type imenu '())) + imenu)))) ;; Now sort all the lists, label them, and place them in one list. (message "Sorting declarations in %s..." bufname) - (when index-type-alist - (push (cons "Datatypes" - (sort index-type-alist 'purescript-ds-imenu-label-cmp)) - index-alist)) - (when index-inst-alist - (push (cons "Instances" - (sort index-inst-alist 'purescript-ds-imenu-label-cmp)) - index-alist)) - (when index-imp-alist - (push (cons "Imports" - (sort index-imp-alist 'purescript-ds-imenu-label-cmp)) - index-alist)) - (when index-class-alist - (push (cons "Classes" - (sort index-class-alist 'purescript-ds-imenu-label-cmp)) - index-alist)) - (when index-var-alist + (dolist (type '((datatype . "Datatypes") (instance . "Instances") + (import . "Imports") (class . "Classes"))) + (purescript-when-let ((curr-alist (gethash (car type) imenu))) + (push (cons (cdr type) + (sort curr-alist 'purescript-ds-imenu-label-cmp)) + index-alist))) + (purescript-when-let ((var-alist (gethash 'variable imenu))) (if purescript-decl-scan-bindings-as-variables (push (cons "Variables" - (sort index-var-alist 'purescript-ds-imenu-label-cmp)) + (sort var-alist 'purescript-ds-imenu-label-cmp)) index-alist) (setq index-alist (append index-alist - (sort index-var-alist 'purescript-ds-imenu-label-cmp))))) + (sort var-alist 'purescript-ds-imenu-label-cmp))))) (message "Sorting declarations in %s...done" bufname) ;; Return the alist. index-alist))