From 60b4a738a2956ad9b5ef803ee4e0e45b5dac28ef Mon Sep 17 00:00:00 2001 From: Konstantin Kharlamov Date: Wed, 6 Nov 2024 02:45:51 +0300 Subject: [PATCH] Migrate `purescript-ds-create-imenu-index` to hashtables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function has implemented a poor man's hash table by manually enlisting keys and then jumping through the hoops by fetching them from one place, converting values to symbols to values… In particular, it was using `symbol-value` to map a symbol to its value, however the symbol was a local variable, and `symbol-value` doesn't work with them under lexical-binding, which the file was converted to since commit 9a9f550. So fix the regression and simplify the code at the same time. Fixes: https://github.com/purescript-emacs/purescript-mode/issues/25 --- purescript-decl-scan.el | 48 +++++++++++++---------------------------- 1 file changed, 15 insertions(+), 33 deletions(-) diff --git a/purescript-decl-scan.el b/purescript-decl-scan.el index b3b61ed..fae1169 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)." @@ -462,11 +463,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 +483,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"))) + (when-let ((curr-alist (gethash (car type) imenu))) + (push (cons (cdr type) + (sort curr-alist 'purescript-ds-imenu-label-cmp)) + index-alist))) + (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))