Skip to content

Commit b95296a

Browse files
committed
Optimize and simplify haskell-ds-create-imenu-index with hashtable
The function has implemented a poor man's hash table by manually enlisting keys and then using `cl-case` on values. Just replace this with a hashtable and thus simplify the code considerably. This makes it faster as well because the `cl-case + setq` is O(n) whereas `puthash` is O(1). The output of the function was tested on Pandoc's `Writers/Powerpoint/Output.hs` file of 2841 lines and comparing the hashsum of the output before the changes and after. It didn't change. The commit is also basically a backport of a similar change on purescript-mode that has been forked form haskell-mode at some point: purescript-emacs/purescript-mode#27
1 parent 7d4529a commit b95296a

File tree

1 file changed

+13
-41
lines changed

1 file changed

+13
-41
lines changed

Diff for: haskell-decl-scan.el

+13-41
Original file line numberDiff line numberDiff line change
@@ -537,11 +537,7 @@ datatypes) in a Haskell file for the `imenu' package."
537537
;; These lists are nested using `(INDEX-TITLE . INDEX-ALIST)'.
538538
(let* ((bird-literate (haskell-ds-bird-p))
539539
(index-alist '())
540-
(index-class-alist '()) ;; Classes
541-
(index-var-alist '()) ;; Variables
542-
(index-imp-alist '()) ;; Imports
543-
(index-inst-alist '()) ;; Instances
544-
(index-type-alist '()) ;; Datatypes
540+
(imenu (make-hash-table :test 'equal))
545541
;; The result we wish to return.
546542
result)
547543
(goto-char (point-min))
@@ -557,47 +553,23 @@ datatypes) in a Haskell file for the `imenu' package."
557553
(posns (cdr name-posns))
558554
(start-pos (car posns))
559555
(type (cdr result)))
560-
;; Place `(name . start-pos)' in the correct alist.
561-
(cl-case type
562-
(variable
563-
(setq index-var-alist
564-
(cl-acons name start-pos index-var-alist)))
565-
(datatype
566-
(setq index-type-alist
567-
(cl-acons name start-pos index-type-alist)))
568-
(class
569-
(setq index-class-alist
570-
(cl-acons name start-pos index-class-alist)))
571-
(import
572-
(setq index-imp-alist
573-
(cl-acons name start-pos index-imp-alist)))
574-
(instance
575-
(setq index-inst-alist
576-
(cl-acons name start-pos index-inst-alist)))))))
556+
(puthash type
557+
(cons (cons name start-pos) (gethash type imenu '()))
558+
imenu))))
577559
;; Now sort all the lists, label them, and place them in one list.
578-
(when index-type-alist
579-
(push (cons "Datatypes"
580-
(sort index-type-alist 'haskell-ds-imenu-label-cmp))
581-
index-alist))
582-
(when index-inst-alist
583-
(push (cons "Instances"
584-
(sort index-inst-alist 'haskell-ds-imenu-label-cmp))
585-
index-alist))
586-
(when index-imp-alist
587-
(push (cons "Imports"
588-
(sort index-imp-alist 'haskell-ds-imenu-label-cmp))
589-
index-alist))
590-
(when index-class-alist
591-
(push (cons "Classes"
592-
(sort index-class-alist 'haskell-ds-imenu-label-cmp))
593-
index-alist))
594-
(when index-var-alist
560+
(dolist (type '((datatype . "Datatypes") (instance . "Instances")
561+
(import . "Imports") (class . "Classes")))
562+
(when-let* ((curr-alist (gethash (car type) imenu)))
563+
(push (cons (cdr type)
564+
(sort curr-alist 'haskell-ds-imenu-label-cmp))
565+
index-alist)))
566+
(when-let* ((var-alist (gethash 'variable imenu)))
595567
(if haskell-decl-scan-bindings-as-variables
596568
(push (cons "Variables"
597-
(sort index-var-alist 'haskell-ds-imenu-label-cmp))
569+
(sort var-alist 'haskell-ds-imenu-label-cmp))
598570
index-alist)
599571
(setq index-alist (append index-alist
600-
(sort index-var-alist 'haskell-ds-imenu-label-cmp)))))
572+
(sort var-alist 'haskell-ds-imenu-label-cmp)))))
601573
;; Return the alist.
602574
index-alist))
603575

0 commit comments

Comments
 (0)